summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Decl.h10
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp1
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp17
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp1
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-a.h2
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-b.h2
-rw-r--r--clang/test/Modules/Inputs/cxx-templates-common.h4
-rw-r--r--clang/test/Modules/cxx-templates.cpp2
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;
OpenPOWER on IntegriCloud