Encapsulate "an array of TemplateArgumentLocs and two angle bracket locations" into

a new class.  Use it pervasively throughout Sema.

My fingers hurt.

llvm-svn: 89638
This commit is contained in:
John McCall 2009-11-23 01:53:49 +00:00
parent 1251697156
commit 6b51f28e82
24 changed files with 414 additions and 538 deletions

View File

@ -532,8 +532,7 @@ public:
QualType Canon = QualType()); QualType Canon = QualType());
QualType getTemplateSpecializationType(TemplateName T, QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgumentLoc *Args, const TemplateArgumentListInfo &Args,
unsigned NumArgs,
QualType Canon = QualType()); QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS, QualType getQualifiedNameType(NestedNameSpecifier *NNS,

View File

@ -54,6 +54,30 @@ public:
TypeLoc getTypeLoc() const; TypeLoc getTypeLoc() const;
}; };
/// UnresolvedSet - A set of unresolved declarations. This is needed
/// in a lot of places, but isn't really worth breaking into its own
/// header right now.
class UnresolvedSet {
typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
DeclsTy Decls;
public:
void addDecl(NamedDecl *D) {
Decls.push_back(D);
}
bool replace(const NamedDecl* Old, NamedDecl *New) {
for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
if (*I == Old)
return (*I = New, true);
return false;
}
typedef DeclsTy::const_iterator iterator;
iterator begin() const { return Decls.begin(); }
iterator end() const { return Decls.end(); }
};
/// TranslationUnitDecl - The top declaration context. /// TranslationUnitDecl - The top declaration context.
class TranslationUnitDecl : public Decl, public DeclContext { class TranslationUnitDecl : public Decl, public DeclContext {
ASTContext &Ctx; ASTContext &Ctx;

View File

@ -88,28 +88,6 @@ namespace llvm {
namespace clang { namespace clang {
/// UnresolvedSet - A set of unresolved declarations.
class UnresolvedSet {
typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
DeclsTy Decls;
public:
void addDecl(NamedDecl *D) {
Decls.push_back(D);
}
bool replace(const NamedDecl* Old, NamedDecl *New) {
for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I)
if (*I == Old)
return (*I = New, true);
return false;
}
typedef DeclsTy::const_iterator iterator;
iterator begin() const { return Decls.begin(); }
iterator end() const { return Decls.end(); }
};
/// OverloadedFunctionDecl - An instance of this class represents a /// OverloadedFunctionDecl - An instance of this class represents a
/// set of overloaded functions. All of the functions have the same /// set of overloaded functions. All of the functions have the same
/// name and occur within the same scope. /// name and occur within the same scope.

View File

@ -955,8 +955,7 @@ public:
TemplateParameterList *Params, TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate, ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder, TemplateArgumentListBuilder &Builder,
TemplateArgumentLoc *ArgInfos, const TemplateArgumentListInfo &ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl); ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters /// Get the list of template parameters

View File

@ -35,6 +35,7 @@ namespace clang {
class CXXOperatorCallExpr; class CXXOperatorCallExpr;
class CXXMemberCallExpr; class CXXMemberCallExpr;
class TemplateArgumentLoc; class TemplateArgumentLoc;
class TemplateArgumentListInfo;
/// Expr - This represents one expression. Note that Expr's are subclasses of /// 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 /// Stmt. This allows an expression to be transparently used any place a Stmt
@ -366,6 +367,10 @@ struct ExplicitTemplateArgumentList {
const TemplateArgumentLoc *getTemplateArgs() const { const TemplateArgumentLoc *getTemplateArgs() const {
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
} }
void initializeFrom(const TemplateArgumentListInfo &List);
void copyInto(TemplateArgumentListInfo &List) const;
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
}; };
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function, /// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
@ -423,11 +428,7 @@ class DeclRefExpr : public Expr {
DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc, NamedDecl *D, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList, const TemplateArgumentListInfo *TemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD); QualType T, bool TD, bool VD);
protected: protected:
@ -465,11 +466,7 @@ public:
SourceRange QualifierRange, SourceRange QualifierRange,
NamedDecl *D, NamedDecl *D,
SourceLocation NameLoc, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList, const TemplateArgumentListInfo *TemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD); QualType T, bool TD, bool VD);
NamedDecl *getDecl() { return DecoratedD.getPointer(); } NamedDecl *getDecl() { return DecoratedD.getPointer(); }
@ -508,6 +505,13 @@ public:
bool hasExplicitTemplateArgumentList() const { bool hasExplicitTemplateArgumentList() const {
return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag; return DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag;
} }
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgumentList())
getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the /// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any. /// member name ('<'), if any.
@ -1313,9 +1317,7 @@ class MemberExpr : public Expr {
MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l, SourceRange qualrange, NamedDecl *memberdecl, SourceLocation l,
bool has_explicit, SourceLocation langle, const TemplateArgumentListInfo *targs, QualType ty);
const TemplateArgumentLoc *targs, unsigned numtargs,
SourceLocation rangle, QualType ty);
public: public:
MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l, MemberExpr(Expr *base, bool isarrow, NamedDecl *memberdecl, SourceLocation l,
@ -1334,11 +1336,7 @@ public:
NestedNameSpecifier *qual, SourceRange qualrange, NestedNameSpecifier *qual, SourceRange qualrange,
NamedDecl *memberdecl, NamedDecl *memberdecl,
SourceLocation l, SourceLocation l,
bool has_explicit, const TemplateArgumentListInfo *targs,
SourceLocation langle,
const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty); QualType ty);
void setBase(Expr *E) { Base = E; } void setBase(Expr *E) { Base = E; }
@ -1378,10 +1376,17 @@ public:
/// \brief Determines whether this member expression actually had a C++ /// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>. /// template argument list explicitly specified, e.g., x.f<int>.
bool hasExplicitTemplateArgumentList() { bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList; return HasExplicitTemplateArgumentList;
} }
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgumentList())
getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the /// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any. /// member name ('<'), if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {

View File

@ -17,7 +17,7 @@
#include "clang/Basic/TypeTraits.h" #include "clang/Basic/TypeTraits.h"
#include "clang/AST/Expr.h" #include "clang/AST/Expr.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h" #include "clang/AST/TemplateBase.h"
namespace clang { namespace clang {
@ -25,6 +25,7 @@ namespace clang {
class CXXDestructorDecl; class CXXDestructorDecl;
class CXXMethodDecl; class CXXMethodDecl;
class CXXTemporary; class CXXTemporary;
class TemplateArgumentListInfo;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// C++ Expressions. // C++ Expressions.
@ -1215,10 +1216,7 @@ class TemplateIdRefExpr : public Expr {
TemplateIdRefExpr(QualType T, TemplateIdRefExpr(QualType T,
NestedNameSpecifier *Qualifier, SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc, TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs);
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
virtual void DoDestroy(ASTContext &Context); virtual void DoDestroy(ASTContext &Context);
@ -1227,8 +1225,7 @@ public:
Create(ASTContext &Context, QualType T, Create(ASTContext &Context, QualType T,
NestedNameSpecifier *Qualifier, SourceRange QualifierRange, NestedNameSpecifier *Qualifier, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc, TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentLoc *TemplateArgs, const TemplateArgumentListInfo &TemplateArgs);
unsigned NumTemplateArgs, SourceLocation RAngleLoc);
/// \brief Retrieve the nested name specifier used to qualify the name of /// \brief Retrieve the nested name specifier used to qualify the name of
/// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL /// this template-id, e.g., the "std::sort" in @c std::sort<int>, or NULL
@ -1261,6 +1258,15 @@ public:
/// template-id. /// template-id.
unsigned getNumTemplateArgs() const { return NumTemplateArgs; } unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
/// \brief Copies the template-argument information into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &Info) const {
Info.setLAngleLoc(LAngleLoc);
Info.setRAngleLoc(RAngleLoc);
for (unsigned i = 0; i < NumTemplateArgs; ++i)
Info.addArgument(getTemplateArgs()[i]);
}
/// \brief Retrieve the location of the right angle bracket following the /// \brief Retrieve the location of the right angle bracket following the
/// template arguments ('>'). /// template arguments ('>').
SourceLocation getRAngleLoc() const { return RAngleLoc; } SourceLocation getRAngleLoc() const { return RAngleLoc; }
@ -1496,11 +1502,7 @@ class CXXDependentScopeMemberExpr : public Expr {
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member, DeclarationName Member,
SourceLocation MemberLoc, SourceLocation MemberLoc,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *TemplateArgs);
SourceLocation LAngleLoc,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
public: public:
CXXDependentScopeMemberExpr(ASTContext &C, CXXDependentScopeMemberExpr(ASTContext &C,
@ -1527,11 +1529,7 @@ public:
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member, DeclarationName Member,
SourceLocation MemberLoc, SourceLocation MemberLoc,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *TemplateArgs);
SourceLocation LAngleLoc,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
/// \brief Retrieve the base object of this member expressions, /// \brief Retrieve the base object of this member expressions,
/// e.g., the \c x in \c x.m. /// e.g., the \c x in \c x.m.
@ -1582,10 +1580,17 @@ public:
/// \brief Determines whether this member expression actually had a C++ /// \brief Determines whether this member expression actually had a C++
/// template argument list explicitly specified, e.g., x.f<int>. /// template argument list explicitly specified, e.g., x.f<int>.
bool hasExplicitTemplateArgumentList() { bool hasExplicitTemplateArgumentList() const {
return HasExplicitTemplateArgumentList; return HasExplicitTemplateArgumentList;
} }
/// \brief Copies the template arguments (if present) into the given
/// structure.
void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
if (hasExplicitTemplateArgumentList())
getExplicitTemplateArgumentList()->copyInto(List);
}
/// \brief Retrieve the location of the left angle bracket following the /// \brief Retrieve the location of the left angle bracket following the
/// member name ('<'), if any. /// member name ('<'), if any.
SourceLocation getLAngleLoc() const { SourceLocation getLAngleLoc() const {

View File

@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "clang/AST/Type.h" #include "clang/AST/Type.h"
#include "clang/AST/TemplateName.h" #include "clang/AST/TemplateName.h"
@ -437,6 +438,41 @@ public:
} }
}; };
/// A convenient class for passing around template argument
/// information. Designed to be passed by reference.
class TemplateArgumentListInfo {
llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
public:
TemplateArgumentListInfo() {}
TemplateArgumentListInfo(SourceLocation LAngleLoc,
SourceLocation RAngleLoc)
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
unsigned size() const { return Arguments.size(); }
const TemplateArgumentLoc *getArgumentArray() const {
return Arguments.data();
}
const TemplateArgumentLoc &operator[](unsigned I) const {
return Arguments[I];
}
void addArgument(const TemplateArgumentLoc &Loc) {
Arguments.push_back(Loc);
}
};
} }
#endif #endif

View File

@ -82,6 +82,7 @@ namespace clang {
class StmtIteratorBase; class StmtIteratorBase;
class TemplateArgument; class TemplateArgument;
class TemplateArgumentLoc; class TemplateArgumentLoc;
class TemplateArgumentListInfo;
class QualifiedNameType; class QualifiedNameType;
struct PrintingPolicy; struct PrintingPolicy;
@ -2280,6 +2281,8 @@ public:
static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args,
unsigned NumArgs); unsigned NumArgs);
static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &);
/// \brief Print a template argument list, including the '<' and '>' /// \brief Print a template argument list, including the '<' and '>'
/// enclosing the template arguments. /// enclosing the template arguments.
static std::string PrintTemplateArgumentList(const TemplateArgument *Args, static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
@ -2290,6 +2293,9 @@ public:
unsigned NumArgs, unsigned NumArgs,
const PrintingPolicy &Policy); const PrintingPolicy &Policy);
static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
const PrintingPolicy &Policy);
typedef const TemplateArgument * iterator; typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); } iterator begin() const { return getArgs(); }

View File

@ -1832,9 +1832,10 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
QualType QualType
ASTContext::getTemplateSpecializationType(TemplateName Template, ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgumentLoc *Args, const TemplateArgumentListInfo &Args,
unsigned NumArgs,
QualType Canon) { QualType Canon) {
unsigned NumArgs = Args.size();
llvm::SmallVector<TemplateArgument, 4> ArgVec; llvm::SmallVector<TemplateArgument, 4> ArgVec;
ArgVec.reserve(NumArgs); ArgVec.reserve(NumArgs);
for (unsigned i = 0; i != NumArgs; ++i) for (unsigned i = 0; i != NumArgs; ++i)

View File

@ -453,8 +453,9 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
TemplateParameterList *Params, TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate, ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder, TemplateArgumentListBuilder &Builder,
TemplateArgumentLoc *ArgInfos, unsigned N, const TemplateArgumentListInfo &ArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl) { ClassTemplatePartialSpecializationDecl *PrevDecl) {
unsigned N = ArgInfos.size();
TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
for (unsigned I = 0; I != N; ++I) for (unsigned I = 0; I != N; ++I)
ClonedArgs[I] = ArgInfos[I]; ClonedArgs[I] = ArgInfos[I];

View File

@ -31,20 +31,40 @@ using namespace clang;
// Primary Expressions. // Primary Expressions.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void ExplicitTemplateArgumentList::initializeFrom(
const TemplateArgumentListInfo &Info) {
LAngleLoc = Info.getLAngleLoc();
RAngleLoc = Info.getRAngleLoc();
NumTemplateArgs = Info.size();
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
for (unsigned i = 0; i != NumTemplateArgs; ++i)
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
}
void ExplicitTemplateArgumentList::copyInto(
TemplateArgumentListInfo &Info) const {
Info.setLAngleLoc(LAngleLoc);
Info.setRAngleLoc(RAngleLoc);
for (unsigned I = 0; I != NumTemplateArgs; ++I)
Info.addArgument(getTemplateArgs()[I]);
}
std::size_t ExplicitTemplateArgumentList::sizeFor(
const TemplateArgumentListInfo &Info) {
return sizeof(ExplicitTemplateArgumentList) +
sizeof(TemplateArgumentLoc) * Info.size();
}
DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, SourceRange QualifierRange,
NamedDecl *D, SourceLocation NameLoc, NamedDecl *D, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList, const TemplateArgumentListInfo *TemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD) QualType T, bool TD, bool VD)
: Expr(DeclRefExprClass, T, TD, VD), : Expr(DeclRefExprClass, T, TD, VD),
DecoratedD(D, DecoratedD(D,
(Qualifier? HasQualifierFlag : 0) | (Qualifier? HasQualifierFlag : 0) |
(HasExplicitTemplateArgumentList? (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)),
HasExplicitTemplateArgumentListFlag : 0)),
Loc(NameLoc) { Loc(NameLoc) {
assert(!isa<OverloadedFunctionDecl>(D)); assert(!isa<OverloadedFunctionDecl>(D));
if (Qualifier) { if (Qualifier) {
@ -53,17 +73,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier,
NQ->Range = QualifierRange; NQ->Range = QualifierRange;
} }
if (HasExplicitTemplateArgumentList) { if (TemplateArgs)
ExplicitTemplateArgumentList *ETemplateArgs getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
= getExplicitTemplateArgumentList();
ETemplateArgs->LAngleLoc = LAngleLoc;
ETemplateArgs->RAngleLoc = RAngleLoc;
ETemplateArgs->NumTemplateArgs = NumExplicitTemplateArgs;
TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < NumExplicitTemplateArgs; ++I)
new (TemplateArgs + I) TemplateArgumentLoc(ExplicitTemplateArgs[I]);
}
} }
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@ -73,8 +84,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
SourceLocation NameLoc, SourceLocation NameLoc,
QualType T, bool TD, bool VD) { QualType T, bool TD, bool VD) {
return Create(Context, Qualifier, QualifierRange, D, NameLoc, return Create(Context, Qualifier, QualifierRange, D, NameLoc,
false, SourceLocation(), 0, 0, SourceLocation(), /*TemplateArgs*/ 0, T, TD, VD);
T, TD, VD);
} }
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
@ -82,28 +92,18 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
SourceRange QualifierRange, SourceRange QualifierRange,
NamedDecl *D, NamedDecl *D,
SourceLocation NameLoc, SourceLocation NameLoc,
bool HasExplicitTemplateArgumentList, const TemplateArgumentListInfo *TemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
QualType T, bool TD, bool VD) { QualType T, bool TD, bool VD) {
std::size_t Size = sizeof(DeclRefExpr); std::size_t Size = sizeof(DeclRefExpr);
if (Qualifier != 0) if (Qualifier != 0)
Size += sizeof(NameQualifier); Size += sizeof(NameQualifier);
if (HasExplicitTemplateArgumentList) if (TemplateArgs)
Size += sizeof(ExplicitTemplateArgumentList) + Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
sizeof(TemplateArgumentLoc) * NumExplicitTemplateArgs;
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>()); void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc, return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameLoc,
HasExplicitTemplateArgumentList, TemplateArgs, T, TD, VD);
LAngleLoc,
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
RAngleLoc,
T, TD, VD);
} }
SourceRange DeclRefExpr::getSourceRange() const { SourceRange DeclRefExpr::getSourceRange() const {
@ -428,15 +428,13 @@ QualType CallExpr::getCallReturnType() const {
MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual, MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
SourceRange qualrange, NamedDecl *memberdecl, SourceRange qualrange, NamedDecl *memberdecl,
SourceLocation l, bool has_explicit, SourceLocation l, const TemplateArgumentListInfo *targs,
SourceLocation langle, QualType ty)
const TemplateArgumentLoc *targs, unsigned numtargs,
SourceLocation rangle, QualType ty)
: Expr(MemberExprClass, ty, : Expr(MemberExprClass, ty,
base->isTypeDependent() || (qual && qual->isDependent()), base->isTypeDependent() || (qual && qual->isDependent()),
base->isValueDependent() || (qual && qual->isDependent())), base->isValueDependent() || (qual && qual->isDependent())),
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow), Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
HasQualifier(qual != 0), HasExplicitTemplateArgumentList(has_explicit) { HasQualifier(qual != 0), HasExplicitTemplateArgumentList(targs) {
// Initialize the qualifier, if any. // Initialize the qualifier, if any.
if (HasQualifier) { if (HasQualifier) {
NameQualifier *NQ = getMemberQualifier(); NameQualifier *NQ = getMemberQualifier();
@ -445,17 +443,8 @@ MemberExpr::MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
} }
// Initialize the explicit template argument list, if any. // Initialize the explicit template argument list, if any.
if (HasExplicitTemplateArgumentList) { if (targs)
ExplicitTemplateArgumentList *ETemplateArgs getExplicitTemplateArgumentList()->initializeFrom(*targs);
= getExplicitTemplateArgumentList();
ETemplateArgs->LAngleLoc = langle;
ETemplateArgs->RAngleLoc = rangle;
ETemplateArgs->NumTemplateArgs = numtargs;
TemplateArgumentLoc *TemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < numtargs; ++I)
new (TemplateArgs + I) TemplateArgumentLoc(targs[I]);
}
} }
MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
@ -463,24 +452,18 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow,
SourceRange qualrange, SourceRange qualrange,
NamedDecl *memberdecl, NamedDecl *memberdecl,
SourceLocation l, SourceLocation l,
bool has_explicit, const TemplateArgumentListInfo *targs,
SourceLocation langle,
const TemplateArgumentLoc *targs,
unsigned numtargs,
SourceLocation rangle,
QualType ty) { QualType ty) {
std::size_t Size = sizeof(MemberExpr); std::size_t Size = sizeof(MemberExpr);
if (qual != 0) if (qual != 0)
Size += sizeof(NameQualifier); Size += sizeof(NameQualifier);
if (has_explicit) if (targs)
Size += sizeof(ExplicitTemplateArgumentList) + Size += ExplicitTemplateArgumentList::sizeFor(*targs);
sizeof(TemplateArgumentLoc) * numtargs;
void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>()); void *Mem = C.Allocate(Size, llvm::alignof<MemberExpr>());
return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l, return new (Mem) MemberExpr(base, isarrow, qual, qualrange, memberdecl, l,
has_explicit, langle, targs, numtargs, rangle, targs, ty);
ty);
} }
const char *CastExpr::getCastKindName() const { const char *CastExpr::getCastKindName() const {

View File

@ -150,20 +150,19 @@ TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
SourceRange QualifierRange, SourceRange QualifierRange,
TemplateName Template, TemplateName Template,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs)
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(TemplateIdRefExprClass, T, : Expr(TemplateIdRefExprClass, T,
(Template.isDependent() || (Template.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments( TemplateSpecializationType
TemplateArgs, NumTemplateArgs)), ::anyDependentTemplateArguments(TemplateArgs)),
(Template.isDependent() || (Template.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments( TemplateSpecializationType
TemplateArgs, NumTemplateArgs))), ::anyDependentTemplateArguments(TemplateArgs))),
Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template), Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc), TemplateNameLoc(TemplateNameLoc),
RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs) { LAngleLoc(TemplateArgs.getLAngleLoc()),
RAngleLoc(TemplateArgs.getRAngleLoc()),
NumTemplateArgs(TemplateArgs.size()) {
TemplateArgumentLoc *StoredTemplateArgs TemplateArgumentLoc *StoredTemplateArgs
= reinterpret_cast<TemplateArgumentLoc *> (this+1); = reinterpret_cast<TemplateArgumentLoc *> (this+1);
for (unsigned I = 0; I != NumTemplateArgs; ++I) for (unsigned I = 0; I != NumTemplateArgs; ++I)
@ -175,14 +174,11 @@ TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
NestedNameSpecifier *Qualifier, NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, SourceRange QualifierRange,
TemplateName Template, SourceLocation TemplateNameLoc, TemplateName Template, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) + void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
sizeof(TemplateArgumentLoc) * NumTemplateArgs); sizeof(TemplateArgumentLoc) * TemplateArgs.size());
return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template, return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
TemplateNameLoc, LAngleLoc, TemplateArgs, TemplateNameLoc, TemplateArgs);
NumTemplateArgs, RAngleLoc);
} }
void TemplateIdRefExpr::DoDestroy(ASTContext &Context) { void TemplateIdRefExpr::DoDestroy(ASTContext &Context) {
@ -534,29 +530,16 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member, DeclarationName Member,
SourceLocation MemberLoc, SourceLocation MemberLoc,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *TemplateArgs)
SourceLocation LAngleLoc,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc)
: Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
Base(Base), IsArrow(IsArrow), Base(Base), IsArrow(IsArrow),
HasExplicitTemplateArgumentList(HasExplicitTemplateArgs), HasExplicitTemplateArgumentList(TemplateArgs),
OperatorLoc(OperatorLoc), OperatorLoc(OperatorLoc),
Qualifier(Qualifier), QualifierRange(QualifierRange), Qualifier(Qualifier), QualifierRange(QualifierRange),
FirstQualifierFoundInScope(FirstQualifierFoundInScope), FirstQualifierFoundInScope(FirstQualifierFoundInScope),
Member(Member), MemberLoc(MemberLoc) { Member(Member), MemberLoc(MemberLoc) {
if (HasExplicitTemplateArgumentList) { if (TemplateArgs)
ExplicitTemplateArgumentList *ETemplateArgs getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
= getExplicitTemplateArgumentList();
ETemplateArgs->LAngleLoc = LAngleLoc;
ETemplateArgs->RAngleLoc = RAngleLoc;
ETemplateArgs->NumTemplateArgs = NumTemplateArgs;
TemplateArgumentLoc *SavedTemplateArgs = ETemplateArgs->getTemplateArgs();
for (unsigned I = 0; I < NumTemplateArgs; ++I)
new (SavedTemplateArgs + I) TemplateArgumentLoc(TemplateArgs[I]);
}
} }
CXXDependentScopeMemberExpr * CXXDependentScopeMemberExpr *
@ -568,31 +551,24 @@ CXXDependentScopeMemberExpr::Create(ASTContext &C,
NamedDecl *FirstQualifierFoundInScope, NamedDecl *FirstQualifierFoundInScope,
DeclarationName Member, DeclarationName Member,
SourceLocation MemberLoc, SourceLocation MemberLoc,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *TemplateArgs) {
SourceLocation LAngleLoc, if (!TemplateArgs)
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
if (!HasExplicitTemplateArgs)
return new (C) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc, return new (C) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Qualifier, QualifierRange, Qualifier, QualifierRange,
FirstQualifierFoundInScope, FirstQualifierFoundInScope,
Member, MemberLoc); Member, MemberLoc);
void *Mem = C.Allocate(sizeof(CXXDependentScopeMemberExpr) + std::size_t size = sizeof(CXXDependentScopeMemberExpr);
sizeof(ExplicitTemplateArgumentList) + if (TemplateArgs)
sizeof(TemplateArgumentLoc) * NumTemplateArgs, size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
llvm::alignof<CXXDependentScopeMemberExpr>());
void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
return new (Mem) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc, return new (Mem) CXXDependentScopeMemberExpr(C, Base, IsArrow, OperatorLoc,
Qualifier, QualifierRange, Qualifier, QualifierRange,
FirstQualifierFoundInScope, FirstQualifierFoundInScope,
Member, Member,
MemberLoc, MemberLoc,
HasExplicitTemplateArgs, TemplateArgs);
LAngleLoc,
TemplateArgs,
NumTemplateArgs,
RAngleLoc);
} }
Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() { Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {

View File

@ -865,6 +865,11 @@ static bool isDependent(const TemplateArgument &Arg) {
return false; return false;
} }
bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) {
return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size());
}
bool TemplateSpecializationType:: bool TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) {
for (unsigned i = 0; i != N; ++i) for (unsigned i = 0; i != N; ++i)

View File

@ -601,6 +601,14 @@ static void PrintTemplateArgument(std::string &Buffer,
} }
} }
std::string TemplateSpecializationType::
PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
const PrintingPolicy &Policy) {
return PrintTemplateArgumentList(Args.getArgumentArray(),
Args.size(),
Policy);
}
std::string std::string
TemplateSpecializationType::PrintTemplateArgumentList( TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args, const TemplateArgument *Args,

View File

@ -894,17 +894,13 @@ public:
bool SuppressUserConversions = false, bool SuppressUserConversions = false,
bool ForceRValue = false); bool ForceRValue = false);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr *Object, Expr **Args, unsigned NumArgs, Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false, bool SuppressUserConversions = false,
bool ForceRValue = false); bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false, bool SuppressUserConversions = false,
@ -940,9 +936,7 @@ public:
OverloadCandidateSet& CandidateSet); OverloadCandidateSet& CandidateSet);
void AddArgumentDependentLookupCandidates(DeclarationName Name, void AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool PartialOverloading = false); bool PartialOverloading = false);
bool isBetterOverloadCandidate(const OverloadCandidate& Cand1, bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
@ -962,9 +956,7 @@ public:
void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees, void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees,
DeclarationName &UnqualifiedName, DeclarationName &UnqualifiedName,
bool ArgumentDependentLookup, bool ArgumentDependentLookup,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet, OverloadCandidateSet &CandidateSet,
bool PartialOverloading = false); bool PartialOverloading = false);
@ -972,9 +964,7 @@ public:
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, FunctionDecl *ResolveOverloadedCallFn(Expr *Fn,
llvm::SmallVectorImpl<NamedDecl*> &Fns, llvm::SmallVectorImpl<NamedDecl*> &Fns,
DeclarationName UnqualifiedName, DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc, SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs, SourceLocation *CommaLocs,
@ -1496,8 +1486,7 @@ public:
// BuildMemberReferenceExpr to support explicitly-specified template // BuildMemberReferenceExpr to support explicitly-specified template
// arguments. // arguments.
return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc, return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
MemberName, false, SourceLocation(), 0, 0, MemberName, 0, ImplDecl, SS,
SourceLocation(), ImplDecl, SS,
FirstQualifierInScope); FirstQualifierInScope);
} }
@ -1506,11 +1495,7 @@ public:
tok::TokenKind OpKind, tok::TokenKind OpKind,
SourceLocation MemberLoc, SourceLocation MemberLoc,
DeclarationName MemberName, DeclarationName MemberName,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
DeclPtrTy ImplDecl, DeclPtrTy ImplDecl,
const CXXScopeSpec *SS, const CXXScopeSpec *SS,
NamedDecl *FirstQualifierInScope = 0); NamedDecl *FirstQualifierInScope = 0);
@ -1537,9 +1522,8 @@ public:
SourceRange &QualifierRange, SourceRange &QualifierRange,
bool &ArgumentDependentLookup, bool &ArgumentDependentLookup,
bool &Overloaded, bool &Overloaded,
bool &HasExplicitTemplateArguments, bool &HasExplicitTemplateArgs,
const TemplateArgumentLoc *&ExplicitTemplateArgs, TemplateArgumentListInfo &ExplicitTemplateArgs);
unsigned &NumExplicitTemplateArgs);
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
/// This provides the location of the left/right parens and a list of comma /// This provides the location of the left/right parens and a list of comma
@ -2273,15 +2257,12 @@ public:
TemplateParameterList *TemplateParams, TemplateParameterList *TemplateParams,
AccessSpecifier AS); AccessSpecifier AS);
void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn, void translateTemplateArguments(const ASTTemplateArgsPtr &In,
llvm::SmallVectorImpl<TemplateArgumentLoc> &TempArgs); TemplateArgumentListInfo &Out);
QualType CheckTemplateIdType(TemplateName Template, QualType CheckTemplateIdType(TemplateName Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs);
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
virtual TypeResult virtual TypeResult
ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc, ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
@ -2298,10 +2279,7 @@ public:
SourceRange QualifierRange, SourceRange QualifierRange,
TemplateName Template, TemplateName Template,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs);
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc);
OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS, OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
TemplateTy Template, TemplateTy Template,
@ -2350,11 +2328,7 @@ public:
bool &SuppressNew); bool &SuppressNew);
bool CheckFunctionTemplateSpecialization(FunctionDecl *FD, bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
LookupResult &Previous); LookupResult &Previous);
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous); bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
@ -2397,10 +2371,7 @@ public:
bool CheckTemplateArgumentList(TemplateDecl *Template, bool CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
bool PartialTemplateArgs, bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted); TemplateArgumentListBuilder &Converted);
@ -2626,8 +2597,7 @@ public:
TemplateDeductionResult TemplateDeductionResult
SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate, SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
const TemplateArgumentLoc *ExplicitTemplateArgs, const TemplateArgumentListInfo &ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
llvm::SmallVectorImpl<TemplateArgument> &Deduced, llvm::SmallVectorImpl<TemplateArgument> &Deduced,
llvm::SmallVectorImpl<QualType> &ParamTypes, llvm::SmallVectorImpl<QualType> &ParamTypes,
QualType *FunctionType, QualType *FunctionType,
@ -2641,18 +2611,14 @@ public:
TemplateDeductionResult TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization, FunctionDecl *&Specialization,
TemplateDeductionInfo &Info); TemplateDeductionInfo &Info);
TemplateDeductionResult TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
QualType ArgFunctionType, QualType ArgFunctionType,
FunctionDecl *&Specialization, FunctionDecl *&Specialization,
TemplateDeductionInfo &Info); TemplateDeductionInfo &Info);

View File

@ -1474,13 +1474,11 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
bool ArgumentDependentLookup; bool ArgumentDependentLookup;
bool Overloaded; bool Overloaded;
bool HasExplicitTemplateArgs; bool HasExplicitTemplateArgs;
const TemplateArgumentLoc *ExplicitTemplateArgs; TemplateArgumentListInfo ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs;
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange, DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
ArgumentDependentLookup, Overloaded, ArgumentDependentLookup, Overloaded,
HasExplicitTemplateArgs, ExplicitTemplateArgs, HasExplicitTemplateArgs, ExplicitTemplateArgs);
NumExplicitTemplateArgs);
// FIXME: What if we're calling something that isn't a function declaration? // FIXME: What if we're calling something that isn't a function declaration?
@ -1490,8 +1488,8 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
// Build an overload candidate set based on the functions we find. // Build an overload candidate set based on the functions we find.
OverloadCandidateSet CandidateSet; OverloadCandidateSet CandidateSet;
AddOverloadedCallCandidates(Fns, UnqualifiedName, AddOverloadedCallCandidates(Fns, UnqualifiedName,
ArgumentDependentLookup, HasExplicitTemplateArgs, ArgumentDependentLookup,
ExplicitTemplateArgs, NumExplicitTemplateArgs, (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
Args, NumArgs, Args, NumArgs,
CandidateSet, CandidateSet,
/*PartialOverloading=*/true); /*PartialOverloading=*/true);

View File

@ -2974,10 +2974,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// If the declarator is a template-id, translate the parser's template // If the declarator is a template-id, translate the parser's template
// argument list into our AST format. // argument list into our AST format.
bool HasExplicitTemplateArgs = false; bool HasExplicitTemplateArgs = false;
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs;
SourceLocation LAngleLoc, RAngleLoc;
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getName().TemplateId; TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
ASTTemplateArgsPtr TemplateArgsPtr(*this, ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(), TemplateId->getTemplateArgs(),
TemplateId->NumArgs); TemplateId->NumArgs);
@ -2986,8 +2987,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TemplateArgsPtr.release(); TemplateArgsPtr.release();
HasExplicitTemplateArgs = true; HasExplicitTemplateArgs = true;
LAngleLoc = TemplateId->LAngleLoc;
RAngleLoc = TemplateId->RAngleLoc;
if (FunctionTemplate) { if (FunctionTemplate) {
// FIXME: Diagnose function template with explicit template // FIXME: Diagnose function template with explicit template
@ -3009,9 +3008,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
} }
if (isFunctionTemplateSpecialization) { if (isFunctionTemplateSpecialization) {
if (CheckFunctionTemplateSpecialization(NewFD, HasExplicitTemplateArgs, if (CheckFunctionTemplateSpecialization(NewFD,
LAngleLoc, TemplateArgs.data(), (HasExplicitTemplateArgs ? &TemplateArgs : 0),
TemplateArgs.size(), RAngleLoc,
Previous)) Previous))
NewFD->setInvalidDecl(); NewFD->setInvalidDecl();
} else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD) && } else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD) &&

View File

@ -3489,7 +3489,8 @@ static void AddConstructorInitializationCandidates(Sema &SemaRef,
Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) || Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) ||
(Kind == Sema::IK_Default && Constructor->isDefaultConstructor())) { (Kind == Sema::IK_Default && Constructor->isDefaultConstructor())) {
if (ConstructorTmpl) if (ConstructorTmpl)
SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl, false, 0, 0, SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl,
/*ExplicitArgs*/ 0,
Args, NumArgs, CandidateSet); Args, NumArgs, CandidateSet);
else else
SemaRef.AddOverloadCandidate(Constructor, Args, NumArgs, CandidateSet); SemaRef.AddOverloadCandidate(Constructor, Args, NumArgs, CandidateSet);

View File

@ -910,8 +910,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
(NestedNameSpecifier *)SS->getScopeRep(), (NestedNameSpecifier *)SS->getScopeRep(),
SS->getRange(), Member, Loc, SS->getRange(), Member, Loc,
// FIXME: Explicit template argument lists // FIXME: Explicit template argument lists
false, SourceLocation(), 0, 0, SourceLocation(), 0, Ty);
Ty);
return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty); return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
} }
@ -1853,11 +1852,7 @@ Action::OwningExprResult
Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc, tok::TokenKind OpKind, SourceLocation MemberLoc,
DeclarationName MemberName, DeclarationName MemberName,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS, DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS,
NamedDecl *FirstQualifierInScope) { NamedDecl *FirstQualifierInScope) {
if (SS && SS->isInvalid()) if (SS && SS->isInvalid())
@ -1990,11 +1985,7 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
FirstQualifierInScope, FirstQualifierInScope,
MemberName, MemberName,
MemberLoc, MemberLoc,
HasExplicitTemplateArgs, ExplicitTemplateArgs));
LAngleLoc,
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
RAngleLoc));
} }
else if (const PointerType *PT = BaseType->getAs<PointerType>()) else if (const PointerType *PT = BaseType->getAs<PointerType>())
BaseType = PT->getPointeeType(); BaseType = PT->getPointeeType();
@ -2032,11 +2023,7 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
FirstQualifierInScope, FirstQualifierInScope,
MemberName, MemberName,
MemberLoc, MemberLoc,
HasExplicitTemplateArgs, ExplicitTemplateArgs));
LAngleLoc,
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
RAngleLoc));
} }
} }
@ -2157,13 +2144,12 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
= dyn_cast<FunctionTemplateDecl>(MemberDecl)) { = dyn_cast<FunctionTemplateDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl); MarkDeclarationReferenced(MemberLoc, MemberDecl);
if (HasExplicitTemplateArgs) if (ExplicitTemplateArgs)
return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow, return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow,
(NestedNameSpecifier *)(SS? SS->getScopeRep() : 0), (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0),
SS? SS->getRange() : SourceRange(), SS? SS->getRange() : SourceRange(),
FunTmpl, MemberLoc, true, FunTmpl, MemberLoc,
LAngleLoc, ExplicitTemplateArgs, ExplicitTemplateArgs,
NumExplicitTemplateArgs, RAngleLoc,
Context.OverloadTy)); Context.OverloadTy));
return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS, return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
@ -2172,13 +2158,11 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
} }
if (OverloadedFunctionDecl *Ovl if (OverloadedFunctionDecl *Ovl
= dyn_cast<OverloadedFunctionDecl>(MemberDecl)) { = dyn_cast<OverloadedFunctionDecl>(MemberDecl)) {
if (HasExplicitTemplateArgs) if (ExplicitTemplateArgs)
return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow, return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow,
(NestedNameSpecifier *)(SS? SS->getScopeRep() : 0), (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0),
SS? SS->getRange() : SourceRange(), SS? SS->getRange() : SourceRange(),
Ovl, MemberLoc, true, Ovl, MemberLoc, ExplicitTemplateArgs,
LAngleLoc, ExplicitTemplateArgs,
NumExplicitTemplateArgs, RAngleLoc,
Context.OverloadTy)); Context.OverloadTy));
return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS, return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
@ -2481,17 +2465,16 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base,
Member.TemplateId->getTemplateArgs(), Member.TemplateId->getTemplateArgs(),
Member.TemplateId->NumArgs); Member.TemplateId->NumArgs);
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs;
translateTemplateArguments(TemplateArgsPtr, TemplateArgs.setLAngleLoc(Member.TemplateId->LAngleLoc);
TemplateArgs); TemplateArgs.setRAngleLoc(Member.TemplateId->RAngleLoc);
translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
TemplateArgsPtr.release(); TemplateArgsPtr.release();
// Do we have the save the actual template name? We might need it... // Do we have the save the actual template name? We might need it...
return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind,
Member.TemplateId->TemplateNameLoc, Member.TemplateId->TemplateNameLoc,
Name, true, Member.TemplateId->LAngleLoc, Name, &TemplateArgs, DeclPtrTy(),
TemplateArgs.data(), TemplateArgs.size(),
Member.TemplateId->RAngleLoc, DeclPtrTy(),
&SS); &SS);
} }
@ -2680,8 +2663,7 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
bool &ArgumentDependentLookup, bool &ArgumentDependentLookup,
bool &Overloaded, bool &Overloaded,
bool &HasExplicitTemplateArguments, bool &HasExplicitTemplateArguments,
const TemplateArgumentLoc *&ExplicitTemplateArgs, TemplateArgumentListInfo &ExplicitTemplateArgs) {
unsigned &NumExplicitTemplateArgs) {
// Set defaults for all of the output parameters. // Set defaults for all of the output parameters.
Name = DeclarationName(); Name = DeclarationName();
Qualifier = 0; Qualifier = 0;
@ -2739,8 +2721,7 @@ void Sema::DeconstructCallFunction(Expr *FnExpr,
} }
Overloaded = true; Overloaded = true;
HasExplicitTemplateArguments = true; HasExplicitTemplateArguments = true;
ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs(); TemplateIdRef->copyTemplateArgumentsInto(ExplicitTemplateArgs);
NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
// C++ [temp.arg.explicit]p6: // C++ [temp.arg.explicit]p6:
// [Note: For simple function names, argument dependent lookup (3.4.2) // [Note: For simple function names, argument dependent lookup (3.4.2)
@ -2878,13 +2859,12 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
bool Overloaded; bool Overloaded;
bool ADL; bool ADL;
bool HasExplicitTemplateArgs = 0; bool HasExplicitTemplateArgs = 0;
const TemplateArgumentLoc *ExplicitTemplateArgs = 0; TemplateArgumentListInfo ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs = 0;
NestedNameSpecifier *Qualifier = 0; NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange; SourceRange QualifierRange;
DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange, DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
ADL, Overloaded, HasExplicitTemplateArgs, ADL, Overloaded, HasExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs); ExplicitTemplateArgs);
NamedDecl *NDecl; // the specific declaration we're calling, if applicable NamedDecl *NDecl; // the specific declaration we're calling, if applicable
FunctionDecl *FDecl; // same, if it's known to be a function FunctionDecl *FDecl; // same, if it's known to be a function
@ -2917,9 +2897,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
#endif #endif
FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName, FDecl = ResolveOverloadedCallFn(Fn, Fns, UnqualifiedName,
HasExplicitTemplateArgs, (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
LParenLoc, Args, NumArgs, CommaLocs, LParenLoc, Args, NumArgs, CommaLocs,
RParenLoc, ADL); RParenLoc, ADL);
if (!FDecl) if (!FDecl)

View File

@ -1419,8 +1419,8 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
if (!Constructor->isInvalidDecl() && if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) { Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl) if (ConstructorTmpl)
AddTemplateOverloadCandidate(ConstructorTmpl, false, 0, 0, &From, AddTemplateOverloadCandidate(ConstructorTmpl, /*ExplicitArgs*/ 0,
1, CandidateSet, &From, 1, CandidateSet,
SuppressUserConversions, ForceRValue); SuppressUserConversions, ForceRValue);
else else
// Allow one user-defined conversion when user specifies a // Allow one user-defined conversion when user specifies a
@ -2351,13 +2351,13 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) && if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
!cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
AddMethodTemplateCandidate(FunTmpl, AddMethodTemplateCandidate(FunTmpl,
/*FIXME: explicit args */false, 0, 0, /*FIXME: explicit args */ 0,
Args[0], Args + 1, NumArgs - 1, Args[0], Args + 1, NumArgs - 1,
CandidateSet, CandidateSet,
SuppressUserConversions); SuppressUserConversions);
else else
AddTemplateOverloadCandidate(FunTmpl, AddTemplateOverloadCandidate(FunTmpl,
/*FIXME: explicit args */false, 0, 0, /*FIXME: explicit args */ 0,
Args, NumArgs, CandidateSet, Args, NumArgs, CandidateSet,
SuppressUserConversions); SuppressUserConversions);
} }
@ -2380,7 +2380,7 @@ void Sema::AddMethodCandidate(NamedDecl *Decl, Expr *Object,
if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) { if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) {
assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) && assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
"Expected a member function template"); "Expected a member function template");
AddMethodTemplateCandidate(TD, false, 0, 0, AddMethodTemplateCandidate(TD, /*ExplicitArgs*/ 0,
Object, Args, NumArgs, Object, Args, NumArgs,
CandidateSet, CandidateSet,
SuppressUserConversions, SuppressUserConversions,
@ -2495,9 +2495,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
/// function template specialization. /// function template specialization.
void void
Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr *Object, Expr **Args, unsigned NumArgs, Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions, bool SuppressUserConversions,
@ -2517,8 +2515,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
TemplateDeductionInfo Info(Context); TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0; FunctionDecl *Specialization = 0;
if (TemplateDeductionResult Result if (TemplateDeductionResult Result
= DeduceTemplateArguments(MethodTmpl, HasExplicitTemplateArgs, = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs,
Args, NumArgs, Specialization, Info)) { Args, NumArgs, Specialization, Info)) {
// FIXME: Record what happened with template argument deduction, so // FIXME: Record what happened with template argument deduction, so
// that we can give the user a beautiful diagnostic. // that we can give the user a beautiful diagnostic.
@ -2540,9 +2537,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
/// an appropriate function template specialization. /// an appropriate function template specialization.
void void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions, bool SuppressUserConversions,
@ -2562,8 +2557,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
TemplateDeductionInfo Info(Context); TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0; FunctionDecl *Specialization = 0;
if (TemplateDeductionResult Result if (TemplateDeductionResult Result
= DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs, = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs,
Args, NumArgs, Specialization, Info)) { Args, NumArgs, Specialization, Info)) {
// FIXME: Record what happened with template argument deduction, so // FIXME: Record what happened with template argument deduction, so
// that we can give the user a beautiful diagnostic. // that we can give the user a beautiful diagnostic.
@ -3941,9 +3935,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
void void
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool PartialOverloading) { bool PartialOverloading) {
FunctionSet Functions; FunctionSet Functions;
@ -3982,16 +3974,14 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
FuncEnd = Functions.end(); FuncEnd = Functions.end();
Func != FuncEnd; ++Func) { Func != FuncEnd; ++Func) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) {
if (HasExplicitTemplateArgs) if (ExplicitTemplateArgs)
continue; continue;
AddOverloadCandidate(FD, Args, NumArgs, CandidateSet, AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
false, false, PartialOverloading); false, false, PartialOverloading);
} else } else
AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func), AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
HasExplicitTemplateArgs,
ExplicitTemplateArgs, ExplicitTemplateArgs,
NumExplicitTemplateArgs,
Args, NumArgs, CandidateSet); Args, NumArgs, CandidateSet);
} }
} }
@ -4333,8 +4323,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
} }
bool HasExplicitTemplateArgs = false; bool HasExplicitTemplateArgs = false;
const TemplateArgumentLoc *ExplicitTemplateArgs = 0; TemplateArgumentListInfo ExplicitTemplateArgs;
unsigned NumExplicitTemplateArgs = 0;
llvm::SmallVector<NamedDecl*,8> Fns; llvm::SmallVector<NamedDecl*,8> Fns;
@ -4345,8 +4334,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
assert(!isa<OverloadedFunctionDecl>(DR->getDecl())); assert(!isa<OverloadedFunctionDecl>(DR->getDecl()));
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl()); FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl());
HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList(); HasExplicitTemplateArgs = DR->hasExplicitTemplateArgumentList();
ExplicitTemplateArgs = DR->getTemplateArgs(); if (HasExplicitTemplateArgs)
NumExplicitTemplateArgs = DR->getNumTemplateArgs(); DR->copyTemplateArgumentsInto(ExplicitTemplateArgs);
} else if (UnresolvedLookupExpr *UL } else if (UnresolvedLookupExpr *UL
= dyn_cast<UnresolvedLookupExpr>(OvlExpr)) { = dyn_cast<UnresolvedLookupExpr>(OvlExpr)) {
Fns.append(UL->decls_begin(), UL->decls_end()); Fns.append(UL->decls_begin(), UL->decls_end());
@ -4354,8 +4343,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl()); Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl());
FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl()); FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl());
HasExplicitTemplateArgs = ME->hasExplicitTemplateArgumentList(); HasExplicitTemplateArgs = ME->hasExplicitTemplateArgumentList();
ExplicitTemplateArgs = ME->getTemplateArgs(); if (HasExplicitTemplateArgs)
NumExplicitTemplateArgs = ME->getNumTemplateArgs(); ME->copyTemplateArgumentsInto(ExplicitTemplateArgs);
} else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(OvlExpr)) { } else if (TemplateIdRefExpr *TIRE = dyn_cast<TemplateIdRefExpr>(OvlExpr)) {
TemplateName Name = TIRE->getTemplateName(); TemplateName Name = TIRE->getTemplateName();
Ovl = Name.getAsOverloadedFunctionDecl(); Ovl = Name.getAsOverloadedFunctionDecl();
@ -4363,8 +4352,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
dyn_cast_or_null<FunctionTemplateDecl>(Name.getAsTemplateDecl()); dyn_cast_or_null<FunctionTemplateDecl>(Name.getAsTemplateDecl());
HasExplicitTemplateArgs = true; HasExplicitTemplateArgs = true;
ExplicitTemplateArgs = TIRE->getTemplateArgs(); TIRE->copyTemplateArgumentsInto(ExplicitTemplateArgs);
NumExplicitTemplateArgs = TIRE->getNumTemplateArgs();
} }
if (Ovl) Fns.append(Ovl->function_begin(), Ovl->function_end()); if (Ovl) Fns.append(Ovl->function_begin(), Ovl->function_end());
@ -4408,9 +4396,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
FunctionDecl *Specialization = 0; FunctionDecl *Specialization = 0;
TemplateDeductionInfo Info(Context); TemplateDeductionInfo Info(Context);
if (TemplateDeductionResult Result if (TemplateDeductionResult Result
= DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs, = DeduceTemplateArguments(FunctionTemplate,
ExplicitTemplateArgs, (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
NumExplicitTemplateArgs,
FunctionType, Specialization, Info)) { FunctionType, Specialization, Info)) {
// FIXME: make a note of the failed deduction for diagnostics. // FIXME: make a note of the failed deduction for diagnostics.
(void)Result; (void)Result;
@ -4509,9 +4496,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
/// \brief Add a single candidate to the overload set. /// \brief Add a single candidate to the overload set.
static void AddOverloadedCallCandidate(Sema &S, static void AddOverloadedCallCandidate(Sema &S,
NamedDecl *Callee, NamedDecl *Callee,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet, OverloadCandidateSet &CandidateSet,
bool PartialOverloading) { bool PartialOverloading) {
@ -4519,7 +4504,7 @@ static void AddOverloadedCallCandidate(Sema &S,
Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl(); Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) { if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
assert(!HasExplicitTemplateArgs && "Explicit template arguments?"); assert(!ExplicitTemplateArgs && "Explicit template arguments?");
S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false, S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false,
PartialOverloading); PartialOverloading);
return; return;
@ -4527,9 +4512,7 @@ static void AddOverloadedCallCandidate(Sema &S,
if (FunctionTemplateDecl *FuncTemplate if (FunctionTemplateDecl *FuncTemplate
= dyn_cast<FunctionTemplateDecl>(Callee)) { = dyn_cast<FunctionTemplateDecl>(Callee)) {
S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs, S.AddTemplateOverloadCandidate(FuncTemplate, ExplicitTemplateArgs,
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
Args, NumArgs, CandidateSet); Args, NumArgs, CandidateSet);
return; return;
} }
@ -4544,9 +4527,7 @@ static void AddOverloadedCallCandidate(Sema &S,
void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns, void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns,
DeclarationName &UnqualifiedName, DeclarationName &UnqualifiedName,
bool ArgumentDependentLookup, bool ArgumentDependentLookup,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet, OverloadCandidateSet &CandidateSet,
bool PartialOverloading) { bool PartialOverloading) {
@ -4581,16 +4562,13 @@ void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns,
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(), for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Fns.begin(),
E = Fns.end(); I != E; ++I) E = Fns.end(); I != E; ++I)
AddOverloadedCallCandidate(*this, *I, HasExplicitTemplateArgs, AddOverloadedCallCandidate(*this, *I, ExplicitTemplateArgs,
ExplicitTemplateArgs, NumExplicitTemplateArgs,
Args, NumArgs, CandidateSet, Args, NumArgs, CandidateSet,
PartialOverloading); PartialOverloading);
if (ArgumentDependentLookup) if (ArgumentDependentLookup)
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs, AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
HasExplicitTemplateArgs,
ExplicitTemplateArgs, ExplicitTemplateArgs,
NumExplicitTemplateArgs,
CandidateSet, CandidateSet,
PartialOverloading); PartialOverloading);
} }
@ -4605,9 +4583,7 @@ void Sema::AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*> &Fns,
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn,
llvm::SmallVectorImpl<NamedDecl*> &Fns, llvm::SmallVectorImpl<NamedDecl*> &Fns,
DeclarationName UnqualifiedName, DeclarationName UnqualifiedName,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc, SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs, SourceLocation *CommaLocs,
@ -4618,8 +4594,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn,
// Add the functions denoted by Callee to the set of candidate // Add the functions denoted by Callee to the set of candidate
// functions. // functions.
AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup, AddOverloadedCallCandidates(Fns, UnqualifiedName, ArgumentDependentLookup,
HasExplicitTemplateArgs, ExplicitTemplateArgs, ExplicitTemplateArgs, Args, NumArgs,
NumExplicitTemplateArgs, Args, NumArgs,
CandidateSet); CandidateSet);
OverloadCandidateSet::iterator Best; OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) { switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
@ -5178,14 +5153,19 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet, AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/false); /*SuppressUserConversions=*/false);
} else } else {
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgs;
if (MemExpr->hasExplicitTemplateArgumentList())
MemExpr->copyTemplateArgumentsInto(TemplateArgs);
AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func), AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
MemExpr->hasExplicitTemplateArgumentList(), (MemExpr->hasExplicitTemplateArgumentList()
MemExpr->getTemplateArgs(), ? &TemplateArgs : 0),
MemExpr->getNumTemplateArgs(),
ObjectArg, Args, NumArgs, ObjectArg, Args, NumArgs,
CandidateSet, CandidateSet,
/*SuppressUsedConversions=*/false); /*SuppressUsedConversions=*/false);
}
} }
OverloadCandidateSet::iterator Best; OverloadCandidateSet::iterator Best;
@ -5657,16 +5637,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
assert((isa<FunctionTemplateDecl>(DRE->getDecl()) || assert((isa<FunctionTemplateDecl>(DRE->getDecl()) ||
isa<FunctionDecl>(DRE->getDecl())) && isa<FunctionDecl>(DRE->getDecl())) &&
"Expected function or function template"); "Expected function or function template");
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgs;
if (DRE->hasExplicitTemplateArgumentList())
DRE->copyTemplateArgumentsInto(TemplateArgs);
return DeclRefExpr::Create(Context, return DeclRefExpr::Create(Context,
DRE->getQualifier(), DRE->getQualifier(),
DRE->getQualifierRange(), DRE->getQualifierRange(),
Fn, Fn,
DRE->getLocation(), DRE->getLocation(),
DRE->hasExplicitTemplateArgumentList(), (DRE->hasExplicitTemplateArgumentList()
DRE->getLAngleLoc(), ? &TemplateArgs : 0),
DRE->getTemplateArgs(),
DRE->getNumTemplateArgs(),
DRE->getRAngleLoc(),
Fn->getType(), Fn->getType(),
DRE->isTypeDependent(), DRE->isTypeDependent(),
DRE->isValueDependent()); DRE->isValueDependent());
@ -5689,17 +5671,19 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
isa<FunctionTemplateDecl>(MemExpr->getMemberDecl()) || isa<FunctionTemplateDecl>(MemExpr->getMemberDecl()) ||
isa<FunctionDecl>(MemExpr->getMemberDecl())) && isa<FunctionDecl>(MemExpr->getMemberDecl())) &&
"Expected member function or member function template"); "Expected member function or member function template");
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgs;
if (MemExpr->hasExplicitTemplateArgumentList())
MemExpr->copyTemplateArgumentsInto(TemplateArgs);
return MemberExpr::Create(Context, MemExpr->getBase()->Retain(), return MemberExpr::Create(Context, MemExpr->getBase()->Retain(),
MemExpr->isArrow(), MemExpr->isArrow(),
MemExpr->getQualifier(), MemExpr->getQualifier(),
MemExpr->getQualifierRange(), MemExpr->getQualifierRange(),
Fn, Fn,
MemExpr->getMemberLoc(), MemExpr->getMemberLoc(),
MemExpr->hasExplicitTemplateArgumentList(), (MemExpr->hasExplicitTemplateArgumentList()
MemExpr->getLAngleLoc(), ? &TemplateArgs : 0),
MemExpr->getTemplateArgs(),
MemExpr->getNumTemplateArgs(),
MemExpr->getRAngleLoc(),
Fn->getType()); Fn->getType());
} }
@ -5707,14 +5691,15 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
// FIXME: Don't destroy TID here, since we need its template arguments // FIXME: Don't destroy TID here, since we need its template arguments
// to survive. // to survive.
// TID->Destroy(Context); // TID->Destroy(Context);
// FIXME: avoid copy.
TemplateArgumentListInfo TemplateArgs;
TID->copyTemplateArgumentsInto(TemplateArgs);
return DeclRefExpr::Create(Context, return DeclRefExpr::Create(Context,
TID->getQualifier(), TID->getQualifierRange(), TID->getQualifier(), TID->getQualifierRange(),
Fn, TID->getTemplateNameLoc(), Fn, TID->getTemplateNameLoc(),
true, &TemplateArgs,
TID->getLAngleLoc(),
TID->getTemplateArgs(),
TID->getNumTemplateArgs(),
TID->getRAngleLoc(),
Fn->getType(), Fn->getType(),
/*FIXME?*/false, /*FIXME?*/false); /*FIXME?*/false, /*FIXME?*/false);
} }

View File

@ -317,12 +317,11 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
/// \brief Translates template arguments as provided by the parser /// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis. /// into template arguments used by semantic analysis.
void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn, void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
llvm::SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { TemplateArgumentListInfo &TemplateArgs) {
TemplateArgs.reserve(TemplateArgsIn.size());
for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I) for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I)
TemplateArgs.push_back(translateTemplateArgument(*this, TemplateArgsIn[I])); TemplateArgs.addArgument(translateTemplateArgument(*this,
TemplateArgsIn[I]));
} }
/// ActOnTypeParameter - Called when a C++ template type parameter /// ActOnTypeParameter - Called when a C++ template type parameter
@ -1161,24 +1160,19 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
QualType Sema::CheckTemplateIdType(TemplateName Name, QualType Sema::CheckTemplateIdType(TemplateName Name,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
TemplateDecl *Template = Name.getAsTemplateDecl(); TemplateDecl *Template = Name.getAsTemplateDecl();
if (!Template) { if (!Template) {
// The template name does not resolve to a template, so we just // The template name does not resolve to a template, so we just
// build a dependent template-id type. // build a dependent template-id type.
return Context.getTemplateSpecializationType(Name, TemplateArgs, return Context.getTemplateSpecializationType(Name, TemplateArgs);
NumTemplateArgs);
} }
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
TemplateArgumentListBuilder Converted(Template->getTemplateParameters(), TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
NumTemplateArgs); TemplateArgs.size());
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc, if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
TemplateArgs, NumTemplateArgs, RAngleLoc,
false, Converted)) false, Converted))
return QualType(); return QualType();
@ -1190,8 +1184,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
if (Name.isDependent() || if (Name.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments( TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs, TemplateArgs)) {
NumTemplateArgs)) {
// This class template specialization is a dependent // This class template specialization is a dependent
// type. Therefore, its canonical type is another class template // type. Therefore, its canonical type is another class template
// specialization type that contains all of the converted // specialization type that contains all of the converted
@ -1240,8 +1233,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Build the fully-sugared type for this class template // Build the fully-sugared type for this class template
// specialization, which refers back to the class template // specialization, which refers back to the class template
// specialization we created or found. // specialization we created or found.
return Context.getTemplateSpecializationType(Name, TemplateArgs, return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
NumTemplateArgs, CanonType);
} }
Action::TypeResult Action::TypeResult
@ -1252,13 +1244,10 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
TemplateName Template = TemplateD.getAsVal<TemplateName>(); TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format. // Translate the parser's template argument list in our AST format.
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs); translateTemplateArguments(TemplateArgsIn, TemplateArgs);
QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc, QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
TemplateArgs.data(),
TemplateArgs.size(),
RAngleLoc);
TemplateArgsIn.release(); TemplateArgsIn.release();
if (Result.isNull()) if (Result.isNull())
@ -1314,10 +1303,7 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange, SourceRange QualifierRange,
TemplateName Template, TemplateName Template,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
// FIXME: Can we do any checking at this point? I guess we could check the // FIXME: Can we do any checking at this point? I guess we could check the
// template arguments that we have against the template name, if the template // template arguments that we have against the template name, if the template
// name refers to a single template. That's not a terribly common case, // name refers to a single template. That's not a terribly common case,
@ -1337,17 +1323,14 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType); Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
return Owned(MemberExpr::Create(Context, This, true, return Owned(MemberExpr::Create(Context, This, true,
Qualifier, QualifierRange, Qualifier, QualifierRange,
D, TemplateNameLoc, true, D, TemplateNameLoc, &TemplateArgs,
LAngleLoc, TemplateArgs,
NumTemplateArgs, RAngleLoc,
Context.OverloadTy)); Context.OverloadTy));
} }
return Owned(TemplateIdRefExpr::Create(Context, Context.OverloadTy, return Owned(TemplateIdRefExpr::Create(Context, Context.OverloadTy,
Qualifier, QualifierRange, Qualifier, QualifierRange,
Template, TemplateNameLoc, LAngleLoc, Template, TemplateNameLoc,
TemplateArgs, TemplateArgs));
NumTemplateArgs, RAngleLoc));
} }
Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS, Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
@ -1359,15 +1342,13 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
TemplateName Template = TemplateD.getAsVal<TemplateName>(); TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format. // Translate the parser's template argument list in our AST format.
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs); translateTemplateArguments(TemplateArgsIn, TemplateArgs);
TemplateArgsIn.release(); TemplateArgsIn.release();
return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(), return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
SS.getRange(), SS.getRange(),
Template, TemplateNameLoc, LAngleLoc, Template, TemplateNameLoc, TemplateArgs);
TemplateArgs.data(), TemplateArgs.size(),
RAngleLoc);
} }
/// \brief Form a dependent template name. /// \brief Form a dependent template name.
@ -1799,17 +1780,16 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
/// for specializing the given template. /// for specializing the given template.
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
bool PartialTemplateArgs, bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted) { TemplateArgumentListBuilder &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters(); TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size(); unsigned NumParams = Params->size();
unsigned NumArgs = NumTemplateArgs; unsigned NumArgs = TemplateArgs.size();
bool Invalid = false; bool Invalid = false;
SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
bool HasParameterPack = bool HasParameterPack =
NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack(); NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
@ -3047,16 +3027,17 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
} }
// Translate the parser's template argument list in our AST format. // Translate the parser's template argument list in our AST format.
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs;
TemplateArgs.setLAngleLoc(LAngleLoc);
TemplateArgs.setRAngleLoc(RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs); translateTemplateArguments(TemplateArgsIn, TemplateArgs);
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
TemplateArgs.size()); TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
TemplateArgs.data(), TemplateArgs.size(), TemplateArgs, false, Converted))
RAngleLoc, false, Converted))
return true; return true;
assert((Converted.structuredSize() == assert((Converted.structuredSize() ==
@ -3155,8 +3136,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TemplateParams, TemplateParams,
ClassTemplate, ClassTemplate,
Converted, Converted,
TemplateArgs.data(), TemplateArgs,
TemplateArgs.size(),
PrevPartial); PrevPartial);
if (PrevPartial) { if (PrevPartial) {
@ -3268,10 +3248,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// name based on the "canonical" representation used to store the // name based on the "canonical" representation used to store the
// template arguments in the specialization. // template arguments in the specialization.
QualType WrittenTy QualType WrittenTy
= Context.getTemplateSpecializationType(Name, = Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
TemplateArgs.data(),
TemplateArgs.size(),
CanonType);
if (TUK != TUK_Friend) if (TUK != TUK_Friend)
Specialization->setTypeAsWritten(WrittenTy); Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release(); TemplateArgsIn.release();
@ -3534,11 +3511,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
/// \param PrevDecl the set of declarations that /// \param PrevDecl the set of declarations that
bool bool
Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
LookupResult &Previous) { LookupResult &Previous) {
// The set of function template specializations that could match this // The set of function template specializations that could match this
// explicit function template specialization. // explicit function template specialization.
@ -3565,9 +3538,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
TemplateDeductionInfo Info(Context); TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0; FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK if (TemplateDeductionResult TDK
= DeduceTemplateArguments(FunTmpl, HasExplicitTemplateArgs, = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs,
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
FD->getType(), FD->getType(),
Specialization, Specialization,
Info)) { Info)) {
@ -3590,7 +3561,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
PartialDiagnostic(diag::err_function_template_spec_no_match) PartialDiagnostic(diag::err_function_template_spec_no_match)
<< FD->getDeclName(), << FD->getDeclName(),
PartialDiagnostic(diag::err_function_template_spec_ambiguous) PartialDiagnostic(diag::err_function_template_spec_ambiguous)
<< FD->getDeclName() << HasExplicitTemplateArgs, << FD->getDeclName() << (ExplicitTemplateArgs != 0),
PartialDiagnostic(diag::note_function_template_spec_matched)); PartialDiagnostic(diag::note_function_template_spec_matched));
if (!Specialization) if (!Specialization)
return true; return true;
@ -3902,16 +3873,15 @@ Sema::ActOnExplicitInstantiation(Scope *S,
: TSK_ExplicitInstantiationDeclaration; : TSK_ExplicitInstantiationDeclaration;
// Translate the parser's template argument list in our AST format. // Translate the parser's template argument list in our AST format.
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs); translateTemplateArguments(TemplateArgsIn, TemplateArgs);
// Check that the template argument list is well-formed for this // Check that the template argument list is well-formed for this
// template. // template.
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(), TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
TemplateArgs.size()); TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
TemplateArgs.data(), TemplateArgs.size(), TemplateArgs, false, Converted))
RAngleLoc, false, Converted))
return true; return true;
assert((Converted.structuredSize() == assert((Converted.structuredSize() ==
@ -3992,9 +3962,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// on the "canonical" representation used to store the template // on the "canonical" representation used to store the template
// arguments in the specialization. // arguments in the specialization.
QualType WrittenTy QualType WrittenTy
= Context.getTemplateSpecializationType(Name, = Context.getTemplateSpecializationType(Name, TemplateArgs,
TemplateArgs.data(),
TemplateArgs.size(),
Context.getTypeDeclType(Specialization)); Context.getTypeDeclType(Specialization));
Specialization->setTypeAsWritten(WrittenTy); Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release(); TemplateArgsIn.release();
@ -4278,14 +4246,15 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// If the declarator is a template-id, translate the parser's template // If the declarator is a template-id, translate the parser's template
// argument list into our AST format. // argument list into our AST format.
bool HasExplicitTemplateArgs = false; bool HasExplicitTemplateArgs = false;
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; TemplateArgumentListInfo TemplateArgs;
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getName().TemplateId; TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
ASTTemplateArgsPtr TemplateArgsPtr(*this, ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(), TemplateId->getTemplateArgs(),
TemplateId->NumArgs); TemplateId->NumArgs);
translateTemplateArguments(TemplateArgsPtr, translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
TemplateArgs);
HasExplicitTemplateArgs = true; HasExplicitTemplateArgs = true;
TemplateArgsPtr.release(); TemplateArgsPtr.release();
} }
@ -4316,8 +4285,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
TemplateDeductionInfo Info(Context); TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0; FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK if (TemplateDeductionResult TDK
= DeduceTemplateArguments(FunTmpl, HasExplicitTemplateArgs, = DeduceTemplateArguments(FunTmpl,
TemplateArgs.data(), TemplateArgs.size(), (HasExplicitTemplateArgs ? &TemplateArgs : 0),
R, Specialization, Info)) { R, Specialization, Info)) {
// FIXME: Keep track of almost-matches? // FIXME: Keep track of almost-matches?
(void)TDK; (void)TDK;

View File

@ -1050,35 +1050,34 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
const TemplateArgumentLoc *PartialTemplateArgs const TemplateArgumentLoc *PartialTemplateArgs
= Partial->getTemplateArgsAsWritten(); = Partial->getTemplateArgsAsWritten();
unsigned N = Partial->getNumTemplateArgsAsWritten(); unsigned N = Partial->getNumTemplateArgsAsWritten();
llvm::SmallVector<TemplateArgumentLoc, 16> InstArgs(N);
// Note that we don't provide the langle and rangle locations.
TemplateArgumentListInfo InstArgs;
for (unsigned I = 0; I != N; ++I) { for (unsigned I = 0; I != N; ++I) {
Decl *Param = const_cast<NamedDecl *>( Decl *Param = const_cast<NamedDecl *>(
ClassTemplate->getTemplateParameters()->getParam(I)); ClassTemplate->getTemplateParameters()->getParam(I));
if (Subst(PartialTemplateArgs[I], InstArgs[I], TemplateArgumentLoc InstArg;
if (Subst(PartialTemplateArgs[I], InstArg,
MultiLevelTemplateArgumentList(*DeducedArgumentList))) { MultiLevelTemplateArgumentList(*DeducedArgumentList))) {
Info.Param = makeTemplateParameter(Param); Info.Param = makeTemplateParameter(Param);
Info.FirstArg = PartialTemplateArgs[I].getArgument(); Info.FirstArg = PartialTemplateArgs[I].getArgument();
return TDK_SubstitutionFailure; return TDK_SubstitutionFailure;
} }
InstArgs.addArgument(InstArg);
} }
TemplateArgumentListBuilder ConvertedInstArgs( TemplateArgumentListBuilder ConvertedInstArgs(
ClassTemplate->getTemplateParameters(), N); ClassTemplate->getTemplateParameters(), N);
if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(), if (CheckTemplateArgumentList(ClassTemplate, Partial->getLocation(),
/*LAngle*/ SourceLocation(), InstArgs, false, ConvertedInstArgs)) {
InstArgs.data(), N,
/*RAngle*/ SourceLocation(),
false, ConvertedInstArgs)) {
// FIXME: fail with more useful information? // FIXME: fail with more useful information?
return TDK_SubstitutionFailure; return TDK_SubstitutionFailure;
} }
for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) { for (unsigned I = 0, E = ConvertedInstArgs.flatSize(); I != E; ++I) {
// We don't really care if we overwrite the internal structures of TemplateArgument InstArg = ConvertedInstArgs.getFlatArguments()[I];
// 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 *>( Decl *Param = const_cast<NamedDecl *>(
ClassTemplate->getTemplateParameters()->getParam(I)); ClassTemplate->getTemplateParameters()->getParam(I));
@ -1130,9 +1129,6 @@ static bool isSimpleTemplateIdType(QualType T) {
/// \param ExplicitTemplateArguments the explicitly-specified template /// \param ExplicitTemplateArguments the explicitly-specified template
/// arguments. /// arguments.
/// ///
/// \param NumExplicitTemplateArguments the number of explicitly-specified
/// template arguments in @p ExplicitTemplateArguments. This value may be zero.
///
/// \param Deduced the deduced template arguments, which will be populated /// \param Deduced the deduced template arguments, which will be populated
/// with the converted and checked explicit template arguments. /// with the converted and checked explicit template arguments.
/// ///
@ -1151,8 +1147,7 @@ static bool isSimpleTemplateIdType(QualType T) {
Sema::TemplateDeductionResult Sema::TemplateDeductionResult
Sema::SubstituteExplicitTemplateArguments( Sema::SubstituteExplicitTemplateArguments(
FunctionTemplateDecl *FunctionTemplate, FunctionTemplateDecl *FunctionTemplate,
const TemplateArgumentLoc *ExplicitTemplateArgs, const TemplateArgumentListInfo &ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
llvm::SmallVectorImpl<TemplateArgument> &Deduced, llvm::SmallVectorImpl<TemplateArgument> &Deduced,
llvm::SmallVectorImpl<QualType> &ParamTypes, llvm::SmallVectorImpl<QualType> &ParamTypes,
QualType *FunctionType, QualType *FunctionType,
@ -1161,7 +1156,7 @@ Sema::SubstituteExplicitTemplateArguments(
TemplateParameterList *TemplateParams TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters(); = FunctionTemplate->getTemplateParameters();
if (NumExplicitTemplateArgs == 0) { if (ExplicitTemplateArgs.size() == 0) {
// No arguments to substitute; just copy over the parameter types and // No arguments to substitute; just copy over the parameter types and
// fill in the function type. // fill in the function type.
for (FunctionDecl::param_iterator P = Function->param_begin(), for (FunctionDecl::param_iterator P = Function->param_begin(),
@ -1185,7 +1180,7 @@ Sema::SubstituteExplicitTemplateArguments(
// template argument list shall not specify more template-arguments than // template argument list shall not specify more template-arguments than
// there are corresponding template-parameters. // there are corresponding template-parameters.
TemplateArgumentListBuilder Builder(TemplateParams, TemplateArgumentListBuilder Builder(TemplateParams,
NumExplicitTemplateArgs); ExplicitTemplateArgs.size());
// Enter a new template instantiation context where we check the // Enter a new template instantiation context where we check the
// explicitly-specified template arguments against this function template, // explicitly-specified template arguments against this function template,
@ -1197,10 +1192,8 @@ Sema::SubstituteExplicitTemplateArguments(
return TDK_InstantiationDepth; return TDK_InstantiationDepth;
if (CheckTemplateArgumentList(FunctionTemplate, if (CheckTemplateArgumentList(FunctionTemplate,
SourceLocation(), SourceLocation(),
ExplicitTemplateArgs,
NumExplicitTemplateArgs,
SourceLocation(), SourceLocation(),
ExplicitTemplateArgs,
true, true,
Builder) || Trap.hasErrorOccurred()) Builder) || Trap.hasErrorOccurred())
return TDK_InvalidExplicitArguments; return TDK_InvalidExplicitArguments;
@ -1368,9 +1361,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
/// \returns the result of template argument deduction. /// \returns the result of template argument deduction.
Sema::TemplateDeductionResult Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization, FunctionDecl *&Specialization,
TemplateDeductionInfo &Info) { TemplateDeductionInfo &Info) {
@ -1398,11 +1389,10 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
= FunctionTemplate->getTemplateParameters(); = FunctionTemplate->getTemplateParameters();
llvm::SmallVector<TemplateArgument, 4> Deduced; llvm::SmallVector<TemplateArgument, 4> Deduced;
llvm::SmallVector<QualType, 4> ParamTypes; llvm::SmallVector<QualType, 4> ParamTypes;
if (NumExplicitTemplateArgs) { if (ExplicitTemplateArgs) {
TemplateDeductionResult Result = TemplateDeductionResult Result =
SubstituteExplicitTemplateArguments(FunctionTemplate, SubstituteExplicitTemplateArguments(FunctionTemplate,
ExplicitTemplateArgs, *ExplicitTemplateArgs,
NumExplicitTemplateArgs,
Deduced, Deduced,
ParamTypes, ParamTypes,
0, 0,
@ -1538,9 +1528,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
/// \returns the result of template argument deduction. /// \returns the result of template argument deduction.
Sema::TemplateDeductionResult Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
QualType ArgFunctionType, QualType ArgFunctionType,
FunctionDecl *&Specialization, FunctionDecl *&Specialization,
TemplateDeductionInfo &Info) { TemplateDeductionInfo &Info) {
@ -1552,11 +1540,10 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// Substitute any explicit template arguments. // Substitute any explicit template arguments.
llvm::SmallVector<TemplateArgument, 4> Deduced; llvm::SmallVector<TemplateArgument, 4> Deduced;
llvm::SmallVector<QualType, 4> ParamTypes; llvm::SmallVector<QualType, 4> ParamTypes;
if (HasExplicitTemplateArgs) { if (ExplicitTemplateArgs) {
if (TemplateDeductionResult Result if (TemplateDeductionResult Result
= SubstituteExplicitTemplateArguments(FunctionTemplate, = SubstituteExplicitTemplateArguments(FunctionTemplate,
ExplicitTemplateArgs, *ExplicitTemplateArgs,
NumExplicitTemplateArgs,
Deduced, ParamTypes, Deduced, ParamTypes,
&FunctionType, Info)) &FunctionType, Info))
return Result; return Result;

View File

@ -1153,11 +1153,12 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
= PartialSpec->getTemplateArgsAsWritten(); = PartialSpec->getTemplateArgsAsWritten();
unsigned N = PartialSpec->getNumTemplateArgsAsWritten(); unsigned N = PartialSpec->getNumTemplateArgsAsWritten();
llvm::SmallVector<TemplateArgumentLoc, 4> InstTemplateArgs(N); TemplateArgumentListInfo InstTemplateArgs; // no angle locations
for (unsigned I = 0; I != N; ++I) { for (unsigned I = 0; I != N; ++I) {
if (SemaRef.Subst(PartialSpecTemplateArgs[I], InstTemplateArgs[I], TemplateArgumentLoc Loc;
TemplateArgs)) if (SemaRef.Subst(PartialSpecTemplateArgs[I], Loc, TemplateArgs))
return true; return true;
InstTemplateArgs.addArgument(Loc);
} }
@ -1167,10 +1168,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
InstTemplateArgs.size()); InstTemplateArgs.size());
if (SemaRef.CheckTemplateArgumentList(ClassTemplate, if (SemaRef.CheckTemplateArgumentList(ClassTemplate,
PartialSpec->getLocation(), PartialSpec->getLocation(),
/*FIXME:*/PartialSpec->getLocation(), InstTemplateArgs,
InstTemplateArgs.data(),
InstTemplateArgs.size(),
/*FIXME:*/PartialSpec->getLocation(),
false, false,
Converted)) Converted))
return true; return true;
@ -1203,8 +1201,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// template arguments in the specialization. // template arguments in the specialization.
QualType WrittenTy QualType WrittenTy
= SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate), = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),
InstTemplateArgs.data(), InstTemplateArgs,
InstTemplateArgs.size(),
CanonType); CanonType);
if (PrevDecl) { if (PrevDecl) {
@ -1238,8 +1235,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
InstParams, InstParams,
ClassTemplate, ClassTemplate,
Converted, Converted,
InstTemplateArgs.data(), InstTemplateArgs,
InstTemplateArgs.size(),
0); 0);
InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setInstantiatedFromMember(PartialSpec);
InstPartialSpec->setTypeAsWritten(WrittenTy); InstPartialSpec->setTypeAsWritten(WrittenTy);

View File

@ -503,10 +503,7 @@ public:
/// different behavior. /// different behavior.
QualType RebuildTemplateSpecializationType(TemplateName Template, QualType RebuildTemplateSpecializationType(TemplateName Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &Args);
const TemplateArgumentLoc *Args,
unsigned NumArgs,
SourceLocation RAngleLoc);
/// \brief Build a new qualified name type. /// \brief Build a new qualified name type.
/// ///
@ -942,11 +939,7 @@ public:
SourceRange QualifierRange, SourceRange QualifierRange,
SourceLocation MemberLoc, SourceLocation MemberLoc,
NamedDecl *Member, NamedDecl *Member,
bool HasExplicitTemplateArgs, const TemplateArgumentListInfo *ExplicitTemplateArgs,
SourceLocation LAngleLoc,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
NamedDecl *FirstQualifierInScope) { NamedDecl *FirstQualifierInScope) {
if (!Member->getDeclName()) { if (!Member->getDeclName()) {
// We have a reference to an unnamed field. // We have a reference to an unnamed field.
@ -969,11 +962,7 @@ public:
isArrow? tok::arrow : tok::period, isArrow? tok::arrow : tok::period,
MemberLoc, MemberLoc,
Member->getDeclName(), Member->getDeclName(),
HasExplicitTemplateArgs,
LAngleLoc,
ExplicitTemplateArgs, ExplicitTemplateArgs,
NumExplicitTemplateArgs,
RAngleLoc,
/*FIXME?*/Sema::DeclPtrTy::make((Decl*)0), /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
&SS, &SS,
FirstQualifierInScope); FirstQualifierInScope);
@ -1480,15 +1469,9 @@ public:
SourceRange QualifierRange, SourceRange QualifierRange,
TemplateName Template, TemplateName Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange, return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
Template, TemplateLoc, Template, TemplateLoc, TemplateArgs);
LAngleLoc,
TemplateArgs, NumTemplateArgs,
RAngleLoc);
} }
/// \brief Build a new object-construction expression. /// \brief Build a new object-construction expression.
@ -1583,10 +1566,7 @@ public:
TemplateName Template, TemplateName Template,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
NamedDecl *FirstQualifierInScope, NamedDecl *FirstQualifierInScope,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
OwningExprResult Base = move(BaseE); OwningExprResult Base = move(BaseE);
tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period; tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
@ -1610,12 +1590,11 @@ public:
Name = SemaRef.Context.DeclarationNames.getCXXOperatorName( Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
DTN->getOperator()); DTN->getOperator());
} }
return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base), return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
OperatorLoc, OpKind, OperatorLoc, OpKind,
TemplateNameLoc, Name, true, TemplateNameLoc, Name,
LAngleLoc, TemplateArgs, &TemplateArgs,
NumTemplateArgs, RAngleLoc, Sema::DeclPtrTy(), &SS);
Sema::DeclPtrTy(), &SS);
} }
/// \brief Build a new Objective-C @encode expression. /// \brief Build a new Objective-C @encode expression.
@ -2879,21 +2858,23 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
if (Template.isNull()) if (Template.isNull())
return QualType(); return QualType();
llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs()); TemplateArgumentListInfo NewTemplateArgs;
for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
if (getDerived().TransformTemplateArgument(TL.getArgLoc(i), NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
NewTemplateArgs[i]))
for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
TemplateArgumentLoc Loc;
if (getDerived().TransformTemplateArgument(TL.getArgLoc(i), Loc))
return QualType(); return QualType();
NewTemplateArgs.addArgument(Loc);
}
// FIXME: maybe don't rebuild if all the template arguments are the same. // FIXME: maybe don't rebuild if all the template arguments are the same.
QualType Result = QualType Result =
getDerived().RebuildTemplateSpecializationType(Template, getDerived().RebuildTemplateSpecializationType(Template,
TL.getTemplateNameLoc(), TL.getTemplateNameLoc(),
TL.getLAngleLoc(), NewTemplateArgs);
NewTemplateArgs.data(),
NewTemplateArgs.size(),
TL.getRAngleLoc());
if (!Result.isNull()) { if (!Result.isNull()) {
TemplateSpecializationTypeLoc NewTL TemplateSpecializationTypeLoc NewTL
@ -3695,13 +3676,15 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
!E->hasExplicitTemplateArgumentList()) !E->hasExplicitTemplateArgumentList())
return SemaRef.Owned(E->Retain()); return SemaRef.Owned(E->Retain());
llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs; TemplateArgumentListInfo TransArgs;
if (E->hasExplicitTemplateArgumentList()) { if (E->hasExplicitTemplateArgumentList()) {
TransArgs.resize(E->getNumTemplateArgs()); TransArgs.setLAngleLoc(E->getLAngleLoc());
TransArgs.setRAngleLoc(E->getRAngleLoc());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], TemplateArgumentLoc Loc;
TransArgs[I])) if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
return SemaRef.ExprError(); return SemaRef.ExprError();
TransArgs.addArgument(Loc);
} }
} }
@ -3715,11 +3698,8 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
E->getQualifierRange(), E->getQualifierRange(),
E->getMemberLoc(), E->getMemberLoc(),
Member, Member,
E->hasExplicitTemplateArgumentList(), (E->hasExplicitTemplateArgumentList()
E->getLAngleLoc(), ? &TransArgs : 0),
TransArgs.data(),
TransArgs.size(),
E->getRAngleLoc(),
0); 0);
} }
@ -4636,12 +4616,13 @@ TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
if (!Qualifier) if (!Qualifier)
return SemaRef.ExprError(); return SemaRef.ExprError();
} }
llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs()); TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], TemplateArgumentLoc Loc;
TransArgs[I])) if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
return SemaRef.ExprError(); return SemaRef.ExprError();
TransArgs.addArgument(Loc);
} }
// FIXME: Would like to avoid rebuilding if nothing changed, but we can't // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
@ -4652,10 +4633,7 @@ TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
// with a functional cast. Give a reasonable error message! // with a functional cast. Give a reasonable error message!
return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(), return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
Template, E->getTemplateNameLoc(), Template, E->getTemplateNameLoc(),
E->getLAngleLoc(), TransArgs);
TransArgs.data(),
TransArgs.size(),
E->getRAngleLoc());
} }
template<typename Derived> template<typename Derived>
@ -4905,11 +4883,12 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
if (Template.isNull()) if (Template.isNull())
return SemaRef.ExprError(); return SemaRef.ExprError();
llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs()); TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], TemplateArgumentLoc Loc;
TransArgs[I])) if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
return SemaRef.ExprError(); return SemaRef.ExprError();
TransArgs.addArgument(Loc);
} }
return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base), return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
@ -4920,10 +4899,7 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
Template, Template,
E->getMemberLoc(), E->getMemberLoc(),
FirstQualifierInScope, FirstQualifierInScope,
E->getLAngleLoc(), TransArgs);
TransArgs.data(),
TransArgs.size(),
E->getRAngleLoc());
} }
template<typename Derived> template<typename Derived>
@ -5266,12 +5242,8 @@ template<typename Derived>
QualType TreeTransform<Derived>::RebuildTemplateSpecializationType( QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
TemplateName Template, TemplateName Template,
SourceLocation TemplateNameLoc, SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc, const TemplateArgumentListInfo &TemplateArgs) {
const TemplateArgumentLoc *Args, return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
unsigned NumArgs,
SourceLocation RAngleLoc) {
return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
Args, NumArgs, RAngleLoc);
} }
template<typename Derived> template<typename Derived>
@ -5280,7 +5252,7 @@ TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
SourceRange Range, SourceRange Range,
IdentifierInfo &II, IdentifierInfo &II,
QualType ObjectType, QualType ObjectType,
NamedDecl *FirstQualifierInScope) { NamedDecl *FirstQualifierInScope) {
CXXScopeSpec SS; CXXScopeSpec SS;
// FIXME: The source location information is all wrong. // FIXME: The source location information is all wrong.
SS.setRange(Range); SS.setRange(Range);