aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TreeTransform.h
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/TreeTransform.h
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/TreeTransform.h')
-rw-r--r--lib/Sema/TreeTransform.h56
1 files changed, 29 insertions, 27 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 74e918bf86..a7dc920f84 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1373,11 +1373,13 @@ public:
assert(Member->getType()->isRecordType() &&
"unnamed member not of record type?");
- if (getSema().PerformObjectMemberConversion(Base,
- QualifierLoc.getNestedNameSpecifier(),
- FoundDecl, Member))
+ ExprResult BaseResult =
+ getSema().PerformObjectMemberConversion(Base,
+ QualifierLoc.getNestedNameSpecifier(),
+ FoundDecl, Member);
+ if (BaseResult.isInvalid())
return ExprError();
-
+ Base = BaseResult.take();
ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
MemberExpr *ME =
new (getSema().Context) MemberExpr(Base, isArrow,
@@ -1390,7 +1392,10 @@ public:
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
- getSema().DefaultFunctionArrayConversion(Base);
+ ExprResult BaseResult = getSema().DefaultFunctionArrayConversion(Base);
+ if (BaseResult.isInvalid())
+ return ExprError();
+ Base = BaseResult.take();
QualType BaseType = Base->getType();
// FIXME: this involves duplicating earlier analysis in a lot of
@@ -2060,20 +2065,20 @@ public:
bool IsArrow, bool IsFreeIvar) {
// FIXME: We lose track of the IsFreeIvar bit.
CXXScopeSpec SS;
- Expr *Base = BaseArg;
+ ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IvarLoc,
SS, 0,
false);
- if (Result.isInvalid())
+ if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/IvarLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@@ -2088,20 +2093,20 @@ public:
ObjCPropertyDecl *Property,
SourceLocation PropertyLoc) {
CXXScopeSpec SS;
- Expr *Base = BaseArg;
+ ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
Sema::LookupMemberName);
bool IsArrow = false;
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/PropertyLoc,
SS, 0, false);
- if (Result.isInvalid())
+ if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/PropertyLoc, IsArrow,
SS,
/*FirstQualifierInScope=*/0,
@@ -2132,19 +2137,19 @@ public:
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
bool IsArrow) {
CXXScopeSpec SS;
- Expr *Base = BaseArg;
+ ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IsaLoc,
SS, 0, false);
- if (Result.isInvalid())
+ if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
- return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
+ return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/IsaLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@@ -2167,28 +2172,25 @@ public:
// Build a reference to the __builtin_shufflevector builtin
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
- Expr *Callee
- = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
- VK_LValue, BuiltinLoc);
- SemaRef.UsualUnaryConversions(Callee);
+ ExprResult Callee
+ = SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
+ VK_LValue, BuiltinLoc));
+ Callee = SemaRef.UsualUnaryConversions(Callee.take());
+ if (Callee.isInvalid())
+ return ExprError();
// Build the CallExpr
unsigned NumSubExprs = SubExprs.size();
Expr **Subs = (Expr **)SubExprs.release();
- CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
+ ExprResult TheCall = SemaRef.Owned(
+ new (SemaRef.Context) CallExpr(SemaRef.Context, Callee.take(),
Subs, NumSubExprs,
Builtin->getCallResultType(),
Expr::getValueKindForType(Builtin->getResultType()),
- RParenLoc);
- ExprResult OwnedCall(SemaRef.Owned(TheCall));
+ RParenLoc));
// Type-check the __builtin_shufflevector expression.
- ExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
- if (Result.isInvalid())
- return ExprError();
-
- OwnedCall.release();
- return move(Result);
+ return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
}
/// \brief Build a new template argument pack expansion.