aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@boostpro.com>2011-04-08 18:41:53 +0000
committerJohn Wiegley <johnw@boostpro.com>2011-04-08 18:41:53 +0000
commit429bb276991ff2dbc7c5b438828b9b7737cb15eb (patch)
tree14890bc7a1e5bb1c92d25f58a67daec2a16c28e0 /lib/Sema/SemaOverload.cpp
parentb7bc34a83aff8af09f2a78aa6d1dcafe18ad8619 (diff)
Use ExprResult& instead of Expr *& in Sema
This patch authored by Eric Niebler. Many methods on the Sema class (e.g. ConvertPropertyForRValue) take Expr pointers as in/out parameters (Expr *&). This is especially true for the routines that apply implicit conversions to nodes in-place. This design is workable only as long as those conversions cannot fail. If they are allowed to fail, they need a way to report their failures. The typical way of doing this in clang is to use an ExprResult, which has an extra bit to signal a valid/invalid state. Returning ExprResult is de riguour elsewhere in the Sema interface. We suggest changing the Expr *& parameters in the Sema interface to ExprResult &. This increases interface consistency and maintainability. This interface change is important for work supporting MS-style C++ properties. For reasons explained here <http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-February/013180.html>, seemingly trivial operations like rvalue/lvalue conversions that formerly could not fail now can. (The reason is that given the semantics of the feature, getter/setter method lookup cannot happen until the point of use, at which point it may be found that the method does not exist, or it may have the wrong type, or overload resolution may fail, or it may be inaccessible.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129143 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp338
1 files changed, 208 insertions, 130 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 5b444c14d6..3212c36b9a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -36,12 +36,14 @@ using namespace sema;
/// A convenience routine for creating a decayed reference to a
/// function.
-static Expr *
+static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn,
SourceLocation Loc = SourceLocation()) {
- Expr *E = new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc);
- S.DefaultFunctionArrayConversion(E);
- return E;
+ ExprResult E = S.Owned(new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc));
+ E = S.DefaultFunctionArrayConversion(E.take());
+ if (E.isInvalid())
+ return ExprError();
+ return move(E);
}
static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
@@ -886,20 +888,19 @@ bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
}
/// PerformImplicitConversion - Perform an implicit conversion of the
-/// expression From to the type ToType. Returns true if there was an
-/// error, false otherwise. The expression From is replaced with the
+/// expression From to the type ToType. Returns the
/// converted expression. Flavor is the kind of conversion we're
/// performing, used in the error message. If @p AllowExplicit,
/// explicit user-defined conversions are permitted.
-bool
-Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+ExprResult
+Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit) {
ImplicitConversionSequence ICS;
return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS);
}
-bool
-Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
+ExprResult
+Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
ICS = clang::TryImplicitConversion(*this, From, ToType,
@@ -3525,8 +3526,8 @@ TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
/// PerformObjectArgumentInitialization - Perform initialization of
/// the implicit object parameter for the given Method with the given
/// expression.
-bool
-Sema::PerformObjectArgumentInitialization(Expr *&From,
+ExprResult
+Sema::PerformObjectArgumentInitialization(Expr *From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
@@ -3562,7 +3563,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
<< From->getSourceRange();
Diag(Method->getLocation(), diag::note_previous_decl)
<< Method->getDeclName();
- return true;
+ return ExprError();
}
}
@@ -3571,13 +3572,18 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
}
- if (ICS.Standard.Second == ICK_Derived_To_Base)
- return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
+ if (ICS.Standard.Second == ICK_Derived_To_Base) {
+ ExprResult FromRes =
+ PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
+ if (FromRes.isInvalid())
+ return ExprError();
+ From = FromRes.take();
+ }
if (!Context.hasSameType(From->getType(), DestType))
- ImpCastExprToType(From, DestType, CK_NoOp,
- From->getType()->isPointerType() ? VK_RValue : VK_LValue);
- return false;
+ From = ImpCastExprToType(From, DestType, CK_NoOp,
+ From->getType()->isPointerType() ? VK_RValue : VK_LValue).take();
+ return Owned(From);
}
/// TryContextuallyConvertToBool - Attempt to contextually convert the
@@ -3595,7 +3601,7 @@ TryContextuallyConvertToBool(Sema &S, Expr *From) {
/// PerformContextuallyConvertToBool - Perform a contextual conversion
/// of the expression From to bool (C++0x [conv]p3).
-bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
+ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) {
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
@@ -3604,7 +3610,7 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
- return true;
+ return ExprError();
}
/// TryContextuallyConvertToObjCId - Attempt to contextually convert the
@@ -3622,12 +3628,12 @@ TryContextuallyConvertToObjCId(Sema &S, Expr *From) {
/// PerformContextuallyConvertToObjCId - Perform a contextual conversion
/// of the expression From to 'id'.
-bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
+ExprResult Sema::PerformContextuallyConvertToObjCId(Expr *From) {
QualType Ty = Context.getObjCIdType();
ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Ty, ICS, AA_Converting);
- return true;
+ return ExprError();
}
/// \brief Attempt to convert the given expression to an integral or
@@ -7565,19 +7571,20 @@ ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
assert(SrcExpr->getType() == Context.OverloadTy);
DeclAccessPair Found;
- Expr* SingleFunctionExpression = 0;
+ ExprResult SingleFunctionExpression;
if (FunctionDecl* Fn = ResolveSingleFunctionTemplateSpecialization(
SrcExpr, false, // false -> Complain
&Found)) {
if (!DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) {
// mark the expression as resolved to Fn
- SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr,
- Found, Fn);
+ SingleFunctionExpression = Owned(FixOverloadedFunctionReference(SrcExpr,
+ Found, Fn));
if (DoFunctionPointerConverion)
- DefaultFunctionArrayLvalueConversion(SingleFunctionExpression);
+ SingleFunctionExpression =
+ DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.take());
}
}
- if (!SingleFunctionExpression) {
+ if (!SingleFunctionExpression.isUsable()) {
if (Complain) {
OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
@@ -7847,8 +7854,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// TODO: provide better source location info.
DeclarationNameInfo OpNameInfo(OpName, OpLoc);
- if (Input->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Input);
+ if (Input->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = ConvertPropertyForRValue(Input);
+ if (Result.isInvalid())
+ return ExprError();
+ Input = Result.take();
+ }
Expr *Args[2] = { Input, 0 };
unsigned NumArgs = 1;
@@ -7919,9 +7930,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl);
- if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
- Best->FoundDecl, Method))
+ ExprResult InputRes =
+ PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
+ Best->FoundDecl, Method);
+ if (InputRes.isInvalid())
return ExprError();
+ Input = InputRes.take();
} else {
// Convert the arguments.
ExprResult InputInit
@@ -7943,11 +7957,13 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
- Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl);
+ ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl);
+ if (FnExpr.isInvalid())
+ return ExprError();
Args[0] = Input;
CallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
Args, NumArgs, ResultTy, VK, OpLoc);
if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
@@ -7959,38 +7975,40 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
- if (PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0],
- Best->Conversions[0], AA_Passing))
- return ExprError();
-
- break;
- }
- }
-
- case OR_No_Viable_Function:
- // No viable function; fall through to handling this as a
- // built-in operator, which will produce an error message for us.
+ ExprResult InputRes =
+ PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0],
+ Best->Conversions[0], AA_Passing);
+ if (InputRes.isInvalid())
+ return ExprError();
+ Input = InputRes.take();
break;
+ }
+ }
- case OR_Ambiguous:
- Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
- << UnaryOperator::getOpcodeStr(Opc)
- << Input->getType()
- << Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
- Args, NumArgs,
- UnaryOperator::getOpcodeStr(Opc), OpLoc);
- return ExprError();
+ case OR_No_Viable_Function:
+ // No viable function; fall through to handling this as a
+ // built-in operator, which will produce an error message for us.
+ break;
- case OR_Deleted:
- Diag(OpLoc, diag::err_ovl_deleted_oper)
- << Best->Function->isDeleted()
+ case OR_Ambiguous:
+ Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
<< UnaryOperator::getOpcodeStr(Opc)
- << getDeletedOrUnavailableSuffix(Best->Function)
+ << Input->getType()
<< Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
- return ExprError();
- }
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
+ Args, NumArgs,
+ UnaryOperator::getOpcodeStr(Opc), OpLoc);
+ return ExprError();
+
+ case OR_Deleted:
+ Diag(OpLoc, diag::err_ovl_deleted_oper)
+ << Best->Function->isDeleted()
+ << UnaryOperator::getOpcodeStr(Opc)
+ << getDeletedOrUnavailableSuffix(Best->Function)
+ << Input->getSourceRange();
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
+ return ExprError();
+ }
// Either we found no viable overloaded operator or we matched a
// built-in operator. In either case, fall through to trying to
@@ -8065,8 +8083,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
}
// Always do property rvalue conversions on the RHS.
- if (Args[1]->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Args[1]);
+ if (Args[1]->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = ConvertPropertyForRValue(Args[1]);
+ if (Result.isInvalid())
+ return ExprError();
+ Args[1] = Result.take();
+ }
// The LHS is more complicated.
if (Args[0]->getObjectKind() == OK_ObjCProperty) {
@@ -8094,7 +8116,10 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
- ConvertPropertyForRValue(Args[0]);
+ ExprResult Result = ConvertPropertyForRValue(Args[0]);
+ if (Result.isInvalid())
+ return ExprError();
+ Args[0] = Result.take();
}
// If this is the assignment operator, we only perform overload resolution
@@ -8155,10 +8180,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Arg1.isInvalid())
return ExprError();
- if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
- Best->FoundDecl, Method))
+ ExprResult Arg0 =
+ PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ Best->FoundDecl, Method);
+ if (Arg0.isInvalid())
return ExprError();
-
+ Args[0] = Arg0.takeAs<Expr>();
Args[1] = RHS = Arg1.takeAs<Expr>();
} else {
// Convert the arguments.
@@ -8188,10 +8215,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
- Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc);
+ ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc);
+ if (FnExpr.isInvalid())
+ return ExprError();
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
Args, 2, ResultTy, VK, OpLoc);
if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
@@ -8203,12 +8232,19 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
- if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
- Best->Conversions[0], AA_Passing) ||
- PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
- Best->Conversions[1], AA_Passing))
+ ExprResult ArgsRes0 =
+ PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
+ Best->Conversions[0], AA_Passing);
+ if (ArgsRes0.isInvalid())
return ExprError();
+ Args[0] = ArgsRes0.take();
+ ExprResult ArgsRes1 =
+ PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
+ Best->Conversions[1], AA_Passing);
+ if (ArgsRes1.isInvalid())
+ return ExprError();
+ Args[1] = ArgsRes1.take();
break;
}
}
@@ -8297,10 +8333,18 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
RLoc));
}
- if (Args[0]->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Args[0]);
- if (Args[1]->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Args[1]);
+ if (Args[0]->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = ConvertPropertyForRValue(Args[0]);
+ if (Result.isInvalid())
+ return ExprError();
+ Args[0] = Result.take();
+ }
+ if (Args[1]->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = ConvertPropertyForRValue(Args[1]);
+ if (Result.isInvalid())
+ return ExprError();
+ Args[1] = Result.take();
+ }
// Build an empty overload set.
OverloadCandidateSet CandidateSet(LLoc);
@@ -8331,9 +8375,12 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
- if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
- Best->FoundDecl, Method))
+ ExprResult Arg0 =
+ PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ Best->FoundDecl, Method);
+ if (Arg0.isInvalid())
return ExprError();
+ Args[0] = Arg0.take();
// Convert the arguments.
ExprResult InputInit
@@ -8353,11 +8400,13 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
- Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc);
+ ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc);
+ if (FnExpr.isInvalid())
+ return ExprError();
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
- FnExpr, Args, 2,
+ FnExpr.take(), Args, 2,
ResultTy, VK, RLoc);
if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
@@ -8369,11 +8418,19 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
- if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
- Best->Conversions[0], AA_Passing) ||
- PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
- Best->Conversions[1], AA_Passing))
+ ExprResult ArgsRes0 =
+ PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
+ Best->Conversions[0], AA_Passing);
+ if (ArgsRes0.isInvalid())
return ExprError();
+ Args[0] = ArgsRes0.take();
+
+ ExprResult ArgsRes1 =
+ PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
+ Best->Conversions[1], AA_Passing);
+ if (ArgsRes1.isInvalid())
+ return ExprError();
+ Args[1] = ArgsRes1.take();
break;
}
@@ -8559,12 +8616,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Convert the object argument (for a non-static member function call).
// We only need to do this if there was actually an overload; otherwise
// it was done at lookup.
- Expr *ObjectArg = MemExpr->getBase();
- if (!Method->isStatic() &&
- PerformObjectArgumentInitialization(ObjectArg, Qualifier,
- FoundDecl, Method))
- return ExprError();
- MemExpr->setBase(ObjectArg);
+ if (!Method->isStatic()) {
+ ExprResult ObjectArg =
+ PerformObjectArgumentInitialization(MemExpr->getBase(), Qualifier,
+ FoundDecl, Method);
+ if (ObjectArg.isInvalid())
+ return ExprError();
+ MemExpr->setBase(ObjectArg.take());
+ }
// Convert the rest of the arguments
const FunctionProtoType *Proto =
@@ -8584,15 +8643,19 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
/// overloaded function call operator (@c operator()) or performing a
/// user-defined conversion on the object argument.
ExprResult
-Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
+Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc) {
- if (Object->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Object);
+ ExprResult Object = Owned(Obj);
+ if (Object.get()->getObjectKind() == OK_ObjCProperty) {
+ Object = ConvertPropertyForRValue(Object.take());
+ if (Object.isInvalid())
+ return ExprError();
+ }
- assert(Object->getType()->isRecordType() && "Requires object type argument");
- const RecordType *Record = Object->getType()->getAs<RecordType>();
+ assert(Object.get()->getType()->isRecordType() && "Requires object type argument");
+ const RecordType *Record = Object.get()->getType()->getAs<RecordType>();
// C++ [over.call.object]p1:
// If the primary-expression E in the function call syntax
@@ -8604,9 +8667,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
OverloadCandidateSet CandidateSet(LParenLoc);
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
- if (RequireCompleteType(LParenLoc, Object->getType(),
+ if (RequireCompleteType(LParenLoc, Object.get()->getType(),
PDiag(diag::err_incomplete_object_call)
- << Object->getSourceRange()))
+ << Object.get()->getSourceRange()))
return true;
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
@@ -8615,8 +8678,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
- AddMethodCandidate(Oper.getPair(), Object->getType(),
- Object->Classify(Context), Args, NumArgs, CandidateSet,
+ AddMethodCandidate(Oper.getPair(), Object.get()->getType(),
+ Object.get()->Classify(Context), Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/ false);
}
@@ -8661,12 +8724,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (const FunctionProtoType *Proto = ConvType->getAs<FunctionProtoType>())
AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto,
- Object, Args, NumArgs, CandidateSet);
+ Object.get(), Args, NumArgs, CandidateSet);
}
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
- switch (CandidateSet.BestViableFunction(*this, Object->getLocStart(),
+ switch (CandidateSet.BestViableFunction(*this, Object.get()->getLocStart(),
Best)) {
case OR_Success:
// Overload resolution succeeded; we'll build the appropriate call
@@ -8675,30 +8738,30 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
case OR_No_Viable_Function:
if (CandidateSet.empty())
- Diag(Object->getSourceRange().getBegin(), diag::err_ovl_no_oper)
- << Object->getType() << /*call*/ 1
- << Object->getSourceRange();
+ Diag(Object.get()->getSourceRange().getBegin(), diag::err_ovl_no_oper)
+ << Object.get()->getType() << /*call*/ 1
+ << Object.get()->getSourceRange();
else
- Diag(Object->getSourceRange().getBegin(),
+ Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_no_viable_object_call)
- << Object->getType() << Object->getSourceRange();
+ << Object.get()->getType() << Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Ambiguous:
- Diag(Object->getSourceRange().getBegin(),
+ Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_ambiguous_object_call)
- << Object->getType() << Object->getSourceRange();
+ << Object.get()->getType() << Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_Deleted:
- Diag(Object->getSourceRange().getBegin(),
+ Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_deleted_object_call)
<< Best->Function->isDeleted()
- << Object->getType()
+ << Object.get()->getType()
<< getDeletedOrUnavailableSuffix(Best->Function)
- << Object->getSourceRange();
+ << Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
}
@@ -8713,7 +8776,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
= cast<CXXConversionDecl>(
Best->Conversions[0].UserDefined.ConversionFunction);
- CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+ CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
// We selected one of the surrogate functions that converts the
@@ -8722,7 +8785,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Create an implicit member expr to refer to the conversion operator.
// and then call it.
- ExprResult Call = BuildCXXMemberCallExpr(Object, Best->FoundDecl, Conv);
+ ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl, Conv);
if (Call.isInvalid())
return ExprError();
@@ -8731,7 +8794,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
}
MarkDeclarationReferenced(LParenLoc, Best->Function);
- CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
+ CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
// We found an overloaded operator(). Build a CXXOperatorCallExpr
@@ -8754,11 +8817,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
} else {
MethodArgs = new Expr*[NumArgs + 1];
}
- MethodArgs[0] = Object;
+ MethodArgs[0] = Object.get();
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
MethodArgs[ArgIdx + 1] = Args[ArgIdx];
- Expr *NewFn = CreateFunctionRefExpr(*this, Method);
+ ExprResult NewFn = CreateFunctionRefExpr(*this, Method);
+ if (NewFn.isInvalid())
+ return true;
// Once we've built TheCall, all of the expressions are properly
// owned.
@@ -8767,7 +8832,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+ new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn.take(),
MethodArgs, NumArgs + 1,
ResultTy, VK, RParenLoc);
delete [] MethodArgs;
@@ -8786,10 +8851,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
bool IsError = false;
// Initialize the implicit object parameter.
- IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
- Best->FoundDecl, Method);
- TheCall->setArg(0, Object);
-
+ ExprResult ObjRes =
+ PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/0,
+ Best->FoundDecl, Method);
+ if (ObjRes.isInvalid())
+ IsError = true;
+ else
+ Object = move(ObjRes);
+ TheCall->setArg(0, Object.take());
// Check the argument types.
for (unsigned i = 0; i != NumArgsToCheck; i++) {
@@ -8825,9 +8894,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (Proto->isVariadic()) {
// Promote the arguments (C99 6.5.2.2p7).
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
- Expr *Arg = Args[i];
- IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod, 0);
- TheCall->setArg(i + 1, Arg);
+ ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
+ IsError |= Arg.isInvalid();
+ TheCall->setArg(i + 1, Arg.take());
}
}
@@ -8847,8 +8916,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
assert(Base->getType()->isRecordType() &&
"left-hand side must have class type");
- if (Base->getObjectKind() == OK_ObjCProperty)
- ConvertPropertyForRValue(Base);
+ if (Base->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = ConvertPropertyForRValue(Base);
+ if (Result.isInvalid())
+ return ExprError();
+ Base = Result.take();
+ }
SourceLocation Loc = Base->getExprLoc();
@@ -8917,18 +8990,23 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
- if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
- Best->FoundDecl, Method))
+ ExprResult BaseResult =
+ PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
+ Best->FoundDecl, Method);
+ if (BaseResult.isInvalid())
return ExprError();
+ Base = BaseResult.take();
// Build the operator call.
- Expr *FnExpr = CreateFunctionRefExpr(*this, Method);
+ ExprResult FnExpr = CreateFunctionRefExpr(*this, Method);
+ if (FnExpr.isInvalid())
+ return ExprError();
QualType ResultTy = Method->getResultType();
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
+ new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(),
&Base, 1, ResultTy, VK, OpLoc);
if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,