[cfe-commits] r110803 - in /cfe/trunk: include/clang/AST/ lib/AST/ lib/Frontend/ lib/Sema/ test/Index/

Douglas Gregor dgregor at apple.com
Wed Aug 11 05:19:30 PDT 2010


Author: dgregor
Date: Wed Aug 11 07:19:30 2010
New Revision: 110803

URL: http://llvm.org/viewvc/llvm-project?rev=110803&view=rev
Log:
Speculatively revert r110610 " Make ObjCInterfaceDecl redeclarable,
and create separate decl nodes for forward declarations and the
definition," which appears to be causing significant Objective-C
breakage.

Modified:
    cfe/trunk/include/clang/AST/ASTConsumer.h
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTConsumer.cpp
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/Index/TestClassDecl.m

Modified: cfe/trunk/include/clang/AST/ASTConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTConsumer.h (original)
+++ cfe/trunk/include/clang/AST/ASTConsumer.h Wed Aug 11 07:19:30 2010
@@ -49,11 +49,6 @@
   /// elements). Use Decl::getNextDeclarator() to walk the chain.
   virtual void HandleTopLevelDecl(DeclGroupRef D);
 
-  /// HandleInterestingDecl - Handle the specified interesting declaration. This
-  /// is called by the PCH reader when deserializing things that might interest
-  /// the consumer. The default implementation forwards to HandleTopLevelDecl.
-  virtual void HandleInterestingDecl(DeclGroupRef D);
-
   /// HandleTranslationUnit - This method is called when the ASTs for entire
   /// translation unit have been parsed.
   virtual void HandleTranslationUnit(ASTContext &Ctx) {}

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug 11 07:19:30 2010
@@ -668,10 +668,7 @@
                                                   unsigned NumArgs,
                                                   const TemplateArgument *Args);
 
-  /// getObjCInterfaceType - Return the unique reference to the type for the
-  /// specified ObjC interface decl.
-  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
-                                const ObjCInterfaceDecl *PrevDecl = 0);
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
 
   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=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Aug 11 07:19:30 2010
@@ -450,10 +450,7 @@
 ///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
 ///   typically inherit from NSObject (an exception is NSProxy).
 ///
-class ObjCInterfaceDecl : public ObjCContainerDecl,
-                          public Redeclarable<ObjCInterfaceDecl> {
-  typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
-
+class ObjCInterfaceDecl : public ObjCContainerDecl {
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
   mutable Type *TypeForDecl;
@@ -477,52 +474,15 @@
   SourceLocation EndLoc; // marks the '>', '}', or identifier.
 
   ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                    bool FD, bool isInternal);
-
-protected:
-  virtual ObjCInterfaceDecl *getNextRedeclaration() {
-    return RedeclLink.getNext();
-  }
+                    SourceLocation CLoc, bool FD, bool isInternal);
 
 public:
-  typedef redeclarable_base::redecl_iterator redecl_iterator;
-  redecl_iterator redecls_begin() const {
-    return redeclarable_base::redecls_begin();
-  }
-  redecl_iterator redecls_end() const {
-    return redeclarable_base::redecls_end();
-  }
-
   static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation atLoc,
                                    IdentifierInfo *Id,
-                                   SourceLocation ClassLoc,
-                                   ObjCInterfaceDecl *PrevDecl,
+                                   SourceLocation ClassLoc = SourceLocation(),
                                    bool ForwardDecl = false,
                                    bool isInternal = false);
-
-  static ObjCInterfaceDecl *Create(ASTContext &C, EmptyShell Empty);
-
-  void setPreviousDeclaration(ObjCInterfaceDecl *Prev) {
-    // Adopt a type pointer if it exists.
-    TypeForDecl = Prev->TypeForDecl;
-    redeclarable_base::setPreviousDeclaration(Prev);
-  }
-
-  virtual ObjCInterfaceDecl *getCanonicalDecl() {
-    return getFirstDeclaration();
-  }
-  const ObjCInterfaceDecl *getCanonicalDecl() const {
-    return const_cast<ObjCInterfaceDecl*>(this)->getCanonicalDecl();
-  }
-
-  /// Get the interface declaration that is a definition, if there is one.
-  ObjCInterfaceDecl *getDefinition();
-  const ObjCInterfaceDecl *getDefinition() const {
-    return const_cast<ObjCInterfaceDecl*>(this)->getDefinition();
-  }
-
   const ObjCProtocolList &getReferencedProtocols() const {
     return ReferencedProtocols;
   }
@@ -575,7 +535,6 @@
                                        ASTContext &C);
 
   bool isForwardDecl() const { return ForwardDecl; }
-  bool isDefinition() const { return !ForwardDecl; }
   void setForwardDecl(bool val) { ForwardDecl = val; }
 
   ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Aug 11 07:19:30 2010
@@ -3038,7 +3038,7 @@
   friend class ASTContext;  // ASTContext creates these.
 public:
   /// getDecl - Get the declaration of this interface.
-  ObjCInterfaceDecl *getDecl() const;
+  ObjCInterfaceDecl *getDecl() const { return Decl; }
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }

Modified: cfe/trunk/lib/AST/ASTConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTConsumer.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTConsumer.cpp (original)
+++ cfe/trunk/lib/AST/ASTConsumer.cpp Wed Aug 11 07:19:30 2010
@@ -17,6 +17,3 @@
 
 void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {}
 
-void ASTConsumer::HandleInterestingDecl(DeclGroupRef D) {
-  HandleTopLevelDecl(D);
-}

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 11 07:19:30 2010
@@ -872,7 +872,7 @@
 /// CollectNonClassIvars -
 /// This routine collects all other ivars which are not declared in the class.
 /// This includes synthesized ivars (via @synthesize) and those in
-/// class's @implementation.
+//  class's @implementation.
 ///
 void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
@@ -2212,24 +2212,18 @@
   return QualType(QType, 0);
 }
 
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
-                                          const ObjCInterfaceDecl *PrevDecl) {
-  assert(Decl && "Passed null for Decl param");
-
-  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
-  if (PrevDecl) {
-    assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
-    Decl->TypeForDecl = PrevDecl->TypeForDecl;
-    return QualType(PrevDecl->TypeForDecl, 0);
-  }
-
-  assert(!Decl->getPreviousDeclaration() &&
-         "interface has previous declaration");
-
-  Decl->TypeForDecl = new (*this, TypeAlignment) ObjCInterfaceType(Decl);
-  Types.push_back(Decl->TypeForDecl);
-  return QualType(Decl->TypeForDecl, 0);
+/// 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) {
+  if (Decl->TypeForDecl)
+    return QualType(Decl->TypeForDecl, 0);
+
+  // FIXME: redeclarations?
+  void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
+  ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
+  Decl->TypeForDecl = T;
+  Types.push_back(T);
+  return QualType(T, 0);
 }
 
 /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Aug 11 07:19:30 2010
@@ -2467,18 +2467,6 @@
 }
 
 Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
-  // If this interface has a definition in the translation unit we're coming
-  // from, but this particular declaration is not that definition, import the
-  // definition and map to that.
-  ObjCInterfaceDecl *Definition = D->getDefinition();
-  if (Definition && Definition != D) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return 0;
-
-    return Importer.Imported(D, ImportedDef);
-  }
-
   // Import the major distinguishing characteristics of an @interface.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -2503,7 +2491,7 @@
       ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
                                           DC, Loc,
                                           Name.getAsIdentifierInfo(),
-                                          Importer.Import(D->getClassLoc()), 0,
+                                          Importer.Import(D->getClassLoc()),
                                           D->isForwardDecl(),
                                           D->isImplicitInterfaceDecl());
       ToIface->setForwardDecl(D->isForwardDecl());

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Aug 11 07:19:30 2010
@@ -45,14 +45,6 @@
 // ObjCInterfaceDecl
 //===----------------------------------------------------------------------===//
 
-ObjCInterfaceDecl *ObjCInterfaceDecl::getDefinition() {
-  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
-    if (I->isDefinition())
-      return *I;
-  }
-  return 0;
-}
-
 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
 ///
 ObjCIvarDecl *
@@ -440,30 +432,18 @@
                                              SourceLocation atLoc,
                                              IdentifierInfo *Id,
                                              SourceLocation ClassLoc,
-                                             ObjCInterfaceDecl *PrevDecl,
                                              bool ForwardDecl, bool isInternal){
-  ObjCInterfaceDecl *D = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
-                                                   PrevDecl, ForwardDecl,
-                                                   isInternal);
-  C.getObjCInterfaceType(D, PrevDecl);
-  return D;
-}
-
-ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, EmptyShell) {
-  return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
-                                   0, false, false);
+  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
+                                     isInternal);
 }
 
 ObjCInterfaceDecl::
 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                  SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                  bool FD, bool isInternal)
+                  SourceLocation CLoc, bool FD, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
     TypeForDecl(0), SuperClass(0),
     CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
     ClassLoc(CLoc) {
-  if (PrevDecl)
-    setPreviousDeclaration(PrevDecl);
 }
 
 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Wed Aug 11 07:19:30 2010
@@ -727,19 +727,12 @@
 
 void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
   std::string I = OID->getNameAsString();
-
-  if (OID->isForwardDecl()) {
-    // These shouldn't be directly visited, but in case they are, write them
-    // as an @class declaration.
-    Out << "@class " << I;
-    return;
-  }
-
   ObjCInterfaceDecl *SID = OID->getSuperClass();
 
-  Out << "@interface " << I;
   if (SID)
-    Out << " : " << SID;
+    Out << "@interface " << I << " : " << SID;
+  else
+    Out << "@interface " << I;
 
   // Protocols?
   const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Aug 11 07:19:30 2010
@@ -360,17 +360,6 @@
   return 0;
 }
 
-ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
-  for (ObjCInterfaceDecl::redecl_iterator I = Decl->redecls_begin(),
-                                          E = Decl->redecls_end();
-       I != E; ++I) {
-    if (I->isDefinition())
-      return *I;
-  }
-  // If we can't find a definition, return whatever we have.
-  return Decl;
-}
-
 const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const {
   if (const PointerType *PT = getAs<PointerType>())
     if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>())

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Wed Aug 11 07:19:30 2010
@@ -320,9 +320,6 @@
       Unit.addTopLevelDecl(D);
     }
   }
-
-  // We're not interested in "interesting" decls.
-  void HandleInterestingDecl(DeclGroupRef) {}
 };
 
 class TopLevelDeclTrackerAction : public ASTFrontendAction {

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Aug 11 07:19:30 2010
@@ -2262,7 +2262,7 @@
   SavedStreamPosition SavedPosition(DeclsCursor);
 
   ReadingKindTracker ReadingKind(Read_Type, *this);
-
+  
   // Note that we are loading a type record.
   Deserializing AType(this);
 
@@ -3027,7 +3027,7 @@
   while (!InterestingDecls.empty()) {
     DeclGroupRef DG(InterestingDecls.front());
     InterestingDecls.pop_front();
-    Consumer->HandleInterestingDecl(DG);
+    Consumer->HandleTopLevelDecl(DG);
   }
 }
 

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Wed Aug 11 07:19:30 2010
@@ -34,7 +34,7 @@
     const pch::DeclID ThisDeclID;
     const PCHReader::RecordData &Record;
     unsigned &Idx;
-    pch::TypeID TypeIDForDecl;
+    pch::TypeID TypeIDForTypeDecl;
 
     uint64_t GetCurrentCursorOffset();
 
@@ -43,7 +43,7 @@
                   pch::DeclID thisDeclID, const PCHReader::RecordData &Record,
                   unsigned &Idx)
       : Reader(Reader), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record),
-        Idx(Idx), TypeIDForDecl(0) { }
+        Idx(Idx), TypeIDForTypeDecl(0) { }
 
     void Visit(Decl *D);
 
@@ -132,11 +132,9 @@
 void PCHDeclReader::Visit(Decl *D) {
   DeclVisitor<PCHDeclReader, void>::Visit(D);
 
-  // if we have a fully initialized Decl, we can safely read its type now.
   if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
-    TD->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
-  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    ID->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
+    // if we have a fully initialized TypeDecl, we can safely read its type now.
+    TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // FunctionDecl's body was written last after all other Stmts/Exprs.
     if (Record[Idx++])
@@ -172,7 +170,7 @@
 void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
   VisitNamedDecl(TD);
   // Delay type reading until after we have fully initialized the decl.
-  TypeIDForDecl = Record[Idx++];
+  TypeIDForTypeDecl = Record[Idx++];
 }
 
 void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
@@ -369,11 +367,7 @@
 
 void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
   VisitObjCContainerDecl(ID);
-  ID->setForwardDecl(Record[Idx++]);
-  ID->setImplicitInterfaceDecl(Record[Idx++]);
-  VisitRedeclarable(ID);
-  // Must delay type reading until the redecl chain is complete.
-  TypeIDForDecl = Record[Idx++];
+  ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
   ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
                        (Reader.GetDecl(Record[Idx++])));
   unsigned NumProtocols = Record[Idx++];
@@ -394,6 +388,8 @@
     IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
   ID->setCategoryList(
                cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+  ID->setForwardDecl(Record[Idx++]);
+  ID->setImplicitInterfaceDecl(Record[Idx++]);
   ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -1463,7 +1459,7 @@
                                Selector(), QualType(), 0, 0);
     break;
   case pch::DECL_OBJC_INTERFACE:
-    D = ObjCInterfaceDecl::Create(*Context, Decl::EmptyShell());
+    D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
     break;
   case pch::DECL_OBJC_IVAR:
     D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Aug 11 07:19:30 2010
@@ -305,9 +305,7 @@
 }
 
 void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
-  // The stored declaration must be the first, but getDecl() returns the
-  // definition.
-  Writer.AddDeclRef(T->getDecl()->getFirstDeclaration(), Record);
+  Writer.AddDeclRef(T->getDecl(), Record);
   Code = pch::TYPE_OBJC_INTERFACE;
 }
 

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Wed Aug 11 07:19:30 2010
@@ -340,9 +340,6 @@
 
 void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
   VisitObjCContainerDecl(D);
-  Record.push_back(D->isForwardDecl());
-  Record.push_back(D->isImplicitInterfaceDecl());
-  VisitRedeclarable(D);
   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
   Writer.AddDeclRef(D->getSuperClass(), Record);
   Record.push_back(D->protocol_size());
@@ -359,6 +356,8 @@
                                      IEnd = D->ivar_end(); I != IEnd; ++I)
     Writer.AddDeclRef(*I, Record);
   Writer.AddDeclRef(D->getCategoryList(), Record);
+  Record.push_back(D->isForwardDecl());
+  Record.push_back(D->isImplicitInterfaceDecl());
   Writer.AddSourceLocation(D->getClassLoc(), Record);
   Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
   Writer.AddSourceLocation(D->getLocEnd(), Record);

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Aug 11 07:19:30 2010
@@ -89,7 +89,7 @@
     ObjCInterfaceDecl *ProtocolDecl =
       ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
                                 &Context.Idents.get("Protocol"),
-                                SourceLocation(), 0, true);
+                                SourceLocation(), true);
     Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
     PushOnScopeChains(ProtocolDecl, TUScope, false);
   }

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Aug 11 07:19:30 2010
@@ -3748,28 +3748,20 @@
   for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
                                DEnd = Ctx->decls_end();
        D != DEnd; ++D) {
-    // Record any interfaces we find. Forward declarations are never registered
-    // in the lexical contest, so if we're only looking for those, don't bother.
-    if (!OnlyForwardDeclarations)
-      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
-        if (!OnlyUnimplemented || !Class->getImplementation())
-          Results.AddResult(Result(Class, 0), CurContext, 0, false);
+    // Record any interfaces we find.
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
+      if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+          (!OnlyUnimplemented || !Class->getImplementation()))
+        Results.AddResult(Result(Class, 0), CurContext, 0, false);
 
     // Record any forward-declared interfaces we find.
     if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
       for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
-           C != CEnd; ++C) {
-        ObjCInterfaceDecl *IDecl = C->getInterface();
-        ObjCInterfaceDecl *IDef = IDecl->getDefinition();
-        // If there's a definition, and we're looking for everything, then we
-        // already added the decl in question above.
-        if (!OnlyForwardDeclarations && !OnlyUnimplemented && IDef)
-          continue;
-        if ((!OnlyForwardDeclarations || !IDef) &&
-            (!OnlyUnimplemented || !IDef || !IDef->getImplementation()))
-          Results.AddResult(Result(IDecl, 0), CurContext,
+           C != CEnd; ++C)
+        if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
+            (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
+          Results.AddResult(Result(C->getInterface(), 0), CurContext,
                             0, false);
-      }
     }
   }
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug 11 07:19:30 2010
@@ -606,6 +606,45 @@
   }
 }
 
+/// \brief Look for an Objective-C class in the translation unit.
+///
+/// \param Id The name of the Objective-C class we're looking for. If
+/// typo-correction fixes this name, the Id will be updated
+/// to the fixed name.
+///
+/// \param IdLoc The location of the name in the translation unit.
+///
+/// \param TypoCorrection If true, this routine will attempt typo correction
+/// if there is no class with the given name.
+///
+/// \returns The declaration of the named Objective-C class, or NULL if the
+/// class could not be found.
+ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                              SourceLocation IdLoc,
+                                              bool TypoCorrection) {
+  // The third "scope" argument is 0 since we aren't enabling lazy built-in
+  // creation from this context.
+  NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
+
+  if (!IDecl && TypoCorrection) {
+    // Perform typo correction at the given location, but only if we
+    // find an Objective-C class name.
+    LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
+    if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
+        (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+      Diag(IdLoc, diag::err_undef_interface_suggest)
+        << Id << IDecl->getDeclName() 
+        << FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString());
+      Diag(IDecl->getLocation(), diag::note_previous_decl)
+        << IDecl->getDeclName();
+      
+      Id = IDecl->getIdentifier();
+    }
+  }
+
+  return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
+}
+
 /// getNonFieldDeclScope - Retrieves the innermost scope, starting
 /// from S, where a non-field would be declared. This routine copes
 /// with the difference between C and C++ scoping rules in structs and

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Aug 11 07:19:30 2010
@@ -20,50 +20,6 @@
 #include "clang/Parse/DeclSpec.h"
 using namespace clang;
 
-/// \brief Look for an Objective-C class in the translation unit.
-///
-/// \param Id The name of the Objective-C class we're looking for. If
-/// typo-correction fixes this name, the Id will be updated
-/// to the fixed name.
-///
-/// \param IdLoc The location of the name in the translation unit.
-///
-/// \param TypoCorrection If true, this routine will attempt typo correction
-/// if there is no class with the given name.
-///
-/// \returns The declaration of the named Objective-C class, which is also the
-/// definition if one is available, or NULL if the class could not be found.
-ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
-                                              SourceLocation IdLoc,
-                                              bool TypoCorrection) {
-  // The third "scope" argument is 0 since we aren't enabling lazy built-in
-  // creation from this context.
-  NamedDecl *Decl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
-
-  if (!Decl && TypoCorrection) {
-    // Perform typo correction at the given location, but only if we
-    // find an Objective-C class name.
-    LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
-    if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
-        (Decl = R.getAsSingle<ObjCInterfaceDecl>())) {
-      Diag(IdLoc, diag::err_undef_interface_suggest)
-        << Id << Decl->getDeclName() 
-        << FixItHint::CreateReplacement(IdLoc, Decl->getNameAsString());
-      Diag(Decl->getLocation(), diag::note_previous_decl)
-        << Decl->getDeclName();
-
-      Id = Decl->getIdentifier();
-    }
-  }
-
-  ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Decl);
-  if (IDecl) {
-    if (ObjCInterfaceDecl *Def = IDecl->getDefinition())
-      IDecl = Def;
-  }
-  return IDecl;
-}
-
 /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
 /// and user declared, in the method definition's AST.
 void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
@@ -109,8 +65,6 @@
                          SourceLocation EndProtoLoc, AttributeList *AttrList) {
   assert(ClassName && "Missing class identifier");
 
-  bool Invalid = false;
-
   // Check for another declaration kind with the same name.
   NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
                                          LookupOrdinaryName, ForRedeclaration);
@@ -118,34 +72,41 @@
   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-    // Set the new decl invalid and ignore the old.
-    Invalid = true;
-    PrevDecl = 0;
   }
 
-  ObjCInterfaceDecl *ODecl = cast_or_null<ObjCInterfaceDecl>(PrevDecl);
-  if (ODecl) {
+  ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+  if (IDecl) {
     // Class already seen. Is it a forward declaration?
-    if (ObjCInterfaceDecl *Def = ODecl->getDefinition()) {
-      Invalid = true;
-      Diag(AtInterfaceLoc, diag::err_duplicate_class_def) << Def->getDeclName();
-      Diag(Def->getLocation(), diag::note_previous_definition);
+    if (!IDecl->isForwardDecl()) {
+      IDecl->setInvalidDecl();
+      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
+      Diag(IDecl->getLocation(), diag::note_previous_definition);
 
-      // Return the previous class interface and ignore the new one.
-      return DeclPtrTy::make(ODecl);
+      // Return the previous class interface.
+      // FIXME: don't leak the objects passed in!
+      return DeclPtrTy::make(IDecl);
+    } else {
+      IDecl->setLocation(AtInterfaceLoc);
+      IDecl->setForwardDecl(false);
+      IDecl->setClassLoc(ClassLoc);
+      
+      // Since this ObjCInterfaceDecl was created by a forward declaration,
+      // we now add it to the DeclContext since it wasn't added before
+      // (see ActOnForwardClassDeclaration).
+      IDecl->setLexicalDeclContext(CurContext);
+      CurContext->addDecl(IDecl);
+      
+      if (AttrList)
+        ProcessDeclAttributeList(TUScope, IDecl, AttrList);
     }
-  }
-
-  ObjCInterfaceDecl *IDecl =
-      ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
-                                ClassName, ClassLoc, ODecl);
-  if (Invalid)
-    IDecl->setInvalidDecl();
-
-  if (AttrList)
-    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  } else {
+    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
+                                      ClassName, ClassLoc);
+    if (AttrList)
+      ProcessDeclAttributeList(TUScope, IDecl, AttrList);
 
-  PushOnScopeChains(IDecl, TUScope);
+    PushOnScopeChains(IDecl, TUScope);
+  }
 
   if (SuperName) {
     // Check if a different kind of symbol declared in this scope.
@@ -164,8 +125,6 @@
       }
     }
 
-    // Since we just pushed IDecl on the scope chain, if PrevDecl is the same
-    // class, it will be the same declaration.
     if (PrevDecl == IDecl) {
       Diag(SuperLoc, diag::err_recursive_superclass)
         << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
@@ -181,11 +140,11 @@
       if (PrevDecl && SuperClassDecl == 0) {
         // The previous declaration was not a class decl. Check if we have a
         // typedef. If we do, get the underlying class type.
-        if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)){
+        if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
           QualType T = TDecl->getUnderlyingType();
           if (T->isObjCObjectType()) {
-            if (NamedDecl *NDecl = T->getAs<ObjCObjectType>()->getInterface())
-              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(NDecl);
+            if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
+              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
           }
         }
 
@@ -200,11 +159,6 @@
         }
       }
 
-      if (SuperClassDecl) {
-        if (ObjCInterfaceDecl *Def = SuperClassDecl->getDefinition())
-          SuperClassDecl = Def;
-      }
-
       if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
         if (!SuperClassDecl)
           Diag(SuperLoc, diag::err_undef_superclass)
@@ -576,7 +530,7 @@
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *SuperClassname,
                       SourceLocation SuperClassLoc) {
-  ObjCInterfaceDecl *IDecl = 0, *ODecl = 0;
+  ObjCInterfaceDecl* IDecl = 0;
   // Check for another declaration kind with the same name.
   NamedDecl *PrevDecl
     = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
@@ -584,10 +538,11 @@
   if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-  } else if ((ODecl = cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
-    // If we can't find a definition of the interface, warn.
-    if (!(IDecl = ODecl->getDefinition())) {
+  } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
+    // If this is a forward declaration of an interface, warn.
+    if (IDecl->isForwardDecl()) {
       Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
+      IDecl = 0;
     }
   } else {
     // We did not find anything with the name ClassName; try to correct for 
@@ -597,7 +552,7 @@
         (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
       // Suggest the (potentially) correct interface name. However, put the
       // fix-it hint itself in a separate note, since changing the name in 
-      // the warning would make the fix-it change semantics. Also, don't
+      // the warning would make the fix-it change semantics.However, don't
       // provide a code-modification hint or use the typo name for recovery,
       // because this is just a warning. The program may actually be correct.
       Diag(ClassLoc, diag::warn_undef_interface_suggest)
@@ -644,11 +599,16 @@
     // FIXME: Do we support attributes on the @implementation? If so we should
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
-                                      ClassName, ClassLoc, ODecl, false, true);
+                                      ClassName, ClassLoc, false, true);
     IDecl->setSuperClass(SDecl);
     IDecl->setLocEnd(ClassLoc);
 
     PushOnScopeChains(IDecl, TUScope);
+  } else {
+    // Mark the interface as being completed, even if it was just as
+    //   @class ....;
+    // declaration; the user cannot reopen it.
+    IDecl->setForwardDecl(false);
   }
 
   ObjCImplementationDecl* IMPDecl =
@@ -659,15 +619,15 @@
     return DeclPtrTy::make(IMPDecl);
 
   // Check that there is no duplicate implementation of this class.
-  if (IDecl && IDecl->getImplementation()) {
+  if (IDecl->getImplementation()) {
+    // FIXME: Don't leak everything!
     Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
     Diag(IDecl->getImplementation()->getLocation(),
          diag::note_previous_definition);
-  } else {
+  } else { // add it to the list.
     IDecl->setImplementation(IMPDecl);
     PushOnScopeChains(IMPDecl, TUScope);
   }
-
   return DeclPtrTy::make(IMPDecl);
 }
 
@@ -1069,18 +1029,19 @@
           PrevDecl = OI->getInterface();
       }
     }
-    ObjCInterfaceDecl *ODecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
-    ObjCInterfaceDecl *IDecl =
-        ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
-                                  IdentList[i], IdentLocs[i], ODecl, true);
-
-    // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
-    // the current DeclContext.  This prevents clients that walk DeclContext
-    // from seeing the imaginary ObjCInterfaceDecl until it is actually
-    // declared later (if at all).  We also take care to explicitly make
-    // sure this declaration is visible for name lookup.
-    PushOnScopeChains(IDecl, TUScope, false);
-    CurContext->makeDeclVisibleInContext(IDecl, true);
+    ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+    if (!IDecl) {  // Not already seen?  Make a forward decl.
+      IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
+                                        IdentList[i], IdentLocs[i], true);
+      
+      // Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
+      // the current DeclContext.  This prevents clients that walk DeclContext
+      // from seeing the imaginary ObjCInterfaceDecl until it is actually
+      // declared later (if at all).  We also take care to explicitly make
+      // sure this declaration is visible for name lookup.
+      PushOnScopeChains(IDecl, TUScope, false);
+      CurContext->makeDeclVisibleInContext(IDecl, true);
+    }
 
     Interfaces.push_back(IDecl);
   }

Modified: cfe/trunk/test/Index/TestClassDecl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/TestClassDecl.m?rev=110803&r1=110802&r2=110803&view=diff
==============================================================================
--- cfe/trunk/test/Index/TestClassDecl.m (original)
+++ cfe/trunk/test/Index/TestClassDecl.m Wed Aug 11 07:19:30 2010
@@ -17,7 +17,7 @@
 
 // CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
 // CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
-// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:8:8
+// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:10:12
 // CHECK-scan: [8:11 - 10:1] Invalid Cursor => NoDeclFound
 // CHECK-scan: [10:1 - 11:5] ObjCInterfaceDecl=Foo:10:12
 // CHECK-scan: [11:5 - 13:6] Invalid Cursor => NoDeclFound





More information about the cfe-commits mailing list