[PATCH] Fix PR18307: Properly (de)serialize inherited constructors and their using declarations

Stephan Tolksdorf st at quanttec.com
Tue Mar 25 16:44:19 PDT 2014


  I've rebased the patch.

Hi rsmith,

http://llvm-reviews.chandlerc.com/D3102

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D3102?vs=7961&id=8118#toc

Files:
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/PCH/cxx11-inheriting-ctors.cpp

Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1348,7 +1348,9 @@
 
 void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   VisitCXXMethodDecl(D);
-  
+
+  if (auto *CD = ReadDeclAs<CXXConstructorDecl>(Record, Idx))
+    D->setInheritedConstructor(CD);
   D->IsExplicitSpecified = Record[Idx++];
   std::tie(D->CtorInitializers, D->NumCtorInitializers) =
       Reader.ReadCXXCtorInitializers(F, Record, Idx);
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3411,24 +3411,35 @@
   ASTDeclContextNameLookupTrait Trait(*this);
 
   // Create the on-disk hash table representation.
+  DeclarationName ConstructorName;
   DeclarationName ConversionName;
+  SmallVector<NamedDecl *, 8> ConstructorDecls;
   SmallVector<NamedDecl *, 4> ConversionDecls;
 
   auto AddLookupResult = [&](DeclarationName Name,
                              DeclContext::lookup_result Result) {
     if (Result.empty())
       return;
 
-    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.
+    // Different DeclarationName values of certain kinds are mapped to
+    // identical serialized keys, because we don't want to use type
+    // identifiers in the keys (since type ids are local to the module).
+    switch (Name.getNameKind()) {
+    case DeclarationName::CXXConstructorName:
+      // There may be different CXXConstructorName DeclarationName values
+      // in a DeclContext because a UsingDecl that inherits constructors
+      // has the DeclarationName of the inherited constructors.
+      if (!ConstructorName)
+        ConstructorName = Name;
+      ConstructorDecls.append(Result.begin(), Result.end());
+      return;
+    case DeclarationName::CXXConversionFunctionName:
       if (!ConversionName)
         ConversionName = Name;
       ConversionDecls.append(Result.begin(), Result.end());
       return;
+    default:
+      break;
     }
 
     Generator.insert(Name, Result, Trait);
@@ -3458,7 +3469,14 @@
     // FIXME: const_cast since OnDiskHashTable wants a non-const lookup result.
     AddLookupResult(Name, const_cast<DeclContext*>(DC)->lookup(Name));
 
-  // Add the conversion functions
+  // Add the constructors.
+  if (!ConstructorDecls.empty()) {
+    Generator.insert(ConstructorName,
+                     DeclContext::lookup_result(ConstructorDecls.begin(),
+                                                ConstructorDecls.end()),
+                     Trait);
+  }
+  // Add the conversion functions.
   if (!ConversionDecls.empty()) {
     Generator.insert(ConversionName,
                      DeclContext::lookup_result(ConversionDecls.begin(),
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1030,6 +1030,7 @@
 void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   VisitCXXMethodDecl(D);
 
+  Writer.AddDeclRef(D->getInheritedConstructor(), Record);
   Record.push_back(D->IsExplicitSpecified);
   Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers,
                                 Record);
Index: test/PCH/cxx11-inheriting-ctors.cpp
===================================================================
--- /dev/null
+++ test/PCH/cxx11-inheriting-ctors.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+struct Base {
+  Base(int) {}
+
+  template <typename T>
+  Base(T) {}
+};
+
+struct Test : Base {
+  using Base::Base;
+};
+
+template <typename T>
+struct Test2 : Base {
+  using Base::Base;
+};
+
+template <typename B>
+struct Test3 : B {
+  using B::B;
+};
+
+#else
+
+Test test1a(42);
+Test test1b(nullptr);
+Test2<int> test2a(42);
+Test2<int> test2b(nullptr);
+Test3<Base> test3a(42);
+Test3<Base> test3b(nullptr);
+
+#endif // HEADER_INCLUDED
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3102.3.patch
Type: text/x-patch
Size: 4593 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140325/a0eb242e/attachment.bin>


More information about the cfe-commits mailing list