balazske created this revision.
Herald added subscribers: cfe-commits, martong.
Herald added a reviewer: a.sidorin.
At import of a record describing a template set its type to
InjectedClassNameType (instead of RecordType).
Repository:
rC Clang
https://reviews.llvm.org/D47450
Files:
lib/AST/ASTImporter.cpp
test/ASTMerge/injected-class-name-decl-1/Inputs/inject1.cpp
test/ASTMerge/injected-class-name-decl-1/test.cpp
test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
test/ASTMerge/injected-class-name-decl/test.cpp
Index: test/ASTMerge/injected-class-name-decl/test.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/injected-class-name-decl/test.cpp
@@ -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
Index: test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
@@ -0,0 +1 @@
+template<class X> X C<X>::x;
Index: test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
@@ -0,0 +1 @@
+template<class X> class C { static X x; };
Index: test/ASTMerge/injected-class-name-decl-1/test.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/injected-class-name-decl-1/test.cpp
@@ -0,0 +1,6 @@
+// Trigger a case when at import of template record and replacing its type
+// with InjectedClassNameType there is a PrevDecl of the record.
+
+// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.ast %S/Inputs/inject1.cpp
+// RUN: %clang_cc1 -std=c++1z -fsyntax-only -ast-merge %t.ast %s
+// expected-no-diagnostics
Index: test/ASTMerge/injected-class-name-decl-1/Inputs/inject1.cpp
===================================================================
--- /dev/null
+++ test/ASTMerge/injected-class-name-decl-1/Inputs/inject1.cpp
@@ -0,0 +1,43 @@
+namespace a {
+template <typename> struct b;
+template <typename> struct c;
+template <typename, typename d> using e = d;
+class f;
+} // namespace a
+namespace google {
+namespace protobuf {
+namespace internal {
+class LogMessage {
+ LogMessage &operator<<(const char *);
+};
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+namespace a {
+template <typename> class g;
+namespace i {
+struct h;
+template <typename> struct F;
+struct G;
+template <bool> struct j;
+using k = g<int>;
+template <typename> struct l {};
+} // namespace i
+} // namespace a
+namespace a {
+using n = c<b<i::h>>;
+template <typename m> class g : i::F<e<int, i::j<m::p>>> {
+ template <typename> friend struct i::l;
+};
+} // namespace a
+namespace a {
+using i::G;
+}
+namespace google {
+namespace protobuf {
+namespace internal {
+LogMessage &LogMessage::operator<<(const char *) { return *this; }
+a::f *o;
+} // namespace internal
+} // namespace protobuf
+} // namespace google
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -2128,6 +2128,29 @@
if (!ToDescribed)
return nullptr;
D2CXX->setDescribedClassTemplate(ToDescribed);
+ if (!DCXX->isInjectedClassName()) {
+ // In a record describing a template the type should be a
+ // 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 =
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits