r196315 - [objc] Introduce ObjCInterfaceDecl::getDesignatedInitializers() to get the

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Dec 3 13:11:30 PST 2013


Author: akirtzidis
Date: Tue Dec  3 15:11:30 2013
New Revision: 196315

URL: http://llvm.org/viewvc/llvm-project?rev=196315&view=rev
Log:
[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.

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=196315&r1=196314&r2=196315&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Dec  3 15:11:30 2013
@@ -661,6 +661,10 @@ class ObjCInterfaceDecl : public ObjCCon
     /// 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 ObjCCon
 
     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 { 

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=196315&r1=196314&r2=196315&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Dec  3 15:11:30 2013
@@ -380,6 +380,30 @@ void ObjCInterfaceDecl::mergeClassExtens
   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::setExternallyCom
   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)

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=196315&r1=196314&r2=196315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Dec  3 15:11:30 2013
@@ -3723,13 +3723,15 @@ static void handleObjCDesignatedInitiali
     << 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()));

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=196315&r1=196314&r2=196315&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Dec  3 15:11:30 2013
@@ -755,6 +755,7 @@ void ASTDeclReader::VisitObjCInterfaceDe
     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++];

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=196315&r1=196314&r2=196315&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Dec  3 15:11:30 2013
@@ -489,6 +489,7 @@ void ASTDeclWriter::VisitObjCInterfaceDe
     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());





More information about the cfe-commits mailing list