Add SourceLocations to ObjCClassDecl for the class identifiers referenced by @class.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89170 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index c3c506e..abcffed 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -678,7 +678,7 @@
       if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
         for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
              I != IEnd; ++I)
-          makeDeclVisibleInContextImpl(*I);
+          makeDeclVisibleInContextImpl(I->getInterface());
       
       // If this declaration is itself a transparent declaration context,
       // add its members (recursively).
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 7b48b72..9d43c7c 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -571,31 +571,46 @@
 //===----------------------------------------------------------------------===//
 
 ObjCClassDecl::ObjCClassDecl(DeclContext *DC, SourceLocation L,
-                             ObjCInterfaceDecl *const *Elts, unsigned nElts,
+                             ObjCInterfaceDecl *const *Elts,
+                             const SourceLocation *Locs,
+                             unsigned nElts,
                              ASTContext &C)
   : Decl(ObjCClass, DC, L) {
-  ForwardDecls.set(Elts, nElts, C);
+  setClassList(C, Elts, Locs, nElts);
 }
 
+void ObjCClassDecl::setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+                                 const SourceLocation *Locs, unsigned Num) {
+  ForwardDecls = (ObjCClassRef*) C.Allocate(sizeof(ObjCClassRef)*Num,
+                                            llvm::alignof<ObjCClassRef>());
+  for (unsigned i = 0; i < Num; ++i)
+    new (&ForwardDecls[i]) ObjCClassRef(List[i], Locs[i]);
+  
+  NumDecls = Num;
+}
 
 ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation L,
                                      ObjCInterfaceDecl *const *Elts,
+                                     const SourceLocation *Locs,
                                      unsigned nElts) {
-  return new (C) ObjCClassDecl(DC, L, Elts, nElts, C);
+  return new (C) ObjCClassDecl(DC, L, Elts, Locs, nElts, C);
 }
 
 void ObjCClassDecl::Destroy(ASTContext &C) {
-
-  // FIXME: There is no clear ownership policy now for referenced
-  //  ObjCInterfaceDecls.  Some of them can be forward declarations that
-  //  are never later defined (in which case the ObjCClassDecl owns them)
-  //  or the ObjCInterfaceDecl later becomes a real definition later.  Ideally
-  //  we should have separate objects for forward declarations and definitions,
-  //  obviating this problem.  Because of this situation, referenced
-  //  ObjCInterfaceDecls are destroyed in ~TranslationUnit.
-
-  ForwardDecls.Destroy(C);
+  // ObjCInterfaceDecls registered with a DeclContext will get destroyed
+  // when the DeclContext is destroyed.  For those created only by a forward
+  // declaration, the first @class that created the ObjCInterfaceDecl gets
+  // to destroy it.
+  // FIXME: Note that this ownership role is very brittle; a better
+  // polict is surely need in the future.
+  for (iterator I = begin(), E = end(); I !=E ; ++I) {
+    ObjCInterfaceDecl *ID = I->getInterface();
+    if (ID->isForwardDecl() && ID->getLocStart() == getLocStart())
+      ID->Destroy(C);
+  }
+  
+  C.Deallocate(ForwardDecls);
   Decl::Destroy(C);
 }
 
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 199ed35..645133b 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -624,7 +624,7 @@
   for (ObjCClassDecl::iterator I = D->begin(), E = D->end();
        I != E; ++I) {
     if (I != D->begin()) Out << ", ";
-    Out << (*I)->getNameAsString();
+    Out << I->getInterface()->getNameAsString();
   }
 }