summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-03 21:11:30 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-12-03 21:11:30 +0000
commit9ed9e5f31c1fe946a5c6c1ffb651052925570fd4 (patch)
tree605b946afd00d0cd5ed2e51a74d0b4a127aa8b0b
parentd1438b446e7463db7207720321e0bdf5fc6654ea (diff)
downloadbcm5719-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.h19
-rw-r--r--clang/lib/AST/DeclObjC.cpp29
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp6
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp1
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp1
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());
OpenPOWER on IntegriCloud