summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-24 01:46:41 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-24 01:46:41 +0000
commit51445cd3078617c84e87d9c97b129f59aa906cc5 (patch)
tree9d6e983ac956253508608fe230e54feb716f8dc8 /clang/lib/AST/DeclBase.cpp
parent6ea058245e0192c82274b3f5b3161c63722488dc (diff)
downloadbcm5719-llvm-51445cd3078617c84e87d9c97b129f59aa906cc5.tar.gz
bcm5719-llvm-51445cd3078617c84e87d9c97b129f59aa906cc5.zip
When setting the external visible declarations for a decl context, check
whether they replace any existing lookups in the context, rather than accumulating a bunch of lookup results referring to the same entity. llvm-svn: 184679
Diffstat (limited to 'clang/lib/AST/DeclBase.cpp')
-rw-r--r--clang/lib/AST/DeclBase.cpp39
1 files changed, 32 insertions, 7 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 084a4321d8f..fb13766ad0a 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -1012,13 +1012,38 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
Map = DC->CreateStoredDeclsMap(Context);
StoredDeclsList &List = (*Map)[Name];
- for (ArrayRef<NamedDecl*>::iterator
- I = Decls.begin(), E = Decls.end(); I != E; ++I) {
- if (List.isNull())
- List.setOnlyValue(*I);
- else
- // FIXME: Need declarationReplaces handling for redeclarations in modules.
- List.AddSubsequentDecl(*I);
+
+ // Clear out any old external visible declarations, to avoid quadratic
+ // performance in the redeclaration checks below.
+ List.removeExternalDecls();
+
+ if (!List.isNull()) {
+ // We have both existing declarations and new declarations for this name.
+ // Some of the declarations may simply replace existing ones. Handle those
+ // first.
+ llvm::SmallVector<unsigned, 8> Skip;
+ for (unsigned I = 0, N = Decls.size(); I != N; ++I)
+ if (List.HandleRedeclaration(Decls[I]))
+ Skip.push_back(I);
+ Skip.push_back(Decls.size());
+
+ // Add in any new declarations.
+ unsigned SkipPos = 0;
+ for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
+ if (I == Skip[SkipPos])
+ ++SkipPos;
+ else
+ List.AddSubsequentDecl(Decls[I]);
+ }
+ } else {
+ // Convert the array to a StoredDeclsList.
+ for (ArrayRef<NamedDecl*>::iterator
+ I = Decls.begin(), E = Decls.end(); I != E; ++I) {
+ if (List.isNull())
+ List.setOnlyValue(*I);
+ else
+ List.AddSubsequentDecl(*I);
+ }
}
return List.getLookupResult();
OpenPOWER on IntegriCloud