aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprClassification.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-11-16 10:08:07 +0000
committerJohn McCall <rjmccall@apple.com>2010-11-16 10:08:07 +0000
commitb418d74c11498b7e1044103131e2e3be4d63512e (patch)
tree36330e02a9b184864d87e3dff7fcbe0ffe68961d /lib/AST/ExprClassification.cpp
parentac21a21a49131544777f3bd56d2351a4072954ca (diff)
Simplify some complex emission and implement correct semantics for
assignment to volatiles in C. This in effect reverts some of mjs's work in and around r72572. Basically, the C++ standard is quite clear, except that it lies about volatile behavior approximating C's, whereas the C standard is almost actively misleading. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119344 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprClassification.cpp')
-rw-r--r--lib/AST/ExprClassification.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 1daa475b9e..60fbfd298f 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -171,11 +171,23 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
return Cl::CL_LValue;
// GNU extensions, simply look through them.
- case UO_Real:
- case UO_Imag:
case UO_Extension:
return ClassifyInternal(Ctx, cast<UnaryOperator>(E)->getSubExpr());
+ // Treat _Real and _Imag basically as if they were member
+ // expressions: l-value only if the operand is a true l-value.
+ case UO_Real:
+ case UO_Imag: {
+ const Expr *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
+ Cl::Kinds K = ClassifyInternal(Ctx, Op);
+ if (K != Cl::CL_LValue) return K;
+
+ if (isa<ObjCPropertyRefExpr>(Op) ||
+ isa<ObjCImplicitSetterGetterRefExpr>(Op))
+ return Cl::CL_SubObjCPropertySetting;
+ return Cl::CL_LValue;
+ }
+
// C++ [expr.pre.incr]p1: The result is the updated operand; it is an
// lvalue, [...]
// Not so in C.
@@ -343,7 +355,7 @@ static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) {
if (E->isArrow())
return Cl::CL_LValue;
// ObjC property accesses are not lvalues, but get special treatment.
- Expr *Base = E->getBase();
+ Expr *Base = E->getBase()->IgnoreParens();
if (isa<ObjCPropertyRefExpr>(Base) ||
isa<ObjCImplicitSetterGetterRefExpr>(Base))
return Cl::CL_SubObjCPropertySetting;