[cfe-commits] r146722 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/DeclObjC.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/DeclObjC.cpp lib/Sema/Sema.cpp lib/Sema/SemaDeclObjC.cpp lib/Serialization/ASTReaderDecl.cpp test/Modules/Inputs/decl2.h test/Modules/Inputs/module.map test/SemaObjC/forward-class-1.m

Douglas Gregor dgregor at apple.com
Thu Dec 15 19:12:42 PST 2011


Author: dgregor
Date: Thu Dec 15 21:12:41 2011
New Revision: 146722

URL: http://llvm.org/viewvc/llvm-project?rev=146722&view=rev
Log:
Fix chaining of ObjCInterfaceDecl redeclarations

Added:
    cfe/trunk/test/Modules/Inputs/decl2.h
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/SemaObjC/forward-class-1.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Dec 15 21:12:41 2011
@@ -853,7 +853,8 @@
   QualType getPackExpansionType(QualType Pattern,
                                 llvm::Optional<unsigned> NumExpansions);
 
-  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const;
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                ObjCInterfaceDecl *PrevDecl = 0) const;
 
   QualType getObjCObjectType(QualType Base,
                              ObjCProtocolDecl * const *Protocols,

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Dec 15 21:12:41 2011
@@ -614,9 +614,12 @@
   static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation atLoc,
                                    IdentifierInfo *Id,
+                                   ObjCInterfaceDecl *PrevDecl,
                                    SourceLocation ClassLoc = SourceLocation(),
                                    bool isInternal = false);
 
+  static ObjCInterfaceDecl *CreateEmpty(ASTContext &C);
+
   virtual SourceRange getSourceRange() const {
     if (isThisDeclarationADefinition())
       return ObjCContainerDecl::getSourceRange();
@@ -916,8 +919,6 @@
     return getFirstDeclaration();
   }
 
-  void setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl);
-
   // Low-level accessor
   const Type *getTypeForDecl() const { return TypeForDecl; }
   void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Dec 15 21:12:41 2011
@@ -2808,11 +2808,17 @@
 
 /// getObjCInterfaceType - Return the unique reference to the type for the
 /// specified ObjC interface decl. The list of protocols is optional.
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const {
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                          ObjCInterfaceDecl *PrevDecl) const {
   if (Decl->TypeForDecl)
     return QualType(Decl->TypeForDecl, 0);
 
-  // FIXME: redeclarations?
+  if (PrevDecl) {
+    assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+    Decl->TypeForDecl = PrevDecl->TypeForDecl;
+    return QualType(PrevDecl->TypeForDecl, 0);
+  }
+
   void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
   ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
   Decl->TypeForDecl = T;

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Dec 15 21:12:41 2011
@@ -3182,7 +3182,8 @@
     if (!ToIface) {
       ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
                                           Importer.Import(D->getAtStartLoc()),
-                                          Name.getAsIdentifierInfo(), Loc,
+                                          Name.getAsIdentifierInfo(), 
+                                          /*PrevDecl=*/0,Loc,
                                           D->isImplicitInterfaceDecl());
       ToIface->setLexicalDeclContext(LexicalDC);
       LexicalDC->addDeclInternal(ToIface);

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Dec 15 21:12:41 2011
@@ -225,18 +225,19 @@
 void ObjCInterfaceDecl::allocateDefinitionData() {
   assert(!hasDefinition() && "ObjC class already has a definition");
   Data = new (getASTContext()) DefinitionData();
-  Data->Definition = this;
-  
+  Data->Definition = this;  
+}
+
+void ObjCInterfaceDecl::startDefinition() {
+  allocateDefinitionData();
+
   // Update all of the declarations with a pointer to the definition.
   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
        RD != RDEnd; ++RD) {
     if (*RD != this)
       RD->Data = Data;
   }
-}
 
-void ObjCInterfaceDecl::startDefinition() {
-  allocateDefinitionData();
   if (ASTMutationListener *L = getASTContext().getASTMutationListener())
     L->CompletedObjCForwardRef(this);
 }
@@ -674,9 +675,24 @@
                                              DeclContext *DC,
                                              SourceLocation atLoc,
                                              IdentifierInfo *Id,
+                                             ObjCInterfaceDecl *PrevDecl,
                                              SourceLocation ClassLoc,
                                              bool isInternal){
-  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, isInternal);
+  ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, 
+                                                        isInternal);
+  C.getObjCInterfaceType(Result, PrevDecl);
+  
+  if (PrevDecl) {
+    Result->Data = PrevDecl->Data;
+    Result->setPreviousDeclaration(PrevDecl);
+  }
+
+  return Result;
+}
+
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateEmpty(ASTContext &C) {
+  return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
+                                   false);
 }
 
 ObjCInterfaceDecl::
@@ -851,14 +867,6 @@
   return false;
 }
 
-void ObjCInterfaceDecl::setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl) {
-  redeclarable_base::setPreviousDeclaration(PrevDecl);
-  
-  // Inherit the 'Data' pointer from the previous declaration.
-  if (PrevDecl)
-    Data = PrevDecl->Data;
-}
-
 //===----------------------------------------------------------------------===//
 // ObjCIvarDecl
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Dec 15 21:12:41 2011
@@ -82,6 +82,7 @@
       ObjCInterfaceDecl *ProtocolDecl =
         ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
                                   &Context.Idents.get("Protocol"),
+                                  /*PrevDecl=*/0,
                                   SourceLocation(), true);
       Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
       PushOnScopeChains(ProtocolDecl, TUScope, false);

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Dec 15 21:12:41 2011
@@ -366,11 +366,11 @@
   }
 
   // Create a declaration to describe this @interface.
+  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
   ObjCInterfaceDecl *IDecl
     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
-                                ClassLoc);
+                                PrevIDecl, ClassLoc);
   
-  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
   if (PrevIDecl) {
     // Class already seen. Was it a definition?
     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -379,9 +379,6 @@
       Diag(Def->getLocation(), diag::note_previous_definition);
       IDecl->setInvalidDecl();
     }
-
-    // Link to the previous declaration.
-    IDecl->setPreviousDeclaration(PrevIDecl);
   }
   
   if (AttrList)
@@ -870,9 +867,8 @@
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
   } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
-    if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
-                            diag::warn_undef_interface))
-      IDecl = 0;
+    RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
+                        diag::warn_undef_interface);
   } else {
     // We did not find anything with the name ClassName; try to correct for 
     // typos in the class name.
@@ -928,7 +924,8 @@
     // FIXME: Do we support attributes on the @implementation? If so we should
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
-                                      ClassName, ClassLoc, true);
+                                      ClassName, /*PrevDecl=*/0, ClassLoc, 
+                                      true);
     IDecl->startDefinition();
     if (SDecl) {
       IDecl->setSuperClass(SDecl);
@@ -1774,16 +1771,13 @@
     }
     
     // Create a declaration to describe this forward declaration.
+    ObjCInterfaceDecl *PrevIDecl
+      = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
     ObjCInterfaceDecl *IDecl
       = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
-                                  IdentList[i], IdentLocs[i], true);
+                                  IdentList[i], PrevIDecl, IdentLocs[i], true);
     IDecl->setAtEndRange(IdentLocs[i]);
     
-    // If there was a previous declaration, link to it.
-    if (ObjCInterfaceDecl *PrevIDecl
-        = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))
-      IDecl->setPreviousDeclaration(PrevIDecl);
-
     // Create the forward declaration. Note that we intentionally do this 
     // before we add the ObjCInterfaceDecl we just created, so that the
     // rewriter sees the ObjCClassDecl first.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Dec 15 21:12:41 2011
@@ -223,6 +223,9 @@
   if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
     // if we have a fully initialized TypeDecl, we can safely read its type now.
     TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    // if we have a fully initialized TypeDecl, we can safely read its type now.
+    ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // FunctionDecl's body was written last after all other Stmts/Exprs.
     if (Record[Idx++])
@@ -556,7 +559,7 @@
 void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
   VisitRedeclarable(ID);
   VisitObjCContainerDecl(ID);
-  ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
+  TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
   
   ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
   if (ID == Def) {
@@ -621,13 +624,13 @@
       // pending references were linked.
       Reader.PendingForwardRefs.erase(ID);
 #endif
-    } else if (Def) {
-      if (Def->Data) {
-        ID->Data = Def->Data;
-      } else {
-        // The definition is still initializing.
-        Reader.PendingForwardRefs[Def].push_back(ID);
-      }
+    }
+  } else if (Def) {
+    if (Def->Data) {
+      ID->Data = Def->Data;
+    } else {
+      // The definition is still initializing.
+      Reader.PendingForwardRefs[Def].push_back(ID);
     }
   }
 }
@@ -1561,6 +1564,8 @@
     FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
   } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
     VD->RedeclLink.setPointer(cast<VarDecl>(previous));
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(previous)) {
+    ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
   } else {
     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
     TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1736,7 +1741,7 @@
                                Selector(), QualType(), 0, 0);
     break;
   case DECL_OBJC_INTERFACE:
-    D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
+    D = ObjCInterfaceDecl::CreateEmpty(Context);
     break;
   case DECL_OBJC_IVAR:
     D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),

Added: cfe/trunk/test/Modules/Inputs/decl2.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/decl2.h?rev=146722&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/decl2.h (added)
+++ cfe/trunk/test/Modules/Inputs/decl2.h Thu Dec 15 21:12:41 2011
@@ -0,0 +1 @@
+ at class A;

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Thu Dec 15 21:12:41 2011
@@ -39,5 +39,6 @@
 
 module decldef {
   explicit module Decl { header "decl.h" }
+  explicit module Decl2 { header "decl2.h" }
   explicit module Def { header "def.h" }
 }
\ No newline at end of file

Modified: cfe/trunk/test/SemaObjC/forward-class-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/forward-class-1.m?rev=146722&r1=146721&r2=146722&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/forward-class-1.m (original)
+++ cfe/trunk/test/SemaObjC/forward-class-1.m Thu Dec 15 21:12:41 2011
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
- at class FOO, BAR; 
 @class FOO, BAR; // expected-note {{forward declaration of class here}}
+ at class FOO, BAR; 
 
 @interface INTF : FOO	// expected-error {{attempting to use the forward class 'FOO' as superclass of 'INTF'}}
 @end





More information about the cfe-commits mailing list