[cfe-commits] r89160 - in /cfe/trunk/lib: AST/DeclBase.cpp Sema/SemaDeclObjC.cpp

Ted Kremenek kremenek at apple.com
Tue Nov 17 14:58:30 PST 2009


Author: kremenek
Date: Tue Nov 17 16:58:30 2009
New Revision: 89160

URL: http://llvm.org/viewvc/llvm-project?rev=89160&view=rev
Log:
Do not register ObjCInterfaceDecls implicitly created by @class in the
current DeclContext.  These "imaginary" declarations pose issues for
clients searching DeclContext for actual declarations.  Instead,
register them for name lookup, and add the ObjCInterfaceDecl later to
the DeclContext when we hit an actual @interface declaration.

This also fixes a bug where the invariant that the Decls in a
DeclContext are sorted in order of their appearance is no longer
violated.  What could happen is that an @class causes an
ObjCInterfaceDecl to get added first to the DeclContext, then the
ObjCClassDecl itself is added, and then later the SourceLocation of
the ObjCInterfaceDecl is updated with the correct location (which is
later in the file).  This breaks an assumed invariant in
ResolveLocation.cpp (and possibly other clients).

Modified:
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

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

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Nov 17 16:58:30 2009
@@ -673,6 +673,13 @@
         if (D->getDeclContext() == DCtx)
           makeDeclVisibleInContextImpl(ND);
 
+      // Insert any forward-declared Objective-C interfaces into the lookup
+      // data structure.
+      if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
+        for (ObjCClassDecl::iterator I = Class->begin(), IEnd = Class->end();
+             I != IEnd; ++I)
+          makeDeclVisibleInContextImpl(*I);
+      
       // If this declaration is itself a transparent declaration context,
       // add its members (recursively).
       if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Nov 17 16:58:30 2009
@@ -112,6 +112,12 @@
       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).
+      CurContext->addDecl(IDecl);
+      
       if (AttrList)
         ProcessDeclAttributeList(TUScope, IDecl, AttrList);
     }
@@ -1194,7 +1200,14 @@
                                         // FIXME: need to get the 'real'
                                         // identifier loc from the parser.
                                         AtClassLoc, true);
-      PushOnScopeChains(IDecl, TUScope);
+      
+      // 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);





More information about the cfe-commits mailing list