forked from OSchip/llvm-project
When writing out the entries in a lookup table for a DeclContext, make
sure that all of the CXXConversionDecls go into the same bucket. Otherwise, name lookup might not find them all. Fixes <rdar://problem/10041960>. llvm-svn: 138824
This commit is contained in:
parent
f3458e5594
commit
05ef93158d
|
@ -2624,14 +2624,37 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
|
|||
ASTDeclContextNameLookupTrait Trait(*this);
|
||||
|
||||
// Create the on-disk hash table representation.
|
||||
DeclarationName ConversionName;
|
||||
llvm::SmallVector<NamedDecl *, 4> ConversionDecls;
|
||||
for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
|
||||
D != DEnd; ++D) {
|
||||
DeclarationName Name = D->first;
|
||||
DeclContext::lookup_result Result = D->second.getLookupResult();
|
||||
if (Result.first != Result.second)
|
||||
if (Result.first != Result.second) {
|
||||
if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
|
||||
// Hash all conversion function names to the same name. The actual
|
||||
// type information in conversion function name is not used in the
|
||||
// key (since such type information is not stable across different
|
||||
// modules), so the intended effect is to coalesce all of the conversion
|
||||
// functions under a single key.
|
||||
if (!ConversionName)
|
||||
ConversionName = Name;
|
||||
ConversionDecls.append(Result.first, Result.second);
|
||||
continue;
|
||||
}
|
||||
|
||||
Generator.insert(Name, Result, Trait);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the conversion functions
|
||||
if (!ConversionDecls.empty()) {
|
||||
Generator.insert(ConversionName,
|
||||
DeclContext::lookup_result(ConversionDecls.begin(),
|
||||
ConversionDecls.end()),
|
||||
Trait);
|
||||
}
|
||||
|
||||
// Create the on-disk hash table in a buffer.
|
||||
llvm::SmallString<4096> LookupTable;
|
||||
uint32_t BucketOffset;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
struct S {
|
||||
void m(int x);
|
||||
|
||||
operator const char*();
|
||||
operator char*();
|
||||
};
|
|
@ -1,7 +1,8 @@
|
|||
// RUN: %clang_cc1 -emit-pch %s -o %t
|
||||
|
||||
struct S {
|
||||
void m(int x);
|
||||
};
|
||||
// RUN: %clang_cc1 -x c++ -emit-pch %S/Inputs/cxx-method.h -o %t
|
||||
// RUN: %clang_cc1 -include-pch %t -verify %s
|
||||
|
||||
void S::m(int x) { }
|
||||
|
||||
S::operator char *() { return 0; }
|
||||
|
||||
S::operator const char *() { return 0; }
|
||||
|
|
Loading…
Reference in New Issue