Track source information for template arguments and template specialization
types. Preserve it through template instantiation. Preserve it through PCH,
although TSTs themselves aren't serializable, so that's pretty much meaningless.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85500 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7be55eb..d60a820 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1765,6 +1765,19 @@
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
+ const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ QualType Canon) {
+ llvm::SmallVector<TemplateArgument, 4> ArgVec;
+ ArgVec.reserve(NumArgs);
+ for (unsigned i = 0; i != NumArgs; ++i)
+ ArgVec.push_back(Args[i].getArgument());
+
+ return getTemplateSpecializationType(Template, ArgVec.data(), NumArgs, Canon);
+}
+
+QualType
+ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgument *Args,
unsigned NumArgs,
QualType Canon) {
@@ -2298,17 +2311,14 @@
return Arg;
case TemplateArgument::Declaration:
- return TemplateArgument(SourceLocation(),
- Arg.getAsDecl()->getCanonicalDecl());
+ return TemplateArgument(Arg.getAsDecl()->getCanonicalDecl());
case TemplateArgument::Integral:
- return TemplateArgument(SourceLocation(),
- *Arg.getAsIntegral(),
+ return TemplateArgument(*Arg.getAsIntegral(),
getCanonicalType(Arg.getIntegralType()));
case TemplateArgument::Type:
- return TemplateArgument(SourceLocation(),
- getCanonicalType(Arg.getAsType()));
+ return TemplateArgument(getCanonicalType(Arg.getAsType()));
case TemplateArgument::Pack: {
// FIXME: Allocate in ASTContext
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 49244e1..9ebc91a 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
using namespace clang;
@@ -209,8 +210,7 @@
Param != ParamEnd; ++Param) {
if (isa<TemplateTypeParmDecl>(*Param)) {
QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
- TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
- ParamType));
+ TemplateArgs.push_back(TemplateArgument(ParamType));
} else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
@@ -220,7 +220,7 @@
TemplateArgs.push_back(TemplateArgument(E));
} else {
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
- TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
+ TemplateArgs.push_back(TemplateArgument(TTP));
}
}
@@ -244,6 +244,10 @@
return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
}
+SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
+ return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
+}
+
unsigned TemplateTypeParmDecl::getDepth() const {
return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
}
@@ -454,12 +458,19 @@
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos, unsigned N,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
+ TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
+ for (unsigned I = 0; I != N; ++I)
+ ClonedArgs[I] = ArgInfos[I];
+
ClassTemplatePartialSpecializationDecl *Result
= new (Context)ClassTemplatePartialSpecializationDecl(Context,
DC, L, Params,
SpecializedTemplate,
- Builder, PrevDecl);
+ Builder,
+ ClonedArgs, N,
+ PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
Context.getTypeDeclType(Result, PrevDecl);
return Result;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index ad9c9cb..ad91cd3 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -35,7 +35,7 @@
NamedDecl *D, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD)
@@ -58,9 +58,9 @@
ETemplateArgs->RAngleLoc = RAngleLoc;
ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
- TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+ TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
- new (TemplateArgs + I) TemplateArgument(ExplicitTemplateArgs[I]);
+ new (TemplateArgs + I) TemplateArgumentLoc(ExplicitTemplateArgs[I]);
}
}
@@ -82,7 +82,7 @@
SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD) {
@@ -92,7 +92,7 @@
if (HasExplicitTemplateArgumentList)
Size += sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgument) * NumExplicitTemplateArgs;
+ sizeof(TemplateArgumentLoc) * NumExplicitTemplateArgs;
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
@@ -428,7 +428,7 @@
SourceRange qualrange, NamedDecl *memberdecl,
SourceLocation l, bool has_explicit,
SourceLocation langle,
- const TemplateArgument *targs, unsigned numtargs,
+ const TemplateArgumentLoc *targs, unsigned numtargs,
SourceLocation rangle, QualType ty)
: Expr(MemberExprClass, ty,
base->isTypeDependent() || (qual && qual->isDependent()),
@@ -450,9 +450,9 @@
ETemplateArgs->RAngleLoc = rangle;
ETemplateArgs->NumTemplateArgs = numtargs;
- TemplateArgument *TemplateArgs = ETemplateArgs->getTemplateArgs();
+ TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < numtargs; ++I)
- new (TemplateArgs + I) TemplateArgument(targs[I]);
+ new (TemplateArgs + I) TemplateArgumentLoc(targs[I]);
}
}
@@ -463,7 +463,7 @@
SourceLocation l,
bool has_explicit,
SourceLocation langle,
- const TemplateArgument *targs,
+ const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty) {
@@ -473,7 +473,7 @@
if (has_explicit)
Size += sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgument) * numtargs;
+ sizeof(TemplateArgumentLoc) * numtargs;
void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l,
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index cba0e22..7c6fc41 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -151,7 +151,7 @@
TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(TemplateIdRefExprClass, T,
@@ -164,10 +164,10 @@
Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs) {
- TemplateArgument *StoredTemplateArgs
- = reinterpret_cast<TemplateArgument *> (this+1);
+ TemplateArgumentLoc *StoredTemplateArgs
+ = reinterpret_cast<TemplateArgumentLoc *> (this+1);
for (unsigned I = 0; I != NumTemplateArgs; ++I)
- new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+ new (StoredTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
}
TemplateIdRefExpr *
@@ -176,19 +176,19 @@
SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
- sizeof(TemplateArgument) * NumTemplateArgs);
+ sizeof(TemplateArgumentLoc) * NumTemplateArgs);
return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
TemplateNameLoc, LAngleLoc, TemplateArgs,
NumTemplateArgs, RAngleLoc);
}
void TemplateIdRefExpr::DoDestroy(ASTContext &Context) {
- const TemplateArgument *TemplateArgs = getTemplateArgs();
+ const TemplateArgumentLoc *TemplateArgs = getTemplateArgs();
for (unsigned I = 0; I != NumTemplateArgs; ++I)
- if (Expr *E = TemplateArgs[I].getAsExpr())
+ if (Expr *E = TemplateArgs[I].getArgument().getAsExpr())
E->Destroy(Context);
this->~TemplateIdRefExpr();
Context.Deallocate(this);
@@ -528,7 +528,7 @@
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(CXXUnresolvedMemberExprClass, C.DependentTy, true, true),
@@ -545,9 +545,9 @@
ETemplateArgs->RAngleLoc = RAngleLoc;
ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
- TemplateArgument *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
+ TemplateArgumentLoc *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < NumTemplateArgs; ++I)
- new (SavedTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+ new (SavedTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
}
}
@@ -562,7 +562,7 @@
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
if (!HasExplicitTemplateArgs)
@@ -573,7 +573,7 @@
void *Mem = C.Allocate(sizeof(CXXUnresolvedMemberExpr) +
sizeof(ExplicitTemplateArgumentList) +
- sizeof(TemplateArgument) * NumTemplateArgs,
+ sizeof(TemplateArgumentLoc) * NumTemplateArgs,
llvm::alignof<CXXUnresolvedMemberExpr>());
return new (Mem) CXXUnresolvedMemberExpr(C, Base, IsArrow, OperatorLoc,
Qualifier, QualifierRange,
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index a6327c9..02e0c74 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -60,7 +60,10 @@
/// \brief Visit template arguments that occur within an expression or
/// statement.
- void VisitTemplateArguments(const TemplateArgument *Args, unsigned NumArgs);
+ void VisitTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs);
+
+ /// \brief Visit a single template argument.
+ void VisitTemplateArgument(const TemplateArgument &Arg);
};
}
@@ -674,39 +677,42 @@
Name.Profile(ID);
}
-void StmtProfiler::VisitTemplateArguments(const TemplateArgument *Args,
+void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
unsigned NumArgs) {
ID.AddInteger(NumArgs);
- for (unsigned I = 0; I != NumArgs; ++I) {
- const TemplateArgument &Arg = Args[I];
+ for (unsigned I = 0; I != NumArgs; ++I)
+ VisitTemplateArgument(Args[I].getArgument());
+}
- // Mostly repetitive with TemplateArgument::Profile!
- ID.AddInteger(Arg.getKind());
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- break;
+void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
+ // Mostly repetitive with TemplateArgument::Profile!
+ ID.AddInteger(Arg.getKind());
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ break;
- case TemplateArgument::Type:
- VisitType(Arg.getAsType());
- break;
+ case TemplateArgument::Type:
+ VisitType(Arg.getAsType());
+ break;
- case TemplateArgument::Declaration:
- VisitDecl(Arg.getAsDecl());
- break;
+ case TemplateArgument::Declaration:
+ VisitDecl(Arg.getAsDecl());
+ break;
- case TemplateArgument::Integral:
- Arg.getAsIntegral()->Profile(ID);
- VisitType(Arg.getIntegralType());
- break;
+ case TemplateArgument::Integral:
+ Arg.getAsIntegral()->Profile(ID);
+ VisitType(Arg.getIntegralType());
+ break;
- case TemplateArgument::Expression:
- Visit(Arg.getAsExpr());
- break;
+ case TemplateArgument::Expression:
+ Visit(Arg.getAsExpr());
+ break;
- case TemplateArgument::Pack:
- VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size());
- break;
- }
+ case TemplateArgument::Pack:
+ const TemplateArgument *Pack = Arg.pack_begin();
+ for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
+ VisitTemplateArgument(Pack[i]);
+ break;
}
}
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 3b3ec2b..b136fe0 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
using namespace clang;
@@ -23,11 +24,6 @@
// TemplateArgument Implementation
//===----------------------------------------------------------------------===//
-TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
- TypeOrValue = reinterpret_cast<uintptr_t>(E);
- StartLoc = E->getSourceRange().getBegin();
-}
-
/// \brief Construct a template argument pack.
void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
bool CopyArgs) {
@@ -77,3 +73,25 @@
Args.Args[I].Profile(ID, Context);
}
}
+
+//===----------------------------------------------------------------------===//
+// TemplateArgumentLoc Implementation
+//===----------------------------------------------------------------------===//
+
+SourceLocation TemplateArgumentLoc::getLocation() const {
+ switch (Argument.getKind()) {
+ case TemplateArgument::Expression:
+ return getSourceExpression()->getExprLoc();
+ case TemplateArgument::Type:
+ return getSourceDeclaratorInfo()->
+ getTypeLoc().getFullSourceRange().getBegin();
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ case TemplateArgument::Null:
+ return SourceLocation();
+ }
+
+ // Silence bonus gcc warning.
+ return SourceLocation();
+}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5fb0178..65ed767 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -791,40 +791,48 @@
return isa<EnumDecl>(TT->getDecl());
}
-bool
-TemplateSpecializationType::
-anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
- switch (Args[Idx].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Should not have a NULL template argument");
- break;
+static bool isDependent(const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ assert(false && "Should not have a NULL template argument");
+ return false;
- case TemplateArgument::Type:
- if (Args[Idx].getAsType()->isDependentType())
- return true;
- break;
+ case TemplateArgument::Type:
+ return Arg.getAsType()->isDependentType();
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- // Never dependent
- break;
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ // Never dependent
+ return false;
- case TemplateArgument::Expression:
- if (Args[Idx].getAsExpr()->isTypeDependent() ||
- Args[Idx].getAsExpr()->isValueDependent())
- return true;
- break;
+ case TemplateArgument::Expression:
+ return (Arg.getAsExpr()->isTypeDependent() ||
+ Arg.getAsExpr()->isValueDependent());
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- break;
- }
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ return false;
}
return false;
}
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
+ for (unsigned i = 0; i != N; ++i)
+ if (isDependent(Args[i].getArgument()))
+ return true;
+ return false;
+}
+
+bool TemplateSpecializationType::
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) {
+ for (unsigned i = 0; i != N; ++i)
+ if (isDependent(Args[i]))
+ return true;
+ return false;
+}
+
TemplateSpecializationType::
TemplateSpecializationType(ASTContext &Context, TemplateName T,
const TemplateArgument *Args,
@@ -1260,6 +1268,38 @@
getReplacementType().getAsStringInternal(InnerString, Policy);
}
+static void PrintTemplateArgument(std::string &Buffer,
+ const TemplateArgument &Arg,
+ const PrintingPolicy &Policy) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ assert(false && "Null template argument");
+ break;
+
+ case TemplateArgument::Type:
+ Arg.getAsType().getAsStringInternal(Buffer, Policy);
+ break;
+
+ case TemplateArgument::Declaration:
+ Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
+ break;
+
+ case TemplateArgument::Integral:
+ Buffer = Arg.getAsIntegral()->toString(10, true);
+ break;
+
+ case TemplateArgument::Expression: {
+ llvm::raw_string_ostream s(Buffer);
+ Arg.getAsExpr()->printPretty(s, 0, Policy);
+ break;
+ }
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
+ }
+}
+
std::string
TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
@@ -1273,32 +1313,41 @@
// Print the argument into a string.
std::string ArgString;
- switch (Args[Arg].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Null template argument");
- break;
+ PrintTemplateArgument(ArgString, Args[Arg], Policy);
- case TemplateArgument::Type:
- Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
- break;
+ // If this is the first argument and its string representation
+ // begins with the global scope specifier ('::foo'), add a space
+ // to avoid printing the diagraph '<:'.
+ if (!Arg && !ArgString.empty() && ArgString[0] == ':')
+ SpecString += ' ';
- case TemplateArgument::Declaration:
- ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
- break;
+ SpecString += ArgString;
+ }
- case TemplateArgument::Integral:
- ArgString = Args[Arg].getAsIntegral()->toString(10, true);
- break;
+ // If the last character of our string is '>', add another space to
+ // keep the two '>''s separate tokens. We don't *have* to do this in
+ // C++0x, but it's still good hygiene.
+ if (SpecString[SpecString.size() - 1] == '>')
+ SpecString += ' ';
- case TemplateArgument::Expression: {
- llvm::raw_string_ostream s(ArgString);
- Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
- break;
- }
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- break;
- }
+ SpecString += '>';
+
+ return SpecString;
+}
+
+// Sadly, repeat all that with TemplateArgLoc.
+std::string TemplateSpecializationType::
+PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
+ const PrintingPolicy &Policy) {
+ std::string SpecString;
+ SpecString += '<';
+ for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
+ if (Arg)
+ SpecString += ", ";
+
+ // Print the argument into a string.
+ std::string ArgString;
+ PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
// If this is the first argument and its string representation
// begins with the global scope specifier ('::foo'), add a space