forked from OSchip/llvm-project
Fix stack overflow and improve performance when a module contains many
overloads of a name by claiming that there are no lookup results for that name in modules while loading the names from the module. Lookups in deserialization really don't want to find names which they themselves are in the process of introducing. This also has the pleasant side-effect of automatically caching PCH lookups which found no names. The runtime here is still quadratic in the number of overloads, but the constant is lower. llvm-svn: 174685
This commit is contained in:
parent
e4c7e855f1
commit
75fc3bf5fe
|
@ -1203,14 +1203,16 @@ DeclContext::lookup(DeclarationName Name) {
|
|||
if (LookupPtr.getInt())
|
||||
Map = buildLookup();
|
||||
|
||||
if (!Map)
|
||||
Map = CreateStoredDeclsMap(getParentASTContext());
|
||||
|
||||
// If a PCH/module has a result for this name, and we have a local
|
||||
// declaration, we will have imported the PCH/module result when adding the
|
||||
// local declaration or when reconciling the module.
|
||||
if (Map) {
|
||||
StoredDeclsMap::iterator I = Map->find(Name);
|
||||
if (I != Map->end())
|
||||
return I->second.getLookupResult();
|
||||
}
|
||||
std::pair<StoredDeclsMap::iterator, bool> R =
|
||||
Map->insert(std::make_pair(Name, StoredDeclsList()));
|
||||
if (!R.second)
|
||||
return R.first->second.getLookupResult();
|
||||
|
||||
ExternalASTSource *Source = getParentASTContext().getExternalSource();
|
||||
if (Source->FindExternalVisibleDeclsByName(this, Name)) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -167,3 +167,7 @@ module weird_objc {
|
|||
module ignored_macros {
|
||||
header "ignored_macros.h"
|
||||
}
|
||||
|
||||
module cxx_many_overloads {
|
||||
header "cxx-many-overloads.h"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodule-cache-path %t -I %S/Inputs %s -verify
|
||||
|
||||
// expected-no-diagnostics
|
||||
@import cxx_many_overloads;
|
||||
|
||||
void g() {
|
||||
f(N::X<0>());
|
||||
}
|
Loading…
Reference in New Issue