]> granicus.if.org Git - clang/commitdiff
implement codegen support for most unary operators when
authorChris Lattner <sabre@nondot.org>
Sat, 29 Dec 2007 23:43:37 +0000 (23:43 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 29 Dec 2007 23:43:37 +0000 (23:43 +0000)
initializing a global.  This handles important cases like:
float foo3 = -0.01f;

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45427 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CodeGenModule.cpp

index 506db8d6c60c9cff3f1a22cefe5fb3ee8f724fa8..866ba47b2a59f88e6e2aae32d393548dc9515a29 100644 (file)
@@ -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);