r204951 - Fix PR18307: Properly (de)serialize inherited constructors and their using declarations

Stephan Tolksdorf st at quanttec.com
Thu Mar 27 12:22:20 PDT 2014


Author: stephant
Date: Thu Mar 27 14:22:19 2014
New Revision: 204951

URL: http://llvm.org/viewvc/llvm-project?rev=204951&view=rev
Log:
Fix PR18307: Properly (de)serialize inherited constructors and their using declarations

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

Added:
    cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp
Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=204951&r1=204950&r2=204951&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Mar 27 14:22:19 2014
@@ -1348,7 +1348,9 @@ void ASTDeclReader::VisitCXXMethodDecl(C
 
 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);

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=204951&r1=204950&r2=204951&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Mar 27 14:22:19 2014
@@ -3411,7 +3411,9 @@ ASTWriter::GenerateNameLookupTable(const
   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,
@@ -3419,16 +3421,25 @@ ASTWriter::GenerateNameLookupTable(const
     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 @@ ASTWriter::GenerateNameLookupTable(const
     // 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(),

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=204951&r1=204950&r2=204951&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Thu Mar 27 14:22:19 2014
@@ -1030,6 +1030,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(C
 void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   VisitCXXMethodDecl(D);
 
+  Writer.AddDeclRef(D->getInheritedConstructor(), Record);
   Record.push_back(D->IsExplicitSpecified);
   Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers,
                                 Record);

Added: cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp?rev=204951&view=auto
==============================================================================
--- cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp (added)
+++ cfe/trunk/test/PCH/cxx11-inheriting-ctors.cpp Thu Mar 27 14:22:19 2014
@@ -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





More information about the cfe-commits mailing list