From: Fariborz Jahanian Date: Tue, 6 Nov 2007 22:01:00 +0000 (+0000) Subject: Patch for objc2's property ASTs, as well as pretty-priting the ASTs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=82a5fe3d1cf204b672cdab24d72275b6ad2c3527;p=clang Patch for objc2's property ASTs, as well as pretty-priting the ASTs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/Decl.cpp b/AST/Decl.cpp index 5187982757..3cfe4aeed9 100644 --- a/AST/Decl.cpp +++ b/AST/Decl.cpp @@ -36,6 +36,7 @@ static unsigned nIvarDecls = 0; static unsigned nObjcImplementationDecls = 0; static unsigned nObjcCategoryImpl = 0; static unsigned nObjcCompatibleAlias = 0; +static unsigned nObjcPropertyDecl = 0; static bool StatSwitch = false; @@ -146,6 +147,10 @@ void Decl::PrintStats() { nObjcCompatibleAlias, (int)sizeof(ObjcCompatibleAliasDecl), int(nObjcCompatibleAlias*sizeof(ObjcCompatibleAliasDecl))); + fprintf(stderr, " %d property decls, %d each (%d bytes)\n", + nObjcPropertyDecl, (int)sizeof(ObjcPropertyDecl), + int(nObjcPropertyDecl*sizeof(ObjcPropertyDecl))); + fprintf(stderr, "Total bytes = %d\n", int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+ nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+ @@ -215,6 +220,9 @@ void Decl::addDeclKind(const Kind k) { case CompatibleAlias: nObjcCompatibleAlias++; break; + case PropertyDecl: + nObjcPropertyDecl++; + break; } } diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 04c238287a..3c07c37077 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -103,10 +103,78 @@ static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) { fprintf(stderr, "\t%s %s;\n", Ivars[i]->getType().getAsString().c_str(), Ivars[i]->getName()); } - fprintf(stderr, "}\n@end\n"); + fprintf(stderr, "}\n"); } - else - fprintf(stderr,"@end\n"); + + int NumProperties = OID->getNumPropertyDecl(); + if (NumProperties > 0) { + for (int i = 0; i < NumProperties; i++) { + ObjcPropertyDecl *PDecl = OID->getPropertyDecl()[i]; + fprintf(stderr, "@property"); + if (PDecl->getPropertyAttributes() != ObjcPropertyDecl::OBJC_PR_noattr) { + bool first = true; + fprintf(stderr, " ("); + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readonly) + { + fprintf(stderr, "%creadonly", first ? ' ' : ','); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_getter) + { + fprintf(stderr, "%cgetter = %s", first ? ' ' : ',' + , PDecl->getGetterName()->getName()); + first = false; + } + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_setter) + { + fprintf(stderr, "%csetter = %s:", first ? ' ' : ',' + , PDecl->getSetterName()->getName()); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_assign) + { + fprintf(stderr, "%cassign", first ? ' ' : ','); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_readwrite) + { + fprintf(stderr, "%creadwrite", first ? ' ' : ','); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_retain) + { + fprintf(stderr, "%cretain", first ? ' ' : ','); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_copy) + { + fprintf(stderr, "%ccopy", first ? ' ' : ','); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjcPropertyDecl::OBJC_PR_nonatomic) + { + fprintf(stderr, "%cnonatomic", first ? ' ' : ','); + first = false; + } + fprintf(stderr, " )"); + } + ObjcIvarDecl **IDecl = PDecl->getPropertyDecls(); + fprintf(stderr, " %s %s", IDecl[0]->getType().getAsString().c_str(), + IDecl[0]->getName()); + + for (int j = 1; j < PDecl->getNumPropertyDecls(); j++) { + fprintf(stderr, ", %s", IDecl[j]->getName()); + } + fprintf(stderr, ";\n"); + } + } + fprintf(stderr,"@end\n"); // FIXME: implement the rest... } diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index 6464ca18c9..4290fc5044 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -225,6 +225,7 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, tok::ObjCKeywordKind contextKey) { llvm::SmallVector allMethods; + llvm::SmallVector allProperties; tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; SourceLocation AtEndLoc; @@ -247,7 +248,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, if (contextKey != tok::objc_protocol) Diag(AtLoc, diag::err_objc_protocol_optional); } else if (ocKind == tok::objc_property) { - ParseObjCPropertyDecl(interfaceDecl); + allProperties.push_back(ParseObjCPropertyDecl(interfaceDecl, AtLoc)); continue; } else { Diag(Tok, diag::err_objc_illegal_interface_qual); @@ -277,7 +278,9 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, /// This action is executed even if we don't have any methods (so the @end /// can be recorded properly). Actions.ActOnAddMethodsToObjcDecl(CurScope, interfaceDecl, &allMethods[0], - allMethods.size(), AtEndLoc); + allMethods.size(), + &allProperties[0], allProperties.size(), + AtEndLoc); } /// Parse property attribute declarations. @@ -296,7 +299,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl, /// copy /// nonatomic /// -void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) { +void Parser::ParseObjCPropertyAttribute (ObjcDeclSpec &DS) { SourceLocation loc = ConsumeParen(); // consume '(' while (isObjCPropertyAttribute()) { const IdentifierInfo *II = Tok.getIdentifierInfo(); @@ -309,6 +312,8 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) { loc = ConsumeToken(); if (Tok.is(tok::identifier)) { if (II == ObjcPropertyAttrs[objc_setter]) { + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_setter); + DS.setSetterName(Tok.getIdentifierInfo()); loc = ConsumeToken(); // consume method name if (Tok.isNot(tok::colon)) { Diag(loc, diag::err_expected_colon); @@ -316,6 +321,10 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) { break; } } + else { + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_getter); + DS.setGetterName(Tok.getIdentifierInfo()); + } } else { Diag(loc, diag::err_expected_ident); @@ -329,6 +338,20 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) { break; } } + + else if (II == ObjcPropertyAttrs[objc_readonly]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_readonly); + else if (II == ObjcPropertyAttrs[objc_assign]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_assign); + else if (II == ObjcPropertyAttrs[objc_readwrite]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_readwrite); + else if (II == ObjcPropertyAttrs[objc_retain]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_retain); + else if (II == ObjcPropertyAttrs[objc_copy]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_copy); + else if (II == ObjcPropertyAttrs[objc_nonatomic]) + DS.setPropertyAttributes(ObjcDeclSpec::DQ_PR_nonatomic); + ConsumeToken(); // consume last attribute token if (Tok.is(tok::comma)) { loc = ConsumeToken(); @@ -352,17 +375,19 @@ void Parser::ParseObjCPropertyAttribute (DeclTy *interfaceDecl) { /// /// @property property-attr-decl[opt] property-component-decl ';' /// -void Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl) { +Parser::DeclTy *Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl, + SourceLocation AtLoc) { assert(Tok.isObjCAtKeyword(tok::objc_property) && "ParseObjCPropertyDecl(): Expected @property"); + ObjcDeclSpec DS; ConsumeToken(); // the "property" identifier // Parse property attribute list, if any. if (Tok.is(tok::l_paren)) { // property has attribute list. - ParseObjCPropertyAttribute(0/*FIXME*/); + ParseObjCPropertyAttribute(DS); } // Parse declaration portion of @property. - llvm::SmallVector PropertyDecls; + llvm::SmallVector PropertyDecls; ParseStructDeclaration(interfaceDecl, PropertyDecls); if (Tok.is(tok::semi)) ConsumeToken(); @@ -370,6 +395,8 @@ void Parser::ParseObjCPropertyDecl(DeclTy *interfaceDecl) { Diag(Tok, diag::err_expected_semi_decl_list); SkipUntil(tok::r_brace, true, true); } + return Actions.ActOnAddObjcProperties(AtLoc, + &PropertyDecls[0], PropertyDecls.size(), DS); } /// objc-method-proto: @@ -919,6 +946,7 @@ Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) { /// Insert collected methods declarations into the @interface object. Actions.ActOnAddMethodsToObjcDecl(CurScope, ObjcImpDecl, &AllImplMethods[0], AllImplMethods.size(), + (DeclTy **)0, 0, atLoc); ObjcImpDecl = 0; AllImplMethods.clear(); diff --git a/Sema/Sema.h b/Sema/Sema.h index f6aa5b18dc..01ac1e4a14 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -531,8 +531,14 @@ public: virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl, DeclTy **allMethods, unsigned allNum, + DeclTy **allProperties, unsigned pNum, SourceLocation AtEndLoc); + virtual DeclTy *ActOnAddObjcProperties(SourceLocation AtLoc, + DeclTy **allProperties, + unsigned NumProperties, + ObjcDeclSpec &DS); + virtual DeclTy *ActOnMethodDeclaration( SourceLocation BeginLoc, // location of the + or -. SourceLocation EndLoc, // location of the ; or {. diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 7eec3b0093..4892847e73 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1916,6 +1916,7 @@ void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) { void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, DeclTy **allMethods, unsigned allNum, + DeclTy **allProperties, unsigned pNum, SourceLocation AtEndLoc) { Decl *ClassDecl = static_cast(classDecl); @@ -1931,11 +1932,19 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, llvm::DenseMap InsMap; llvm::DenseMap ClsMap; - bool checkDuplicateMethods = + bool isInterfaceDeclKind = (isa(ClassDecl) || isa(ClassDecl) || isa(ClassDecl)); bool checkIdenticalMethods = isa(ClassDecl); + // TODO: property declaration in category and protocols. + if (pNum != 0 && isa(ClassDecl)) { + ObjcPropertyDecl **properties = new ObjcPropertyDecl*[pNum]; + memcpy(properties, allProperties, pNum*sizeof(ObjcPropertyDecl*)); + dyn_cast(ClassDecl)->setPropertyDecls(properties); + dyn_cast(ClassDecl)->setNumPropertyDecl(pNum); + } + for (unsigned i = 0; i < allNum; i++ ) { ObjcMethodDecl *Method = cast_or_null(static_cast(allMethods[i])); @@ -1946,7 +1955,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, const ObjcMethodDecl *&PrevMethod = InsMap[Method->getSelector()]; bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) : false; - if (checkDuplicateMethods && PrevMethod && !match + if (isInterfaceDeclKind && PrevMethod && !match || checkIdenticalMethods && match) { Diag(Method->getLocation(), diag::error_duplicate_method_decl, Method->getSelector().getName()); @@ -1963,7 +1972,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, const ObjcMethodDecl *&PrevMethod = ClsMap[Method->getSelector()]; bool match = PrevMethod ? MatchTwoMethodDeclarations(Method, PrevMethod) : false; - if (checkDuplicateMethods && PrevMethod && !match + if (isInterfaceDeclKind && PrevMethod && !match || checkIdenticalMethods && match) { Diag(Method->getLocation(), diag::error_duplicate_method_decl, Method->getSelector().getName()); @@ -2077,6 +2086,47 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( return ObjcMethod; } +Sema::DeclTy *Sema::ActOnAddObjcProperties(SourceLocation AtLoc, + DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) { + ObjcPropertyDecl *PDecl = new ObjcPropertyDecl(AtLoc); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readonly) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readonly); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_getter) { + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_getter); + PDecl->setGetterName(DS.getGetterName()); + } + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_setter) { + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_setter); + PDecl->setSetterName(DS.getSetterName()); + } + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_assign) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_assign); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_readwrite) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_readwrite); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_retain) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_retain); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_copy) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_copy); + + if(DS.getPropertyAttributes() & ObjcDeclSpec::DQ_PR_nonatomic) + PDecl->setPropertyAttributes(ObjcPropertyDecl::OBJC_PR_nonatomic); + + PDecl->setNumPropertyDecls(NumProperties); + if (NumProperties != 0) { + ObjcIvarDecl **properties = new ObjcIvarDecl*[NumProperties]; + memcpy(properties, allProperties, NumProperties*sizeof(ObjcIvarDecl*)); + PDecl->setPropertyDecls(properties); + } + return PDecl; +} + Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, DeclTy *lastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 008901d85d..d38187645c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -48,6 +48,7 @@ public: ObjcCategoryImpl, ObjcImplementation, ObjcProtocol, + PropertyDecl, // ScopedDecl CompatibleAlias, // TypeDecl diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 8c8a1a4ecb..2a9c40df8d 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -26,6 +26,7 @@ class ObjcIvarDecl; class ObjcMethodDecl; class ObjcProtocolDecl; class ObjcCategoryDecl; +class ObjcPropertyDecl; /// ObjcInterfaceDecl - Represents an ObjC class declaration. For example: /// @@ -71,6 +72,10 @@ class ObjcInterfaceDecl : public TypeDecl { /// List of categories defined for this class. ObjcCategoryDecl *CategoryList; + + /// class properties + ObjcPropertyDecl **PropertyDecl; // Null if no property + int NumPropertyDecl; // -1 if no property bool ForwardDecl:1; // declared with @class. bool InternalInterface:1; // true - no @interface for @implementation @@ -86,7 +91,8 @@ public: NumIvars(-1), InstanceMethods(0), NumInstanceMethods(-1), ClassMethods(0), NumClassMethods(-1), - CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal) { + CategoryList(0), PropertyDecl(0), NumPropertyDecl(-1), + ForwardDecl(FD), InternalInterface(isInternal) { AllocIntfRefProtocols(numRefProtos); } @@ -146,6 +152,16 @@ public: // We also need to record the @end location. SourceLocation getAtEndLoc() const { return AtEndLoc; } + + const int getNumPropertyDecl() const { return NumPropertyDecl; } + int getNumPropertyDecl() { return NumPropertyDecl; } + void setNumPropertyDecl(int num) { NumPropertyDecl = num; } + + ObjcPropertyDecl **const getPropertyDecl() const { return PropertyDecl; } + ObjcPropertyDecl **getPropertyDecl() { return PropertyDecl; } + void setPropertyDecls(ObjcPropertyDecl **properties) { + PropertyDecl = properties; + } /// ImplicitInterfaceDecl - check that this is an implicitely declared /// ObjcInterfaceDecl node. This is for legacy objective-c @implementation @@ -669,6 +685,61 @@ public: static bool classof(const ObjcCompatibleAliasDecl *D) { return true; } }; + +class ObjcPropertyDecl : public Decl { +public: + enum PrpoertyAttributeKind { OBJC_PR_noattr = 0x0, + OBJC_PR_readonly = 0x01, + OBJC_PR_getter = 0x02, + OBJC_PR_assign = 0x04, + OBJC_PR_readwrite = 0x08, + OBJC_PR_retain = 0x10, + OBJC_PR_copy = 0x20, + OBJC_PR_nonatomic = 0x40, + OBJC_PR_setter = 0x80 }; +private: + // List of property name declarations + // FIXME: Property is not an ivar. + ObjcIvarDecl **PropertyDecls; + int NumPropertyDecls; + + PrpoertyAttributeKind PropertyAttributes : 8; + + IdentifierInfo *GetterName; // getter name of NULL if no getter + IdentifierInfo *SetterName; // setter name of NULL if no setter + +public: + ObjcPropertyDecl(SourceLocation L) + : Decl(PropertyDecl, L), + PropertyDecls(0), NumPropertyDecls(-1), PropertyAttributes(OBJC_PR_noattr), + GetterName(0), SetterName(0) {} + + ObjcIvarDecl **const getPropertyDecls() const { return PropertyDecls; } + void setPropertyDecls(ObjcIvarDecl **property) { PropertyDecls = property; } + + const int getNumPropertyDecls() const { return NumPropertyDecls; } + void setNumPropertyDecls(int num) { NumPropertyDecls = num; } + + const PrpoertyAttributeKind getPropertyAttributes() const + { return PropertyAttributes; } + void setPropertyAttributes(PrpoertyAttributeKind PRVal) { + PropertyAttributes = + (PrpoertyAttributeKind) (PropertyAttributes | PRVal); + } + + const IdentifierInfo *getGetterName() const { return GetterName; } + IdentifierInfo *getGetterName() { return GetterName; } + void setGetterName(IdentifierInfo *Id) { GetterName = Id; } + + const IdentifierInfo *getSetterName() const { return SetterName; } + IdentifierInfo *getSetterName() { return SetterName; } + void setSetterName(IdentifierInfo *Id) { SetterName = Id; } + + static bool classof(const Decl *D) { + return D->getKind() == PropertyDecl; + } + static bool classof(const ObjcPropertyDecl *D) { return true; } +}; } // end namespace clang #endif diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index c198e74d67..41c60f4e5d 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -565,9 +565,18 @@ public: DeclTy *ClassDecl, DeclTy **allMethods, unsigned allNum, + DeclTy **allProperties, + unsigned NumProperties, SourceLocation AtEndLoc) { return; } + + // ActOnAddObjcProperties - called to build one property AST + virtual DeclTy *ActOnAddObjcProperties (SourceLocation AtLoc, + DeclTy **allProperties, unsigned NumProperties, ObjcDeclSpec &DS) { + return 0; + } + // ActOnClassMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 6c636e7ca8..d8189c414d 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -292,13 +292,48 @@ public: DQ_Oneway = 0x20 }; - ObjcDeclSpec() : objcDeclQualifier(DQ_None) {} + /// PrpoertyAttributeKind - list of property attributes. + enum ObjcPrpoertyAttributeKind { DQ_PR_noattr = 0x0, + DQ_PR_readonly = 0x01, + DQ_PR_getter = 0x02, + DQ_PR_assign = 0x04, + DQ_PR_readwrite = 0x08, + DQ_PR_retain = 0x10, + DQ_PR_copy = 0x20, + DQ_PR_nonatomic = 0x40, + DQ_PR_setter = 0x80 + }; + + + ObjcDeclSpec() : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr) + {} ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; } void setObjcDeclQualifier(ObjcDeclQualifier DQVal) { objcDeclQualifier = (ObjcDeclQualifier) (objcDeclQualifier | DQVal); } + const ObjcPrpoertyAttributeKind getPropertyAttributes() const + { return PropertyAttributes; } + void setPropertyAttributes(ObjcPrpoertyAttributeKind PRVal) { + PropertyAttributes = + (ObjcPrpoertyAttributeKind) (PropertyAttributes | PRVal); + } + + const IdentifierInfo *getGetterName() const { return GetterName; } + IdentifierInfo *getGetterName() { return GetterName; } + void setGetterName(IdentifierInfo *name) { GetterName = name; } + + const IdentifierInfo *getSetterName() const { return SetterName; } + IdentifierInfo *getSetterName() { return SetterName; } + void setSetterName(IdentifierInfo *name) { SetterName = name; } private: + // FIXME: These two are unrelated and mutially exclusive. So perhaps + // we can put them in a union to reflect their mutual exclusiveness + // (space saving is negligible). ObjcDeclQualifier objcDeclQualifier : 6; + + ObjcPrpoertyAttributeKind PropertyAttributes : 8; + IdentifierInfo *GetterName; // getter name of NULL if no getter + IdentifierInfo *SetterName; // setter name of NULL if no setter }; /// DeclaratorChunk - One instance of this struct is used for each type in a diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 95473d3c98..1bdf2e743e 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -298,8 +298,8 @@ private: tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); - void ParseObjCPropertyAttribute(DeclTy *interfaceDecl); - void ParseObjCPropertyDecl(DeclTy *interfaceDecl); + void ParseObjCPropertyAttribute(ObjcDeclSpec &DS); + DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc); void ParseObjCInstanceMethodDefinition(); void ParseObjCClassMethodDefinition();