[cfe-commits] r89170 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclBase.cpp lib/AST/DeclObjC.cpp lib/AST/DeclPrinter.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp lib/Frontend/RewriteObjC.cpp lib/Sema/SemaDeclObjC.cpp

Ted Kremenek kremenek at apple.com
Tue Nov 17 16:28:11 PST 2009


Author: kremenek
Date: Tue Nov 17 18:28:11 2009
New Revision: 89170

URL: http://llvm.org/viewvc/llvm-project?rev=89170&view=rev
Log:
Add SourceLocations to ObjCClassDecl for the class identifiers referenced by @class.

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/lib/Frontend/RewriteObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Nov 17 18:28:11 2009
@@ -718,10 +718,22 @@
 /// @class NSCursor, NSImage, NSPasteboard, NSWindow;
 ///
 class ObjCClassDecl : public Decl {
-  ObjCList<ObjCInterfaceDecl> ForwardDecls;
+public:
+  class ObjCClassRef {
+    ObjCInterfaceDecl *ID;
+    SourceLocation L;
+  public:
+    ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
+    SourceLocation getLocation() const { return L; }
+    ObjCInterfaceDecl *getInterface() const { return ID; }
+  };
+private:
+  ObjCClassRef *ForwardDecls;
+  unsigned NumDecls;
 
   ObjCClassDecl(DeclContext *DC, SourceLocation L,
-                ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C);
+                ObjCInterfaceDecl *const *Elts, const SourceLocation *Locs,                
+                unsigned nElts, ASTContext &C);
   virtual ~ObjCClassDecl() {}
 public:
 
@@ -730,17 +742,17 @@
 
   static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                                ObjCInterfaceDecl *const *Elts = 0,
+                               const SourceLocation *Locs = 0,
                                unsigned nElts = 0);
 
-  typedef ObjCList<ObjCInterfaceDecl>::iterator iterator;
-  iterator begin() const { return ForwardDecls.begin(); }
-  iterator end() const { return ForwardDecls.end(); }
-  unsigned size() const { return ForwardDecls.size(); }
+  typedef const ObjCClassRef* iterator;
+  iterator begin() const { return ForwardDecls; }
+  iterator end() const { return ForwardDecls + NumDecls; }
+  unsigned size() const { return NumDecls; }
 
   /// setClassList - Set the list of forward classes.
-  void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) {
-    ForwardDecls.set(List, Num, C);
-  }
+  void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List,
+                    const SourceLocation *Locs, unsigned Num);
 
   static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
   static bool classof(const ObjCClassDecl *D) { return true; }

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Nov 17 18:28:11 2009
@@ -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).

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Nov 17 18:28:11 2009
@@ -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);
 }
 

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Nov 17 18:28:11 2009
@@ -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();
   }
 }
 

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Tue Nov 17 18:28:11 2009
@@ -264,7 +264,12 @@
   ClassRefs.reserve(NumClassRefs);
   for (unsigned I = 0; I != NumClassRefs; ++I)
     ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
-  CD->setClassList(*Reader.getContext(), ClassRefs.data(), NumClassRefs);
+  llvm::SmallVector<SourceLocation, 16> SLocs;
+  SLocs.reserve(NumClassRefs);
+  for (unsigned I = 0; I != NumClassRefs; ++I)
+    SLocs.push_back(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  CD->setClassList(*Reader.getContext(), ClassRefs.data(), SLocs.data(),
+                   NumClassRefs);
 }
 
 void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Tue Nov 17 18:28:11 2009
@@ -260,7 +260,9 @@
   VisitDecl(D);
   Record.push_back(D->size());
   for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
-    Writer.AddDeclRef(*I, Record);
+    Writer.AddDeclRef(I->getInterface(), Record);
+  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
+    Writer.AddSourceLocation(I->getLocation(), Record);
   Code = pch::DECL_OBJC_CLASS;
 }
 

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue Nov 17 18:28:11 2009
@@ -744,7 +744,7 @@
   typedefString += "\n";
   for (ObjCClassDecl::iterator I = ClassDecl->begin(), E = ClassDecl->end();
        I != E; ++I) {
-    ObjCInterfaceDecl *ForwardDecl = *I;
+    ObjCInterfaceDecl *ForwardDecl = I->getInterface();
     typedefString += "#ifndef _REWRITER_typedef_";
     typedefString += ForwardDecl->getNameAsString();
     typedefString += "\n";

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=89170&r1=89169&r2=89170&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Nov 17 18:28:11 2009
@@ -1197,10 +1197,7 @@
     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],
-                                        // FIXME: need to get the 'real'
-                                        // identifier loc from the parser.
-                                        AtClassLoc, true);
+                                        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
@@ -1214,8 +1211,9 @@
     Interfaces.push_back(IDecl);
   }
 
+  assert(Interfaces.size() == NumElts);
   ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
-                                               &Interfaces[0],
+                                               Interfaces.data(), IdentLocs,
                                                Interfaces.size());
   CurContext->addDecl(CDecl);
   CheckObjCDeclScope(CDecl);





More information about the cfe-commits mailing list