From: Douglas Gregor Date: Tue, 30 Aug 2011 20:49:19 +0000 (+0000) Subject: When writing out the entries in a lookup table for a DeclContext, make X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5a54b600f74dcb6cca27543df2757115711d80a;p=clang 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 . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138824 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 0cd2c8c7b0..b52baaf933 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2624,14 +2624,37 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, ASTDeclContextNameLookupTrait Trait(*this); // Create the on-disk hash table representation. + DeclarationName ConversionName; + llvm::SmallVector 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; diff --git a/test/PCH/Inputs/cxx-method.h b/test/PCH/Inputs/cxx-method.h new file mode 100644 index 0000000000..6adb859170 --- /dev/null +++ b/test/PCH/Inputs/cxx-method.h @@ -0,0 +1,6 @@ +struct S { + void m(int x); + + operator const char*(); + operator char*(); +}; diff --git a/test/PCH/cxx-method.cpp b/test/PCH/cxx-method.cpp index 37dabcc466..6ec65b2486 100644 --- a/test/PCH/cxx-method.cpp +++ b/test/PCH/cxx-method.cpp @@ -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; }