]> granicus.if.org Git - clang/commitdiff
When writing out the entries in a lookup table for a DeclContext, make
authorDouglas Gregor <dgregor@apple.com>
Tue, 30 Aug 2011 20:49:19 +0000 (20:49 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 30 Aug 2011 20:49:19 +0000 (20:49 +0000)
sure that all of the CXXConversionDecls go into the same
bucket. Otherwise, name lookup might not find them all. Fixes
<rdar://problem/10041960>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138824 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTWriter.cpp
test/PCH/Inputs/cxx-method.h [new file with mode: 0644]
test/PCH/cxx-method.cpp

index 0cd2c8c7b0b1b414e0f1cbdc2695f3c174b2afff..b52baaf9335cadcb643174f7ff0b9472e95324f1 100644 (file)
@@ -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;
diff --git a/test/PCH/Inputs/cxx-method.h b/test/PCH/Inputs/cxx-method.h
new file mode 100644 (file)
index 0000000..6adb859
--- /dev/null
@@ -0,0 +1,6 @@
+struct S {
+  void m(int x);
+
+  operator const char*();
+  operator char*();
+};
index 37dabcc466a8b65ee93ba96b129ee5d28449cff2..6ec65b24861810c7ed5bfc2b0e7022fb9fa62cad 100644 (file)
@@ -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; }