diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-24 01:46:41 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-24 01:46:41 +0000 |
commit | 51445cd3078617c84e87d9c97b129f59aa906cc5 (patch) | |
tree | 9d6e983ac956253508608fe230e54feb716f8dc8 /clang/lib/AST/DeclBase.cpp | |
parent | 6ea058245e0192c82274b3f5b3161c63722488dc (diff) | |
download | bcm5719-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.cpp | 39 |
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(); |