aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp124
1 files changed, 65 insertions, 59 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 68cb6f4dfe..7bc5904e9a 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -680,10 +680,12 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
return Param;
TemplateArgument Converted;
- if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
+ ExprResult DefaultRes = CheckTemplateArgument(Param, Param->getType(), Default, Converted);
+ if (DefaultRes.isInvalid()) {
Param->setInvalidDecl();
return Param;
}
+ Default = DefaultRes.take();
Param->setDefaultArgument(Default, false);
}
@@ -2418,9 +2420,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return true;
case TemplateArgument::Expression: {
- Expr *E = Arg.getArgument().getAsExpr();
TemplateArgument Result;
- if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK))
+ ExprResult Res =
+ CheckTemplateArgument(NTTP, NTTPType, Arg.getArgument().getAsExpr(),
+ Result, CTAK);
+ if (Res.isInvalid())
return true;
Converted.push_back(Result);
@@ -2451,23 +2455,21 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
CXXScopeSpec SS;
SS.Adopt(Arg.getTemplateQualifierLoc());
- Expr *E = DependentScopeDeclRefExpr::Create(Context,
+ ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
SS.getWithLocInContext(Context),
- NameInfo);
+ NameInfo));
// If we parsed the template argument as a pack expansion, create a
// pack expansion expression.
if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
- ExprResult Expansion = ActOnPackExpansion(E,
- Arg.getTemplateEllipsisLoc());
- if (Expansion.isInvalid())
+ E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
+ if (E.isInvalid())
return true;
-
- E = Expansion.get();
}
TemplateArgument Result;
- if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
+ E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
+ if (E.isInvalid())
return true;
Converted.push_back(Result);
@@ -3389,15 +3391,14 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
/// non-type template parameter.
///
/// This routine implements the semantics of C++ [temp.arg.nontype].
-/// It returns true if an error occurred, and false otherwise. \p
+/// If an error occurred, it returns ExprError(); otherwise, it
+/// returns the converted template argument. \p
/// InstantiatedParamType is the type of the non-type template
/// parameter after it has been instantiated.
-///
-/// If no error was detected, Converted receives the converted template argument.
-bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
- QualType InstantiatedParamType, Expr *&Arg,
- TemplateArgument &Converted,
- CheckTemplateArgumentKind CTAK) {
+ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
+ QualType InstantiatedParamType, Expr *Arg,
+ TemplateArgument &Converted,
+ CheckTemplateArgumentKind CTAK) {
SourceLocation StartLoc = Arg->getSourceRange().getBegin();
// If either the parameter has a dependent type or the argument is
@@ -3405,7 +3406,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
// FIXME: Produce a cloned, canonical expression?
Converted = TemplateArgument(Arg);
- return false;
+ return Owned(Arg);
}
// C++ [temp.arg.nontype]p5:
@@ -3435,12 +3436,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
diag::err_template_arg_not_integral_or_enumeral)
<< ArgType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+ return ExprError();
} else if (!Arg->isValueDependent() &&
!Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) {
Diag(NonConstantLoc, diag::err_template_arg_not_ice)
<< ArgType << Arg->getSourceRange();
- return true;
+ return ExprError();
}
// From here on out, all we care about are the unqualified forms
@@ -3463,21 +3464,21 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
<< ArgType << ParamType;
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+ return ExprError();
} else if (ParamType->isBooleanType()) {
// This is an integral-to-boolean conversion.
- ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean);
+ Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
} else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
!ParamType->isEnumeralType()) {
// This is an integral promotion or conversion.
- ImpCastExprToType(Arg, ParamType, CK_IntegralCast);
+ Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+ return ExprError();
}
QualType IntegerType = Context.getCanonicalType(ParamType);
@@ -3527,13 +3528,13 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// The argument is value-dependent. Create a new
// TemplateArgument with the converted expression.
Converted = TemplateArgument(Arg);
- return false;
+ return Owned(Arg);
}
Converted = TemplateArgument(Value,
ParamType->isEnumeralType() ? ParamType
: IntegerType);
- return false;
+ return Owned(Arg);
}
DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction
@@ -3545,7 +3546,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (ArgType->isNullPtrType() &&
(ParamType->isPointerType() || ParamType->isMemberPointerType())) {
Converted = TemplateArgument((NamedDecl *)0);
- return false;
+ return Owned(Arg);
}
// Handle pointer-to-function, reference-to-function, and
@@ -3577,22 +3578,25 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
- return true;
+ return ExprError();
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
ArgType = Arg->getType();
} else
- return true;
+ return ExprError();
}
- if (!ParamType->isMemberPointerType())
- return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
- ParamType,
- Arg, Converted);
+ if (!ParamType->isMemberPointerType()) {
+ if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+ ParamType,
+ Arg, Converted))
+ return ExprError();
+ return Owned(Arg);
+ }
if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(),
false)) {
- ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
+ Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take();
} else if (!Context.hasSameUnqualifiedType(ArgType,
ParamType.getNonReferenceType())) {
// We can't perform this conversion.
@@ -3600,10 +3604,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+ return ExprError();
}
- return CheckTemplateArgumentPointerToMember(Arg, Converted);
+ if (CheckTemplateArgumentPointerToMember(Arg, Converted))
+ return ExprError();
+ return Owned(Arg);
}
if (ParamType->isPointerType()) {
@@ -3614,9 +3620,11 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
"Only object pointers allowed here");
- return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
- ParamType,
- Arg, Converted);
+ if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+ ParamType,
+ Arg, Converted))
+ return ExprError();
+ return Owned(Arg);
}
if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
@@ -3635,17 +3643,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
- return true;
+ return ExprError();
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
ArgType = Arg->getType();
} else
- return true;
+ return ExprError();
}
- return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
- ParamType,
- Arg, Converted);
+ if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
+ ParamType,
+ Arg, Converted))
+ return ExprError();
+ return Owned(Arg);
}
// -- For a non-type template-parameter of type pointer to data
@@ -3655,17 +3665,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
// Types match exactly: nothing more to do here.
} else if (IsQualificationConversion(ArgType, ParamType, false)) {
- ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
+ Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take();
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+ return ExprError();
}
- return CheckTemplateArgumentPointerToMember(Arg, Converted);
+ if (CheckTemplateArgumentPointerToMember(Arg, Converted))
+ return ExprError();
+ return Owned(Arg);
}
/// \brief Check a template argument against its corresponding
@@ -3759,11 +3771,8 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
// the element type on the parameter could be more qualified than the
// element type in the expression we constructed.
if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
- ParamType.getUnqualifiedType(), false)) {
- Expr *RefE = RefExpr.takeAs<Expr>();
- ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
- RefExpr = Owned(RefE);
- }
+ ParamType.getUnqualifiedType(), false))
+ RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
assert(!RefExpr.isInvalid() &&
Context.hasSameType(((Expr*) RefExpr.get())->getType(),
@@ -3782,12 +3791,9 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
if (T->isFunctionType() || T->isArrayType()) {
// Decay functions and arrays.
- Expr *RefE = (Expr *)RefExpr.get();
- DefaultFunctionArrayConversion(RefE);
- if (RefE != RefExpr.get()) {
- RefExpr.release();
- RefExpr = Owned(RefE);
- }
+ RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
+ if (RefExpr.isInvalid())
+ return ExprError();
return move(RefExpr);
}