aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-11-23 01:53:49 +0000
committerJohn McCall <rjmccall@apple.com>2009-11-23 01:53:49 +0000
commitd5532b6cfff2977e0c59fa6ead7f7973984a620d (patch)
treec4dc0e61ccf65cd514611f1a596d3cb29bf5d658 /lib/Sema/SemaTemplate.cpp
parent93b189ff4a9bf9fc1901b227657d07ef8383d4e7 (diff)
Encapsulate "an array of TemplateArgumentLocs and two angle bracket locations" into
a new class. Use it pervasively throughout Sema. My fingers hurt. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89638 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp115
1 files changed, 42 insertions, 73 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f013343894..096289fa35 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -317,12 +317,11 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
/// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis.
-void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
- llvm::SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
- TemplateArgs.reserve(TemplateArgsIn.size());
-
+void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
+ TemplateArgumentListInfo &TemplateArgs) {
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
@@ -1161,24 +1160,19 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
QualType Sema::CheckTemplateIdType(TemplateName Name,
SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc) {
+ const TemplateArgumentListInfo &TemplateArgs) {
TemplateDecl *Template = Name.getAsTemplateDecl();
if (!Template) {
// The template name does not resolve to a template, so we just
// build a dependent template-id type.
- return Context.getTemplateSpecializationType(Name, TemplateArgs,
- NumTemplateArgs);
+ return Context.getTemplateSpecializationType(Name, TemplateArgs);
}
// Check that the template argument list is well-formed for this
// template.
TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
- NumTemplateArgs);
- if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
- TemplateArgs, NumTemplateArgs, RAngleLoc,
+ TemplateArgs.size());
+ if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
false, Converted))
return QualType();
@@ -1190,8 +1184,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
if (Name.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs,
- NumTemplateArgs)) {
+ TemplateArgs)) {
// This class template specialization is a dependent
// type. Therefore, its canonical type is another class template
// 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
// specialization, which refers back to the class template
// specialization we created or found.
- return Context.getTemplateSpecializationType(Name, TemplateArgs,
- NumTemplateArgs, CanonType);
+ return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
}
Action::TypeResult
@@ -1252,13 +1244,10 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
- QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
- TemplateArgs.data(),
- TemplateArgs.size(),
- RAngleLoc);
+ QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
TemplateArgsIn.release();
if (Result.isNull())
@@ -1314,10 +1303,7 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
TemplateName Template,
SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc) {
+ const TemplateArgumentListInfo &TemplateArgs) {
// 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
// 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);
return Owned(MemberExpr::Create(Context, This, true,
Qualifier, QualifierRange,
- D, TemplateNameLoc, true,
- LAngleLoc, TemplateArgs,
- NumTemplateArgs, RAngleLoc,
+ D, TemplateNameLoc, &TemplateArgs,
Context.OverloadTy));
}
return Owned(TemplateIdRefExpr::Create(Context, Context.OverloadTy,
Qualifier, QualifierRange,
- Template, TemplateNameLoc, LAngleLoc,
- TemplateArgs,
- NumTemplateArgs, RAngleLoc));
+ Template, TemplateNameLoc,
+ TemplateArgs));
}
Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
@@ -1359,15 +1342,13 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
TemplateName Template = TemplateD.getAsVal<TemplateName>();
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
TemplateArgsIn.release();
return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
SS.getRange(),
- Template, TemplateNameLoc, LAngleLoc,
- TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc);
+ Template, TemplateNameLoc, TemplateArgs);
}
/// \brief Form a dependent template name.
@@ -1799,17 +1780,16 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
/// for specializing the given template.
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc,
+ const TemplateArgumentListInfo &TemplateArgs,
bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size();
- unsigned NumArgs = NumTemplateArgs;
+ unsigned NumArgs = TemplateArgs.size();
bool Invalid = false;
+ SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
+
bool HasParameterPack =
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.
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ TemplateArgumentListInfo TemplateArgs;
+ TemplateArgs.setLAngleLoc(LAngleLoc);
+ TemplateArgs.setRAngleLoc(RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
// Check that the template argument list is well-formed for this
// template.
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
TemplateArgs.size());
- if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
- TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, false, Converted))
+ if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
+ TemplateArgs, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -3155,8 +3136,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TemplateParams,
ClassTemplate,
Converted,
- TemplateArgs.data(),
- TemplateArgs.size(),
+ TemplateArgs,
PrevPartial);
if (PrevPartial) {
@@ -3268,10 +3248,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// name based on the "canonical" representation used to store the
// template arguments in the specialization.
QualType WrittenTy
- = Context.getTemplateSpecializationType(Name,
- TemplateArgs.data(),
- TemplateArgs.size(),
- CanonType);
+ = Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
if (TUK != TUK_Friend)
Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release();
@@ -3534,11 +3511,7 @@ Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
/// \param PrevDecl the set of declarations that
bool
Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
- bool HasExplicitTemplateArgs,
- SourceLocation LAngleLoc,
- const TemplateArgumentLoc *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation RAngleLoc,
+ const TemplateArgumentListInfo *ExplicitTemplateArgs,
LookupResult &Previous) {
// The set of function template specializations that could match this
// explicit function template specialization.
@@ -3565,9 +3538,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
- = DeduceTemplateArguments(FunTmpl, HasExplicitTemplateArgs,
- ExplicitTemplateArgs,
- NumExplicitTemplateArgs,
+ = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs,
FD->getType(),
Specialization,
Info)) {
@@ -3590,7 +3561,7 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
PartialDiagnostic(diag::err_function_template_spec_no_match)
<< FD->getDeclName(),
PartialDiagnostic(diag::err_function_template_spec_ambiguous)
- << FD->getDeclName() << HasExplicitTemplateArgs,
+ << FD->getDeclName() << (ExplicitTemplateArgs != 0),
PartialDiagnostic(diag::note_function_template_spec_matched));
if (!Specialization)
return true;
@@ -3902,16 +3873,15 @@ Sema::ActOnExplicitInstantiation(Scope *S,
: TSK_ExplicitInstantiationDeclaration;
// Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
// Check that the template argument list is well-formed for this
// template.
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
TemplateArgs.size());
- if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
- TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, false, Converted))
+ if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
+ TemplateArgs, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -3992,9 +3962,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// on the "canonical" representation used to store the template
// arguments in the specialization.
QualType WrittenTy
- = Context.getTemplateSpecializationType(Name,
- TemplateArgs.data(),
- TemplateArgs.size(),
+ = Context.getTemplateSpecializationType(Name, TemplateArgs,
Context.getTypeDeclType(Specialization));
Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release();
@@ -4278,14 +4246,15 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ TemplateArgumentListInfo TemplateArgs;
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+ TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
+ TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- translateTemplateArguments(TemplateArgsPtr,
- TemplateArgs);
+ translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
HasExplicitTemplateArgs = true;
TemplateArgsPtr.release();
}
@@ -4316,8 +4285,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
- = DeduceTemplateArguments(FunTmpl, HasExplicitTemplateArgs,
- TemplateArgs.data(), TemplateArgs.size(),
+ = DeduceTemplateArguments(FunTmpl,
+ (HasExplicitTemplateArgs ? &TemplateArgs : 0),
R, Specialization, Info)) {
// FIXME: Keep track of almost-matches?
(void)TDK;