[llvm-branch-commits] [cfe-branch] r146720 - in /cfe/branches/tooling: ./ docs/ include/clang/AST/ lib/ARCMigrate/ lib/AST/ lib/Analysis/ lib/Basic/ lib/CodeGen/ lib/Rewrite/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Core/ test/CodeGenObjC/ test/Index/ test/Modules/ test/SemaObjC/ test/SemaObjCXX/ tools/libclang/

Chandler Carruth chandlerc at gmail.com
Thu Dec 15 17:59:36 PST 2011


Author: chandlerc
Date: Thu Dec 15 19:59:36 2011
New Revision: 146720

URL: http://llvm.org/viewvc/llvm-project?rev=146720&view=rev
Log:
Merge mainline through r146719.

Modified:
    cfe/branches/tooling/   (props changed)
    cfe/branches/tooling/docs/LanguageExtensions.html
    cfe/branches/tooling/include/clang/AST/DeclBase.h
    cfe/branches/tooling/include/clang/AST/DeclObjC.h
    cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp
    cfe/branches/tooling/lib/AST/ASTImporter.cpp
    cfe/branches/tooling/lib/AST/DeclBase.cpp
    cfe/branches/tooling/lib/AST/DeclObjC.cpp
    cfe/branches/tooling/lib/AST/DeclPrinter.cpp
    cfe/branches/tooling/lib/AST/DumpXML.cpp
    cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
    cfe/branches/tooling/lib/AST/Type.cpp
    cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp
    cfe/branches/tooling/lib/Basic/SourceManager.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
    cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
    cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp
    cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
    cfe/branches/tooling/lib/Sema/SemaDecl.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
    cfe/branches/tooling/lib/Sema/SemaLookup.cpp
    cfe/branches/tooling/lib/Sema/SemaOverload.cpp
    cfe/branches/tooling/lib/Sema/SemaType.cpp
    cfe/branches/tooling/lib/Serialization/ASTCommon.h
    cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/Store.cpp
    cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-getter-name.m
    cfe/branches/tooling/test/Index/TestClassDecl.m
    cfe/branches/tooling/test/Modules/decldef.mm
    cfe/branches/tooling/test/SemaObjC/forward-class-1.m
    cfe/branches/tooling/test/SemaObjCXX/overload.mm
    cfe/branches/tooling/tools/libclang/CIndex.cpp
    cfe/branches/tooling/tools/libclang/IndexDecl.cpp
    cfe/branches/tooling/tools/libclang/IndexingContext.h

Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Dec 15 19:59:36 2011
@@ -1,3 +1,3 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-146653
+/cfe/trunk:146581-146719
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/tooling/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/LanguageExtensions.html?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/docs/LanguageExtensions.html (original)
+++ cfe/branches/tooling/docs/LanguageExtensions.html Thu Dec 15 19:59:36 2011
@@ -357,20 +357,25 @@
   <dd>Defined when compiling with Clang</dd>
 
   <dt><code>__clang_major__</code></dt>
-  <dd>Defined to the major version number of Clang (e.g., the 2 in
-  2.0.1).</dd> 
+  <dd>Defined to the major marketing version number of Clang (e.g., the 
+  2 in 2.0.1).  Note that marketing version numbers should not be used to 
+  check for language features, as different vendors use different numbering
+  schemes.  Instead, use the <a href="#feature_check">feature checking
+  macros</a>.</dd> 
 
   <dt><code>__clang_minor__</code></dt>
   <dd>Defined to the minor version number of Clang (e.g., the 0 in
-  2.0.1).</dd> 
+  2.0.1).  Note that marketing version numbers should not be used to 
+  check for language features, as different vendors use different numbering
+  schemes.  Instead, use the <a href="#feature_check">feature checking
+  macros</a>.</dd> 
 
   <dt><code>__clang_patchlevel__</code></dt>
-  <dd>Defined to the patch level of Clang (e.g., the 1 in 2.0.1).</dd>
+  <dd>Defined to the marketing patch level of Clang (e.g., the 1 in 2.0.1).</dd>
 
   <dt><code>__clang_version__</code></dt>
-  <dd>Defined to a string that captures the Clang version, including
-  the Subversion tag or revision number, e.g., "1.5 (trunk
-  102332)".</dd> 
+  <dd>Defined to a string that captures the Clang marketing version, including
+  the Subversion tag or revision number, e.g., "1.5 (trunk 102332)".</dd> 
 </dl>
 
 <!-- ======================================================================= -->

Modified: cfe/branches/tooling/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclBase.h?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclBase.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclBase.h Thu Dec 15 19:59:36 2011
@@ -762,12 +762,12 @@
 
 /// \brief Determine whether two declarations declare the same entity.
 inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
-  if (D1 == D2)
-    return true;
-  
   if (!D1 || !D2)
     return false;
   
+  if (D1 == D2)
+    return true;
+  
   return D1->getCanonicalDecl() == D2->getCanonicalDecl();
 }
   

Modified: cfe/branches/tooling/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclObjC.h?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclObjC.h Thu Dec 15 19:59:36 2011
@@ -540,13 +540,18 @@
 ///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
 ///   typically inherit from NSObject (an exception is NSProxy).
 ///
-class ObjCInterfaceDecl : public ObjCContainerDecl {
+class ObjCInterfaceDecl : public ObjCContainerDecl
+                        , public Redeclarable<ObjCInterfaceDecl> {
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
   mutable const Type *TypeForDecl;
   friend class ASTContext;
   
   struct DefinitionData {
+    /// \brief The definition of this class, for quick access from any 
+    /// declaration.
+    ObjCInterfaceDecl *Definition;
+    
     /// Class's super class.
     ObjCInterfaceDecl *SuperClass;
 
@@ -571,49 +576,52 @@
     /// completed by the external AST source when required.
     mutable bool ExternallyCompleted : 1;
 
-    SourceLocation SuperClassLoc; // location of the super class identifier.
+    /// \brief The location of the superclass, if any.
+    SourceLocation SuperClassLoc;
+    
+    /// \brief The location of the last location in this declaration, before
+    /// the properties/methods. For example, this will be the '>', '}', or 
+    /// identifier, 
+    SourceLocation EndLoc; 
+
+    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 
+                       ExternallyCompleted() { }
   };
 
   ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, bool FD, bool isInternal);
+                    SourceLocation CLoc, bool isInternal);
 
   void LoadExternalDefinition() const;
 
   /// \brief Contains a pointer to the data associated with this class,
   /// which will be NULL if this class has not yet been defined.
-  DefinitionData *Definition;
-
-  /// \brief The location of the last location in this declaration, e.g.,
-  /// the '>', '}', or identifier.
-  /// FIXME: This seems like the wrong location to care about.
-  SourceLocation EndLoc; 
-
-  /// \brief True if it was initially declared with @class.
-  /// Differs with \see ForwardDecl in that \see ForwardDecl will change to
-  /// false when we see the @interface, but InitiallyForwardDecl will remain
-  /// true.
-  bool InitiallyForwardDecl : 1;
+  DefinitionData *Data;
 
   DefinitionData &data() const {
-    assert(Definition != 0 && "Declaration is not a definition!");
-    return *Definition;
+    assert(Data != 0 && "Declaration has no definition!");
+    return *Data;
   }
 
   /// \brief Allocate the definition data for this class.
   void allocateDefinitionData();
   
+  typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
+  virtual ObjCInterfaceDecl *getNextRedeclaration() { 
+    return RedeclLink.getNext(); 
+  }
+
 public:
   static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation atLoc,
                                    IdentifierInfo *Id,
                                    SourceLocation ClassLoc = SourceLocation(),
-                                   bool ForwardDecl = false,
                                    bool isInternal = false);
 
   virtual SourceRange getSourceRange() const {
-    if (isForwardDecl())
-      return SourceRange(getAtStartLoc(), getLocation());
-    return ObjCContainerDecl::getSourceRange();
+    if (isThisDeclarationADefinition())
+      return ObjCContainerDecl::getSourceRange();
+    
+    return SourceRange(getAtStartLoc(), getLocation());
   }
 
   /// \brief Indicate that this Objective-C class is complete, but that
@@ -759,32 +767,27 @@
                                        unsigned Num,
                                        ASTContext &C);
 
-  /// \brief True if it was initially declared with @class.
-  /// Differs with \see isForwardDecl in that \see isForwardDecl will change to
-  /// false when we see the @interface, but this will remain true.
-  bool isInitiallyForwardDecl() const { 
-    return InitiallyForwardDecl; 
+  /// \brief Determine whether this particular declaration of this class is
+  /// actually also a definition.
+  bool isThisDeclarationADefinition() const { 
+    return Data && Data->Definition == this;
   }
-
-  /// \brief Determine whether this declaration is a forward declaration of
-  /// the class.
-  bool isForwardDecl() const { return Definition == 0; }
-
+                          
   /// \brief Determine whether this class has been defined.
-  bool hasDefinition() const { return Definition != 0; }
-  
+  bool hasDefinition() const { return Data; }
+                        
   /// \brief Retrieve the definition of this class, or NULL if this class 
   /// has been forward-declared (with @class) but not yet defined (with 
   /// @interface).
   ObjCInterfaceDecl *getDefinition() {
-    return hasDefinition()? this : 0;
+    return hasDefinition()? Data->Definition : 0;
   }
 
   /// \brief Retrieve the definition of this class, or NULL if this class 
   /// has been forward-declared (with @class) but not yet defined (with 
   /// @interface).
   const ObjCInterfaceDecl *getDefinition() const {
-    return hasDefinition()? this : 0;
+    return hasDefinition()? Data->Definition : 0;
   }
 
   /// \brief Starts the definition of this Objective-C class, taking it from
@@ -872,10 +875,14 @@
   // Lookup a method in the classes implementation hierarchy.
   ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true);
 
-  // Location information, modeled after the Stmt API.
-  SourceLocation getLocStart() const { return getAtStartLoc(); } // '@'interface
-  SourceLocation getLocEnd() const { return EndLoc; }
-  void setLocEnd(SourceLocation LE) { EndLoc = LE; }
+  SourceLocation getEndOfDefinitionLoc() const { 
+    if (!hasDefinition())
+      return getLocation();
+    
+    return data().EndLoc; 
+  }
+                          
+  void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
 
   void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
   SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
@@ -893,6 +900,24 @@
                                bool lookupCategory,
                                bool RHSIsQualifiedID = false);
 
+  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();
+  }
+
+  /// Retrieves the canonical declaration of this Objective-C class.
+  ObjCInterfaceDecl *getCanonicalDecl() {
+    return getFirstDeclaration();
+  }
+  const ObjCInterfaceDecl *getCanonicalDecl() const {
+    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/branches/tooling/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp Thu Dec 15 19:59:36 2011
@@ -80,7 +80,7 @@
     ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl();
     if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject"))
       return false; // id/NSObject is not safe for weak.
-    if (!AllowOnUnknownClass && Class->isForwardDecl())
+    if (!AllowOnUnknownClass && !Class->hasDefinition())
       return false; // forward classes are not verifiable, therefore not safe.
     if (Class->isArcWeakrefUnavailable())
       return false;

Modified: cfe/branches/tooling/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTImporter.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTImporter.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTImporter.cpp Thu Dec 15 19:59:36 2011
@@ -3183,7 +3183,6 @@
       ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
                                           Importer.Import(D->getAtStartLoc()),
                                           Name.getAsIdentifierInfo(), Loc,
-                                          D->isInitiallyForwardDecl(),
                                           D->isImplicitInterfaceDecl());
       ToIface->setLexicalDeclContext(LexicalDC);
       LexicalDC->addDeclInternal(ToIface);

Modified: cfe/branches/tooling/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclBase.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclBase.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclBase.cpp Thu Dec 15 19:59:36 2011
@@ -779,9 +779,16 @@
     return this;
 
   case Decl::ObjCInterface:
+    if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(this)->getDefinition())
+      return Def;
+      
+    return this;
+      
   case Decl::ObjCProtocol:
+    // FIXME: Update when protocols properly model forward declarations.
+    // For now, it's fine to fall through
+      
   case Decl::ObjCCategory:
-    // FIXME: Can Objective-C interfaces be forward-declared?
     return this;
 
   case Decl::ObjCImplementation:

Modified: cfe/branches/tooling/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclObjC.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclObjC.cpp Thu Dec 15 19:59:36 2011
@@ -224,7 +224,15 @@
 
 void ObjCInterfaceDecl::allocateDefinitionData() {
   assert(!hasDefinition() && "ObjC class already has a definition");
-  Definition = new (getASTContext()) DefinitionData();  
+  Data = new (getASTContext()) DefinitionData();
+  Data->Definition = this;
+  
+  // 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() {
@@ -667,16 +675,15 @@
                                              SourceLocation atLoc,
                                              IdentifierInfo *Id,
                                              SourceLocation ClassLoc,
-                                             bool ForwardDecl, bool isInternal){
-  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
-                                     isInternal);
+                                             bool isInternal){
+  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, isInternal);
 }
 
 ObjCInterfaceDecl::
 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                  SourceLocation CLoc, bool FD, bool isInternal)
+                  SourceLocation CLoc, bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
-    TypeForDecl(0), Definition(), InitiallyForwardDecl(FD) 
+    TypeForDecl(0), Data()
 {
   setImplicit(isInternal);
 }
@@ -697,19 +704,20 @@
 }
 
 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
+  if (const ObjCInterfaceDecl *Def = getDefinition()) {
+    if (data().ExternallyCompleted)
+      LoadExternalDefinition();
+    
+    return getASTContext().getObjCImplementation(
+             const_cast<ObjCInterfaceDecl*>(Def));
+  }
+  
   // FIXME: Should make sure no callers ever do this.
-  if (!hasDefinition())
-    return 0;
-      
-  if (data().ExternallyCompleted)
-    LoadExternalDefinition();
-
-  return getASTContext().getObjCImplementation(
-                                          const_cast<ObjCInterfaceDecl*>(this));
+  return 0;
 }
 
 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
-  getASTContext().setObjCImplementation(this, ImplD);
+  getASTContext().setObjCImplementation(getDefinition(), ImplD);
 }
 
 /// all_declared_ivar_begin - return first ivar declared in this class,
@@ -843,6 +851,14 @@
   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/branches/tooling/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclPrinter.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclPrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclPrinter.cpp Thu Dec 15 19:59:36 2011
@@ -900,16 +900,16 @@
   std::string I = OID->getNameAsString();
   ObjCInterfaceDecl *SID = OID->getSuperClass();
 
+  if (!OID->isThisDeclarationADefinition()) {
+    Out << "@class " << I << ";";
+    return;
+  }
+  
   if (SID)
     Out << "@interface " << I << " : " << *SID;
   else
     Out << "@interface " << I;
 
-  if (OID->isForwardDecl()) {
-    Out << "@end";
-    return;
-  }
-  
   // Protocols?
   const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
   if (!Protocols.empty()) {

Modified: cfe/branches/tooling/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DumpXML.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DumpXML.cpp (original)
+++ cfe/branches/tooling/lib/AST/DumpXML.cpp Thu Dec 15 19:59:36 2011
@@ -755,7 +755,7 @@
   }
   void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
     setPointer("typeptr", D->getTypeForDecl());
-    setFlag("forward_decl", D->isForwardDecl());
+    setFlag("forward_decl", !D->isThisDeclarationADefinition());
     setFlag("implicit_interface", D->isImplicitInterfaceDecl());
   }
   void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {

Modified: cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp Thu Dec 15 19:59:36 2011
@@ -2161,7 +2161,7 @@
 const ASTRecordLayout &
 ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
                           const ObjCImplementationDecl *Impl) const {
-  assert(!D->isForwardDecl() && "Invalid interface decl!");
+  assert(D->isThisDeclarationADefinition() && "Invalid interface decl!");
 
   // Look up this layout, if already laid out, return what we have.
   ObjCContainerDecl *Key =

Modified: cfe/branches/tooling/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Type.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Type.cpp (original)
+++ cfe/branches/tooling/lib/AST/Type.cpp Thu Dec 15 19:59:36 2011
@@ -927,7 +927,7 @@
                                                          ->isIncompleteType();
   case ObjCInterface:
     // ObjC interfaces are incomplete if they are @class, not @interface.
-    return cast<ObjCInterfaceType>(CanonicalType)->getDecl()->isForwardDecl();
+    return !cast<ObjCInterfaceType>(CanonicalType)->getDecl()->hasDefinition();
   }
 }
 

Modified: cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp Thu Dec 15 19:59:36 2011
@@ -115,7 +115,7 @@
   
   // Assume that anything declared with a forward declaration and no
   // @interface subclasses NSObject.
-  if (ID->isForwardDecl())
+  if (!ID->hasDefinition())
     return true;
   
   for ( ; ID ; ID = ID->getSuperClass())

Modified: cfe/branches/tooling/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/SourceManager.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/SourceManager.cpp (original)
+++ cfe/branches/tooling/lib/Basic/SourceManager.cpp Thu Dec 15 19:59:36 2011
@@ -382,13 +382,17 @@
   // content cache objects are bump pointer allocated, we just have to run the
   // dtors, but we call the deallocate method for completeness.
   for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
-    MemBufferInfos[i]->~ContentCache();
-    ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
+    if (MemBufferInfos[i]) {
+      MemBufferInfos[i]->~ContentCache();
+      ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
+    }
   }
   for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
        I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
-    I->second->~ContentCache();
-    ContentCacheAlloc.Deallocate(I->second);
+    if (I->second) {
+      I->second->~ContentCache();
+      ContentCacheAlloc.Deallocate(I->second);
+    }
   }
   
   delete FakeBufferForRecovery;

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Thu Dec 15 19:59:36 2011
@@ -1211,7 +1211,8 @@
 
   // If this is just a forward declaration return a special forward-declaration
   // debug type since we won't be able to lay out the entire type.
-  if (ID->isForwardDecl()) {
+  ObjCInterfaceDecl *Def = ID->getDefinition();
+  if (!Def) {
     llvm::DIType FwdDecl =
       DBuilder.createStructType(Unit, ID->getName(),
                                 DefUnit, Line, 0, 0,
@@ -1219,6 +1220,7 @@
                                 llvm::DIArray(), RuntimeLang);
     return FwdDecl;
   }
+  ID = Def;
 
   // To handle a recursive interface, we first generate a debug descriptor
   // for the struct as a forward declaration. Then (if it is a definition)

Modified: cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp Thu Dec 15 19:59:36 2011
@@ -653,8 +653,9 @@
       ConstantStringClassReference = FVD;
       return;
     }
-  } else if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D)) {
-    RewriteInterfaceDecl(MD);
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    if (ID->isThisDeclarationADefinition())
+      RewriteInterfaceDecl(ID);
   } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
     RewriteCategoryDecl(CD);
   } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
@@ -673,9 +674,18 @@
         SourceLocation Loc = D->getLocation();
         while (DI != DIEnd &&
                isa<ObjCClassDecl>(D) && D->getLocation() == Loc) {
+          ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
           DG.push_back(D);
           ++DI;
           D = (*DI);
+
+          // Following the ObjCClassDecl, we should have the corresponding
+          // ObjCInterfaceDecl. Skip over it.
+          if (DI != DIEnd && isa<ObjCInterfaceDecl>(D) && 
+              Class->getForwardInterfaceDecl() == D) {
+            ++DI;
+            D = (*DI);
+          }
         }
         RewriteForwardClassDecl(DG);
         continue;
@@ -1179,7 +1189,7 @@
 
 void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
   std::string ResultStr;
-  if (!ObjCForwardDecls.count(ClassDecl)) {
+  if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
     // we haven't seen a forward decl - generate a typedef.
     ResultStr = "#ifndef _REWRITER_typedef_";
     ResultStr += ClassDecl->getNameAsString();
@@ -1191,7 +1201,7 @@
     ResultStr += ClassDecl->getNameAsString();
     ResultStr += ";\n#endif\n";
     // Mark this typedef as having been generated.
-    ObjCForwardDecls.insert(ClassDecl);
+    ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
   }
   RewriteObjCInternalStruct(ClassDecl, ResultStr);
 
@@ -3123,14 +3133,14 @@
   ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
   int NumIvars = CDecl->ivar_size();
   SourceLocation LocStart = CDecl->getLocStart();
-  SourceLocation LocEnd = CDecl->getLocEnd();
+  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
 
   const char *startBuf = SM->getCharacterData(LocStart);
   const char *endBuf = SM->getCharacterData(LocEnd);
 
   // If no ivars and no root or if its root, directly or indirectly,
   // have no ivars (thus not synthesized) then no need to synthesize this class.
-  if ((CDecl->isForwardDecl() || NumIvars == 0) &&
+  if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) &&
       (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
     endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
     ReplaceText(LocStart, endBuf-startBuf, Result);
@@ -5357,7 +5367,7 @@
   
   // Explicitly declared @interface's are already synthesized.
   if (CDecl->isImplicitInterfaceDecl()) {
-    // FIXME: Implementation of a class with no @interface (legacy) doese not
+    // FIXME: Implementation of a class with no @interface (legacy) does not
     // produce correct synthesis as yet.
     RewriteObjCInternalStruct(CDecl, Result);
   }

Modified: cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp Thu Dec 15 19:59:36 2011
@@ -318,15 +318,6 @@
     return DMK_Ignore;
   }
   
-  // If the declarations are both Objective-C classes, and one is a forward
-  // declaration and the other is not, take the full definition.
-  // FIXME: At some point, we'll actually have to detect collisions better.
-  // This logic, however, belongs in the AST reader, not here.
-  if (ObjCInterfaceDecl *ExistingIFace = dyn_cast<ObjCInterfaceDecl>(Existing))
-    if (ObjCInterfaceDecl *NewIFace = dyn_cast<ObjCInterfaceDecl>(New))
-      if (ExistingIFace->isForwardDecl() != NewIFace->isForwardDecl())
-        return ExistingIFace->isForwardDecl()? DMK_Replace : DMK_Ignore;
-        
   return DMK_Different;
 }
 

Modified: cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp Thu Dec 15 19:59:36 2011
@@ -5487,14 +5487,14 @@
        D != DEnd; ++D) {
     // Record any interfaces we find.
     if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
-      if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+      if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
           (!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)) {
       ObjCInterfaceDecl *IDecl = Forward->getForwardInterfaceDecl();
-      if ((!OnlyForwardDeclarations || IDecl->isForwardDecl()) &&
+      if ((!OnlyForwardDeclarations || !IDecl->hasDefinition()) &&
           (!OnlyUnimplemented || !IDecl->getImplementation()))
         Results.AddResult(Result(IDecl, 0), CurContext,
                           0, false);

Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Thu Dec 15 19:59:36 2011
@@ -5946,7 +5946,7 @@
     return;
   }
 
-  // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
+  // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
     TypeSourceInfo *DeducedType = 0;
     if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
@@ -5969,7 +5969,14 @@
     if (VarDecl *Old = VDecl->getPreviousDeclaration())
       MergeVarDeclTypes(VDecl, Old);
   }
-  
+
+  if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
+    // C99 6.7.8p5. C++ has no such restriction, but that is a defect.
+    Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
+    VDecl->setInvalidDecl();
+    return;
+  }
+
 
   // A definition must end up with a complete type, which means it must be
   // complete with the restriction that an array type might be completed by the
@@ -6036,44 +6043,58 @@
     return;
   }
 
-  // Capture the variable that is being initialized and the style of
-  // initialization.
-  InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
-  
-  // FIXME: Poor source location information.
-  InitializationKind Kind
-    = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(),
-                                                   Init->getLocStart(),
-                                                   Init->getLocEnd())
-                : InitializationKind::CreateCopy(VDecl->getLocation(),
-                                                 Init->getLocStart());
-  
   // Get the decls type and save a reference for later, since
   // CheckInitializerTypes may change it.
   QualType DclT = VDecl->getType(), SavT = DclT;
-  if (VDecl->isLocalVarDecl()) {
-    if (VDecl->hasExternalStorage()) { // C99 6.7.8p5
-      Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
+
+  // Perform the initialization.
+  if (!VDecl->isInvalidDecl()) {
+    InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+    InitializationKind Kind
+      = DirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(),
+                                                      Init->getLocStart(),
+                                                      Init->getLocEnd())
+                   : InitializationKind::CreateCopy(VDecl->getLocation(),
+                                                    Init->getLocStart());
+
+    InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+    ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                              MultiExprArg(*this, &Init, 1),
+                                              &DclT);
+    if (Result.isInvalid()) {
       VDecl->setInvalidDecl();
-    } else if (!VDecl->isInvalidDecl()) {
-      InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
-      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                                MultiExprArg(*this, &Init, 1),
-                                                &DclT);
-      if (Result.isInvalid()) {
-        VDecl->setInvalidDecl();
-        return;
-      }
+      return;
+    }
 
-      Init = Result.takeAs<Expr>();
+    Init = Result.takeAs<Expr>();
+  }
 
-      // C++ 3.6.2p2, allow dynamic initialization of static initializers.
-      // Don't check invalid declarations to avoid emitting useless diagnostics.
-      if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
-        if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4.
-          CheckForConstantInitializer(Init, DclT);
-      }
-    }
+  // If the type changed, it means we had an incomplete type that was
+  // completed by the initializer. For example:
+  //   int ary[] = { 1, 3, 5 };
+  // "ary" transitions from a VariableArrayType to a ConstantArrayType.
+  if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
+    VDecl->setType(DclT);
+    Init->setType(DclT.getNonReferenceType());
+  }
+
+  // Check any implicit conversions within the expression.
+  CheckImplicitConversions(Init, VDecl->getLocation());
+
+  if (!VDecl->isInvalidDecl())
+    checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init);
+
+  Init = MaybeCreateExprWithCleanups(Init);
+  // Attach the initializer to the decl.
+  VDecl->setInit(Init);
+
+  if (VDecl->isLocalVarDecl()) {
+    // C99 6.7.8p4: All the expressions in an initializer for an object that has
+    // static storage duration shall be constant expressions or string literals.
+    // C++ does not have this restriction.
+    if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl() &&
+        VDecl->getStorageClass() == SC_Static)
+      CheckForConstantInitializer(Init, DclT);
   } else if (VDecl->isStaticDataMember() &&
              VDecl->getLexicalDeclContext()->isRecord()) {
     // This is an in-class initialization for a static data member, e.g.,
@@ -6082,26 +6103,12 @@
     //   static const int value = 17;
     // };
 
-    // Try to perform the initialization regardless.
-    if (!VDecl->isInvalidDecl()) {
-      InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
-      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                          MultiExprArg(*this, &Init, 1),
-                                          &DclT);
-      if (Result.isInvalid()) {
-        VDecl->setInvalidDecl();
-        return;
-      }
-
-      Init = Result.takeAs<Expr>();
-    }
-
     // C++ [class.mem]p4:
     //   A member-declarator can contain a constant-initializer only
     //   if it declares a static member (9.4) of const integral or
     //   const enumeration type, see 9.4.2.
     //
-    // C++0x [class.static.data]p3:
+    // C++11 [class.static.data]p3:
     //   If a non-volatile const static data member is of integral or
     //   enumeration type, its declaration in the class definition can
     //   specify a brace-or-equal-initializer in which every initalizer-clause
@@ -6110,10 +6117,9 @@
     //   with the constexpr specifier; if so, its declaration shall specify a
     //   brace-or-equal-initializer in which every initializer-clause that is
     //   an assignment-expression is a constant expression.
-    QualType T = VDecl->getType();
 
     // Do nothing on dependent types.
-    if (T->isDependentType()) {
+    if (DclT->isDependentType()) {
 
     // Allow any 'static constexpr' members, whether or not they are of literal
     // type. We separately check that the initializer is a constant expression,
@@ -6121,17 +6127,17 @@
     } else if (VDecl->isConstexpr()) {
 
     // Require constness.
-    } else if (!T.isConstQualified()) {
+    } else if (!DclT.isConstQualified()) {
       Diag(VDecl->getLocation(), diag::err_in_class_initializer_non_const)
         << Init->getSourceRange();
       VDecl->setInvalidDecl();
 
     // We allow integer constant expressions in all cases.
-    } else if (T->isIntegralOrEnumerationType()) {
+    } else if (DclT->isIntegralOrEnumerationType()) {
       // Check whether the expression is a constant expression.
       SourceLocation Loc;
-      if (getLangOptions().CPlusPlus0x && T.isVolatileQualified())
-        // In C++0x, a non-constexpr const static data member with an
+      if (getLangOptions().CPlusPlus0x && DclT.isVolatileQualified())
+        // In C++11, a non-constexpr const static data member with an
         // in-class initializer cannot be volatile.
         Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile);
       else if (Init->isValueDependent())
@@ -6151,77 +6157,43 @@
         VDecl->setInvalidDecl();
       }
 
-    // We allow floating-point constants as an extension.
-    } else if (T->isFloatingType()) { // also permits complex, which is ok
+    // We allow foldable floating-point constants as an extension.
+    } else if (DclT->isFloatingType()) { // also permits complex, which is ok
       Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type)
-        << T << Init->getSourceRange();
+        << DclT << Init->getSourceRange();
       if (getLangOptions().CPlusPlus0x)
         Diag(VDecl->getLocation(),
              diag::note_in_class_initializer_float_type_constexpr)
           << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
 
-      if (!Init->isValueDependent() &&
-          !Init->isConstantInitializer(Context, false)) {
+      if (!Init->isValueDependent() && !Init->isEvaluatable(Context)) {
         Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant)
           << Init->getSourceRange();
         VDecl->setInvalidDecl();
       }
 
-    // Suggest adding 'constexpr' in C++0x for literal types.
-    } else if (getLangOptions().CPlusPlus0x && T->isLiteralType()) {
+    // Suggest adding 'constexpr' in C++11 for literal types.
+    } else if (getLangOptions().CPlusPlus0x && DclT->isLiteralType()) {
       Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type)
-        << T << Init->getSourceRange()
+        << DclT << Init->getSourceRange()
         << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
       VDecl->setConstexpr(true);
 
     } else {
       Diag(VDecl->getLocation(), diag::err_in_class_initializer_bad_type)
-        << T << Init->getSourceRange();
+        << DclT << Init->getSourceRange();
       VDecl->setInvalidDecl();
     }
   } else if (VDecl->isFileVarDecl()) {
-    if (VDecl->getStorageClassAsWritten() == SC_Extern && 
-        (!getLangOptions().CPlusPlus || 
+    if (VDecl->getStorageClassAsWritten() == SC_Extern &&
+        (!getLangOptions().CPlusPlus ||
          !Context.getBaseElementType(VDecl->getType()).isConstQualified()))
       Diag(VDecl->getLocation(), diag::warn_extern_init);
-    if (!VDecl->isInvalidDecl()) {
-      InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
-      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                                MultiExprArg(*this, &Init, 1),
-                                                &DclT);
-      if (Result.isInvalid()) {
-        VDecl->setInvalidDecl();
-        return;
-      }
 
-      Init = Result.takeAs<Expr>();
-    }
-
-    // C++ 3.6.2p2, allow dynamic initialization of static initializers.
-    // Don't check invalid declarations to avoid emitting useless diagnostics.
-    if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
-      // C99 6.7.8p4. All file scoped initializers need to be constant.
+    // C99 6.7.8p4. All file scoped initializers need to be constant.
+    if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl())
       CheckForConstantInitializer(Init, DclT);
-    }
-  }
-  // If the type changed, it means we had an incomplete type that was
-  // completed by the initializer. For example:
-  //   int ary[] = { 1, 3, 5 };
-  // "ary" transitions from a VariableArrayType to a ConstantArrayType.
-  if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
-    VDecl->setType(DclT);
-    Init->setType(DclT.getNonReferenceType());
   }
-  
-  // Check any implicit conversions within the expression.
-  CheckImplicitConversions(Init, VDecl->getLocation());
-  
-  if (!VDecl->isInvalidDecl())
-    checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init);
-
-  Init = MaybeCreateExprWithCleanups(Init);
-  // Attach the initializer to the decl.
-  VDecl->setInit(Init);
 
   CheckCompleteVariableDeclaration(VDecl);
 }
@@ -9369,7 +9341,7 @@
     ObjCIvarDecl **ClsFields =
       reinterpret_cast<ObjCIvarDecl**>(RecFields.data());
     if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) {
-      ID->setLocEnd(RBrac);
+      ID->setEndOfDefinitionLoc(RBrac);
       // Add ivar's to class's DeclContext.
       for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
         ClsFields[i]->setLexicalDeclContext(ID);

Modified: cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp Thu Dec 15 19:59:36 2011
@@ -60,7 +60,7 @@
 
     // It's okay for the result type to still be a forward declaration
     // if we're checking an interface declaration.
-    if (resultClass->isForwardDecl()) {
+    if (!resultClass->hasDefinition()) {
       if (receiverTypeIfCall.isNull() &&
           !isa<ObjCImplementationDecl>(method->getDeclContext()))
         return false;
@@ -365,45 +365,31 @@
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
   }
 
-  ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
-  if (IDecl) {
-    // Class already seen. Is it a forward declaration?
-    if (ObjCInterfaceDecl *Def = IDecl->getDefinition()) {
-      IDecl->setInvalidDecl();
-      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
+  // Create a declaration to describe this @interface.
+  ObjCInterfaceDecl *IDecl
+    = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
+                                ClassLoc);
+  
+  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+  if (PrevIDecl) {
+    // Class already seen. Was it a definition?
+    if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
+      Diag(AtInterfaceLoc, diag::err_duplicate_class_def)
+        << PrevIDecl->getDeclName();
       Diag(Def->getLocation(), diag::note_previous_definition);
-
-      // Create a new one; the other may be in a different DeclContex, (e.g.
-      // this one may be in a LinkageSpecDecl while the other is not) which
-      // will break invariants.
-      IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
-                                        ClassName, ClassLoc);
-      if (AttrList)
-        ProcessDeclAttributeList(TUScope, IDecl, AttrList);
-      PushOnScopeChains(IDecl, TUScope);
-
-    } else {
-      IDecl->setLocation(ClassLoc);
-      IDecl->setAtStartLoc(AtInterfaceLoc);
-      
-      // 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);
+      IDecl->setInvalidDecl();
     }
-  } else {
-    IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
-                                      ClassName, ClassLoc);
-    if (AttrList)
-      ProcessDeclAttributeList(TUScope, IDecl, AttrList);
 
-    PushOnScopeChains(IDecl, TUScope);
+    // Link to the previous declaration.
+    IDecl->setPreviousDeclaration(PrevIDecl);
   }
+  
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  PushOnScopeChains(IDecl, TUScope);
 
+  // Start the definition of this class. If we're in a redefinition case, there 
+  // may already be a definition, so we'll end up adding to it.
   if (!IDecl->hasDefinition())
     IDecl->startDefinition();
   
@@ -433,7 +419,7 @@
     if (declaresSameEntity(PrevDecl, IDecl)) {
       Diag(SuperLoc, diag::err_recursive_superclass)
         << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
-      IDecl->setLocEnd(ClassLoc);
+      IDecl->setEndOfDefinitionLoc(ClassLoc);
     } else {
       ObjCInterfaceDecl *SuperClassDecl =
                                 dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
@@ -480,17 +466,17 @@
       }
       IDecl->setSuperClass(SuperClassDecl);
       IDecl->setSuperClassLoc(SuperLoc);
-      IDecl->setLocEnd(SuperLoc);
+      IDecl->setEndOfDefinitionLoc(SuperLoc);
     }
   } else { // we have a root class.
-    IDecl->setLocEnd(ClassLoc);
+    IDecl->setEndOfDefinitionLoc(ClassLoc);
   }
 
   // Check then save referenced protocols.
   if (NumProtoRefs) {
     IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
                            ProtoLocs, Context);
-    IDecl->setLocEnd(EndProtoLoc);
+    IDecl->setEndOfDefinitionLoc(EndProtoLoc);
   }
 
   CheckObjCDeclScope(IDecl);
@@ -942,11 +928,16 @@
     // FIXME: Do we support attributes on the @implementation? If so we should
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
-                                      ClassName, ClassLoc, false, true);
+                                      ClassName, ClassLoc, true);
     IDecl->startDefinition();
-    IDecl->setSuperClass(SDecl);
-    IDecl->setLocEnd(ClassLoc);
-
+    if (SDecl) {
+      IDecl->setSuperClass(SDecl);
+      IDecl->setSuperClassLoc(SuperClassLoc);
+      IDecl->setEndOfDefinitionLoc(SuperClassLoc);
+    } else {
+      IDecl->setEndOfDefinitionLoc(ClassLoc);
+    }
+    
     PushOnScopeChains(IDecl, TUScope);
   } else {
     // Mark the interface as being completed, even if it was just as
@@ -992,7 +983,7 @@
   /// (legacy objective-c @implementation decl without an @interface decl).
   /// Add implementations's ivar to the synthesize class's ivar list.
   if (IDecl->isImplicitInterfaceDecl()) {
-    IDecl->setLocEnd(RBrace);
+    IDecl->setEndOfDefinitionLoc(RBrace);
     // Add ivar's to class's DeclContext.
     for (unsigned i = 0, e = numIvars; i != e; ++i) {
       ivars[i]->setLexicalDeclContext(ImpDecl);
@@ -1781,22 +1772,28 @@
           PrevDecl = OI->getInterface();
       }
     }
-    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);
-    }
+    
+    // Create a declaration to describe this forward declaration.
+    ObjCInterfaceDecl *IDecl
+      = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
+                                  IdentList[i], 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.
+    // FIXME: ObjCClassDecl should probably just go away.
     ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
                                                  IDecl, IdentLocs[i]);
     CurContext->addDecl(CDecl);
+    
+    PushOnScopeChains(IDecl, TUScope);
+    
     CheckObjCDeclScope(CDecl);
     DeclsInGroup.push_back(CDecl);
   }

Modified: cfe/branches/tooling/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaLookup.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaLookup.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaLookup.cpp Thu Dec 15 19:59:36 2011
@@ -1063,6 +1063,8 @@
     return FD->getPreviousDeclaration();
   if (RedeclarableTemplateDecl *RTD = dyn_cast<RedeclarableTemplateDecl>(D))
     return RTD->getPreviousDeclaration();
+  if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+    return ID->getPreviousDeclaration();
   
   return 0;
 }

Modified: cfe/branches/tooling/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaOverload.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaOverload.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaOverload.cpp Thu Dec 15 19:59:36 2011
@@ -2262,7 +2262,7 @@
 }
 
 /// FunctionArgTypesAreEqual - This routine checks two function proto types
-/// for equlity of their argument types. Caller has already checked that
+/// for equality of their argument types. Caller has already checked that
 /// they have same number of arguments. This routine assumes that Objective-C
 /// pointer types which only differ in their protocol qualifiers are equal.
 /// If the parameters are different, ArgPos will have the the parameter index
@@ -2300,8 +2300,9 @@
                  ToType->getAs<ObjCObjectPointerType>()) {
         if (const ObjCObjectPointerType *PTFr =
               FromType->getAs<ObjCObjectPointerType>())
-          if (declaresSameEntity(PTTo->getInterfaceDecl(), 
-                                 PTFr->getInterfaceDecl()))
+          if (Context.hasSameUnqualifiedType(
+                PTTo->getObjectType()->getBaseType(),
+                PTFr->getObjectType()->getBaseType()))
             continue;
       }
       if (ArgPos) *ArgPos = O - OldType->arg_type_begin();

Modified: cfe/branches/tooling/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaType.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaType.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaType.cpp Thu Dec 15 19:59:36 2011
@@ -4065,6 +4065,34 @@
   if (!T->isIncompleteType())
     return false;
 
+  const TagType *Tag = T->getAs<TagType>();
+  const ObjCInterfaceType *IFace = 0;
+  
+  if (Tag) {
+    // Avoid diagnosing invalid decls as incomplete.
+    if (Tag->getDecl()->isInvalidDecl())
+      return true;
+
+    // Give the external AST source a chance to complete the type.
+    if (Tag->getDecl()->hasExternalLexicalStorage()) {
+      Context.getExternalSource()->CompleteType(Tag->getDecl());
+      if (!Tag->isIncompleteType())
+        return false;
+    }
+  }
+  else if ((IFace = T->getAs<ObjCInterfaceType>())) {
+    // Avoid diagnosing invalid decls as incomplete.
+    if (IFace->getDecl()->isInvalidDecl())
+      return true;
+    
+    // Give the external AST source a chance to complete the type.
+    if (IFace->getDecl()->hasExternalLexicalStorage()) {
+      Context.getExternalSource()->CompleteType(IFace->getDecl());
+      if (!IFace->isIncompleteType())
+        return false;
+    }
+  }
+    
   // If we have a class template specialization or a class member of a
   // class template specialization, or an array with known size of such,
   // try to instantiate it.
@@ -4096,34 +4124,6 @@
 
   if (diag == 0)
     return true;
-
-  const TagType *Tag = T->getAs<TagType>();
-  const ObjCInterfaceType *IFace = 0;
-  
-  if (Tag) {
-    // Avoid diagnosing invalid decls as incomplete.
-    if (Tag->getDecl()->isInvalidDecl())
-      return true;
-
-    // Give the external AST source a chance to complete the type.
-    if (Tag->getDecl()->hasExternalLexicalStorage()) {
-      Context.getExternalSource()->CompleteType(Tag->getDecl());
-      if (!Tag->isIncompleteType())
-        return false;
-    }
-  }
-  else if ((IFace = T->getAs<ObjCInterfaceType>())) {
-    // Avoid diagnosing invalid decls as incomplete.
-    if (IFace->getDecl()->isInvalidDecl())
-      return true;
-    
-    // Give the external AST source a chance to complete the type.
-    if (IFace->getDecl()->hasExternalLexicalStorage()) {
-      Context.getExternalSource()->CompleteType(IFace->getDecl());
-      if (!IFace->isIncompleteType())
-        return false;
-    }
-  }
     
   // We have an incomplete type. Produce a diagnostic.
   Diag(Loc, PD) << T;

Modified: cfe/branches/tooling/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTCommon.h?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTCommon.h (original)
+++ cfe/branches/tooling/lib/Serialization/ASTCommon.h Thu Dec 15 19:59:36 2011
@@ -26,7 +26,8 @@
   UPD_CXX_ADDED_IMPLICIT_MEMBER,
   UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
   UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
-  UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER
+  UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
+  UPD_OBJC_SET_CLASS_DEFINITIONDATA
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);

Modified: cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp Thu Dec 15 19:59:36 2011
@@ -554,6 +554,7 @@
 }
 
 void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
+  VisitRedeclarable(ID);
   VisitObjCContainerDecl(ID);
   ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
   
@@ -568,6 +569,8 @@
     Data.SuperClass = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
     Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
 
+    Data.EndLoc = ReadSourceLocation(Record, Idx);
+    
     // Read the directly referenced protocols and their SourceLocations.
     unsigned NumProtocols = Record[Idx++];
     SmallVector<ObjCProtocolDecl *, 16> Protocols;
@@ -612,25 +615,21 @@
       for (ASTReader::ForwardRefs::iterator I = Refs.begin(), 
                                             E = Refs.end(); 
            I != E; ++I)
-        cast<ObjCInterfaceDecl>(*I)->Definition = ID->Definition;
+        cast<ObjCInterfaceDecl>(*I)->Data = ID->Data;
 #ifndef NDEBUG
       // We later check whether PendingForwardRefs is empty to make sure all
       // pending references were linked.
       Reader.PendingForwardRefs.erase(ID);
 #endif
-    
     } else if (Def) {
-      if (Def->Definition) {
-        ID->Definition = Def->Definition;
+      if (Def->Data) {
+        ID->Data = Def->Data;
       } else {
         // The definition is still initializing.
         Reader.PendingForwardRefs[Def].push_back(ID);
       }
     }
   }
-  
-  ID->InitiallyForwardDecl = Record[Idx++];
-  ID->setLocEnd(ReadSourceLocation(Record, Idx));
 }
 
 void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
@@ -2067,6 +2066,19 @@
       cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
           Reader.ReadSourceLocation(ModuleFile, Record, Idx));
       break;
+    
+    case UPD_OBJC_SET_CLASS_DEFINITIONDATA: {
+      ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
+      ObjCInterfaceDecl *Def
+        = Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
+      if (Def->Data) {
+        ID->Data = Def->Data;
+      } else {
+        // The definition is still initializing.
+        Reader.PendingForwardRefs[Def].push_back(ID);
+      }
+      break;
+    }
     }
   }
 }

Modified: cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriter.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriter.cpp Thu Dec 15 19:59:36 2011
@@ -3439,6 +3439,7 @@
       case UPD_CXX_ADDED_IMPLICIT_MEMBER:
       case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
       case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
+      case UPD_OBJC_SET_CLASS_DEFINITIONDATA:
         URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
         ++Idx;
         break;
@@ -4379,10 +4380,26 @@
 
 void ASTWriter::CompletedObjCForwardRef(const ObjCContainerDecl *D) {
   assert(!WritingAST && "Already writing the AST!");
-  if (!D->isFromASTFile())
-    return; // Declaration not imported from PCH.
+  if (D->isFromASTFile())
+    RewriteDecl(D);
 
-  RewriteDecl(D);
+  if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    for (ObjCInterfaceDecl::redecl_iterator I = ID->redecls_begin(), 
+                                            E = ID->redecls_end(); 
+         I != E; ++I) {
+      if (*I == ID)
+        continue;
+      
+      // We are interested when a PCH decl is modified.
+      if (I->isFromASTFile()) {
+        UpdateRecord &Record = DeclUpdates[*I];
+        Record.push_back(UPD_OBJC_SET_CLASS_DEFINITIONDATA);
+        assert((*I)->hasDefinition());
+        assert((*I)->getDefinition() == D);
+        Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
+      }
+    }
+  }
 }
 
 void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,

Modified: cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp Thu Dec 15 19:59:36 2011
@@ -447,6 +447,7 @@
 }
 
 void ASTDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+  VisitRedeclarable(D);
   VisitObjCContainerDecl(D);
   Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
 
@@ -459,7 +460,8 @@
     
     Writer.AddDeclRef(D->getSuperClass(), Record);
     Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
-    
+    Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record);
+
     // Write out the protocols that are directly referenced by the @interface.
     Record.push_back(Data.ReferencedProtocols.size());
     for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
@@ -488,8 +490,6 @@
     Writer.AddDeclRef(D->getCategoryList(), Record);
   }  
   
-  Record.push_back(D->isInitiallyForwardDecl());
-  Writer.AddSourceLocation(D->getLocEnd(), Record);
   Code = serialization::DECL_OBJC_INTERFACE;
 }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp Thu Dec 15 19:59:36 2011
@@ -327,9 +327,5 @@
     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
   }
 
-  // Check for casts from integers to integers.
-  if (castTy->isIntegerType() && originalTy->isIntegerType())
-    return dispatchCast(val, castTy);
-
   return dispatchCast(val, castTy);
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp Thu Dec 15 19:59:36 2011
@@ -58,9 +58,10 @@
 // Transfer function for Casts.
 //===----------------------------------------------------------------------===//
 
-SVal SimpleSValBuilder::dispatchCast(SVal val, QualType castTy) {
-  return isa<Loc>(val) ? evalCastFromLoc(cast<Loc>(val), castTy)
-                       : evalCastFromNonLoc(cast<NonLoc>(val), castTy);
+SVal SimpleSValBuilder::dispatchCast(SVal Val, QualType CastTy) {
+  assert(isa<Loc>(&Val) || isa<NonLoc>(&Val));
+  return isa<Loc>(Val) ? evalCastFromLoc(cast<Loc>(Val), CastTy)
+                       : evalCastFromNonLoc(cast<NonLoc>(Val), CastTy);
 }
 
 SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/Store.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/Store.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/Store.cpp Thu Dec 15 19:59:36 2011
@@ -227,7 +227,6 @@
     return V;
   }
   
-  assert(isa<Loc>(&V) || isa<NonLoc>(&V));
   return svalBuilder.dispatchCast(V, castTy);
 }
 

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m Thu Dec 15 19:59:36 2011
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-fragile-abi %s -o - | FileCheck %s
 extern void foo(void(^)(void));
 
-// CHECK: !36 = metadata !{i32 720942, i32 0, metadata !6, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !6, i32 24, metadata !37, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !39} ; [ DW_TAG_subprogram ]
+// CHECK: !36 = metadata !{i32 720942, i32 0, metadata !6, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !6, i32 24, metadata !37, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !39} ; [ DW_TAG_subprogram ]
 
 @interface NSObject {
   struct objc_object *isa;

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-getter-name.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-getter-name.m?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-getter-name.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-getter-name.m Thu Dec 15 19:59:36 2011
@@ -1,7 +1,7 @@
 // REQUIRES: x86-64-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -fexceptions -fobjc-exceptions -g %s -o - | FileCheck %s
 
-// CHECK: !30 = metadata !{i32 720942, i32 0, metadata !6, metadata !"-[InstanceVariablesEverywhereButTheInterface someString]", metadata !"-[InstanceVariablesEverywhereButTheInterface someString]", metadata !"", metadata !6, i32 27, metadata !31, i1 true, i1 true, i32 0, i32 0, i32 0, i32 320, i1 false, %1* (%0*, i8*)* @"\01-[InstanceVariablesEverywhereButTheInterface someString]", null, null, metadata !33} ; [ DW_TAG_subprogram ]
+// CHECK: !30 = metadata !{i32 720942, i32 0, metadata !6, metadata !"-[InstanceVariablesEverywhereButTheInterface someString]", metadata !"-[InstanceVariablesEverywhereButTheInterface someString]", metadata !"", metadata !6, i32 27, metadata !31, i1 true, i1 true, i32 0, i32 0, null, i32 320, i1 false, %1* (%0*, i8*)* @"\01-[InstanceVariablesEverywhereButTheInterface someString]", null, null, metadata !33} ; [ DW_TAG_subprogram ]
 
 //rdar: //8498026
 

Modified: cfe/branches/tooling/test/Index/TestClassDecl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/TestClassDecl.m?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/TestClassDecl.m (original)
+++ cfe/branches/tooling/test/Index/TestClassDecl.m Thu Dec 15 19:59:36 2011
@@ -16,7 +16,7 @@
 }
 
 // CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
-// CHECK-scan: [8:1 - 8:8] UnexposedDecl=[10:12]
+// CHECK-scan: [8:1 - 8:8] UnexposedDecl=[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

Modified: cfe/branches/tooling/test/Modules/decldef.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Modules/decldef.mm?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/Modules/decldef.mm (original)
+++ cfe/branches/tooling/test/Modules/decldef.mm Thu Dec 15 19:59:36 2011
@@ -7,9 +7,7 @@
 
 __import_module__ decldef.Decl;
 
-// FIXME: No link between @interface (which we can't see) and @class
-// (which we can).
-// A *a2;
+A *a2;
 B *b;
 
 void testB() {

Modified: cfe/branches/tooling/test/SemaObjC/forward-class-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/forward-class-1.m?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/forward-class-1.m (original)
+++ cfe/branches/tooling/test/SemaObjC/forward-class-1.m Thu Dec 15 19:59:36 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

Modified: cfe/branches/tooling/test/SemaObjCXX/overload.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjCXX/overload.mm?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjCXX/overload.mm (original)
+++ cfe/branches/tooling/test/SemaObjCXX/overload.mm Thu Dec 15 19:59:36 2011
@@ -171,3 +171,9 @@
     int &fr = (f)(x, 0); 
   }
 }
+
+namespace class_id {
+  // it's okay to overload Class with id.
+  void f(Class) { }
+  void f(id) { }
+}

Modified: cfe/branches/tooling/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndex.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndex.cpp Thu Dec 15 19:59:36 2011
@@ -299,12 +299,7 @@
 
     // We handle forward decls via ObjCClassDecl.
     if (ObjCInterfaceDecl *InterD = dyn_cast<ObjCInterfaceDecl>(D)) {
-      if (InterD->isForwardDecl())
-        continue;
-      // An interface that started as a forward decl may have changed location
-      // because its @interface was parsed.
-      if (InterD->isInitiallyForwardDecl() &&
-          !SM.isInFileID(SM.getFileLoc(InterD->getLocation()), File))
+      if (!InterD->isThisDeclarationADefinition())
         continue;
     }
 
@@ -3948,8 +3943,13 @@
     case CXCursor_ObjCProtocolRef: {
       return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu);
 
-    case CXCursor_ObjCClassRef:
-      return MakeCXCursor(getCursorObjCClassRef(C).first, tu );
+    case CXCursor_ObjCClassRef: {
+      ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+      if (ObjCInterfaceDecl *Def = Class->getDefinition())
+        return MakeCXCursor(Def, tu);
+
+      return MakeCXCursor(Class, tu);
+    }
 
     case CXCursor_TypeRef:
       return MakeCXCursor(getCursorTypeRef(C).first, tu );
@@ -4147,8 +4147,8 @@
     // the definition; when we were provided with the interface,
     // produce the @implementation as the definition.
     if (WasReference) {
-      if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl())
-        return C;
+      if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(D)->getDefinition())
+        return MakeCXCursor(Def, TU);
     } else if (ObjCImplementationDecl *Impl
                               = cast<ObjCInterfaceDecl>(D)->getImplementation())
       return MakeCXCursor(Impl, TU);
@@ -4162,8 +4162,8 @@
   case Decl::ObjCCompatibleAlias:
     if (ObjCInterfaceDecl *Class
           = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
-      if (!Class->isForwardDecl())
-        return MakeCXCursor(Class, TU);
+      if (ObjCInterfaceDecl *Def = Class->getDefinition())
+        return MakeCXCursor(Def, TU);
 
     return clang_getNullCursor();
 

Modified: cfe/branches/tooling/tools/libclang/IndexDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexDecl.cpp?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexDecl.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexDecl.cpp Thu Dec 15 19:59:36 2011
@@ -97,7 +97,7 @@
 
   bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
     // Forward decls are handled at VisitObjCClassDecl.
-    if (D->isForwardDecl())
+    if (!D->isThisDeclarationADefinition())
       return true;
 
     IndexCtx.handleObjCInterface(D);

Modified: cfe/branches/tooling/tools/libclang/IndexingContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexingContext.h?rev=146720&r1=146719&r2=146720&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexingContext.h (original)
+++ cfe/branches/tooling/tools/libclang/IndexingContext.h Thu Dec 15 19:59:36 2011
@@ -128,7 +128,7 @@
   ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D)
     : ObjCContainerDeclInfo(Info_ObjCInterface,
                             /*isForwardRef=*/false,
-                            /*isRedeclaration=*/D->isInitiallyForwardDecl(),
+                          /*isRedeclaration=*/D->getPreviousDeclaration() != 0,
                             /*isImplementation=*/false) { }
 
   static bool classof(const DeclInfo *D) {





More information about the llvm-branch-commits mailing list