aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-12-06 20:48:59 +0000
committerJohn McCall <rjmccall@apple.com>2010-12-06 20:48:59 +0000
commit409fa9ab9579de04c5d68fb6a6a8d094545b1e77 (patch)
tree4c6d4e87647e7c2476257e118a3041fdea47a695 /lib/Sema/SemaExpr.cpp
parent1ba14c6efdaf7e12a9ccae3fe21d7c5fa20981cd (diff)
Split out a function to do lvalue conversion on objects; this is basically
FunctionArrayLvalueConversion but without the function/array decay. Generally this is only appropriate for use sites that know the type of the expression and thus that it can't be subject to the decays. Also make sure we do lvalue-to-rvalue on the bases of ivar references. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp93
1 files changed, 51 insertions, 42 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bc8a7527c8..a1ea57ebcf 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -244,53 +244,57 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
}
}
-void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
- DefaultFunctionArrayConversion(E);
-
+void Sema::DefaultLvalueConversion(Expr *&E) {
// C++ [conv.lval]p1:
// A glvalue of a non-function, non-array type T can be
// converted to a prvalue.
- if (E->isGLValue()) {
- QualType T = E->getType();
- assert(!T.isNull() && "r-value conversion on typeless expression?");
+ if (!E->isGLValue()) return;
- // Create a load out of an ObjCProperty l-value, if necessary.
- if (E->getObjectKind() == OK_ObjCProperty) {
- ConvertPropertyForRValue(E);
- if (!E->isGLValue())
- return;
- }
+ QualType T = E->getType();
+ assert(!T.isNull() && "r-value conversion on typeless expression?");
- // We don't want to throw lvalue-to-rvalue casts on top of
- // expressions of certain types in C++.
- if (getLangOptions().CPlusPlus &&
- (E->getType() == Context.OverloadTy ||
- T->isDependentType() ||
- T->isRecordType()))
+ // Create a load out of an ObjCProperty l-value, if necessary.
+ if (E->getObjectKind() == OK_ObjCProperty) {
+ ConvertPropertyForRValue(E);
+ if (!E->isGLValue())
return;
+ }
- // The C standard is actually really unclear on this point, and
- // DR106 tells us what the result should be but not why. It's
- // generally best to say that void just doesn't undergo
- // lvalue-to-rvalue at all.
- if (T->isVoidType())
- return;
+ // We don't want to throw lvalue-to-rvalue casts on top of
+ // expressions of certain types in C++.
+ if (getLangOptions().CPlusPlus &&
+ (E->getType() == Context.OverloadTy ||
+ T->isDependentType() ||
+ T->isRecordType()))
+ return;
- // C++ [conv.lval]p1:
- // [...] If T is a non-class type, the type of the prvalue is the
- // cv-unqualified version of T. Otherwise, the type of the
- // rvalue is T.
- //
- // C99 6.3.2.1p2:
- // If the lvalue has qualified type, the value has the unqualified
- // version of the type of the lvalue; otherwise, the value has the
- // type of the lvalue.
- if (T.hasQualifiers())
- T = T.getUnqualifiedType();
+ // The C standard is actually really unclear on this point, and
+ // DR106 tells us what the result should be but not why. It's
+ // generally best to say that void types just doesn't undergo
+ // lvalue-to-rvalue at all. Note that expressions of unqualified
+ // 'void' type are never l-values, but qualified void can be.
+ if (T->isVoidType())
+ return;
- E = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
- E, 0, VK_RValue);
- }
+ // C++ [conv.lval]p1:
+ // [...] If T is a non-class type, the type of the prvalue is the
+ // cv-unqualified version of T. Otherwise, the type of the
+ // rvalue is T.
+ //
+ // C99 6.3.2.1p2:
+ // If the lvalue has qualified type, the value has the unqualified
+ // version of the type of the lvalue; otherwise, the value has the
+ // type of the lvalue.
+ if (T.hasQualifiers())
+ T = T.getUnqualifiedType();
+
+ E = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
+ E, 0, VK_RValue);
+}
+
+void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
+ DefaultFunctionArrayConversion(E);
+ DefaultLvalueConversion(E);
}
@@ -1722,10 +1726,13 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
if (SelfExpr.isInvalid())
return ExprError();
+ Expr *SelfE = SelfExpr.take();
+ DefaultLvalueConversion(SelfE);
+
MarkDeclarationReferenced(Loc, IV);
return Owned(new (Context)
ObjCIvarRefExpr(IV, IV->getType(), Loc,
- SelfExpr.takeAs<Expr>(), true, true));
+ SelfE, true, true));
}
} else if (CurMethod->isInstanceMethod()) {
// We should warn if a local variable hides an ivar.
@@ -2672,7 +2679,7 @@ static QualType CheckRealImagOperand(Sema &S, Expr *&V, SourceLocation Loc,
// _Real and _Imag are only l-values for normal l-values.
if (V->getObjectKind() != OK_Ordinary)
- S.DefaultFunctionArrayLvalueConversion(V);
+ S.DefaultLvalueConversion(V);
// These operators return the element type of a complex type.
if (const ComplexType *CT = V->getType()->getAs<ComplexType>())
@@ -3712,6 +3719,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
<< IV->getDeclName();
}
+ if (IsArrow) DefaultLvalueConversion(BaseExpr);
+
return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(),
MemberLoc, BaseExpr,
IsArrow));
@@ -3725,7 +3734,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
if (!IsArrow && (BaseType->isObjCIdType() ||
BaseType->isObjCQualifiedIdType())) {
// This actually uses the base as an r-value.
- DefaultFunctionArrayLvalueConversion(BaseExpr);
+ DefaultLvalueConversion(BaseExpr);
assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr->getType()));
const ObjCObjectPointerType *QIdTy = BaseType->getAs<ObjCObjectPointerType>();
@@ -3779,7 +3788,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
if (const ObjCObjectPointerType *OPT =
BaseType->getAsObjCInterfacePointerType()) {
// This actually uses the base as an r-value.
- DefaultFunctionArrayLvalueConversion(BaseExpr);
+ DefaultLvalueConversion(BaseExpr);
return HandleExprPropertyRefExpr(OPT, BaseExpr, MemberName, MemberLoc,
SourceLocation(), QualType(), false);
}