]> granicus.if.org Git - clang/commitdiff
Do not register ObjCInterfaceDecls implicitly created by @class in the
authorTed Kremenek <kremenek@apple.com>
Tue, 17 Nov 2009 22:58:30 +0000 (22:58 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 17 Nov 2009 22:58:30 +0000 (22:58 +0000)
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).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89160 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/DeclBase.cpp
lib/Sema/SemaDeclObjC.cpp

index da3b19df5b60784d9e56f1da5c263a8c95ad4c0a..c3c506e5ba198b999c0da385f74c0708694cb8ca 100644 (file)
@@ -673,6 +673,13 @@ void DeclContext::buildLookup(DeclContext *DCtx) {
         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))
index a5fdb8725c865d6067f6d1f62086c8e57ba82696..54b0c3afab0c5c53835a89048aaa3081e7506bc3 100644 (file)
@@ -112,6 +112,12 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
       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 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
                                         // 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);