Commit a6bbec2b authored by Erik Verbruggen's avatar Erik Verbruggen

Added symbols for property declarations.

parent 72d4493f
......@@ -518,3 +518,16 @@ bool CheckUndefinedSymbols::visit(ObjCProtocolRefsAST *ast)
return false;
}
bool CheckUndefinedSymbols::visit(ObjCPropertyDeclarationAST *ast)
{
for (List<ObjCPropertyDeclaration *> *iter = ast->symbols; iter; iter = iter->next) {
if (Name *getterName = iter->value->getterName())
; // FIXME: resolve the symbol for the name, and check its signature.
if (Name *setterName = iter->value->setterName())
; // FIXME: resolve the symbol for the name, and check its signature.
}
return false;
}
......@@ -96,6 +96,7 @@ protected:
virtual bool visit(ObjCClassDeclarationAST *ast);
virtual bool visit(ObjCProtocolRefsAST *ast);
virtual bool visit(ObjCPropertyDeclarationAST *ast);
private:
Document::Ptr _doc;
......
......@@ -2391,6 +2391,9 @@ public:
unsigned rparen_token;
DeclarationAST *simple_declaration;
public: // annotations
List<ObjCPropertyDeclaration *> *symbols;
public:
virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return this; }
......
......@@ -130,6 +130,7 @@ class ObjCForwardClassDeclaration;
class ObjCProtocol;
class ObjCForwardProtocolDeclaration;
class ObjCMethod;
class ObjCPropertyDeclaration;
} // end of namespace CPlusPlus
......
......@@ -682,21 +682,6 @@ bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast)
return false;
}
enum PropertyAttributes {
None = 0,
Assign = 1 << 0,
Retain = 1 << 1,
Copy = 1 << 2,
ReadOnly = 1 << 3,
ReadWrite = 1 << 4,
Getter = 1 << 5,
Setter = 1 << 6,
NonAtomic = 1 << 7,
WritabilityMask = ReadOnly | ReadWrite,
SetterSemanticsMask = Assign | Retain | Copy,
};
bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
int &flags,
int attr)
......@@ -714,7 +699,17 @@ bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst,
bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
{
int propAttrs = None;
semantic()->check(ast->simple_declaration, _scope);
SimpleDeclarationAST *simpleDecl = ast->simple_declaration->asSimpleDeclaration();
if (!simpleDecl) {
translationUnit()->warning(ast->simple_declaration->firstToken(),
"invalid type for property declaration");
return false;
}
int propAttrs = ObjCPropertyDeclaration::None;
Name *getterName = 0, *setterName = 0;
for (ObjCPropertyAttributeListAST *iter= ast->property_attribute_list; iter; iter = iter->next) {
ObjCPropertyAttributeAST *attrAst = iter->value;
......@@ -723,45 +718,57 @@ bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast)
Identifier *attrId = identifier(attrAst->attribute_identifier_token);
if (attrId == control()->objcGetterId()) {
if (checkPropertyAttribute(attrAst, propAttrs, Getter)) {
// TODO: find method declaration for getter
if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Getter)) {
getterName = semantic()->check(attrAst->method_selector, _scope);
}
} else if (attrId == control()->objcSetterId()) {
if (checkPropertyAttribute(attrAst, propAttrs, Setter)) {
// TODO: find method declaration for setter
if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Setter)) {
setterName = semantic()->check(attrAst->method_selector, _scope);
}
} else if (attrId == control()->objcReadwriteId()) {
checkPropertyAttribute(attrAst, propAttrs, ReadWrite);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadWrite);
} else if (attrId == control()->objcReadonlyId()) {
checkPropertyAttribute(attrAst, propAttrs, ReadOnly);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadOnly);
} else if (attrId == control()->objcAssignId()) {
checkPropertyAttribute(attrAst, propAttrs, Assign);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Assign);
} else if (attrId == control()->objcRetainId()) {
checkPropertyAttribute(attrAst, propAttrs, Retain);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Retain);
} else if (attrId == control()->objcCopyId()) {
checkPropertyAttribute(attrAst, propAttrs, Copy);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Copy);
} else if (attrId == control()->objcNonatomicId()) {
checkPropertyAttribute(attrAst, propAttrs, NonAtomic);
checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::NonAtomic);
}
}
if (propAttrs & ReadOnly && propAttrs & ReadWrite)
if (propAttrs & ObjCPropertyDeclaration::ReadOnly &&
propAttrs & ObjCPropertyDeclaration::ReadWrite)
// Should this be an error instead of only a warning?
translationUnit()->warning(ast->property_token,
"property can have at most one attribute \"readonly\" or \"readwrite\" specified");
int setterSemAttrs = propAttrs & SetterSemanticsMask;
int setterSemAttrs = propAttrs & ObjCPropertyDeclaration::SetterSemanticsMask;
if (setterSemAttrs
&& setterSemAttrs != Assign
&& setterSemAttrs != Retain
&& setterSemAttrs != Copy) {
&& setterSemAttrs != ObjCPropertyDeclaration::Assign
&& setterSemAttrs != ObjCPropertyDeclaration::Retain
&& setterSemAttrs != ObjCPropertyDeclaration::Copy) {
// Should this be an error instead of only a warning?
translationUnit()->warning(ast->property_token,
"property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified");
}
// TODO: Check if the next line is correct (EV)
semantic()->check(ast->simple_declaration, _scope);
List<ObjCPropertyDeclaration *> **lastSymbols = &ast->symbols;
for (List<Declaration*> *iter = simpleDecl->symbols; iter; iter = iter->next) {
ObjCPropertyDeclaration *propDecl = control()->newObjCPropertyDeclaration(ast->firstToken(),
iter->value->name());
propDecl->setType(iter->value->type());
propDecl->setAttributes(propAttrs);
propDecl->setGetterName(getterName);
propDecl->setSetterName(setterName);
_scope->enterSymbol(propDecl);
*lastSymbols = new (translationUnit()->memoryPool()) List<ObjCPropertyDeclaration *>();
(*lastSymbols)->value = propDecl;
lastSymbols = &(*lastSymbols)->next;
}
return false;
}
......@@ -129,6 +129,7 @@ public:
delete_array_entries(objcForwardClassDeclarations);
delete_array_entries(objcForwardProtocolDeclarations);
delete_array_entries(objcMethods);
delete_array_entries(objcPropertyDeclarations);
}
NameId *findOrInsertNameId(Identifier *id)
......@@ -393,6 +394,13 @@ public:
return method;
}
ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name)
{
ObjCPropertyDeclaration *decl = new ObjCPropertyDeclaration(translationUnit, sourceLocation, name);
objcPropertyDeclarations.push_back(decl);
return decl;
}
Enum *newEnum(unsigned sourceLocation, Name *name)
{
Enum *e = new Enum(translationUnit,
......@@ -577,6 +585,7 @@ public:
std::vector<ObjCForwardClassDeclaration *> objcForwardClassDeclarations;
std::vector<ObjCForwardProtocolDeclaration *> objcForwardProtocolDeclarations;
std::vector<ObjCMethod *> objcMethods;
std::vector<ObjCPropertyDeclaration *> objcPropertyDeclarations;
// ObjC context keywords:
Identifier *objcGetterId;
......@@ -787,6 +796,9 @@ ObjCForwardProtocolDeclaration *Control::newObjCForwardProtocolDeclaration(unsig
ObjCMethod *Control::newObjCMethod(unsigned sourceLocation, Name *name)
{ return d->newObjCMethod(sourceLocation, name); }
ObjCPropertyDeclaration *Control::newObjCPropertyDeclaration(unsigned sourceLocation, Name *name)
{ return d->newObjCPropertyDeclaration(sourceLocation, name); }
Identifier *Control::objcGetterId() const
{ return d->objcGetterId; }
......
......@@ -169,6 +169,9 @@ public:
/// Creates a new Objective-C method symbol.
ObjCMethod *newObjCMethod(unsigned sourceLocation, Name *name = 0);
/// Creates a new Objective-C @property declaration symbol.
ObjCPropertyDeclaration *newObjCPropertyDeclaration(unsigned sourceLocation, Name *name);
// Objective-C specific context keywords.
Identifier *objcGetterId() const;
Identifier *objcSetterId() const;
......
......@@ -488,4 +488,5 @@ bool Symbol::isObjCForwardProtocolDeclaration() const
bool Symbol::isObjCMethod() const
{ return asObjCMethod() != 0; }
bool Symbol::isObjCPropertyDeclaration() const
{ return asObjCPropertyDeclaration() != 0; }
......@@ -228,6 +228,9 @@ public:
/// Returns true if this Symbol is an Objective-C method declaration.
bool isObjCMethod() const;
/// Returns true if this Symbol is an Objective-C @property declaration.
bool isObjCPropertyDeclaration() const;
virtual const ScopedSymbol *asScopedSymbol() const { return 0; }
virtual const Enum *asEnum() const { return 0; }
virtual const Function *asFunction() const { return 0; }
......@@ -247,6 +250,7 @@ public:
virtual const ObjCProtocol *asObjCProtocol() const { return 0; }
virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return 0; }
virtual const ObjCMethod *asObjCMethod() const { return 0; }
virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return 0; }
virtual ScopedSymbol *asScopedSymbol() { return 0; }
virtual Enum *asEnum() { return 0; }
......@@ -267,6 +271,7 @@ public:
virtual ObjCProtocol *asObjCProtocol() { return 0; }
virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return 0; }
virtual ObjCMethod *asObjCMethod() { return 0; }
virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return 0; }
/// Returns this Symbol's type.
virtual FullySpecifiedType type() const = 0;
......
......@@ -88,6 +88,7 @@ public:
virtual bool visit(ObjCProtocol *) { return true; }
virtual bool visit(ObjCForwardProtocolDeclaration *) { return true; }
virtual bool visit(ObjCMethod *) { return true; }
virtual bool visit(ObjCPropertyDeclaration *) { return true; }
};
} // end of namespace CPlusPlus
......
......@@ -820,4 +820,23 @@ void ObjCMethod::visitSymbol0(SymbolVisitor *visitor)
}
}
ObjCPropertyDeclaration::ObjCPropertyDeclaration(TranslationUnit *translationUnit,
unsigned sourceLocation,
Name *name):
Symbol(translationUnit, sourceLocation, name),
_propertyAttributes(None),
_getterName(0),
_setterName(0)
{}
ObjCPropertyDeclaration::~ObjCPropertyDeclaration()
{}
FullySpecifiedType ObjCPropertyDeclaration::type() const
{ return _type; }
void ObjCPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor)
{
if (visitor->visit(this)) {
}
}
......@@ -729,6 +729,75 @@ private:
Scope *_arguments;
};
class CPLUSPLUS_EXPORT ObjCPropertyDeclaration: public Symbol
{
public:
enum PropertyAttributes {
None = 0,
Assign = 1 << 0,
Retain = 1 << 1,
Copy = 1 << 2,
ReadOnly = 1 << 3,
ReadWrite = 1 << 4,
Getter = 1 << 5,
Setter = 1 << 6,
NonAtomic = 1 << 7,
WritabilityMask = ReadOnly | ReadWrite,
SetterSemanticsMask = Assign | Retain | Copy,
};
public:
ObjCPropertyDeclaration(TranslationUnit *translationUnit,
unsigned sourceLocation,
Name *name);
virtual ~ObjCPropertyDeclaration();
bool hasAttribute(int attribute) const
{ return _propertyAttributes & attribute; }
void setAttributes(int attributes)
{ _propertyAttributes = attributes; }
bool hasGetter() const
{ return hasAttribute(Getter); }
bool hasSetter() const
{ return hasAttribute(Setter); }
Name *getterName() const
{ return _getterName; }
void setGetterName(Name *getterName)
{ _getterName = getterName; }
Name *setterName() const
{ return _setterName; }
void setSetterName(Name *setterName)
{ _setterName = setterName; }
void setType(const FullySpecifiedType &type)
{ _type = type; }
// Symbol's interface
virtual FullySpecifiedType type() const;
virtual const ObjCPropertyDeclaration *asOObjCPropertyDeclaration() const
{ return this; }
virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration()
{ return this; }
protected:
virtual void visitSymbol0(SymbolVisitor *visitor);
private:
FullySpecifiedType _type;
int _propertyAttributes;
Name *_getterName, *_setterName;
};
} // end of namespace CPlusPlus
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment