From: Fariborz Jahanian Date: Thu, 17 Apr 2008 18:25:18 +0000 (+0000) Subject: Added property decl support for protocols. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3dd4ba4068e953125b95ce85c723322cdd0a3cb5;p=clang Added property decl support for protocols. Added assertion if unexpected property decls are found where they don't belong. Consolidated property decl. printing by using a helper function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49862 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 596fefc8e5..e6e8f45eb6 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -52,6 +52,7 @@ namespace { void PrintObjCCategoryImplDecl(ObjCCategoryImplDecl *PID); void PrintObjCCategoryDecl(ObjCCategoryDecl *PID); void PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID); + void PrintObjCPropertyDecl(ObjCPropertyDecl *PD); }; } // end anonymous namespace @@ -264,65 +265,9 @@ void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) { Out << "}\n"; } - int NumProperties = OID->getNumPropertyDecl(); - if (NumProperties > 0) { - for (int i = 0; i < NumProperties; i++) { - ObjCPropertyDecl *PDecl = OID->getPropertyDecl()[i]; - Out << "@property"; - if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { - bool first = true; - Out << " ("; - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_readonly) { - Out << (first ? ' ' : ',') << "readonly"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { - Out << (first ? ' ' : ',') << "getter = " - << PDecl->getGetterName()->getName(); - first = false; - } - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { - Out << (first ? ' ' : ',') << "setter = " - << PDecl->getSetterName()->getName(); - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { - Out << (first ? ' ' : ',') << "assign"; - first = false; - } - - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_readwrite) { - Out << (first ? ' ' : ',') << "readwrite"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { - Out << (first ? ' ' : ',') << "retain"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { - Out << (first ? ' ' : ',') << "copy"; - first = false; - } - - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_nonatomic) { - Out << (first ? ' ' : ',') << "nonatomic"; - first = false; - } - Out << " )"; - } - Out << ' ' << PDecl->getType().getAsString() - << ' ' << PDecl->getName(); - - Out << ";\n"; - } - } + for (ObjCInterfaceDecl::classprop_iterator I = OID->classprop_begin(), + E = OID->classprop_end(); I != E; ++I) + PrintObjCPropertyDecl(*I); Out << "@end\n"; // FIXME: implement the rest... @@ -330,6 +275,11 @@ void DeclPrinter::PrintObjCInterfaceDecl(ObjCInterfaceDecl *OID) { void DeclPrinter::PrintObjCProtocolDecl(ObjCProtocolDecl *PID) { Out << "@protocol " << PID->getName() << '\n'; + + for (ObjCProtocolDecl::classprop_iterator I = PID->classprop_begin(), + E = PID->classprop_end(); I != E; ++I) + PrintObjCPropertyDecl(*I); + Out << "@end\n"; // FIXME: implement the rest... } @@ -346,66 +296,9 @@ void DeclPrinter::PrintObjCCategoryDecl(ObjCCategoryDecl *PID) { << PID->getClassInterface()->getName() << '(' << PID->getName() << ");\n"; // Output property declarations. - int NumProperties = PID->getNumPropertyDecl(); - if (NumProperties > 0) { - for (int i = 0; i < NumProperties; i++) { - ObjCPropertyDecl *PDecl = PID->getPropertyDecl()[i]; - Out << "@property"; - if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { - bool first = true; - Out << " ("; - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_readonly) { - Out << (first ? ' ' : ',') << "readonly"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { - Out << (first ? ' ' : ',') << "getter = " - << PDecl->getGetterName()->getName(); - first = false; - } - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { - Out << (first ? ' ' : ',') << "setter = " - << PDecl->getSetterName()->getName(); - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { - Out << (first ? ' ' : ',') << "assign"; - first = false; - } - - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_readwrite) { - Out << (first ? ' ' : ',') << "readwrite"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { - Out << (first ? ' ' : ',') << "retain"; - first = false; - } - - if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { - Out << (first ? ' ' : ',') << "copy"; - first = false; - } - - if (PDecl->getPropertyAttributes() & - ObjCPropertyDecl::OBJC_PR_nonatomic) { - Out << (first ? ' ' : ',') << "nonatomic"; - first = false; - } - Out << " )"; - } - Out << ' ' << PDecl->getType().getAsString() - << ' ' << PDecl->getName(); - - Out << ";\n"; - } - } - + for (ObjCCategoryDecl::classprop_iterator I = PID->classprop_begin(), + E = PID->classprop_end(); I != E; ++I) + PrintObjCPropertyDecl(*I); Out << "@end\n"; // FIXME: implement the rest... @@ -416,6 +309,65 @@ void DeclPrinter::PrintObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) { << ' ' << AID->getClassInterface()->getName() << ";\n"; } +/// PrintObjCPropertyDecl - print a property declaration. +/// +void DeclPrinter::PrintObjCPropertyDecl(ObjCPropertyDecl *PDecl) { + + Out << "@property"; + if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { + bool first = true; + Out << " ("; + if (PDecl->getPropertyAttributes() & + ObjCPropertyDecl::OBJC_PR_readonly) { + Out << (first ? ' ' : ',') << "readonly"; + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { + Out << (first ? ' ' : ',') << "getter = " + << PDecl->getGetterName()->getName(); + first = false; + } + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { + Out << (first ? ' ' : ',') << "setter = " + << PDecl->getSetterName()->getName(); + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { + Out << (first ? ' ' : ',') << "assign"; + first = false; + } + + if (PDecl->getPropertyAttributes() & + ObjCPropertyDecl::OBJC_PR_readwrite) { + Out << (first ? ' ' : ',') << "readwrite"; + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { + Out << (first ? ' ' : ',') << "retain"; + first = false; + } + + if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { + Out << (first ? ' ' : ',') << "copy"; + first = false; + } + + if (PDecl->getPropertyAttributes() & + ObjCPropertyDecl::OBJC_PR_nonatomic) { + Out << (first ? ' ' : ',') << "nonatomic"; + first = false; + } + Out << " )"; + } + Out << ' ' << PDecl->getType().getAsString() + << ' ' << PDecl->getName(); + + Out << ";\n"; +} + //===----------------------------------------------------------------------===// /// ASTPrinter - Pretty-printer of ASTs diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 80634fe760..55115055ae 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -309,6 +309,11 @@ public: void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); + typedef ObjCPropertyDecl * const * classprop_iterator; + classprop_iterator classprop_begin() const { return PropertyDecl; } + classprop_iterator classprop_end() const { + return PropertyDecl+NumPropertyDecl; + } bool isForwardDecl() const { return ForwardDecl; } void setForwardDecl(bool val) { ForwardDecl = val; } @@ -463,7 +468,11 @@ class ObjCProtocolDecl : public NamedDecl { /// protocol class methods ObjCMethodDecl **ClassMethods; // Null if not defined unsigned NumClassMethods; // 0 if none - + + /// protocol properties + ObjCPropertyDecl **PropertyDecl; // Null if no property + unsigned NumPropertyDecl; // 0 if none + bool isForwardProtoDecl; // declared with @protocol. SourceLocation EndLoc; // marks the '>' or identifier. @@ -474,6 +483,7 @@ class ObjCProtocolDecl : public NamedDecl { ReferencedProtocols(0), NumReferencedProtocols(0), InstanceMethods(0), NumInstanceMethods(0), ClassMethods(0), NumClassMethods(0), + PropertyDecl(0), NumPropertyDecl(0), isForwardProtoDecl(true) { AllocReferencedProtocols(numRefProtos); } @@ -504,6 +514,19 @@ public: unsigned getNumReferencedProtocols() const { return NumReferencedProtocols; } unsigned getNumInstanceMethods() const { return NumInstanceMethods; } unsigned getNumClassMethods() const { return NumClassMethods; } + + unsigned getNumPropertyDecl() const { return NumPropertyDecl; } + + ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; } + ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; } + + void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); + + typedef ObjCPropertyDecl * const * classprop_iterator; + classprop_iterator classprop_begin() const { return PropertyDecl; } + classprop_iterator classprop_end() const { + return PropertyDecl+NumPropertyDecl; + } typedef ObjCMethodDecl * const * instmeth_iterator; instmeth_iterator instmeth_begin() const { return InstanceMethods; } @@ -709,11 +732,18 @@ public: unsigned getNumInstanceMethods() const { return NumInstanceMethods; } unsigned getNumClassMethods() const { return NumClassMethods; } - void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); unsigned getNumPropertyDecl() const { return NumPropertyDecl; } ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; } + void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); + + typedef ObjCPropertyDecl * const * classprop_iterator; + classprop_iterator classprop_begin() const { return PropertyDecl; } + classprop_iterator classprop_end() const { + return PropertyDecl+NumPropertyDecl; + } + typedef ObjCMethodDecl * const * instmeth_iterator; instmeth_iterator instmeth_begin() const { return InstanceMethods; } instmeth_iterator instmeth_end() const { diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 2d959445d4..a5eb07a84c 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -197,6 +197,18 @@ void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties, memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*)); } +/// addProperties - Insert property declaration AST nodes into +/// ObjCProtocolDecl's PropertyDecl field. +/// +void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties, + unsigned NumProperties) { + if (NumProperties == 0) return; + + NumPropertyDecl = NumProperties; + PropertyDecl = new ObjCPropertyDecl*[NumProperties]; + memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*)); +} + /// addProperties - Insert property declaration AST nodes into /// ObjCCategoryDecl's PropertyDecl field. /// diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 3b6f8eccdb..eb9fa433d9 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -695,13 +695,15 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, || isa(ClassDecl); bool checkIdenticalMethods = isa(ClassDecl); - // TODO: property declaration in category and protocols. if (pNum != 0) if (ObjCInterfaceDecl *IDecl = dyn_cast(ClassDecl)) IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum); + else if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) + CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum); + else if (ObjCProtocolDecl *PDecl = dyn_cast(ClassDecl)) + PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum); else - if (ObjCCategoryDecl *CDecl = dyn_cast(ClassDecl)) - CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum); + assert(false && "ActOnAtEnd - property declaration misplaced"); for (unsigned i = 0; i < allNum; i++ ) { ObjCMethodDecl *Method =