diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/Decl.h | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 1 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 2 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-b.h | 2 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 4 | ||||
| -rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 2 |
9 files changed, 34 insertions, 6 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index c8c118cbcfd..083183525c6 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -43,6 +43,7 @@ class Stmt; class StringLiteral; class TemplateArgumentList; class TemplateParameterList; +class TypeAliasTemplateDecl; class TypeLoc; class UnresolvedSetImpl; class VarTemplateDecl; @@ -2492,9 +2493,13 @@ public: /// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x /// alias-declaration. class TypeAliasDecl : public TypedefNameDecl { + /// The template for which this is the pattern, if any. + TypeAliasTemplateDecl *Template; + TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) - : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {} + : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo), + Template(nullptr) {} public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, @@ -2504,6 +2509,9 @@ public: SourceRange getSourceRange() const override LLVM_READONLY; + TypeAliasTemplateDecl *getDescribedAliasTemplate() const { return Template; } + void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT) { Template = TAT; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TypeAlias; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6a48162502c..82d06d126b2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -8207,6 +8207,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc, Name.Identifier, TemplateParams, NewTD); + NewTD->setDescribedAliasTemplate(NewDecl); NewDecl->setAccess(AS); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c27a2430415..e9d95f2b292 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -363,6 +363,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { TypeAliasTemplateDecl *Inst = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(), D->getDeclName(), InstParams, AliasInst); + AliasInst->setDescribedAliasTemplate(Inst); if (PrevAliasTemplate) Inst->setPreviousDecl(PrevAliasTemplate); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 2503500dcd4..5f7a93f1320 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -234,7 +234,7 @@ namespace clang { void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); void VisitTypeDecl(TypeDecl *TD); - void VisitTypedefNameDecl(TypedefNameDecl *TD); + RedeclarableResult VisitTypedefNameDecl(TypedefNameDecl *TD); void VisitTypedefDecl(TypedefDecl *TD); void VisitTypeAliasDecl(TypeAliasDecl *TD); void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); @@ -456,7 +456,8 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]); } -void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx); @@ -465,15 +466,21 @@ void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { TD->setModedTypeSourceInfo(TInfo, modedT); } else TD->setTypeSourceInfo(TInfo); - mergeRedeclarable(TD, Redecl); + return Redecl; } void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) { - VisitTypedefNameDecl(TD); + RedeclarableResult Redecl = VisitTypedefNameDecl(TD); + mergeRedeclarable(TD, Redecl); } void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { - VisitTypedefNameDecl(TD); + RedeclarableResult Redecl = VisitTypedefNameDecl(TD); + if (auto *Template = ReadDeclAs<TypeAliasTemplateDecl>(Record, Idx)) + // Merged when we merge the template. + TD->setDescribedAliasTemplate(Template); + else + mergeRedeclarable(TD, Redecl); } ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index dca7796c029..cd8f7ddf599 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -236,6 +236,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) { VisitTypedefNameDecl(D); + Writer.AddDeclRef(D->getDescribedAliasTemplate(), Record); Code = serialization::DECL_TYPEALIAS; } diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h index f3150398e7a..928a544fc4d 100644 --- a/clang/test/Modules/Inputs/cxx-templates-a.h +++ b/clang/test/Modules/Inputs/cxx-templates-a.h @@ -85,3 +85,5 @@ template<typename T> struct PartiallyInstantiatePartialSpec<T*> { static T *bar() { return reinterpret_cast<T*>(0); } }; typedef PartiallyInstantiatePartialSpec<int*> PartiallyInstantiatePartialSpecHelper; + +void InstantiateWithAliasTemplate(WithAliasTemplate<int>::X<char>); diff --git a/clang/test/Modules/Inputs/cxx-templates-b.h b/clang/test/Modules/Inputs/cxx-templates-b.h index 8b97d22a370..cfaea282df0 100644 --- a/clang/test/Modules/Inputs/cxx-templates-b.h +++ b/clang/test/Modules/Inputs/cxx-templates-b.h @@ -69,6 +69,8 @@ template<> struct MergeSpecializations<double> { template<typename U> using AliasTemplate = U; +void InstantiateWithAliasTemplate(WithAliasTemplate<int>::X<char>); + @import cxx_templates_a; template<typename T> void UseDefinedInBImplIndirectly(T &v) { PerformDelayedLookup(v); diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h index f3c90223091..d729c6edf4c 100644 --- a/clang/test/Modules/Inputs/cxx-templates-common.h +++ b/clang/test/Modules/Inputs/cxx-templates-common.h @@ -41,4 +41,8 @@ typedef WithExplicitSpecialization<int> WithExplicitSpecializationUse; template<typename T> struct WithImplicitSpecialMembers { int n; }; +template<typename T> struct WithAliasTemplate { + template<typename> using X = T; +}; + #include "cxx-templates-textual.h" diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index fedaa03ef4f..d0a6c0f9e5d 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -143,6 +143,8 @@ MergeSpecializations<double>::explicitly_specialized_in_b spec_in_b_2; MergeSpecializations<bool>::explicitly_specialized_in_c spec_in_c_2; #endif +using AliasTemplateMergingTest = WithAliasTemplate<int>::X<char>; + @import cxx_templates_common; typedef SomeTemplate<int*> SomeTemplateIntPtr; |

