diff options
| author | Chris Lattner <sabre@nondot.org> | 2007-12-29 23:43:37 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2007-12-29 23:43:37 +0000 |
| commit | a77acbdcae573f9094fc9cd4df746ece8d85d4ef (patch) | |
| tree | b07e87c05f697da94be6eb19ec477187860853a0 /clang/CodeGen/CodeGenModule.cpp | |
| parent | 6787a45a65061e9cc4e73d95499df23d02c162fa (diff) | |
| download | bcm5719-llvm-a77acbdcae573f9094fc9cd4df746ece8d85d4ef.tar.gz bcm5719-llvm-a77acbdcae573f9094fc9cd4df746ece8d85d4ef.zip | |
implement codegen support for most unary operators when
initializing a global. This handles important cases like:
float foo3 = -0.01f;
llvm-svn: 45427
Diffstat (limited to 'clang/CodeGen/CodeGenModule.cpp')
| -rw-r--r-- | clang/CodeGen/CodeGenModule.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/clang/CodeGen/CodeGenModule.cpp b/clang/CodeGen/CodeGenModule.cpp index 506db8d6c60..866ba47b2a5 100644 --- a/clang/CodeGen/CodeGenModule.cpp +++ b/clang/CodeGen/CodeGenModule.cpp @@ -424,7 +424,42 @@ static llvm::Constant *GenerateConstantExpr(const Expr *Expression, case Stmt::CastExprClass: return GenerateConstantCast(cast<CastExpr>(Expression)->getSubExpr(), type, CGM); - + case Stmt::UnaryOperatorClass: { + const UnaryOperator *Op = cast<UnaryOperator>(Expression); + llvm::Constant *SubExpr = GenerateConstantExpr(Op->getSubExpr(), CGM); + // FIXME: These aren't right for complex. + switch (Op->getOpcode()) { + default: break; + case UnaryOperator::Plus: + case UnaryOperator::Extension: + return SubExpr; + case UnaryOperator::Minus: + return llvm::ConstantExpr::getNeg(SubExpr); + case UnaryOperator::Not: + return llvm::ConstantExpr::getNot(SubExpr); + case UnaryOperator::LNot: + if (Op->getSubExpr()->getType()->isRealFloatingType()) { + // Compare against 0.0 for fp scalars. + llvm::Constant *Zero = llvm::Constant::getNullValue(SubExpr->getType()); + SubExpr = llvm::ConstantExpr::getFCmp(llvm::FCmpInst::FCMP_UNE, SubExpr, + Zero); + } else { + assert((Op->getSubExpr()->getType()->isIntegerType() || + Op->getSubExpr()->getType()->isPointerType()) && + "Unknown scalar type to convert"); + // Compare against an integer or pointer null. + llvm::Constant *Zero = llvm::Constant::getNullValue(SubExpr->getType()); + SubExpr = llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, SubExpr, + Zero); + } + + return llvm::ConstantExpr::getZExt(SubExpr, Types.ConvertType(type)); + //SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator. + //Real, Imag, // "__real expr"/"__imag expr" Extension. + //OffsetOf // __builtin_offsetof + } + break; + } case Stmt::ImplicitCastExprClass: { const ImplicitCastExpr *ICExpr = cast<ImplicitCastExpr>(Expression); |

