diff options
author | John McCall <rjmccall@apple.com> | 2009-10-29 08:12:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-10-29 08:12:44 +0000 |
commit | 833ca991c1bfc967f0995974ca86f66ba1f666b5 (patch) | |
tree | 54ce834e6510eae21e5cff09573c986e6ee7ca12 | |
parent | 275c10a8a4a43219f67d8d2c912ec6294d9d9af2 (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
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> |