]> granicus.if.org Git - clang/commitdiff
[modules] Track the described template in an alias declaration that is the
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 26 Aug 2014 03:52:16 +0000 (03:52 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 26 Aug 2014 03:52:16 +0000 (03:52 +0000)
pattern of an alias template declaration. Use this to merge alias templates
properly when they're members of class template specializations.

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

include/clang/AST/Decl.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/Modules/Inputs/cxx-templates-a.h
test/Modules/Inputs/cxx-templates-b.h
test/Modules/Inputs/cxx-templates-common.h
test/Modules/cxx-templates.cpp

index c8c118cbcfd19ecf0293fb6c4ead28ec604d6e64..083183525c69b5211f3cb711a17ca56d02da6bee 100644 (file)
@@ -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; }
index 6a48162502cb670bb0f41a6270142d0bd1ebe634..82d06d126b2b45cf29fa0b96f5d4d684348ca38d 100644 (file)
@@ -8207,6 +8207,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,
       TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc,
                                     Name.Identifier, TemplateParams,
                                     NewTD);
+    NewTD->setDescribedAliasTemplate(NewDecl);
 
     NewDecl->setAccess(AS);
 
index c27a2430415314290969ac2b21ddbc6a6cc1db9f..e9d95f2b2925ed0e1309b98c5ac1d5191beb609a 100644 (file)
@@ -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);
 
index 2503500dcd47a1d7f5e30d7ab76e756987fef2a9..5f7a93f13202692c9f1b582a3c5530a867a2342a 100644 (file)
@@ -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) {
index dca7796c029a0255c619f31b72d3a26b28a57d72..cd8f7ddf599a701138ae5e8c3fdee9e824d1a991 100644 (file)
@@ -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;
 }
 
index f3150398e7a988ebb651fb1ae9ea030972a4255b..928a544fc4dc8dc64b32d35bfe3f02cd3e33e4e1 100644 (file)
@@ -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>);
index 8b97d22a370cd110115fc1099d80510144aaccc3..cfaea282df03a6ac9ed714f7ca3d741857ed2220 100644 (file)
@@ -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);
index f3c9022309110ee7cf51d92cecf2ac2c32d80ab7..d729c6edf4c1cbac0b070a16bc9ce9824497e1e0 100644 (file)
@@ -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"
index fedaa03ef4fc5426c7738a825c5a29017de0b27b..d0a6c0f9e5d855f9ef3eeefe13ad25d8a9776591 100644 (file)
@@ -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;