From a6bbec2b56f4a07f408bf3213b3b15fa6fc10330 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Wed, 11 Nov 2009 09:32:05 +0100 Subject: [PATCH] Added symbols for property declarations. --- src/libs/cplusplus/CheckUndefinedSymbols.cpp | 13 ++++ src/libs/cplusplus/CheckUndefinedSymbols.h | 1 + src/shared/cplusplus/AST.h | 3 + .../cplusplus/CPlusPlusForwardDeclarations.h | 1 + src/shared/cplusplus/CheckDeclaration.cpp | 77 ++++++++++--------- src/shared/cplusplus/Control.cpp | 12 +++ src/shared/cplusplus/Control.h | 3 + src/shared/cplusplus/Symbol.cpp | 3 +- src/shared/cplusplus/Symbol.h | 5 ++ src/shared/cplusplus/SymbolVisitor.h | 1 + src/shared/cplusplus/Symbols.cpp | 19 +++++ src/shared/cplusplus/Symbols.h | 69 +++++++++++++++++ 12 files changed, 171 insertions(+), 36 deletions(-) diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp index 7ea1748e648..5d996579eed 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp +++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp @@ -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; +} diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.h b/src/libs/cplusplus/CheckUndefinedSymbols.h index fbdca0f94ec..4a13b6ee2dc 100644 --- a/src/libs/cplusplus/CheckUndefinedSymbols.h +++ b/src/libs/cplusplus/CheckUndefinedSymbols.h @@ -96,6 +96,7 @@ protected: virtual bool visit(ObjCClassDeclarationAST *ast); virtual bool visit(ObjCProtocolRefsAST *ast); + virtual bool visit(ObjCPropertyDeclarationAST *ast); private: Document::Ptr _doc; diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index aec40834751..2a1c2d6ef03 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2391,6 +2391,9 @@ public: unsigned rparen_token; DeclarationAST *simple_declaration; +public: // annotations + List<ObjCPropertyDeclaration *> *symbols; + public: virtual ObjCPropertyDeclarationAST *asObjCPropertyDeclaration() { return this; } diff --git a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h index 9616f51780d..c21d0bbd0e3 100644 --- a/src/shared/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/shared/cplusplus/CPlusPlusForwardDeclarations.h @@ -130,6 +130,7 @@ class ObjCForwardClassDeclaration; class ObjCProtocol; class ObjCForwardProtocolDeclaration; class ObjCMethod; +class ObjCPropertyDeclaration; } // end of namespace CPlusPlus diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp index 728e87385d8..04ee291aef5 100644 --- a/src/shared/cplusplus/CheckDeclaration.cpp +++ b/src/shared/cplusplus/CheckDeclaration.cpp @@ -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; } - - diff --git a/src/shared/cplusplus/Control.cpp b/src/shared/cplusplus/Control.cpp index 249d671ae17..d2b91e14a2b 100644 --- a/src/shared/cplusplus/Control.cpp +++ b/src/shared/cplusplus/Control.cpp @@ -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; } diff --git a/src/shared/cplusplus/Control.h b/src/shared/cplusplus/Control.h index d4db273e431..6abeb8ef6d0 100644 --- a/src/shared/cplusplus/Control.h +++ b/src/shared/cplusplus/Control.h @@ -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; diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp index 6cd6573aa6a..e8b80fdcae9 100644 --- a/src/shared/cplusplus/Symbol.cpp +++ b/src/shared/cplusplus/Symbol.cpp @@ -488,4 +488,5 @@ bool Symbol::isObjCForwardProtocolDeclaration() const bool Symbol::isObjCMethod() const { return asObjCMethod() != 0; } - +bool Symbol::isObjCPropertyDeclaration() const +{ return asObjCPropertyDeclaration() != 0; } diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h index 93d730b0cfb..61abe02c7e1 100644 --- a/src/shared/cplusplus/Symbol.h +++ b/src/shared/cplusplus/Symbol.h @@ -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; diff --git a/src/shared/cplusplus/SymbolVisitor.h b/src/shared/cplusplus/SymbolVisitor.h index 4bfa3794308..0e6440b750c 100644 --- a/src/shared/cplusplus/SymbolVisitor.h +++ b/src/shared/cplusplus/SymbolVisitor.h @@ -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 diff --git a/src/shared/cplusplus/Symbols.cpp b/src/shared/cplusplus/Symbols.cpp index 8ddaf3ef5dd..819c8730ed5 100644 --- a/src/shared/cplusplus/Symbols.cpp +++ b/src/shared/cplusplus/Symbols.cpp @@ -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)) { + } +} diff --git a/src/shared/cplusplus/Symbols.h b/src/shared/cplusplus/Symbols.h index acd13085f5b..88d8d521cda 100644 --- a/src/shared/cplusplus/Symbols.h +++ b/src/shared/cplusplus/Symbols.h @@ -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 -- GitLab