]> granicus.if.org Git - clang/commitdiff
Avoid adding entries to the DeclContext lookup table multiple times when lazily
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Jun 2013 07:20:36 +0000 (07:20 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Jun 2013 07:20:36 +0000 (07:20 +0000)
constructing a lookup table.

Previously, buildLookup would add lookup table entries for each item lexically
within the DC, and adding the first entry with a given name would trigger the
external source to add all its entries with that name. Then buildLookup would
carry on and re-add those entries all over again.

Instead, follow a simple rule: a declaration from an external source is only
ever made visible by the external source. One exception to this: since we don't
usually build a lookup table for the TU in C, and we never serialize one, we
don't expect the external source to provide lookups in the TU in C, so we build
those ones ourselves.

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

lib/AST/DeclBase.cpp
test/Modules/cxx-templates.cpp

index fb13766ad0ae7bee72db6b781b4e557b7d204ba5..815f9ed90c2780642cf73d321903e08760e153a2 100644 (file)
@@ -1216,8 +1216,16 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx) {
     // Insert this declaration into the lookup structure, but only if
     // it's semantically within its decl context. Any other decls which
     // should be found in this context are added eagerly.
+    //
+    // If it's from an AST file, don't add it now. It'll get handled by
+    // FindExternalVisibleDeclsByName if needed. Exception: if we're not
+    // in C++, we do not track external visible decls for the TU, so in
+    // that case we need to collect them all here.
     if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
-      if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND))
+      if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND) &&
+          (!ND->isFromASTFile() ||
+           (isTranslationUnit() &&
+            !getParentASTContext().getLangOpts().CPlusPlus)))
         makeDeclVisibleInContextImpl(ND, false);
 
     // If this declaration is itself a transparent declaration context
index bc96772083ac2ab9b7fc8c7e30421d8ad9f9beec..79268127389a965679256dbad9b8149f361ff7f2 100644 (file)
@@ -27,10 +27,6 @@ void g() {
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
-// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
-// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
-// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
-// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f'
 
 // FIXME: There should only be two 'f's here.