]> granicus.if.org Git - clang/commitdiff
[ASTImporter] Use InjectedClassNameType at import of templated record.
authorGabor Marton <martongabesz@gmail.com>
Tue, 26 Jun 2018 13:44:24 +0000 (13:44 +0000)
committerGabor Marton <martongabesz@gmail.com>
Tue, 26 Jun 2018 13:44:24 +0000 (13:44 +0000)
Summary:
At import of a record describing a template set its type to
InjectedClassNameType (instead of RecordType).

Reviewers: a.sidorin, martong, r.stahl

Reviewed By: a.sidorin, martong, r.stahl

Subscribers: a_sidorin, rnkovacs, martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D47450

Patch by Balazs Keri!

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

lib/AST/ASTImporter.cpp
test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp [new file with mode: 0644]
test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp [new file with mode: 0644]
test/ASTMerge/injected-class-name-decl/test.cpp [new file with mode: 0644]

index f812244ed3ce74ba35b58795a7ab8e388e39e662..6f14ab02ea8ce6b701826dd6e5e88d2c54f7ba58 100644 (file)
@@ -2135,6 +2135,29 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
         if (!ToDescribed)
           return nullptr;
         D2CXX->setDescribedClassTemplate(ToDescribed);
+        if (!DCXX->isInjectedClassName()) {
+          // In a record describing a template the type should be an
+          // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
+          // previously set type to the correct value here (ToDescribed is not
+          // available at record create).
+          // FIXME: The previous type is cleared but not removed from
+          // ASTContext's internal storage.
+          CXXRecordDecl *Injected = nullptr;
+          for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
+            auto *Record = dyn_cast<CXXRecordDecl>(Found);
+            if (Record && Record->isInjectedClassName()) {
+              Injected = Record;
+              break;
+            }
+          }
+          D2CXX->setTypeForDecl(nullptr);
+          Importer.getToContext().getInjectedClassNameType(D2CXX,
+              ToDescribed->getInjectedClassNameSpecialization());
+          if (Injected) {
+            Injected->setTypeForDecl(nullptr);
+            Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+          }
+        }
       } else if (MemberSpecializationInfo *MemberInfo =
                    DCXX->getMemberSpecializationInfo()) {
         TemplateSpecializationKind SK =
diff --git a/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp b/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
new file mode 100644 (file)
index 0000000..f6f7697
--- /dev/null
@@ -0,0 +1,2 @@
+template <class X>
+class C { static X x; };
diff --git a/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp b/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
new file mode 100644 (file)
index 0000000..7cf5fc2
--- /dev/null
@@ -0,0 +1,2 @@
+template <class X>
+X C<X>::x;
diff --git a/test/ASTMerge/injected-class-name-decl/test.cpp b/test/ASTMerge/injected-class-name-decl/test.cpp
new file mode 100644 (file)
index 0000000..9f31674
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.ast %S/Inputs/inject1.cpp
+// RUN: %clang_cc1 -std=c++1z -emit-obj -o /dev/null -ast-merge %t.ast %S/Inputs/inject2.cpp
+// expected-no-diagnostics