summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-24 07:20:36 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-24 07:20:36 +0000
commitcf4ab520b555bb764a72d648f2820f3deb943d29 (patch)
treeceb26c690189dff5c396c40aa1732dfa0920cf4e
parentce1ae387d658f872c8495bf51b6823b1d6aa1fa9 (diff)
downloadbcm5719-llvm-cf4ab520b555bb764a72d648f2820f3deb943d29.tar.gz
bcm5719-llvm-cf4ab520b555bb764a72d648f2820f3deb943d29.zip
Avoid adding entries to the DeclContext lookup table multiple times when lazily
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. llvm-svn: 184696
-rw-r--r--clang/lib/AST/DeclBase.cpp10
-rw-r--r--clang/test/Modules/cxx-templates.cpp4
2 files changed, 9 insertions, 5 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index fb13766ad0a..815f9ed90c2 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -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
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp
index bc96772083a..79268127389 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -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.
OpenPOWER on IntegriCloud