diff options
author | John McCall <rjmccall@apple.com> | 2010-11-16 10:08:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-11-16 10:08:07 +0000 |
commit | b418d74c11498b7e1044103131e2e3be4d63512e (patch) | |
tree | 36330e02a9b184864d87e3dff7fcbe0ffe68961d /lib/AST/ExprClassification.cpp | |
parent | ac21a21a49131544777f3bd56d2351a4072954ca (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.cpp | 18 |
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; |