diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-10-30 22:53:42 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-10-30 22:53:42 +0000 |
| commit | 595db86c9dc8d5fea20de1ae7387d7f030cb7ab8 (patch) | |
| tree | 9b56e54e1a06eed613977762e168c82ecb17a33b /clang | |
| parent | c2dbfee43f87012155fd860e6f67051af817a677 (diff) | |
| download | bcm5719-llvm-595db86c9dc8d5fea20de1ae7387d7f030cb7ab8.tar.gz bcm5719-llvm-595db86c9dc8d5fea20de1ae7387d7f030cb7ab8.zip | |
__real__ and __imag__ can be lvalues. Add support to ast and codegen for them.
llvm-svn: 43525
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/AST/Expr.cpp | 9 | ||||
| -rw-r--r-- | clang/CodeGen/CGExpr.cpp | 18 | ||||
| -rw-r--r-- | clang/test/CodeGen/complex.c | 9 |
3 files changed, 31 insertions, 5 deletions
diff --git a/clang/AST/Expr.cpp b/clang/AST/Expr.cpp index 0c631df5c04..b21aad20cee 100644 --- a/clang/AST/Expr.cpp +++ b/clang/AST/Expr.cpp @@ -278,6 +278,7 @@ bool Expr::hasLocalSideEffect() const { /// - e->name /// - *e, the type of e cannot be a function type /// - string-constant +/// - (__real__ e) and (__imag__ e) where e is an lvalue [GNU extension] /// - reference type [C++ [expr]] /// Expr::isLvalueResult Expr::isLvalue() const { @@ -307,9 +308,13 @@ Expr::isLvalueResult Expr::isLvalue() const { const MemberExpr *m = cast<MemberExpr>(this); return m->isArrow() ? LV_Valid : m->getBase()->isLvalue(); } - case UnaryOperatorClass: // C99 6.5.3p4 + case UnaryOperatorClass: if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Deref) - return LV_Valid; + return LV_Valid; // C99 6.5.3p4 + + if (cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Real || + cast<UnaryOperator>(this)->getOpcode() == UnaryOperator::Imag) + return cast<UnaryOperator>(this)->getSubExpr()->isLvalue(); // GNU. break; case ParenExprClass: // C99 6.5.1p5 return cast<ParenExpr>(this)->getSubExpr()->isLvalue(); diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp index a0ef03bdc8c..b996ecacda5 100644 --- a/clang/CodeGen/CGExpr.cpp +++ b/clang/CodeGen/CGExpr.cpp @@ -283,9 +283,21 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) { if (E->getOpcode() == UnaryOperator::Extension) return EmitLValue(E->getSubExpr()); - assert(E->getOpcode() == UnaryOperator::Deref && - "'*' is the only unary operator that produces an lvalue"); - return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr())); + switch (E->getOpcode()) { + default: assert(0 && "Unknown unary operator lvalue!"); + case UnaryOperator::Deref: + return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr())); + case UnaryOperator::Real: + case UnaryOperator::Imag: + LValue LV = EmitLValue(E->getSubExpr()); + + llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); + llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, + E->getOpcode() == UnaryOperator::Imag); + llvm::Value *Ops[] = {Zero, Idx}; + return LValue::MakeAddr(Builder.CreateGEP(LV.getAddress(), Ops, Ops+2, + "idx")); + } } LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) { diff --git a/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c index 3ac04218cce..0cc002bc6d6 100644 --- a/clang/test/CodeGen/complex.c +++ b/clang/test/CodeGen/complex.c @@ -37,3 +37,12 @@ void test3() { g1 = g1 + D; g1 = D + g1; } + +void t1() { + (__real__ cf) = 4.0; +} + +void t2() { + (__imag__ cf) = 4.0; +} + |

