aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-29 08:12:44 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-29 08:12:44 +0000
commit833ca991c1bfc967f0995974ca86f66ba1f666b5 (patch)
tree54ce834e6510eae21e5cff09573c986e6ee7ca12
parent275c10a8a4a43219f67d8d2c912ec6294d9d9af2 (diff)
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
-rw-r--r--include/clang/AST/ASTContext.h5
-rw-r--r--include/clang/AST/DeclTemplate.h47
-rw-r--r--include/clang/AST/Expr.h21
-rw-r--r--include/clang/AST/ExprCXX.h14
-rw-r--r--include/clang/AST/TemplateBase.h143
-rw-r--r--include/clang/AST/Type.h8
-rw-r--r--include/clang/AST/TypeLoc.h109
-rw-r--r--include/clang/Frontend/PCHReader.h7
-rw-r--r--include/clang/Frontend/PCHWriter.h4
-rw-r--r--lib/AST/ASTContext.cpp22
-rw-r--r--lib/AST/DeclTemplate.cpp19
-rw-r--r--lib/AST/Expr.cpp20
-rw-r--r--lib/AST/ExprCXX.cpp26
-rw-r--r--lib/AST/StmtProfile.cpp70
-rw-r--r--lib/AST/TemplateBase.cpp28
-rw-r--r--lib/AST/Type.cpp159
-rw-r--r--lib/Frontend/PCHReader.cpp28
-rw-r--r--lib/Frontend/PCHWriter.cpp23
-rw-r--r--lib/Sema/Sema.h43
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp6
-rw-r--r--lib/Sema/SemaExprCXX.cpp2
-rw-r--r--lib/Sema/SemaOverload.cpp14
-rw-r--r--lib/Sema/SemaTemplate.cpp195
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp63
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp24
-rw-r--r--lib/Sema/SemaType.cpp15
-rw-r--r--lib/Sema/TreeTransform.h260
30 files changed, 970 insertions, 416 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index c4017d3e37..c70b3640f9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -531,6 +531,11 @@ public:
unsigned NumArgs,
QualType Canon = QualType());
+ QualType getTemplateSpecializationType(TemplateName T,
+ const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ QualType Canon = QualType());
+
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
QualType getTypenameType(NestedNameSpecifier *NNS,
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 1b3ce46ee5..f1a27933a1 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -572,11 +572,8 @@ class TemplateTypeParmDecl : public TypeDecl {
/// \brief Whether this is a parameter pack.
bool ParameterPack : 1;
- /// \brief The location of the default argument, if any.
- SourceLocation DefaultArgumentLoc;
-
/// \brief The default template argument, if any.
- QualType DefaultArgument;
+ DeclaratorInfo *DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
bool Typename, QualType Type, bool ParameterPack)
@@ -598,13 +595,16 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
+ bool hasDefaultArgument() const { return DefaultArgument != 0; }
/// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const { return DefaultArgument; }
+ QualType getDefaultArgument() const { return DefaultArgument->getType(); }
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
+ /// \brief Retrieves the default argument's source information, if any.
+ DeclaratorInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
+
+ /// \brief Retrieves the location of the default argument declaration.
+ SourceLocation getDefaultArgumentLoc() const;
/// \brief Determines whether the default argument was inherited
/// from a previous declaration of this template.
@@ -613,13 +613,17 @@ public:
/// \brief Set the default argument for this template parameter, and
/// whether that default argument was inherited from another
/// declaration.
- void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
- bool Inherited) {
+ void setDefaultArgument(DeclaratorInfo *DefArg, bool Inherited) {
DefaultArgument = DefArg;
- DefaultArgumentLoc = DefArgLoc;
InheritedDefault = Inherited;
}
+ /// \brief Removes the default argument of this template parameter.
+ void removeDefaultArgument() {
+ DefaultArgument = 0;
+ InheritedDefault = false;
+ }
+
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
@@ -917,6 +921,10 @@ class ClassTemplatePartialSpecializationDecl
/// \brief The list of template parameters
TemplateParameterList* TemplateParams;
+ /// \brief The source info for the template arguments as written.
+ TemplateArgumentLoc *ArgsAsWritten;
+ unsigned NumArgsAsWritten;
+
/// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
@@ -930,12 +938,15 @@ class ClassTemplatePartialSpecializationDecl
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
PrevDecl),
- TemplateParams(Params), InstantiatedFromMember(0, false) { }
+ TemplateParams(Params), ArgsAsWritten(ArgInfos),
+ NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -943,6 +954,8 @@ public:
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
+ TemplateArgumentLoc *ArgInfos,
+ unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters
@@ -950,6 +963,16 @@ public:
return TemplateParams;
}
+ /// Get the template arguments as written.
+ TemplateArgumentLoc *getTemplateArgsAsWritten() const {
+ return ArgsAsWritten;
+ }
+
+ /// Get the number of template arguments as written.
+ unsigned getNumTemplateArgsAsWritten() const {
+ return NumArgsAsWritten;
+ }
+
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 51172045c9..bb445f659c 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -34,6 +34,7 @@ namespace clang {
class BlockDecl;
class CXXOperatorCallExpr;
class CXXMemberCallExpr;
+ class TemplateArgumentLoc;
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
@@ -351,13 +352,13 @@ struct ExplicitTemplateArgumentList {
unsigned NumTemplateArgs;
/// \brief Retrieve the template arguments
- TemplateArgument *getTemplateArgs() {
- return reinterpret_cast<TemplateArgument *> (this + 1);
+ TemplateArgumentLoc *getTemplateArgs() {
+ return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
}
/// \brief Retrieve the template arguments
- const TemplateArgument *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgument *> (this + 1);
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
}
};
@@ -418,7 +419,7 @@ class DeclRefExpr : public Expr {
NamedDecl *D, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD);
@@ -460,7 +461,7 @@ public:
SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD);
@@ -513,7 +514,7 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
+ const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgumentList())
return 0;
@@ -1304,7 +1305,7 @@ class MemberExpr : public Expr {
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
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);
public:
@@ -1326,7 +1327,7 @@ public:
SourceLocation l,
bool has_explicit,
SourceLocation langle,
- const TemplateArgument *targs,
+ const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty);
@@ -1383,7 +1384,7 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
+ const TemplateArgumentLoc *getTemplateArgs() const {
if (!HasExplicitTemplateArgumentList)
return 0;
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 8fdb98df1b..5931a3fcf9 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1161,7 +1161,7 @@ class TemplateIdRefExpr : public Expr {
NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1172,7 +1172,7 @@ public:
Create(ASTContext &Context, QualType T,
NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc, const TemplateArgument *TemplateArgs,
+ SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs, SourceLocation RAngleLoc);
/// \brief Retrieve the nested name specifier used to qualify the name of
@@ -1198,8 +1198,8 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
}
/// \brief Retrieve the number of template arguments provided as part of this
@@ -1443,7 +1443,7 @@ class CXXUnresolvedMemberExpr : public Expr {
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1474,7 +1474,7 @@ public:
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -1542,7 +1542,7 @@ public:
/// \brief Retrieve the template arguments provided as part of this
/// template-id.
- const TemplateArgument *getTemplateArgs() const {
+ const TemplateArgumentLoc *getTemplateArgs() const {
if (!HasExplicitTemplateArgumentList)
return 0;
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index a328eafc7e..da956428f1 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "llvm/ADT/APSInt.h"
+#include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h"
namespace llvm {
@@ -26,6 +27,7 @@ namespace clang {
class Decl;
class Expr;
+class DeclaratorInfo;
/// \brief Represents a template argument within a class template
/// specialization.
@@ -43,9 +45,6 @@ class TemplateArgument {
} Args;
};
- /// \brief Location of the beginning of this template argument.
- SourceLocation StartLoc;
-
public:
/// \brief The type of template argument we're storing.
enum ArgKind {
@@ -67,30 +66,26 @@ public:
} Kind;
/// \brief Construct an empty, invalid template argument.
- TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+ TemplateArgument() : TypeOrValue(0), Kind(Null) { }
/// \brief Construct a template type argument.
- TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+ TemplateArgument(QualType T) : Kind(Type) {
TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- StartLoc = Loc;
}
/// \brief Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
- TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+ TemplateArgument(Decl *D) : Kind(Declaration) {
// FIXME: Need to be sure we have the "canonical" declaration!
TypeOrValue = reinterpret_cast<uintptr_t>(D);
- StartLoc = Loc;
}
/// \brief Construct an integral constant template argument.
- TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
- QualType Type)
+ TemplateArgument(const llvm::APSInt &Value, QualType Type)
: Kind(Integral) {
new (Integer.Value) llvm::APSInt(Value);
Integer.Type = Type.getAsOpaquePtr();
- StartLoc = Loc;
}
/// \brief Construct a template argument that is an expression.
@@ -98,7 +93,9 @@ public:
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
/// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E);
+ TemplateArgument(Expr *E) : Kind(Expression) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(E);
+ }
/// \brief Copy constructor for a template argument.
TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
@@ -113,7 +110,6 @@ public:
}
else
TypeOrValue = Other.TypeOrValue;
- StartLoc = Other.StartLoc;
}
TemplateArgument& operator=(const TemplateArgument& Other) {
@@ -142,7 +138,6 @@ public:
} else
TypeOrValue = Other.TypeOrValue;
}
- StartLoc = Other.StartLoc;
return *this;
}
@@ -234,9 +229,6 @@ public:
return Args.NumArgs;
}
- /// \brief Retrieve the location where the template argument starts.
- SourceLocation getLocation() const { return StartLoc; }
-
/// \brief Construct a template argument pack.
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
@@ -244,6 +236,123 @@ public:
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const;
};
+/// Location information for a TemplateArgument.
+struct TemplateArgumentLocInfo {
+private:
+ void *Union;
+
+#ifndef NDEBUG
+ enum Kind {
+ K_None,
+ K_DeclaratorInfo,
+ K_Expression
+ } Kind;
+#endif
+
+public:
+ TemplateArgumentLocInfo()
+ : Union(), Kind(K_None) {}
+ TemplateArgumentLocInfo(DeclaratorInfo *DInfo)
+ : Union(DInfo), Kind(K_DeclaratorInfo) {}
+ TemplateArgumentLocInfo(Expr *E)
+ : Union(E), Kind(K_Expression) {}
+
+ /// \brief Returns whether this
+ bool empty() const {
+ return Union == NULL;
+ }
+
+ DeclaratorInfo *getAsDeclaratorInfo() const {
+ assert(Kind == K_DeclaratorInfo);
+ return reinterpret_cast<DeclaratorInfo*>(Union);
+ }
+
+ Expr *getAsExpr() const {
+ assert(Kind == K_Expression);
+ return reinterpret_cast<Expr*>(Union);
+ }
+
+#ifndef NDEBUG
+ void validateForArgument(const TemplateArgument &Arg) {
+ // We permit empty data. This should be removed when source info
+ // is being uniformly preserved.
+ if (Kind == K_None) return;
+
+ switch (Arg.getKind()) {
+ case TemplateArgument::Type:
+ assert(Kind == K_DeclaratorInfo);
+ break;
+ case TemplateArgument::Expression:
+ assert(Kind == K_Expression);
+ break;
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::Pack:
+ assert(Kind == K_None);
+ break;
+ case TemplateArgument::Null:
+ llvm::llvm_unreachable("source info for null template argument?");
+ }
+ }
+#endif
+};
+
+/// Location wrapper for a TemplateArgument. TemplateArgument is to
+/// TemplateArgumentLoc as Type is to TypeLoc.
+class TemplateArgumentLoc {
+ TemplateArgument Argument;
+ TemplateArgumentLocInfo LocInfo;
+
+ friend class TemplateSpecializationTypeLoc;
+ TemplateArgumentLoc(const TemplateArgument &Argument,
+ TemplateArgumentLocInfo Opaque)
+ : Argument(Argument), LocInfo(Opaque) {
+ }
+
+public:
+ TemplateArgumentLoc() {}
+
+ TemplateArgumentLoc(const TemplateArgument &Argument, DeclaratorInfo *DInfo)
+ : Argument(Argument), LocInfo(DInfo) {
+ assert(Argument.getKind() == TemplateArgument::Type);
+ }
+
+ TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
+ : Argument(Argument), LocInfo(E) {
+ assert(Argument.getKind() == TemplateArgument::Expression);
+ }
+
+ /// This is a temporary measure.
+ TemplateArgumentLoc(const TemplateArgument &Argument)
+ : Argument(Argument), LocInfo() {
+ assert(Argument.getKind() != TemplateArgument::Expression &&
+ Argument.getKind() != TemplateArgument::Type);
+ }
+
+ /// \brief - Fetches the start location of the argument, if possible.
+ SourceLocation getLocation() const;
+
+ const TemplateArgument &getArgument() const {
+ return Argument;
+ }
+
+ TemplateArgumentLocInfo getLocInfo() const {
+ return LocInfo;
+ }
+
+ DeclaratorInfo *getSourceDeclaratorInfo() const {
+ assert(Argument.getKind() == TemplateArgument::Type);
+ if (LocInfo.empty()) return 0;
+ return LocInfo.getAsDeclaratorInfo();
+ }
+
+ Expr *getSourceExpression() const {
+ assert(Argument.getKind() == TemplateArgument::Expression);
+ if (LocInfo.empty()) return 0;
+ return LocInfo.getAsExpr();
+ }
+};
+
}
#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index db02a68a98..daa8147391 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -81,6 +81,7 @@ namespace clang {
class SourceLocation;
class StmtIteratorBase;
class TemplateArgument;
+ class TemplateArgumentLoc;
class QualifiedNameType;
struct PrintingPolicy;
@@ -2275,12 +2276,19 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgument *Args,
unsigned NumArgs);
+ static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
+ unsigned NumArgs);
+
/// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments.
static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
unsigned NumArgs,
const PrintingPolicy &Policy);
+ static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ const PrintingPolicy &Policy);
+
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 1d7181b531..b4e3fc4179 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
namespace clang {
class ParmVarDecl;
@@ -82,6 +83,19 @@ public:
return Data;
}
+ /// \brief Get the full source range.
+ SourceRange getFullSourceRange() const {
+ SourceLocation End = getSourceRange().getEnd();
+ TypeLoc Cur = *this;
+ while (true) {
+ TypeLoc Next = Cur.getNextTypeLoc();
+ if (Next.isNull()) break;
+ Cur = Next;
+ }
+ return SourceRange(Cur.getSourceRange().getBegin(), End);
+ }
+
+ /// \brief Get the local source range.
SourceRange getSourceRange() const {
return getSourceRangeImpl(*this);
}
@@ -810,6 +824,96 @@ class VariableArrayTypeLoc :
VariableArrayType> {
};
+
+// Location information for a TemplateName. Rudimentary for now.
+struct TemplateNameLocInfo {
+ SourceLocation NameLoc;
+};
+
+struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
+};
+
+class TemplateSpecializationTypeLoc :
+ public ConcreteTypeLoc<UnqualTypeLoc,
+ TemplateSpecializationTypeLoc,
+ TemplateSpecializationType,
+ TemplateSpecializationLocInfo> {
+public:
+ SourceLocation getLAngleLoc() const {
+ return getLocalData()->LAngleLoc;
+ }
+ void setLAngleLoc(SourceLocation Loc) {
+ getLocalData()->LAngleLoc = Loc;
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return getLocalData()->RAngleLoc;
+ }
+ void setRAngleLoc(SourceLocation Loc) {
+ getLocalData()->RAngleLoc = Loc;
+ }
+
+ unsigned getNumArgs() const {
+ return getTypePtr()->getNumArgs();
+ }
+ void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
+#ifndef NDEBUG
+ AI.validateForArgument(getTypePtr()->getArg(i));
+#endif
+ getArgInfos()[i] = AI;
+ }
+ TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
+ return getArgInfos()[i];
+ }
+
+ TemplateArgumentLoc getArgLoc(unsigned i) const {
+ return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ }
+
+ SourceLocation getTemplateNameLoc() const {
+ return getLocalData()->NameLoc;
+ }
+ void setTemplateNameLoc(SourceLocation Loc) {
+ getLocalData()->NameLoc = Loc;
+ }
+
+ /// \brief - Copy the location information from the given info.
+ void copy(TemplateSpecializationTypeLoc Loc) {
+ unsigned size = getFullDataSize();
+ assert(size == Loc.getFullDataSize());
+
+ // We're potentially copying Expr references here. We don't
+ // bother retaining them because DeclaratorInfos live forever, so
+ // as long as the Expr was retained when originally written into
+ // the TypeLoc, we're okay.
+ memcpy(Data, Loc.Data, size);
+ }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(getTemplateNameLoc(), getRAngleLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ setTemplateNameLoc(Loc);
+
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+ getArgInfos()[i] = TemplateArgumentLocInfo();
+ }
+
+ unsigned getExtraLocalDataSize() const {
+ return getNumArgs() * sizeof(TemplateArgumentLocInfo);
+ }
+
+private:
+ TemplateArgumentLocInfo *getArgInfos() const {
+ return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
+ }
+};
+
// None of these types have proper implementations yet.
class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
@@ -861,11 +965,6 @@ class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
ElaboratedType> {
};
-class TemplateSpecializationTypeLoc
- : public TypeSpecTypeLoc<TemplateSpecializationTypeLoc,
- TemplateSpecializationType> {
-};
-
class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
QualifiedNameType> {
};
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index f899cdbbb1..cc8b3a03e3 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -19,6 +19,7 @@
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Type.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
@@ -542,6 +543,12 @@ public:
/// comments in the source code.
virtual void ReadComments(std::vector<SourceRange> &Comments);
+ /// \brief Reads a TemplateArgumentLocInfo appropriate for the
+ /// given TemplateArgument kind.
+ TemplateArgumentLocInfo
+ GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+ const RecordData &Record, unsigned &Idx);
+
/// \brief Reads a declarator info from the given record.
virtual DeclaratorInfo *GetDeclaratorInfo(const RecordData &Record,
unsigned &Idx);
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 728e138d9e..22427eb671 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -275,6 +275,10 @@ public:
/// \brief Emits a reference to a declarator info.
void AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record);
+ /// \brief Emits a template argument location.
+ void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+ RecordData &Record);
+
/// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordData &Record);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7be55ebb11..d60a8204c7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1765,6 +1765,19 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
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 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) {
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 49244e1dba..9ebc91afe1 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 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
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 @@ QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
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 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
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 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
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 ad9c9cbe10..ad91cd393f 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -35,7 +35,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
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 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
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 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
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 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
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 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
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 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
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 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
SourceLocation l,
bool has_explicit,
SourceLocation langle,
- const TemplateArgument *targs,
+ const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty) {
@@ -473,7 +473,7 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
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 cba0e22095..7c6fc41ef1 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -151,7 +151,7 @@ TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(TemplateIdRefExprClass, T,
@@ -164,10 +164,10 @@ TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
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 @@ TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
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 @@ CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C,
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 @@ CXXUnresolvedMemberExpr::CXXUnresolvedMemberExpr(ASTContext &C,
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 @@ CXXUnresolvedMemberExpr::Create(ASTContext &C,
SourceLocation MemberLoc,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
if (!HasExplicitTemplateArgs)
@@ -573,7 +573,7 @@ CXXUnresolvedMemberExpr::Create(ASTContext &C,
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 a6327c9ea7..02e0c74bb6 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -60,7 +60,10 @@ namespace {
/// \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 @@ void StmtProfiler::VisitTemplateName(TemplateName Name) {
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];
-
- // 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::Declaration:
- VisitDecl(Arg.getAsDecl());
- break;
-
- case TemplateArgument::Integral:
- Arg.getAsIntegral()->Profile(ID);
- VisitType(Arg.getIntegralType());
- break;
-
- case TemplateArgument::Expression:
- Visit(Arg.getAsExpr());
- break;
-
- case TemplateArgument::Pack:
- VisitTemplateArguments(Arg.pack_begin(), Arg.pack_size());
- break;
- }
+ for (unsigned I = 0; I != NumArgs; ++I)
+ VisitTemplateArgument(Args[I].getArgument());
+}
+
+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::Declaration:
+ VisitDecl(Arg.getAsDecl());
+ break;
+
+ case TemplateArgument::Integral:
+ Arg.getAsIntegral()->Profile(ID);
+ VisitType(Arg.getIntegralType());
+ break;
+
+ case TemplateArgument::Expression:
+ Visit(Arg.getAsExpr());
+ 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 3b3ec2b530..b136fe0d38 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 @@ using namespace clang;
// 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 @@ void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
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 5fb0178834..65ed767522 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -791,40 +791,48 @@ bool EnumType::classof(const TagType *TT) {
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;
-
- case TemplateArgument::Type:
- if (Args[Idx].getAsType()->isDependentType())
- return true;
- break;
-
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- // Never dependent
- break;
-
- case TemplateArgument::Expression:
- if (Args[Idx].getAsExpr()->isTypeDependent() ||
- Args[Idx].getAsExpr()->isValueDependent())
- return true;
- break;
-
- case TemplateArgument::Pack:
- assert(0 && "FIXME: Implement!");
- 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:
+ return Arg.getAsType()->isDependentType();
+
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ // Never dependent
+ return false;
+
+ case TemplateArgument::Expression:
+ return (Arg.getAsExpr()->isTypeDependent() ||
+ Arg.getAsExpr()->isValueDependent());
+
+ 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 @@ void SubstTemplateTypeParmType::getAsStringInternal(std::string &InnerString, co
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 @@ TemplateSpecializationType::PrintTemplateArgumentList(
// Print the argument into a string.
std::string ArgString;
- switch (Args[Arg].getKind()) {
- case TemplateArgument::Null:
- assert(false && "Null template argument");
- break;
-
- case TemplateArgument::Type:
- Args[Arg].getAsType().getAsStringInternal(ArgString, Policy);
- break;
-
- case TemplateArgument::Declaration:
- ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
- break;
-
- case TemplateArgument::Integral:
- ArgString = Args[Arg].getAsIntegral()->toString(10, true);
- break;
-
- 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;
- }
+ PrintTemplateArgument(ArgString, Args[Arg], Policy);
+
+ // 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 += ' ';
+
+ SpecString += ArgString;
+ }
+
+ // 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 += ' ';
+
+ 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
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 9c6059b1c7..26f426ba32 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -32,6 +32,7 @@
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <iterator>
#include <cstdio>
@@ -2104,7 +2105,13 @@ void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
}
void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
- TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+ TL.setArgLocInfo(i,
+ Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
+ Record, Idx));
}
void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -2197,6 +2204,25 @@ QualType PCHReader::GetType(pch::TypeID ID) {
return TypesLoaded[Index].withFastQualifiers(FastQuals);
}
+TemplateArgumentLocInfo
+PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
+ const RecordData &Record,
+ unsigned &Index) {
+ switch (Kind) {
+ case TemplateArgument::Expression:
+ return ReadDeclExpr();
+ case TemplateArgument::Type:
+ return GetDeclaratorInfo(Record, Index);
+ case TemplateArgument::Null:
+ case TemplateArgument::Integral:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Pack:
+ return TemplateArgumentLocInfo();
+ }
+ llvm::llvm_unreachable("unexpected template argument loc");
+ return TemplateArgumentLocInfo();
+}
+
Decl *PCHReader::GetDecl(pch::DeclID ID) {
if (ID == 0)
return 0;
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 4c733db1a0..de56166125 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -368,7 +368,11 @@ void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
}
void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
- Writer.AddSourceLocation(TL.getNameLoc(), Record);
+ Writer.AddSourceLocation(TL.getTemplateNameLoc(), Record);
+ Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+ Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+ Writer.AddTemplateArgumentLoc(TL.getArgLoc(i), Record);
}
void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record);
@@ -2105,6 +2109,23 @@ void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {
Record.push_back(SID);
}
+void PCHWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
+ RecordData &Record) {
+ switch (Arg.getArgument().getKind()) {
+ case TemplateArgument::Expression:
+ AddStmt(Arg.getLocInfo().getAsExpr());
+ break;
+ case TemplateArgument::Type:
+ AddDeclaratorInfo(Arg.getLocInfo().getAsDeclaratorInfo(), Record);
+ break;
+ case TemplateArgument::Null:
+ case TemplateArgument::Integral:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Pack:
+ break;
+ }
+}
+
void PCHWriter::AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record) {
if (DInfo == 0) {
AddTypeRef(QualType(), Record);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 66ee81833e..11a3938544 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -73,6 +73,7 @@ namespace clang {
class TypedefDecl;
class TemplateDecl;
class TemplateArgument;
+ class TemplateArgumentLoc;
class TemplateArgumentList;
class TemplateParameterList;
class TemplateTemplateParmDecl;
@@ -866,7 +867,7 @@ public:
bool ForceRValue = false);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -874,7 +875,7 @@ public:
bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -912,7 +913,7 @@ public:
void AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
bool PartialOverloading = false);
@@ -934,7 +935,7 @@ public:
DeclarationName &UnqualifiedName,
bool &ArgumentDependentLookup,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet,
@@ -943,7 +944,7 @@ public:
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
@@ -1708,7 +1709,7 @@ public:
DeclarationName MemberName,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
DeclPtrTy ImplDecl,
@@ -1741,7 +1742,7 @@ public:
SourceRange &QualifierRange,
bool &ArgumentDependentLookup,
bool &HasExplicitTemplateArguments,
- const TemplateArgument *&ExplicitTemplateArgs,
+ const TemplateArgumentLoc *&ExplicitTemplateArgs,
unsigned &NumExplicitTemplateArgs);
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
@@ -2505,13 +2506,13 @@ public:
AccessSpecifier AS);
void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- llvm::SmallVector<TemplateArgument, 16> &TemplateArgs);
+ SourceLocation *TemplateArgLocsIn,
+ llvm::SmallVector<TemplateArgumentLoc, 16> &TempArgs);
QualType CheckTemplateIdType(TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -2532,7 +2533,7 @@ public:
TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
@@ -2587,7 +2588,7 @@ public:
bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
NamedDecl *&PrevDecl);
@@ -2627,18 +2628,18 @@ public:
bool CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted);
bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- const TemplateArgument &Arg,
+ const TemplateArgumentLoc &Arg,
TemplateArgumentListBuilder &Converted);
- bool CheckTemplateArgument(TemplateTypeParmDecl *Param, QualType Arg,
- SourceLocation ArgLoc);
+ bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
+ DeclaratorInfo *Arg);
bool CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
NamedDecl *&Entity);
bool CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member);
@@ -2813,7 +2814,7 @@ public:
TemplateDeductionResult
SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
llvm::SmallVectorImpl<TemplateArgument> &Deduced,
llvm::SmallVectorImpl<QualType> &ParamTypes,
@@ -2829,7 +2830,7 @@ public:
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
@@ -2838,7 +2839,7 @@ public:
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
QualType ArgFunctionType,
FunctionDecl *&Specialization,
@@ -3220,8 +3221,8 @@ public:
TemplateName
SubstTemplateName(TemplateName Name, SourceLocation Loc,
const MultiLevelTemplateArgumentList &TemplateArgs);
- TemplateArgument Subst(TemplateArgument Arg,
- const MultiLevelTemplateArgumentList &TemplateArgs);
+ bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
FunctionDecl *Function,
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index b877b1cadb..9e4bb35c65 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1234,7 +1234,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
SourceRange QualifierRange;
bool ArgumentDependentLookup;
bool HasExplicitTemplateArgs;
- const TemplateArgument *ExplicitTemplateArgs;
+ const TemplateArgumentLoc *ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs;
DeconstructCallFunction(Fn,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a86857990a..2ba1130c87 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2796,7 +2796,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
SourceLocation LAngleLoc, RAngleLoc;
if (D.getKind() == Declarator::DK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getTemplateId();
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a322eb0499..aa286106b9 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1959,7 +1959,7 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
DeclarationName MemberName,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS,
@@ -2711,7 +2711,7 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
SourceRange &QualifierRange,
bool &ArgumentDependentLookup,
bool &HasExplicitTemplateArguments,
- const TemplateArgument *&ExplicitTemplateArgs,
+ const TemplateArgumentLoc *&ExplicitTemplateArgs,
unsigned &NumExplicitTemplateArgs) {
// Set defaults for all of the output parameters.
Function = 0;
@@ -2892,7 +2892,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// lookup and whether there were any explicitly-specified template arguments.
bool ADL = true;
bool HasExplicitTemplateArgs = 0;
- const TemplateArgument *ExplicitTemplateArgs = 0;
+ const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
unsigned NumExplicitTemplateArgs = 0;
NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange;
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index d5f93dce28..32eeddb0fe 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2191,7 +2191,7 @@ Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
TypeTy *T,
const CXXScopeSpec &SS,
bool HasTrailingLParen) {
- QualType Type = QualType::getFromOpaquePtr(T);
+ QualType Type = GetTypeFromParser(T);
CanQualType CanType = Context.getCanonicalType(Type);
DeclarationName DtorName =
Context.DeclarationNames.getCXXDestructorName(CanType);
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 40e1450414..150f4ae78e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2444,7 +2444,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
void
Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -2489,7 +2489,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
@@ -3886,7 +3886,7 @@ void
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet,
bool PartialOverloading) {
@@ -4278,7 +4278,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
}
bool HasExplicitTemplateArgs = false;
- const TemplateArgument *ExplicitTemplateArgs = 0;
+ const TemplateArgumentLoc *ExplicitTemplateArgs = 0;
unsigned NumExplicitTemplateArgs = 0;
// Try to dig out the overloaded function.
@@ -4451,7 +4451,7 @@ static void AddOverloadedCallCandidate(Sema &S,
AnyFunctionDecl Callee,
bool &ArgumentDependentLookup,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet,
@@ -4483,7 +4483,7 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
DeclarationName &UnqualifiedName,
bool &ArgumentDependentLookup,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet,
@@ -4551,7 +4551,7 @@ void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 36a158d3cd..a2883fa980 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -321,8 +321,11 @@ void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
TypeTy *DefaultT) {
TemplateTypeParmDecl *Parm
= cast<TemplateTypeParmDecl>(TypeParam.getAs<Decl>());
- // FIXME: Preserve type source info.
- QualType Default = GetTypeFromParser(DefaultT);
+
+ DeclaratorInfo *DefaultDInfo;
+ GetTypeFromParser(DefaultT, &DefaultDInfo);
+
+ assert(DefaultDInfo && "expected source information for type");
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
@@ -337,12 +340,12 @@ void Sema::ActOnTypeParameterDefault(DeclPtrTy TypeParam,
// FIXME: Implement this check! Needs a recursive walk over the types.
// Check the template argument itself.
- if (CheckTemplateArgument(Parm, Default, DefaultLoc)) {
+ if (CheckTemplateArgument(Parm, DefaultDInfo)) {
Parm->setInvalidDecl();
return;
}
- Parm->setDefaultArgument(Default, DefaultLoc, false);
+ Parm->setDefaultArgument(DefaultDInfo, false);
}
/// \brief Check that the type of a non-type template parameter is
@@ -843,7 +846,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
SawParameterPack = true;
ParameterPackLoc = NewTypeParm->getLocation();
} else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
- NewTypeParm->hasDefaultArgument()) {
+ NewTypeParm->hasDefaultArgument()) {
OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
SawDefaultArgument = true;
@@ -853,8 +856,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
// Merge the default argument from the old declaration to the
// new declaration.
SawDefaultArgument = true;
- NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgument(),
- OldTypeParm->getDefaultArgumentLoc(),
+ NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgumentInfo(),
true);
PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
} else if (NewTypeParm->hasDefaultArgument()) {
@@ -1096,24 +1098,28 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
/// into template arguments used by semantic analysis.
void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
SourceLocation *TemplateArgLocs,
- llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
+ llvm::SmallVector<TemplateArgumentLoc, 16> &TemplateArgs) {
TemplateArgs.reserve(TemplateArgsIn.size());
void **Args = TemplateArgsIn.getArgs();
bool *ArgIsType = TemplateArgsIn.getArgIsType();
for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
- TemplateArgs.push_back(
- ArgIsType[Arg]? TemplateArgument(TemplateArgLocs[Arg],
- //FIXME: Preserve type source info.
- Sema::GetTypeFromParser(Args[Arg]))
- : TemplateArgument(reinterpret_cast<Expr *>(Args[Arg])));
+ if (ArgIsType[Arg]) {
+ DeclaratorInfo *DI;
+ QualType T = Sema::GetTypeFromParser(Args[Arg], &DI);
+ if (!DI) DI = Context.getTrivialDeclaratorInfo(T, TemplateArgLocs[Arg]);
+ TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(T), DI));
+ } else {
+ Expr *E = reinterpret_cast<Expr *>(Args[Arg]);
+ TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
+ }
}
}
QualType Sema::CheckTemplateIdType(TemplateName Name,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
TemplateDecl *Template = Name.getAsTemplateDecl();
@@ -1155,7 +1161,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
Converted.flatSize());
// FIXME: CanonType is not actually the canonical type, and unfortunately
- // it is a TemplateTypeSpecializationType that we will never use again.
+ // it is a TemplateSpecializationType that we will never use again.
// In the future, we need to teach getTemplateSpecializationType to only
// build the canonical type and return that to us.
CanonType = Context.getCanonicalType(CanonType);
@@ -1190,7 +1196,6 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Build the fully-sugared type for this class template
// specialization, which refers back to the class template
// specialization we created or found.
- //FIXME: Preserve type source info.
return Context.getTemplateSpecializationType(Name, TemplateArgs,
NumTemplateArgs, CanonType);
}
@@ -1199,13 +1204,13 @@ Action::TypeResult
Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
+ SourceLocation *TemplateArgLocsIn,
SourceLocation RAngleLoc) {
TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsIn, TemplateArgLocsIn, TemplateArgs);
QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
TemplateArgs.data(),
@@ -1216,7 +1221,16 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
if (Result.isNull())
return true;
- return Result.getAsOpaquePtr();
+ DeclaratorInfo *DI = Context.CreateDeclaratorInfo(Result);
+ TemplateSpecializationTypeLoc TL
+ = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+ TL.setTemplateNameLoc(TemplateLoc);
+ TL.setLAngleLoc(LAngleLoc);
+ TL.setRAngleLoc(RAngleLoc);
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+ TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
+
+ return CreateLocInfoType(Result, DI).getAsOpaquePtr();
}
Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
@@ -1226,7 +1240,9 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
if (TypeResult.isInvalid())
return Sema::TypeResult();
- QualType Type = QualType::getFromOpaquePtr(TypeResult.get());
+ // FIXME: preserve source info, ideally without copying the DI.
+ DeclaratorInfo *DI;
+ QualType Type = GetTypeFromParser(TypeResult.get(), &DI);
// Verify the tag specifier.
TagDecl::TagKind TagKind = TagDecl::getTagKindForTypeSpec(TagSpec);
@@ -1256,7 +1272,7 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
TemplateName Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
// FIXME: Can we do any checking at this point? I guess we could check the
@@ -1296,13 +1312,13 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
+ SourceLocation *TemplateArgSLs,
SourceLocation RAngleLoc) {
TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsIn, TemplateArgSLs, TemplateArgs);
TemplateArgsIn.release();
return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
@@ -1336,7 +1352,7 @@ Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
Name = Template.getAsDependentTemplateName()->getName();
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
TemplateArgsIn.release();
@@ -1397,8 +1413,10 @@ Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
}
bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- const TemplateArgument &Arg,
+ const TemplateArgumentLoc &AL,
TemplateArgumentListBuilder &Converted) {
+ const TemplateArgument &Arg = AL.getArgument();
+
// Check template type parameter.
if (Arg.getKind() != TemplateArgument::Type) {
// C++ [temp.arg.type]p1:
@@ -1407,19 +1425,18 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
// We have a template type parameter but the template argument
// is not a type.
- Diag(Arg.getLocation(), diag::err_template_arg_must_be_type);
+ Diag(AL.getLocation(), diag::err_template_arg_must_be_type);
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
}
- if (CheckTemplateArgument(Param, Arg.getAsType(), Arg.getLocation()))
+ if (CheckTemplateArgument(Param, AL.getSourceDeclaratorInfo()))
return true;
// Add the converted template type argument.
Converted.Append(
- TemplateArgument(Arg.getLocation(),
- Context.getCanonicalType(Arg.getAsType())));
+ TemplateArgument(Context.getCanonicalType(Arg.getAsType())));
return false;
}
@@ -1428,7 +1445,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
bool PartialTemplateArgs,
@@ -1474,7 +1491,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
break;
// Decode the template argument
- TemplateArgument Arg;
+ TemplateArgumentLoc Arg;
+
if (ArgIdx >= NumArgs) {
// Retrieve the default template argument from the template
// parameter.
@@ -1489,11 +1507,11 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
if (!TTP->hasDefaultArgument())
break;
- QualType ArgType = TTP->getDefaultArgument();
+ DeclaratorInfo *ArgType = TTP->getDefaultArgumentInfo();
// If the argument type is dependent, instantiate it now based
// on the previously-computed template arguments.
- if (ArgType->isDependentType()) {
+ if (ArgType->getType()->isDependentType()) {
InstantiatingTemplate Inst(*this, TemplateLoc,
Template, Converted.getFlatArguments(),
Converted.flatSize(),
@@ -1507,10 +1525,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
TTP->getDeclName());
}
- if (ArgType.isNull())
+ if (!ArgType)
return true;
- Arg = TemplateArgument(TTP->getLocation(), ArgType);
+ Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()), ArgType);
} else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
if (!NTTP->hasDefaultArgument())
@@ -1530,7 +1548,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
if (E.isInvalid())
return true;
- Arg = TemplateArgument(E.takeAs<Expr>());
+ Expr *Ex = E.takeAs<Expr>();
+ Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
} else {
TemplateTemplateParmDecl *TempParm
= cast<TemplateTemplateParmDecl>(*Param);
@@ -1539,7 +1558,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
break;
// FIXME: Subst default argument
- Arg = TemplateArgument(TempParm->getDefaultArgument());
+ // FIXME: preserve source information
+ Arg = TemplateArgumentLoc(TemplateArgument(TempParm->getDefaultArgument()));
}
} else {
// Retrieve the template argument produced by the user.
@@ -1592,13 +1612,13 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
}
}
- switch (Arg.getKind()) {
+ switch (Arg.getArgument().getKind()) {
case TemplateArgument::Null:
assert(false && "Should never see a NULL template argument here");
break;
case TemplateArgument::Expression: {
- Expr *E = Arg.getAsExpr();
+ Expr *E = Arg.getArgument().getAsExpr();
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
Invalid = true;
@@ -1611,10 +1631,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
case TemplateArgument::Integral:
// We've already checked this template argument, so just copy
// it to the list of converted arguments.
- Converted.Append(Arg);
+ Converted.Append(Arg.getArgument());
break;
- case TemplateArgument::Type:
+ case TemplateArgument::Type: {
// We have a non-type template parameter but the template
// argument is a type.
@@ -1625,14 +1645,16 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
//
// We warn specifically about this case, since it can be rather
// confusing for users.
- if (Arg.getAsType()->isFunctionType())
+ QualType T = Arg.getArgument().getAsType();
+ if (T->isFunctionType())
Diag(Arg.getLocation(), diag::err_template_arg_nontype_ambig)
- << Arg.getAsType();
+ << T;
else
Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr);
Diag((*Param)->getLocation(), diag::note_template_param_here);
Invalid = true;
break;
+ }
case TemplateArgument::Pack:
assert(0 && "FIXME: Implement!");
@@ -1643,13 +1665,13 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
TemplateTemplateParmDecl *TempParm
= cast<TemplateTemplateParmDecl>(*Param);
- switch (Arg.getKind()) {
+ switch (Arg.getArgument().getKind()) {
case TemplateArgument::Null:
assert(false && "Should never see a NULL template argument here");
break;
case TemplateArgument::Expression: {
- Expr *ArgExpr = Arg.getAsExpr();
+ Expr *ArgExpr = Arg.getArgument().getAsExpr();
if (ArgExpr && isa<DeclRefExpr>(ArgExpr) &&
isa<TemplateDecl>(cast<DeclRefExpr>(ArgExpr)->getDecl())) {
if (CheckTemplateArgument(TempParm, cast<DeclRefExpr>(ArgExpr)))
@@ -1658,7 +1680,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
// Add the converted template argument.
Decl *D
= cast<DeclRefExpr>(ArgExpr)->getDecl()->getCanonicalDecl();
- Converted.Append(TemplateArgument(Arg.getLocation(), D));
+ Converted.Append(TemplateArgument(D));
continue;
}
}
@@ -1675,7 +1697,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
case TemplateArgument::Declaration:
// We've already checked this template argument, so just copy
// it to the list of converted arguments.
- Converted.Append(Arg);
+ Converted.Append(Arg.getArgument());
break;
case TemplateArgument::Integral:
@@ -1698,7 +1720,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
/// This routine implements the semantics of C++ [temp.arg.type]. It
/// returns true if an error occurred, and false otherwise.
bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
- QualType Arg, SourceLocation ArgLoc) {
+ DeclaratorInfo *ArgInfo) {
+ assert(ArgInfo && "invalid DeclaratorInfo");
+ QualType Arg = ArgInfo->getType();
+
// C++ [temp.arg.type]p2:
// A local type, a type with no linkage, an unnamed type or a type
// compounded from any of these types shall not be used as a
@@ -1710,12 +1735,14 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
Tag = EnumT;
else if (const RecordType *RecordT = Arg->getAs<RecordType>())
Tag = RecordT;
- if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod())
- return Diag(ArgLoc, diag::err_template_arg_local_type)
- << QualType(Tag, 0);
- else if (Tag && !Tag->getDecl()->getDeclName() &&
+ if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
+ SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+ return Diag(SR.getBegin(), diag::err_template_arg_local_type)
+ << QualType(Tag, 0) << SR;
+ } else if (Tag && !Tag->getDecl()->getDeclName() &&
!Tag->getDecl()->getTypedefForAnonDecl()) {
- Diag(ArgLoc, diag::err_template_arg_unnamed_type);
+ SourceRange SR = ArgInfo->getTypeLoc().getFullSourceRange();
+ Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR;
Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
return true;
}
@@ -2015,7 +2042,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return false;
}
- Converted = TemplateArgument(StartLoc, Value,
+ Converted = TemplateArgument(Value,
ParamType->isEnumeralType() ? ParamType
: IntegerType);
return false;
@@ -2089,7 +2116,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Member)
Member = cast<NamedDecl>(Member->getCanonicalDecl());
- Converted = TemplateArgument(StartLoc, Member);
+ Converted = TemplateArgument(Member);
return false;
}
@@ -2099,7 +2126,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Entity)
Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(StartLoc, Entity);
+ Converted = TemplateArgument(Entity);
return false;
}
@@ -2139,7 +2166,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Entity)
Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(StartLoc, Entity);
+ Converted = TemplateArgument(Entity);
return false;
}
@@ -2180,7 +2207,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return true;
Entity = cast<NamedDecl>(Entity->getCanonicalDecl());
- Converted = TemplateArgument(StartLoc, Entity);
+ Converted = TemplateArgument(Entity);
return false;
}
@@ -2210,7 +2237,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Member)
Member = cast<NamedDecl>(Member->getCanonicalDecl());
- Converted = TemplateArgument(StartLoc, Member);
+ Converted = TemplateArgument(Member);
return false;
}
@@ -2722,7 +2749,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
if (TTP->hasDefaultArgument()) {
Diag(TTP->getDefaultArgumentLoc(),
diag::err_default_arg_in_partial_spec);
- TTP->setDefaultArgument(QualType(), SourceLocation(), false);
+ TTP->removeDefaultArgument();
}
} else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
@@ -2781,7 +2808,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
}
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
// Check that the template argument list is well-formed for this
@@ -2889,6 +2916,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TemplateParams,
ClassTemplate,
Converted,
+ TemplateArgs.data(),
+ TemplateArgs.size(),
PrevPartial);
if (PrevPartial) {
@@ -3268,7 +3297,7 @@ bool
Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
bool HasExplicitTemplateArgs,
SourceLocation LAngleLoc,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
NamedDecl *&PrevDecl) {
@@ -3624,7 +3653,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
: TSK_ExplicitInstantiationDeclaration;
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
// Check that the template argument list is well-formed for this
@@ -4003,7 +4032,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
- llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
if (D.getKind() == Declarator::DK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getTemplateId();
ASTTemplateArgsPtr TemplateArgsPtr(*this,
@@ -4310,25 +4339,13 @@ namespace {
/// refers to a member of the current instantiation, and then
/// type-checking and building a QualifiedNameType (when possible).
QualType TransformTypenameType(TypeLocBuilder &TLB, TypenameTypeLoc TL);
- QualType TransformTypenameType(TypenameType *T);
};
}
QualType
CurrentInstantiationRebuilder::TransformTypenameType(TypeLocBuilder &TLB,
TypenameTypeLoc TL) {
- QualType Result = TransformTypenameType(TL.getTypePtr());
- if (Result.isNull())
- return QualType();
-
- TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
-
- return Result;
-}
-
-QualType
-CurrentInstantiationRebuilder::TransformTypenameType(TypenameType *T) {
+ TypenameType *T = TL.getTypePtr();
NestedNameSpecifier *NNS
= TransformNestedNameSpecifier(T->getQualifier(),
@@ -4342,12 +4359,14 @@ CurrentInstantiationRebuilder::TransformTypenameType(TypenameType *T) {
CXXScopeSpec SS;
SS.setRange(SourceRange(getBaseLocation()));
SS.setScopeRep(NNS);
+
+ QualType Result;
if (NNS == T->getQualifier() && getSema().computeDeclContext(SS) == 0)
- return QualType(T, 0);
+ Result = QualType(T, 0);
// Rebuild the typename type, which will probably turn into a
// QualifiedNameType.
- if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
+ else if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
QualType NewTemplateId
= TransformType(QualType(TemplateId, 0));
if (NewTemplateId.isNull())
@@ -4355,12 +4374,16 @@ CurrentInstantiationRebuilder::TransformTypenameType(TypenameType *T) {
if (NNS == T->getQualifier() &&
NewTemplateId == QualType(TemplateId, 0))
- return QualType(T, 0);
-
- return getDerived().RebuildTypenameType(NNS, NewTemplateId);
- }
+ Result = QualType(T, 0);
+ else
+ Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
+ } else
+ Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(),
+ SourceRange(TL.getNameLoc()));
- return getDerived().RebuildTypenameType(NNS, T->getIdentifier());
+ TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
+ NewTL.setNameLoc(TL.getNameLoc());
+ return Result;
}
/// \brief Rebuilds a type within the context of the current instantiation.
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 14373dee73..7b5ad7fc64 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -90,7 +90,7 @@ DeduceNonTypeTemplateArgument(ASTContext &Context,
Value.extOrTrunc(AllowedBits);
Value.setIsSigned(T->isSignedIntegerType());
- Deduced[NTTP->getIndex()] = TemplateArgument(SourceLocation(), Value, T);
+ Deduced[NTTP->getIndex()] = TemplateArgument(Value, T);
return Sema::TDK_Success;
}
@@ -102,7 +102,7 @@ DeduceNonTypeTemplateArgument(ASTContext &Context,
if (PrevValuePtr->isNegative()) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
- Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
+ Info.SecondArg = TemplateArgument(Value, NTTP->getType());
return Sema::TDK_Inconsistent;
}
@@ -115,7 +115,7 @@ DeduceNonTypeTemplateArgument(ASTContext &Context,
if (Value != PrevValue) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
- Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
+ Info.SecondArg = TemplateArgument(Value, NTTP->getType());
return Sema::TDK_Inconsistent;
}
@@ -433,7 +433,7 @@ DeduceTemplateArguments(ASTContext &Context,
if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = Deduced[Index];
- Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
+ Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_InconsistentQuals;
}
@@ -445,7 +445,7 @@ DeduceTemplateArguments(ASTContext &Context,
DeducedType = Context.getCanonicalType(DeducedType);
if (Deduced[Index].isNull())
- Deduced[Index] = TemplateArgument(SourceLocation(), DeducedType);
+ Deduced[Index] = TemplateArgument(DeducedType);
else {
// C++ [temp.deduct.type]p2:
// [...] If type deduction cannot be done for any P/A pair, or if for
@@ -457,7 +457,7 @@ DeduceTemplateArguments(ASTContext &Context,
Info.Param
= cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
Info.FirstArg = Deduced[Index];
- Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
+ Info.SecondArg = TemplateArgument(Arg);
return Sema::TDK_Inconsistent;
}
}
@@ -465,8 +465,8 @@ DeduceTemplateArguments(ASTContext &Context,
}
// Set up the template argument deduction information for a failure.
- Info.FirstArg = TemplateArgument(SourceLocation(), ParamIn);
- Info.SecondArg = TemplateArgument(SourceLocation(), ArgIn);
+ Info.FirstArg = TemplateArgument(ParamIn);
+ Info.SecondArg = TemplateArgument(ArgIn);
// Check the cv-qualifiers on the parameter and argument types.
if (!(TDF & TDF_IgnoreQualifiers)) {
@@ -982,18 +982,41 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
// and are equivalent to the template arguments originally provided
// to the class template.
ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
- const TemplateArgumentList &PartialTemplateArgs = Partial->getTemplateArgs();
- for (unsigned I = 0, N = PartialTemplateArgs.flat_size(); I != N; ++I) {
+ const TemplateArgumentLoc *PartialTemplateArgs
+ = Partial->getTemplateArgsAsWritten();
+ unsigned N = Partial->getNumTemplateArgsAsWritten();
+ llvm::SmallVector<TemplateArgumentLoc, 16> InstArgs(N);
+ for (unsigned I = 0; I != N; ++I) {
Decl *Param = const_cast<NamedDecl *>(
ClassTemplate->getTemplateParameters()->getParam(I));
- TemplateArgument InstArg
- = Subst(PartialTemplateArgs[I],
- MultiLevelTemplateArgumentList(*DeducedArgumentList));
- if (InstArg.isNull()) {
+ if (Subst(PartialTemplateArgs[I], InstArgs[I],
+ MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = PartialTemplateArgs[I];
+ Info.FirstArg = PartialTemplateArgs[I].getArgument();
return TDK_SubstitutionFailure;
}
+ }
+
+ TemplateArgumentListBuilder ConvertedInstArgs(
+ ClassTemplate->getTemplateParameters(), N);
+
+ if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
+ /*LAngle*/ SourceLocation(),
+ InstArgs.data(), N,
+ /*RAngle*/ SourceLocation(),
+ false, ConvertedInstArgs)) {
+ // FIXME: fail with more useful information?
+ return TDK_SubstitutionFailure;
+ }
+
+ for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
+ // We don't really care if we overwrite the internal structures of
+ // the arg list builder, because we're going to throw it all away.
+ TemplateArgument &InstArg
+ = const_cast<TemplateArgument&>(ConvertedInstArgs.getFlatArguments()[I]);
+
+ Decl *Param = const_cast<NamedDecl *>(
+ ClassTemplate->getTemplateParameters()->getParam(I));
if (InstArg.getKind() == TemplateArgument::Expression) {
// When the argument is an expression, check the expression result
@@ -1004,7 +1027,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
if (CheckTemplateArgument(NTTP, NTTP->getType(), InstExpr, InstArg)) {
Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = PartialTemplateArgs[I];
+ Info.FirstArg = Partial->getTemplateArgs()[I];
return TDK_SubstitutionFailure;
}
} else if (TemplateTemplateParmDecl *TTP
@@ -1013,7 +1036,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InstExpr);
if (!DRE || CheckTemplateArgument(TTP, DRE)) {
Info.Param = makeTemplateParameter(Param);
- Info.FirstArg = PartialTemplateArgs[I];
+ Info.FirstArg = Partial->getTemplateArgs()[I];
return TDK_SubstitutionFailure;
}
}
@@ -1072,7 +1095,7 @@ static bool isSimpleTemplateIdType(QualType T) {
Sema::TemplateDeductionResult
Sema::SubstituteExplicitTemplateArguments(
FunctionTemplateDecl *FunctionTemplate,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
llvm::SmallVectorImpl<TemplateArgument> &Deduced,
llvm::SmallVectorImpl<QualType> &ParamTypes,
@@ -1290,7 +1313,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
@@ -1460,7 +1483,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
- const TemplateArgument *ExplicitTemplateArgs,
+ const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
QualType ArgFunctionType,
FunctionDecl *&Specialization,
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 794ec2a9ef..8fab8f62e4 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1261,9 +1261,10 @@ Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
return Instantiator.TransformTemplateName(Name);
}
-TemplateArgument Sema::Subst(TemplateArgument Arg,
- const MultiLevelTemplateArgumentList &TemplateArgs) {
+bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
+ const MultiLevelTemplateArgumentList &TemplateArgs) {
TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
DeclarationName());
- return Instantiator.TransformTemplateArgument(Arg);
+
+ return Instantiator.TransformTemplateArgument(Input, Output);
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 50b0fb81d7..0b54533175 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -886,14 +886,13 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
// FIXME: Do we actually want to perform substitution here? I don't think
// we do.
if (D->hasDefaultArgument()) {
- QualType DefaultPattern = D->getDefaultArgument();
- QualType DefaultInst
+ DeclaratorInfo *DefaultPattern = D->getDefaultArgumentInfo();
+ DeclaratorInfo *DefaultInst
= SemaRef.SubstType(DefaultPattern, TemplateArgs,
D->getDefaultArgumentLoc(),
D->getDeclName());
Inst->setDefaultArgument(DefaultInst,
- D->getDefaultArgumentLoc(),
D->defaultArgumentWasInherited() /* preserve? */);
}
@@ -1026,16 +1025,15 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Substitute into the template arguments of the class template partial
// specialization.
- const TemplateArgumentList &PartialSpecTemplateArgs
- = PartialSpec->getTemplateInstantiationArgs();
- llvm::SmallVector<TemplateArgument, 4> InstTemplateArgs;
- for (unsigned I = 0, N = PartialSpecTemplateArgs.size(); I != N; ++I) {
- TemplateArgument Inst = SemaRef.Subst(PartialSpecTemplateArgs[I],
- TemplateArgs);
- if (Inst.isNull())
+ const TemplateArgumentLoc *PartialSpecTemplateArgs
+ = PartialSpec->getTemplateArgsAsWritten();
+ unsigned N = PartialSpec->getNumTemplateArgsAsWritten();
+
+ llvm::SmallVector<TemplateArgumentLoc, 4> InstTemplateArgs(N);
+ for (unsigned I = 0; I != N; ++I) {
+ if (SemaRef.Subst(PartialSpecTemplateArgs[I], InstTemplateArgs[I],
+ TemplateArgs))
return true;
-
- InstTemplateArgs.push_back(Inst);
}
@@ -1116,6 +1114,8 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
InstParams,
ClassTemplate,
Converted,
+ InstTemplateArgs.data(),
+ InstTemplateArgs.size(),
0);
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
InstPartialSpec->setTypeAsWritten(WrittenTy);
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 8e960a43f7..c135f43209 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1328,6 +1328,21 @@ namespace {
Visit(TL.getBaseTypeLoc());
}
}
+ void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+ DeclaratorInfo *DInfo = 0;
+ Sema::GetTypeFromParser(DS.getTypeRep(), &DInfo);
+
+ // If we got no declarator info from previous Sema routines,
+ // just fill with the typespec loc.
+ if (!DInfo) {
+ TL.initialize(DS.getTypeSpecTypeLoc());
+ return;
+ }
+
+ TemplateSpecializationTypeLoc OldTL =
+ cast<TemplateSpecializationTypeLoc>(DInfo->getTypeLoc());
+ TL.copy(OldTL);
+ }
void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert.
TL.initialize(DS.getTypeSpecTypeLoc());
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index b4ec2fa71e..5b78375e56 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -290,7 +290,20 @@ public:
/// declaration stored within the template argument and constructs a
/// new template argument from the transformed result. Subclasses may
/// override this function to provide alternate behavior.
- TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
+ ///
+ /// Returns true if there was an error.
+ bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
+ TemplateArgumentLoc &Output);
+
+ /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
+ void InventTemplateArgumentLoc(const TemplateArgument &Arg,
+ TemplateArgumentLoc &ArgLoc);
+
+ /// \brief Fakes up a DeclaratorInfo for a type.
+ DeclaratorInfo *InventDeclaratorInfo(QualType T) {
+ return SemaRef.Context.getTrivialDeclaratorInfo(T,
+ getDerived().getBaseLocation());
+ }
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
@@ -300,6 +313,11 @@ public:
QualType
TransformTemplateSpecializationType(const TemplateSpecializationType *T,
QualType ObjectType);
+
+ QualType
+ TransformTemplateSpecializationType(TypeLocBuilder &TLB,
+ TemplateSpecializationTypeLoc TL,
+ QualType ObjectType);
OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
@@ -478,8 +496,11 @@ public:
/// specialization type. Subclasses may override this routine to provide
/// different behavior.
QualType RebuildTemplateSpecializationType(TemplateName Template,
- const TemplateArgument *Args,
- unsigned NumArgs);
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ SourceLocation RAngleLoc);
/// \brief Build a new qualified name type.
///
@@ -509,9 +530,9 @@ public:
/// (or qualified name type). Subclasses may override this routine to provide
/// different behavior.
QualType RebuildTypenameType(NestedNameSpecifier *NNS,
- const IdentifierInfo *Id) {
- return SemaRef.CheckTypenameType(NNS, *Id,
- SourceRange(getDerived().getBaseLocation()));
+ const IdentifierInfo *Id,
+ SourceRange SR) {
+ return SemaRef.CheckTypenameType(NNS, *Id, SR);
}
/// \brief Build a new nested-name-specifier given the prefix and an
@@ -1427,7 +1448,7 @@ public:
TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
- TemplateArgument *TemplateArgs,
+ TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
@@ -1530,7 +1551,7 @@ public:
SourceLocation TemplateNameLoc,
NamedDecl *FirstQualifierInScope,
SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
+ const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
OwningExprResult Base = move(BaseE);
@@ -1876,30 +1897,67 @@ TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
}
template<typename Derived>
-TemplateArgument
-TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
+void TreeTransform<Derived>::InventTemplateArgumentLoc(
+ const TemplateArgument &Arg,
+ TemplateArgumentLoc &Output) {
+ SourceLocation Loc = getDerived().getBaseLocation();
switch (Arg.getKind()) {
case TemplateArgument::Null:
+ llvm::llvm_unreachable("null template argument in TreeTransform");
+ break;
+
+ case TemplateArgument::Type:
+ Output = TemplateArgumentLoc(Arg,
+ SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
+
+ break;
+
+ case TemplateArgument::Expression:
+ Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
+ break;
+
+ case TemplateArgument::Declaration:
case TemplateArgument::Integral:
- return Arg;
+ case TemplateArgument::Pack:
+ Output = TemplateArgumentLoc(Arg);
+ break;
+ }
+}
+
+template<typename Derived>
+bool TreeTransform<Derived>::TransformTemplateArgument(
+ const TemplateArgumentLoc &Input,
+ TemplateArgumentLoc &Output) {
+ const TemplateArgument &Arg = Input.getArgument();
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Integral:
+ Output = Input;
+ return false;
case TemplateArgument::Type: {
- TemporaryBase Rebase(*this, Arg.getLocation(), DeclarationName());
- QualType T = getDerived().TransformType(Arg.getAsType());
- if (T.isNull())
- return TemplateArgument();
- return TemplateArgument(Arg.getLocation(), T);
+ DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
+ if (DI == NULL)
+ DI = InventDeclaratorInfo(Input.getArgument().getAsType());
+
+ DI = getDerived().TransformType(DI);
+ if (!DI) return true;
+
+ Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
+ return false;
}
case TemplateArgument::Declaration: {
+ // FIXME: we should never have to transform one of these.
DeclarationName Name;
if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
Name = ND->getDeclName();
- TemporaryBase Rebase(*this, Arg.getLocation(), Name);
+ TemporaryBase Rebase(*this, SourceLocation(), Name);
Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
- if (!D)
- return TemplateArgument();
- return TemplateArgument(Arg.getLocation(), D);
+ if (!D) return true;
+
+ Output = TemplateArgumentLoc(TemplateArgument(D));
+ return false;
}
case TemplateArgument::Expression: {
@@ -1907,10 +1965,16 @@ TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
EnterExpressionEvaluationContext Unevaluated(getSema(),
Action::Unevaluated);
- Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
- if (E.isInvalid())
- return TemplateArgument();
- return TemplateArgument(E.takeAs<Expr>());
+ Expr *InputExpr = Input.getSourceExpression();
+ if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
+
+ Sema::OwningExprResult E
+ = getDerived().TransformExpr(InputExpr);
+ if (E.isInvalid()) return true;
+
+ Expr *ETaken = E.takeAs<Expr>();
+ Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+ return false;
}
case TemplateArgument::Pack: {
@@ -1919,21 +1983,28 @@ TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
AEnd = Arg.pack_end();
A != AEnd; ++A) {
- TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
- if (TA.isNull())
- return TA;
- TransformedArgs.push_back(TA);
+ // FIXME: preserve source information here when we start
+ // caring about parameter packs.
+
+ TemplateArgumentLoc Input;
+ TemplateArgumentLoc Output;
+ getDerived().InventTemplateArgumentLoc(*A, Input);
+ if (getDerived().TransformTemplateArgument(Input, Output))
+ return true;
+
+ TransformedArgs.push_back(Output.getArgument());
}
TemplateArgument Result;
Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
true);
- return Result;
+ Output = TemplateArgumentLoc(Result);
+ return false;
}
}
// Work around bogus GCC warning
- return TemplateArgument();
+ return true;
}
//===----------------------------------------------------------------------===//
@@ -2678,46 +2749,74 @@ inline QualType
TreeTransform<Derived>::TransformTemplateSpecializationType(
TypeLocBuilder &TLB,
TemplateSpecializationTypeLoc TL) {
- // TODO: figure out how make this work with an ObjectType.
- QualType Result
- = TransformTemplateSpecializationType(TL.getTypePtr(), QualType());
- if (Result.isNull())
- return QualType();
+ return TransformTemplateSpecializationType(TLB, TL, QualType());
+}
- TemplateSpecializationTypeLoc NewTL
- = TLB.push<TemplateSpecializationTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
+ const TemplateSpecializationType *TST,
+ QualType ObjectType) {
+ // FIXME: this entire method is a temporary workaround; callers
+ // should be rewritten to provide real type locs.
- return Result;
+ // Fake up a TemplateSpecializationTypeLoc.
+ TypeLocBuilder TLB;
+ TemplateSpecializationTypeLoc TL
+ = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
+
+ TL.setTemplateNameLoc(getDerived().getBaseLocation());
+ TL.setLAngleLoc(SourceLocation());
+ TL.setRAngleLoc(SourceLocation());
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+ const TemplateArgument &TA = TST->getArg(i);
+ TemplateArgumentLoc TAL;
+ getDerived().InventTemplateArgumentLoc(TA, TAL);
+ TL.setArgLocInfo(i, TAL.getLocInfo());
+ }
+
+ TypeLocBuilder IgnoredTLB;
+ return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
- const TemplateSpecializationType *T,
- QualType ObjectType) {
+ TypeLocBuilder &TLB,
+ TemplateSpecializationTypeLoc TL,
+ QualType ObjectType) {
+ const TemplateSpecializationType *T = TL.getTypePtr();
+
TemplateName Template
= getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
if (Template.isNull())
return QualType();
- llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
- NewTemplateArgs.reserve(T->getNumArgs());
- for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
- Arg != ArgEnd; ++Arg) {
- TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
- if (NewArg.isNull())
+ llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
+ for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
+ if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
+ NewTemplateArgs[i]))
return QualType();
- NewTemplateArgs.push_back(NewArg);
- }
+ // FIXME: maybe don't rebuild if all the template arguments are the same.
+
+ QualType Result =
+ getDerived().RebuildTemplateSpecializationType(Template,
+ TL.getTemplateNameLoc(),
+ TL.getLAngleLoc(),
+ NewTemplateArgs.data(),
+ NewTemplateArgs.size(),
+ TL.getRAngleLoc());
- // FIXME: early abort if all of the template arguments and such are the
- // same.
+ if (!Result.isNull()) {
+ TemplateSpecializationTypeLoc NewTL
+ = TLB.push<TemplateSpecializationTypeLoc>(Result);
+ NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
+ NewTL.setLAngleLoc(TL.getLAngleLoc());
+ NewTL.setRAngleLoc(TL.getRAngleLoc());
+ for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
+ NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
+ }
- // FIXME: We're missing the locations of the template name, '<', and '>'.
- return getDerived().RebuildTemplateSpecializationType(Template,
- NewTemplateArgs.data(),
- NewTemplateArgs.size());
+ return Result;
}
template<typename Derived>
@@ -2754,9 +2853,12 @@ template<typename Derived>
QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
TypenameTypeLoc TL) {
TypenameType *T = TL.getTypePtr();
+
+ /* FIXME: preserve source information better than this */
+ SourceRange SR(TL.getNameLoc());
+
NestedNameSpecifier *NNS
- = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
- SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
+ = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
if (!NNS)
return QualType();
@@ -2775,7 +2877,7 @@ QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
} else {
- Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier());
+ Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
}
if (Result.isNull())
return QualType();
@@ -3287,14 +3389,11 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
// FIXME: We're losing the explicit template arguments in this transformation.
- llvm::SmallVector<TemplateArgument, 4> TransArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
- TemplateArgument TransArg
- = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
- if (TransArg.isNull())
+ if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+ TransArgs[I]))
return SemaRef.ExprError();
-
- TransArgs.push_back(TransArg);
}
// FIXME: Pass the qualifier/qualifier range along.
@@ -4367,14 +4466,11 @@ TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
return SemaRef.ExprError();
}
- llvm::SmallVector<TemplateArgument, 4> TransArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
- TemplateArgument TransArg
- = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
- if (TransArg.isNull())
+ if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+ TransArgs[I]))
return SemaRef.ExprError();
-
- TransArgs.push_back(TransArg);
}
// FIXME: Would like to avoid rebuilding if nothing changed, but we can't
@@ -4627,14 +4723,11 @@ TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
if (Template.isNull())
return SemaRef.ExprError();
- llvm::SmallVector<TemplateArgument, 4> TransArgs;
+ llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
- TemplateArgument TransArg
- = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
- if (TransArg.isNull())
+ if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+ TransArgs[I]))
return SemaRef.ExprError();
-
- TransArgs.push_back(TransArg);
}
return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
@@ -4980,13 +5073,14 @@ QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
template<typename Derived>
QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
- TemplateName Template,
- const TemplateArgument *Args,
- unsigned NumArgs) {
- // FIXME: Missing source locations for the template name, <, >.
- return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
- SourceLocation(), Args, NumArgs,
- SourceLocation());
+ TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgumentLoc *Args,
+ unsigned NumArgs,
+ SourceLocation RAngleLoc) {
+ return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
+ Args, NumArgs, RAngleLoc);
}
template<typename Derived>