summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-05 18:58:31 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-05 18:58:31 +0000
commite4ff4b56fe4bdc051af4ef808ebbbff129bfa804 (patch)
treef8681c6ca5e9ea651274587fb29a82ad0ab8e7b8 /clang/lib
parentdc4e9637acf1d13ee931c6cb976dba8ffb70ffe6 (diff)
downloadbcm5719-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.cpp7
-rw-r--r--clang/lib/AST/ASTImporter.cpp18
-rw-r--r--clang/lib/AST/Decl.cpp4
-rw-r--r--clang/lib/AST/DumpXML.cpp4
-rw-r--r--clang/lib/AST/StmtProfile.cpp3
-rw-r--r--clang/lib/AST/TemplateBase.cpp87
-rw-r--r--clang/lib/CodeGen/Mangle.cpp5
-rw-r--r--clang/lib/Sema/SemaLookup.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp16
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp38
-rw-r--r--clang/lib/Sema/TreeTransform.h19
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp8
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());
OpenPOWER on IntegriCloud