From 05ef93158dc8ac7801129ef328ba1de3bdb4b709 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 30 Aug 2011 20:49:19 +0000 Subject: [PATCH] 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 . llvm-svn: 138824 --- clang/lib/Serialization/ASTWriter.cpp | 25 ++++++++++++++++++++++++- clang/test/PCH/Inputs/cxx-method.h | 6 ++++++ clang/test/PCH/cxx-method.cpp | 11 ++++++----- 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 clang/test/PCH/Inputs/cxx-method.h diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 0cd2c8c7b0b1..b52baaf9335c 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/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/clang/test/PCH/Inputs/cxx-method.h b/clang/test/PCH/Inputs/cxx-method.h new file mode 100644 index 000000000000..6adb8591707d --- /dev/null +++ b/clang/test/PCH/Inputs/cxx-method.h @@ -0,0 +1,6 @@ +struct S { + void m(int x); + + operator const char*(); + operator char*(); +}; diff --git a/clang/test/PCH/cxx-method.cpp b/clang/test/PCH/cxx-method.cpp index 37dabcc466a8..6ec65b248618 100644 --- a/clang/test/PCH/cxx-method.cpp +++ b/clang/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; }