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 cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits