diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-05 18:58:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-05 18:58:31 +0000 |
commit | e4ff4b56fe4bdc051af4ef808ebbbff129bfa804 (patch) | |
tree | f8681c6ca5e9ea651274587fb29a82ad0ab8e7b8 /clang/lib | |
parent | dc4e9637acf1d13ee931c6cb976dba8ffb70ffe6 (diff) | |
download | bcm5719-llvm-e4ff4b56fe4bdc051af4ef808ebbbff129bfa804.tar.gz bcm5719-llvm-e4ff4b56fe4bdc051af4ef808ebbbff129bfa804.zip |
Replace the representation of template template argument pack
expansions with something that is easier to use correctly: a new
template argment kind, rather than a bit on an existing kind. Update
all of the switch statements that deal with template arguments, fixing
a few latent bugs in the process. I"m happy with this representation,
now.
And, oh look! Template instantiation and deduction work for template
template argument pack expansions.
llvm-svn: 122896
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/DumpXML.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/TemplateBase.cpp | 87 | ||||
-rw-r--r-- | clang/lib/CodeGen/Mangle.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 19 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 8 |
13 files changed, 164 insertions, 65 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b4520609ff7..6e7f7c31ea5 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2692,7 +2692,12 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) { case TemplateArgument::Template: return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate())); - + + case TemplateArgument::TemplateExpansion: + return TemplateArgument(getCanonicalTemplateName( + Arg.getAsTemplateOrTemplatePattern()), + true); + case TemplateArgument::Integral: return TemplateArgument(*Arg.getAsIntegral(), getCanonicalType(Arg.getIntegralType())); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 70c86320470..5a94de90201 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -301,7 +301,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, return IsStructurallyEquivalent(Context, Arg1.getAsTemplate(), Arg2.getAsTemplate()); - + + case TemplateArgument::TemplateExpansion: + return IsStructurallyEquivalent(Context, + Arg1.getAsTemplateOrTemplatePattern(), + Arg2.getAsTemplateOrTemplatePattern()); + case TemplateArgument::Expression: return IsStructurallyEquivalent(Context, Arg1.getAsExpr(), Arg2.getAsExpr()); @@ -1785,7 +1790,16 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) { return TemplateArgument(ToTemplate); } - + + case TemplateArgument::TemplateExpansion: { + TemplateName ToTemplate + = Importer.Import(From.getAsTemplateOrTemplatePattern()); + if (ToTemplate.isNull()) + return TemplateArgument(); + + return TemplateArgument(ToTemplate, true); + } + case TemplateArgument::Expression: if (Expr *ToExpr = Importer.Import(From.getAsExpr())) return TemplateArgument(ToExpr); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 08272e76ca4..5b82ddd7c69 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -179,7 +179,9 @@ static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args, break; case TemplateArgument::Template: - if (TemplateDecl *Template = Args[I].getAsTemplate().getAsTemplateDecl()) + case TemplateArgument::TemplateExpansion: + if (TemplateDecl *Template + = Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl()) LV = merge(LV, getLVForDecl(Template, F)); break; diff --git a/clang/lib/AST/DumpXML.cpp b/clang/lib/AST/DumpXML.cpp index 7465ea410d7..65a18aa8d1b 100644 --- a/clang/lib/AST/DumpXML.cpp +++ b/clang/lib/AST/DumpXML.cpp @@ -319,6 +319,10 @@ struct XMLDumper : public XMLDeclVisitor<XMLDumper>, break; } case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: + // FIXME: Implement! + break; + case TemplateArgument::Declaration: { visitDeclRef(A.getAsDecl()); break; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 17a9326cc0b..63c3197ebce 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -972,7 +972,8 @@ void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) { break; case TemplateArgument::Template: - VisitTemplateName(Arg.getAsTemplate()); + case TemplateArgument::TemplateExpansion: + VisitTemplateName(Arg.getAsTemplateOrTemplatePattern()); break; case TemplateArgument::Declaration: diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 6eae6a4192f..de5531f0f71 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -39,7 +39,10 @@ bool TemplateArgument::isDependent() const { case Template: return getAsTemplate().isDependent(); - + + case TemplateExpansion: + return true; + case Declaration: if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) return DC->isDependentContext(); @@ -70,14 +73,15 @@ bool TemplateArgument::isPackExpansion() const { case Declaration: case Integral: case Pack: + case Template: return false; + case TemplateExpansion: + return true; + case Type: return isa<PackExpansionType>(getAsType()); - - case Template: - return TemplateArg.PackExpansion; - + case Expression: return isa<PackExpansionExpr>(getAsExpr()); } @@ -90,6 +94,7 @@ bool TemplateArgument::containsUnexpandedParameterPack() const { case Null: case Declaration: case Integral: + case TemplateExpansion: break; case Type: @@ -98,8 +103,7 @@ bool TemplateArgument::containsUnexpandedParameterPack() const { break; case Template: - if (!TemplateArg.PackExpansion && - getAsTemplate().containsUnexpandedParameterPack()) + if (getAsTemplate().containsUnexpandedParameterPack()) return true; break; @@ -135,20 +139,22 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, break; case Template: - ID.AddBoolean(TemplateArg.PackExpansion); + case TemplateExpansion: { + TemplateName Template = getAsTemplateOrTemplatePattern(); if (TemplateTemplateParmDecl *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( - getAsTemplate().getAsTemplateDecl())) { + Template.getAsTemplateDecl())) { ID.AddBoolean(true); ID.AddInteger(TTP->getDepth()); ID.AddInteger(TTP->getPosition()); ID.AddBoolean(TTP->isParameterPack()); } else { ID.AddBoolean(false); - ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate()) - .getAsVoidPointer()); + ID.AddPointer(Context.getCanonicalTemplateName(Template) + .getAsVoidPointer()); } break; + } case Integral: getAsIntegral()->Profile(ID); @@ -173,13 +179,11 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { case Null: case Type: case Declaration: - case Expression: + case Expression: + case Template: + case TemplateExpansion: return TypeOrValue == Other.TypeOrValue; - case Template: - return TemplateArg.Template == Other.TemplateArg.Template && - TemplateArg.PackExpansion == Other.TemplateArg.PackExpansion; - case Integral: return getIntegralType() == Other.getIntegralType() && *getAsIntegral() == *Other.getAsIntegral(); @@ -206,13 +210,14 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const { case Expression: return cast<PackExpansionExpr>(getAsExpr())->getPattern(); - case Template: - return TemplateArgument(getAsTemplate(), false); + case TemplateExpansion: + return TemplateArgument(getAsTemplateOrTemplatePattern(), false); case Declaration: case Integral: case Pack: case Null: + case Template: return TemplateArgument(); } @@ -248,13 +253,15 @@ void TemplateArgument::print(const PrintingPolicy &Policy, break; } - case Template: { + case Template: getAsTemplate().print(Out, Policy); - if (TemplateArg.PackExpansion) - Out << "..."; break; - } - + + case TemplateExpansion: + getAsTemplateOrTemplatePattern().print(Out, Policy); + Out << "..."; + break; + case Integral: { Out << getAsIntegral()->toString(10); break; @@ -299,15 +306,18 @@ SourceRange TemplateArgumentLoc::getSourceRange() const { else return SourceRange(); - case TemplateArgument::Template: { - SourceLocation End = getTemplateNameLoc(); - if (getTemplateEllipsisLoc().isValid()) - End = getTemplateEllipsisLoc(); + case TemplateArgument::Template: if (getTemplateQualifierRange().isValid()) - return SourceRange(getTemplateQualifierRange().getBegin(), End); - return SourceRange(getTemplateNameLoc(), End); - } - + return SourceRange(getTemplateQualifierRange().getBegin(), + getTemplateNameLoc()); + return SourceRange(getTemplateNameLoc()); + + case TemplateArgument::TemplateExpansion: + if (getTemplateQualifierRange().isValid()) + return SourceRange(getTemplateQualifierRange().getBegin(), + getTemplateEllipsisLoc()); + return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); + case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: @@ -355,13 +365,14 @@ TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, Expr *Pattern = cast<PackExpansionExpr>(Argument.getAsExpr())->getPattern(); return TemplateArgumentLoc(Pattern, Pattern); } - - case TemplateArgument::Template: + + case TemplateArgument::TemplateExpansion: return TemplateArgumentLoc(Argument.getPackExpansionPattern(), getTemplateQualifierRange(), getTemplateNameLoc()); case TemplateArgument::Declaration: + case TemplateArgument::Template: case TemplateArgument::Integral: case TemplateArgument::Pack: case TemplateArgument::Null: @@ -389,11 +400,11 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB << Arg.getAsIntegral()->toString(10); case TemplateArgument::Template: - DB << Arg.getAsTemplate(); - if (Arg.isPackExpansion()) - DB << "..."; - return DB; - + return DB << Arg.getAsTemplate(); + + case TemplateArgument::TemplateExpansion: + return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; + case TemplateArgument::Expression: { // This shouldn't actually ever happen, so it's okay that we're // regurgitating an expression here. diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 0969b8716f6..ff0e9223c81 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -2169,6 +2169,11 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P, // This is mangled as <type>. mangleType(A.getAsTemplate()); break; + case TemplateArgument::TemplateExpansion: + // This is mangled as Dp <type>. + Out << "Dp"; + mangleType(A.getAsTemplateOrTemplatePattern()); + break; case TemplateArgument::Expression: Out << 'X'; mangleExpression(A.getAsExpr()); diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 5ed973b1a80..161908e2007 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1693,11 +1693,12 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, addAssociatedClassesAndNamespaces(Result, Arg.getAsType()); break; - case TemplateArgument::Template: { + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: { // [...] the namespaces in which any template template arguments are // defined; and the classes in which any member templates used as // template template arguments are defined. - TemplateName Template = Arg.getAsTemplate(); + TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) { DeclContext *Ctx = ClassTemplate->getDeclContext(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 9adcf1c81fd..2c9a4307ed5 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2256,10 +2256,12 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, break; case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: // We were given a template template argument. It may not be ill-formed; // see below. if (DependentTemplateName *DTN - = Arg.getArgument().getAsTemplate().getAsDependentTemplateName()) { + = Arg.getArgument().getAsTemplateOrTemplatePattern() + .getAsDependentTemplateName()) { // We have a template argument such as \c T::template X, which we // parsed as a template template argument. However, since we now // know that we need a non-type template argument, convert this @@ -2273,6 +2275,17 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, Arg.getTemplateQualifierRange(), NameInfo); + // If we parsed the template argument as a pack expansion, create a + // pack expansion expression. + if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ + ExprResult Expansion = ActOnPackExpansion(E, + Arg.getTemplateEllipsisLoc()); + if (Expansion.isInvalid()) + return true; + + E = Expansion.get(); + } + TemplateArgument Result; if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) return true; @@ -2348,6 +2361,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, return true; case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: if (CheckTemplateArgument(TempParm, Arg)) return true; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index a72a29378a8..5837ebd8e54 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -168,7 +168,16 @@ checkDeducedTemplateArguments(ASTContext &Context, // All other combinations are incompatible. return DeducedTemplateArgument(); - + + case TemplateArgument::TemplateExpansion: + if (Y.getKind() == TemplateArgument::TemplateExpansion && + Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(), + Y.getAsTemplateOrTemplatePattern())) + return X; + + // All other combinations are incompatible. + return DeducedTemplateArgument(); + case TemplateArgument::Expression: // If we deduced a dependent expression in one case and either an integral // constant or a declaration in another case, keep the integral constant @@ -934,7 +943,7 @@ DeduceTemplateArguments(Sema &S, Info.FirstArg = Param; Info.SecondArg = Arg; return Sema::TDK_NonDeducedMismatch; - + case TemplateArgument::Template: if (Arg.getKind() == TemplateArgument::Template) return DeduceTemplateArguments(S, TemplateParams, @@ -943,6 +952,10 @@ DeduceTemplateArguments(Sema &S, Info.FirstArg = Param; Info.SecondArg = Arg; return Sema::TDK_NonDeducedMismatch; + + case TemplateArgument::TemplateExpansion: + llvm_unreachable("caller should handle pack expansions"); + break; case TemplateArgument::Declaration: if (Arg.getKind() == TemplateArgument::Declaration && @@ -1282,10 +1295,11 @@ static bool isSameTemplateArg(ASTContext &Context, Y.getAsDecl()->getCanonicalDecl(); case TemplateArgument::Template: - return Context.getCanonicalTemplateName(X.getAsTemplate()) - .getAsVoidPointer() == - Context.getCanonicalTemplateName(Y.getAsTemplate()) - .getAsVoidPointer(); + case TemplateArgument::TemplateExpansion: + return Context.getCanonicalTemplateName( + X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() == + Context.getCanonicalTemplateName( + Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer(); case TemplateArgument::Integral: return *X.getAsIntegral() == *Y.getAsIntegral(); @@ -1356,9 +1370,11 @@ getTrivialTemplateArgumentLoc(Sema &S, } case TemplateArgument::Template: - return TemplateArgumentLoc(Arg, SourceRange(), Loc, - Arg.isPackExpansion()? Loc : SourceLocation()); - + return TemplateArgumentLoc(Arg, SourceRange(), Loc); + + case TemplateArgument::TemplateExpansion: + return TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc); + case TemplateArgument::Expression: return TemplateArgumentLoc(Arg, Arg.getAsExpr()); @@ -3244,7 +3260,9 @@ MarkUsedTemplateParameters(Sema &SemaRef, break; case TemplateArgument::Template: - MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsTemplate(), + case TemplateArgument::TemplateExpansion: + MarkUsedTemplateParameters(SemaRef, + TemplateArg.getAsTemplateOrTemplatePattern(), OnlyDeduced, Depth, Used); break; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 919f2c879c8..d15f91a745e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2123,12 +2123,18 @@ public: } case TemplateArgument::Template: - llvm_unreachable("Unsupported pack expansion of templates"); + return TemplateArgumentLoc(TemplateArgument( + Pattern.getArgument().getAsTemplate(), + true), + Pattern.getTemplateQualifierRange(), + Pattern.getTemplateNameLoc(), + EllipsisLoc); case TemplateArgument::Null: case TemplateArgument::Integral: case TemplateArgument::Declaration: case TemplateArgument::Pack: + case TemplateArgument::TemplateExpansion: llvm_unreachable("Pack expansion pattern has no parameter packs"); case TemplateArgument::Type: @@ -2531,7 +2537,11 @@ void TreeTransform<Derived>::InventTemplateArgumentLoc( case TemplateArgument::Template: Output = TemplateArgumentLoc(Arg, SourceRange(), Loc); break; - + + case TemplateArgument::TemplateExpansion: + Output = TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc); + break; + case TemplateArgument::Expression: Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); break; @@ -2600,7 +2610,10 @@ bool TreeTransform<Derived>::TransformTemplateArgument( Input.getTemplateNameLoc()); return false; } - + + case TemplateArgument::TemplateExpansion: + llvm_unreachable("Caller should expand pack expansions"); + case TemplateArgument::Expression: { // Template argument expressions are not potentially evaluated. EnterExpressionEvaluationContext Unevaluated(getSema(), diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ed0e58f18fa..3bf51e6a0e9 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3381,6 +3381,12 @@ ASTReader::GetTemplateArgumentLocInfo(PerFileData &F, case TemplateArgument::Template: { SourceRange QualifierRange = ReadSourceRange(F, Record, Index); SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); + return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, + SourceLocation()); + } + case TemplateArgument::TemplateExpansion: { + SourceRange QualifierRange = ReadSourceRange(F, Record, Index); + SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index); SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index); return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, EllipsisLoc); @@ -4216,7 +4222,8 @@ ASTReader::ReadTemplateName(const RecordData &Record, unsigned &Idx) { TemplateArgument ASTReader::ReadTemplateArgument(PerFileData &F, const RecordData &Record, unsigned &Idx) { - switch ((TemplateArgument::ArgKind)Record[Idx++]) { + TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++]; + switch (Kind) { case TemplateArgument::Null: return TemplateArgument(); case TemplateArgument::Type: @@ -4228,10 +4235,10 @@ ASTReader::ReadTemplateArgument(PerFileData &F, QualType T = GetType(Record[Idx++]); return TemplateArgument(Value, T); } - case TemplateArgument::Template: { + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: { TemplateName Name = ReadTemplateName(Record, Idx); - bool IsPackExpansion = Record[Idx++]; - return TemplateArgument(Name, IsPackExpansion); + return TemplateArgument(Name, Kind == TemplateArgument::TemplateExpansion); } case TemplateArgument::Expression: return TemplateArgument(ReadExpr(F)); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 44f17e40b1a..2c0239de17e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2889,6 +2889,10 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, case TemplateArgument::Template: AddSourceRange(Arg.getTemplateQualifierRange(), Record); AddSourceLocation(Arg.getTemplateNameLoc(), Record); + break; + case TemplateArgument::TemplateExpansion: + AddSourceRange(Arg.getTemplateQualifierRange(), Record); + AddSourceLocation(Arg.getTemplateNameLoc(), Record); AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record); break; case TemplateArgument::Null: @@ -3176,8 +3180,8 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg, AddTypeRef(Arg.getIntegralType(), Record); break; case TemplateArgument::Template: - AddTemplateName(Arg.getAsTemplate(), Record); - Record.push_back(Arg.isPackExpansion()); + case TemplateArgument::TemplateExpansion: + AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record); break; case TemplateArgument::Expression: AddStmt(Arg.getAsExpr()); |