diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:30 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-12-03 21:11:30 +0000 |
commit | 9ed9e5f31c1fe946a5c6c1ffb651052925570fd4 (patch) | |
tree | 605b946afd00d0cd5ed2e51a74d0b4a127aa8b0b | |
parent | d1438b446e7463db7207720321e0bdf5fc6654ea (diff) | |
download | bcm5719-llvm-9ed9e5f31c1fe946a5c6c1ffb651052925570fd4.tar.gz bcm5719-llvm-9ed9e5f31c1fe946a5c6c1ffb651052925570fd4.zip |
[objc] Introduce ObjCInterfaceDecl::getDesignatedInitializers() to get the
designated initializers of an interface.
If the interface declaration does not have methods marked as designated
initializers then the interface inherits the designated initializers of
its super class.
llvm-svn: 196315
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 19 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 1 |
5 files changed, 53 insertions, 3 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index def5817793f..7db912903b4 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -661,6 +661,10 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// declared in the implementation. mutable bool IvarListMissingImplementation : 1; + /// Indicates that this interface decl contains at least one initializer + /// marked with the 'objc_designated_initializer' attribute. + bool HasDesignatedInitializers : 1; + /// \brief The location of the superclass, if any. SourceLocation SuperClassLoc; @@ -671,7 +675,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), ExternallyCompleted(), - IvarListMissingImplementation(true) { } + IvarListMissingImplementation(true), + HasDesignatedInitializers() { } }; ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, @@ -728,6 +733,10 @@ public: /// when a complete class is required. void setExternallyCompleted(); + /// Indicate that this interface decl contains at least one initializer + /// marked with the 'objc_designated_initializer' attribute. + void setHasDesignatedInitializers(); + const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "Caller did not check for forward reference!"); if (data().ExternallyCompleted) @@ -867,6 +876,14 @@ public: unsigned Num, ASTContext &C); + /// Returns the designated initializers for the interface. + /// + /// If this declaration does not have methods marked as designated + /// initializers then the interface inherits the designated initializers of + /// its super class. + void getDesignatedInitializers( + llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const; + /// \brief Determine whether this particular declaration of this class is /// actually also a definition. bool isThisDeclarationADefinition() const { diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index cc3459476ad..528b52fe5d5 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -380,6 +380,30 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList( data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C); } +void ObjCInterfaceDecl::getDesignatedInitializers( + llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const { + assert(hasDefinition()); + if (data().ExternallyCompleted) + LoadExternalDefinition(); + + const ObjCInterfaceDecl *IFace = this; + while (IFace) { + if (IFace->data().HasDesignatedInitializers) + break; + IFace = IFace->getSuperClass(); + } + + if (!IFace) + return; + for (instmeth_iterator I = IFace->instmeth_begin(), + E = IFace->instmeth_end(); I != E; ++I) { + const ObjCMethodDecl *MD = *I; + if (MD->getMethodFamily() == OMF_init && + MD->hasAttr<ObjCDesignatedInitializerAttr>()) + Methods.push_back(MD); + } +} + void ObjCInterfaceDecl::allocateDefinitionData() { assert(!hasDefinition() && "ObjC class already has a definition"); Data.setPointer(new (getASTContext()) DefinitionData()); @@ -1124,6 +1148,11 @@ void ObjCInterfaceDecl::setExternallyCompleted() { data().ExternallyCompleted = true; } +void ObjCInterfaceDecl::setHasDesignatedInitializers() { + assert(hasDefinition() && "Forward declarations can't contain methods"); + data().HasDesignatedInitializers = true; +} + ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { if (const ObjCInterfaceDecl *Def = getDefinition()) { if (data().ExternallyCompleted) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index b732fccacf8..c587452aeb4 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3723,13 +3723,15 @@ static void handleObjCDesignatedInitializer(Sema &S, Decl *D, << SourceRange(Loc, Loc); return; } - DeclContext *DC = Method->getDeclContext(); - if (!isa<ObjCInterfaceDecl>(DC)) { + ObjCInterfaceDecl *IFace = + dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()); + if (!IFace) { S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_interface) << SourceRange(Loc, Loc); return; } + IFace->setHasDesignatedInitializers(); Method->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b8102d84173..4399fec553c 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -755,6 +755,7 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { Data.SuperClassLoc = ReadSourceLocation(Record, Idx); Data.EndLoc = ReadSourceLocation(Record, Idx); + Data.HasDesignatedInitializers = Record[Idx++]; // Read the directly referenced protocols and their SourceLocations. unsigned NumProtocols = Record[Idx++]; diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 55f830a4bad..56ed503e840 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -489,6 +489,7 @@ void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { Writer.AddDeclRef(D->getSuperClass(), Record); Writer.AddSourceLocation(D->getSuperClassLoc(), Record); Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record); + Record.push_back(Data.HasDesignatedInitializers); // Write out the protocols that are directly referenced by the @interface. Record.push_back(Data.ReferencedProtocols.size()); |