[cfe-commits] r41355 - in /cfe/trunk: CodeGen/CGDecl.cpp CodeGen/CGExpr.cpp CodeGen/CGExprComplex.cpp CodeGen/CGExprScalar.cpp CodeGen/CGObjC.cpp CodeGen/CGStmt.cpp CodeGen/CodeGenFunction.h clang.xcodeproj/project.pbxproj

Chris Lattner sabre at nondot.org
Thu Aug 23 22:35:27 PDT 2007


Author: lattner
Date: Fri Aug 24 00:35:26 2007
New Revision: 41355

URL: http://llvm.org/viewvc/llvm-project?rev=41355&view=rev
Log:
completely refactor codegen of scalar expressions out into its own CGExprScalar.cpp file.

This patch temporarily breaks compound assignment operators, but greatly simplifies many
things.


Added:
    cfe/trunk/CodeGen/CGExprScalar.cpp
Modified:
    cfe/trunk/CodeGen/CGDecl.cpp
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CGExprComplex.cpp
    cfe/trunk/CodeGen/CGObjC.cpp
    cfe/trunk/CodeGen/CGStmt.cpp
    cfe/trunk/CodeGen/CodeGenFunction.h
    cfe/trunk/clang.xcodeproj/project.pbxproj

Modified: cfe/trunk/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGDecl.cpp?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/CodeGen/CGDecl.cpp Fri Aug 24 00:35:26 2007
@@ -84,8 +84,10 @@
   DMEntry = DeclPtr;
   
   // If this local has an initializer, emit it now.
-  if (const Expr *Init = D.getInit())
-    EmitStoreThroughLValue(EmitExpr(Init), LValue::MakeAddr(DeclPtr), Ty);
+  if (const Expr *Init = D.getInit()) {
+    // FIXME: This could be much better for aggregates / complex.
+    EmitStoreThroughLValue(EmitAnyExpr(Init), LValue::MakeAddr(DeclPtr), Ty);
+  }
 }
 
 /// Emit an alloca for the specified parameter and set up LocalDeclMap.

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Fri Aug 24 00:35:26 2007
@@ -411,7 +411,7 @@
   
   assert(E->getOpcode() == UnaryOperator::Deref &&
          "'*' is the only unary operator that produces an lvalue");
-  return LValue::MakeAddr(EmitExpr(E->getSubExpr()).getVal());
+  return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
@@ -468,7 +468,7 @@
 
 LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
   // The index must always be an integer, which is not an aggregate.  Emit it.
-  llvm::Value *Idx = EmitExpr(E->getIdx()).getVal();
+  llvm::Value *Idx = EmitScalarExpr(E->getIdx());
   
   // If the base is a vector type, then we are forming a vector element lvalue
   // with this subscript.
@@ -481,7 +481,7 @@
   }
   
   // The base must be a pointer, which is not an aggregate.  Emit it.
-  llvm::Value *Base = EmitExpr(E->getBase()).getVal();
+  llvm::Value *Base = EmitScalarExpr(E->getBase());
   
   // Extend or truncate the index type to 32 or 64-bits.
   QualType IdxTy  = E->getIdx()->getType();
@@ -517,7 +517,7 @@
 /// result of the expression doesn't need to be generated into memory.
 RValue CodeGenFunction::EmitAnyExpr(const Expr *E, bool NeedResult) {
   if (!hasAggregateLLVMType(E->getType()))
-    return EmitExpr(E);
+    return RValue::get(EmitScalarExpr(E));
   
   llvm::Value *DestMem = 0;
   if (NeedResult)
@@ -533,151 +533,6 @@
   return RValue::getAggregate(DestMem);
 }
 
-RValue CodeGenFunction::EmitExpr(const Expr *E) {
-  assert(E && !hasAggregateLLVMType(E->getType()) &&
-         "Invalid scalar expression to emit");
-  
-  switch (E->getStmtClass()) {
-  default:
-    fprintf(stderr, "Unimplemented expr!\n");
-    E->dump();
-    return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
-    
-  // l-values.
-  case Expr::DeclRefExprClass:
-    // DeclRef's of EnumConstantDecl's are simple rvalues.
-    if (const EnumConstantDecl *EC = 
-          dyn_cast<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
-      return RValue::get(llvm::ConstantInt::get(EC->getInitVal()));
-    return EmitLoadOfLValue(E);
-  case Expr::ArraySubscriptExprClass:
-    return EmitArraySubscriptExprRV(cast<ArraySubscriptExpr>(E));
-  case Expr::OCUVectorElementExprClass:
-    return EmitLoadOfLValue(E);
-  case Expr::PreDefinedExprClass:
-  case Expr::StringLiteralClass:
-    return RValue::get(EmitLValue(E).getAddress());
-    
-  // Leaf expressions.
-  case Expr::IntegerLiteralClass:
-    return EmitIntegerLiteral(cast<IntegerLiteral>(E)); 
-  case Expr::FloatingLiteralClass:
-    return EmitFloatingLiteral(cast<FloatingLiteral>(E));
-  case Expr::CharacterLiteralClass:
-    return EmitCharacterLiteral(cast<CharacterLiteral>(E));
-  case Expr::TypesCompatibleExprClass:
-    return EmitTypesCompatibleExpr(cast<TypesCompatibleExpr>(E));
-    
-  // Operators.  
-  case Expr::ParenExprClass:
-    return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
-  case Expr::UnaryOperatorClass:
-    return EmitUnaryOperator(cast<UnaryOperator>(E));
-  case Expr::SizeOfAlignOfTypeExprClass:
-    return EmitSizeAlignOf(cast<SizeOfAlignOfTypeExpr>(E)->getArgumentType(),
-                           E->getType(),
-                           cast<SizeOfAlignOfTypeExpr>(E)->isSizeOf());
-  case Expr::ImplicitCastExprClass:
-    return EmitImplicitCastExpr(cast<ImplicitCastExpr>(E));
-  case Expr::CastExprClass: 
-    return EmitCastExpr(cast<CastExpr>(E)->getSubExpr(), E->getType());
-  case Expr::CallExprClass:
-    return EmitCallExpr(cast<CallExpr>(E));
-  case Expr::BinaryOperatorClass:
-    return EmitBinaryOperator(cast<BinaryOperator>(E));
-  
-  case Expr::ConditionalOperatorClass:
-    return EmitConditionalOperator(cast<ConditionalOperator>(E));
-  case Expr::ChooseExprClass:
-    return EmitChooseExpr(cast<ChooseExpr>(E));
-  case Expr::ObjCStringLiteralClass:
-    return EmitObjCStringLiteral(cast<ObjCStringLiteral>(E));
-  }
-}
-
-RValue CodeGenFunction::EmitIntegerLiteral(const IntegerLiteral *E) {
-  return RValue::get(llvm::ConstantInt::get(E->getValue()));
-}
-RValue CodeGenFunction::EmitFloatingLiteral(const FloatingLiteral *E) {
-  return RValue::get(llvm::ConstantFP::get(ConvertType(E->getType()),
-                                           E->getValue()));
-}
-RValue CodeGenFunction::EmitCharacterLiteral(const CharacterLiteral *E) {
-  return RValue::get(llvm::ConstantInt::get(ConvertType(E->getType()),
-                                            E->getValue()));
-}
-
-RValue CodeGenFunction::EmitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
-  return RValue::get(llvm::ConstantInt::get(ConvertType(E->getType()),
-                                            E->typesAreCompatible()));
-}
-
-/// EmitChooseExpr - Implement __builtin_choose_expr.
-RValue CodeGenFunction::EmitChooseExpr(const ChooseExpr *E) {
-  llvm::APSInt CondVal(32);
-  bool IsConst = E->getCond()->isIntegerConstantExpr(CondVal, getContext());
-  assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
-  
-  // Emit the LHS or RHS as appropriate.
-  return EmitExpr(CondVal != 0 ? E->getLHS() : E->getRHS());
-}
-
-
-RValue CodeGenFunction::EmitArraySubscriptExprRV(const ArraySubscriptExpr *E) {
-  // Emit subscript expressions in rvalue context's.  For most cases, this just
-  // loads the lvalue formed by the subscript expr.  However, we have to be
-  // careful, because the base of a vector subscript is occasionally an rvalue,
-  // so we can't get it as an lvalue.
-  if (!E->getBase()->getType()->isVectorType())
-    return EmitLoadOfLValue(E);
-
-  // Handle the vector case.  The base must be a vector, the index must be an
-  // integer value.
-  llvm::Value *Base = EmitExpr(E->getBase()).getVal();
-  llvm::Value *Idx  = EmitExpr(E->getIdx()).getVal();
-  
-  // FIXME: Convert Idx to i32 type.
-  
-  return RValue::get(Builder.CreateExtractElement(Base, Idx, "vecext"));
-}
-
-// EmitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
-// have to handle a more broad range of conversions than explicit casts, as they
-// handle things like function to ptr-to-function decay etc.
-RValue CodeGenFunction::EmitCastExpr(const Expr *Op, QualType DestTy) {
-  RValue Src = EmitAnyExpr(Op);
-  
-  // If the destination is void, just evaluate the source.
-  if (DestTy->isVoidType())
-    return RValue::getAggregate(0);
-  
-  return EmitConversion(Src, Op->getType(), DestTy);
-}
-
-/// EmitImplicitCastExpr - Implicit casts are the same as normal casts, but also
-/// handle things like function to pointer-to-function decay, and array to
-/// pointer decay.
-RValue CodeGenFunction::EmitImplicitCastExpr(const ImplicitCastExpr *E) {
-  const Expr *Op = E->getSubExpr();
-  QualType OpTy = Op->getType().getCanonicalType();
-  
-  // If this is due to array->pointer conversion, emit the array expression as
-  // an l-value.
-  if (isa<ArrayType>(OpTy)) {
-    // FIXME: For now we assume that all source arrays map to LLVM arrays.  This
-    // will not true when we add support for VLAs.
-    llvm::Value *V = EmitLValue(Op).getAddress();  // Bitfields can't be arrays.
-    
-    assert(isa<llvm::PointerType>(V->getType()) &&
-           isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
-                                ->getElementType()) &&
-           "Doesn't support VLAs yet!");
-    llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
-    return RValue::get(Builder.CreateGEP(V, Idx0, Idx0, "arraydecay"));
-  }
-  
-  return EmitCastExpr(Op, E->getType());
-}
 
 RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
   if (const ImplicitCastExpr *IcExpr = 
@@ -689,7 +544,7 @@
         if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
           return EmitBuiltinExpr(builtinID, E);
         
-  llvm::Value *Callee = EmitExpr(E->getCallee()).getVal();
+  llvm::Value *Callee = EmitScalarExpr(E->getCallee());
   
   // The callee type will always be a pointer to function type, get the function
   // type.
@@ -756,145 +611,7 @@
 //                           Unary Operator Emission
 //===----------------------------------------------------------------------===//
 
-RValue CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) {
-  switch (E->getOpcode()) {
-  default:
-    printf("Unimplemented unary expr!\n");
-    E->dump();
-    return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
-  case UnaryOperator::PostInc:
-  case UnaryOperator::PostDec:
-  case UnaryOperator::PreInc :
-  case UnaryOperator::PreDec : return EmitUnaryIncDec(E);
-  case UnaryOperator::AddrOf : return EmitUnaryAddrOf(E);
-  case UnaryOperator::Deref  : return EmitLoadOfLValue(E);
-  case UnaryOperator::Plus   : return EmitUnaryPlus(E);
-  case UnaryOperator::Minus  : return EmitUnaryMinus(E);
-  case UnaryOperator::Not    : return EmitUnaryNot(E);
-  case UnaryOperator::LNot   : return EmitUnaryLNot(E);
-  case UnaryOperator::SizeOf :
-    return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
-  case UnaryOperator::AlignOf :
-    return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
-  // FIXME: real/imag
-  case UnaryOperator::Extension: return EmitExpr(E->getSubExpr());
-  }
-}
-
-RValue CodeGenFunction::EmitUnaryIncDec(const UnaryOperator *E) {
-  LValue LV = EmitLValue(E->getSubExpr());
-  RValue InVal = EmitLoadOfLValue(LV, E->getSubExpr()->getType());
-  
-  // We know the operand is real or pointer type, so it must be an LLVM scalar.
-  assert(InVal.isScalar() && "Unknown thing to increment");
-  llvm::Value *InV = InVal.getVal();
-
-  int AmountVal = 1;
-  if (E->getOpcode() == UnaryOperator::PreDec ||
-      E->getOpcode() == UnaryOperator::PostDec)
-    AmountVal = -1;
-  
-  llvm::Value *NextVal;
-  if (isa<llvm::IntegerType>(InV->getType())) {
-    NextVal = llvm::ConstantInt::get(InV->getType(), AmountVal);
-    NextVal = Builder.CreateAdd(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
-  } else if (InV->getType()->isFloatingPoint()) {
-    NextVal = llvm::ConstantFP::get(InV->getType(), AmountVal);
-    NextVal = Builder.CreateAdd(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
-  } else {
-    // FIXME: This is not right for pointers to VLA types.
-    assert(isa<llvm::PointerType>(InV->getType()));
-    NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
-    NextVal = Builder.CreateGEP(InV, NextVal, AmountVal == 1 ? "inc" : "dec");
-  }
-
-  RValue NextValToStore = RValue::get(NextVal);
-
-  // Store the updated result through the lvalue.
-  EmitStoreThroughLValue(NextValToStore, LV, E->getSubExpr()->getType());
-                         
-  // If this is a postinc, return the value read from memory, otherwise use the
-  // updated value.
-  if (E->getOpcode() == UnaryOperator::PreDec ||
-      E->getOpcode() == UnaryOperator::PreInc)
-    return NextValToStore;
-  else
-    return InVal;
-}
-
-/// C99 6.5.3.2
-RValue CodeGenFunction::EmitUnaryAddrOf(const UnaryOperator *E) {
-  // The address of the operand is just its lvalue.  It cannot be a bitfield.
-  return RValue::get(EmitLValue(E->getSubExpr()).getAddress());
-}
-
-RValue CodeGenFunction::EmitUnaryPlus(const UnaryOperator *E) {
-  assert(E->getType().getCanonicalType() == 
-         E->getSubExpr()->getType().getCanonicalType() && "Bad unary plus!");
-  // Unary plus just returns its value.
-  return EmitExpr(E->getSubExpr());
-}
-
-RValue CodeGenFunction::EmitUnaryMinus(const UnaryOperator *E) {
-  assert(E->getType().getCanonicalType() == 
-         E->getSubExpr()->getType().getCanonicalType() && "Bad unary minus!");
-
-  // Unary minus performs promotions, then negates its arithmetic operand.
-  RValue V = EmitExpr(E->getSubExpr());
-  
-  if (V.isScalar())
-    return RValue::get(Builder.CreateNeg(V.getVal(), "neg"));
-  
-  assert(0 && "FIXME: This doesn't handle complex operands yet");
-}
-
-RValue CodeGenFunction::EmitUnaryNot(const UnaryOperator *E) {
-  // Unary not performs promotions, then complements its integer operand.
-  RValue V = EmitExpr(E->getSubExpr());
-  
-  if (V.isScalar())
-    return RValue::get(Builder.CreateNot(V.getVal(), "neg"));
-                      
-  assert(0 && "FIXME: This doesn't handle integer complex operands yet (GNU)");
-}
-
-
-/// C99 6.5.3.3
-RValue CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) {
-  // Compare operand to zero.
-  llvm::Value *BoolVal = EvaluateExprAsBool(E->getSubExpr());
-  
-  // Invert value.
-  // TODO: Could dynamically modify easy computations here.  For example, if
-  // the operand is an icmp ne, turn into icmp eq.
-  BoolVal = Builder.CreateNot(BoolVal, "lnot");
-  
-  // ZExt result to int.
-  return RValue::get(Builder.CreateZExt(BoolVal, LLVMIntTy, "lnot.ext"));
-}
-
-/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as
-/// an integer (RetType).
-RValue CodeGenFunction::EmitSizeAlignOf(QualType TypeToSize,
-                                        QualType RetType, bool isSizeOf) {
-  /// FIXME: This doesn't handle VLAs yet!
-  std::pair<uint64_t, unsigned> Info =
-    getContext().getTypeInfo(TypeToSize, SourceLocation());
-  
-  uint64_t Val = isSizeOf ? Info.first : Info.second;
-  Val /= 8;  // Return size in bytes, not bits.
-  
-  assert(RetType->isIntegerType() && "Result type must be an integer!");
-
-  unsigned ResultWidth = getContext().getTypeSize(RetType, SourceLocation());
-  return RValue::get(llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)));
-}
-
-
-//===--------------------------------------------------------------------===//
-//                         Binary Operator Emission
-//===--------------------------------------------------------------------===//
-
+#if 0
 
 /// EmitCompoundAssignmentOperands - Compound assignment operations (like +=)
 /// are strange in that the result of the operation is not the same type as the
@@ -946,18 +663,6 @@
     fprintf(stderr, "Unimplemented binary expr!\n");
     E->dump();
     return RValue::get(llvm::UndefValue::get(llvm::Type::Int32Ty));
-  case BinaryOperator::Mul:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitMul(LHS, RHS, E->getType());
-  case BinaryOperator::Div:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitDiv(LHS, RHS, E->getType());
-  case BinaryOperator::Rem:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitRem(LHS, RHS, E->getType());
   case BinaryOperator::Add:
     LHS = EmitExpr(E->getLHS());
     RHS = EmitExpr(E->getRHS());
@@ -966,61 +671,6 @@
       
     return EmitPointerAdd(LHS, E->getLHS()->getType(),
                           RHS, E->getRHS()->getType(), E->getType());
-  case BinaryOperator::Sub:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-
-    if (!E->getLHS()->getType()->isPointerType())
-      return EmitSub(LHS, RHS, E->getType());
-      
-    return EmitPointerSub(LHS, E->getLHS()->getType(),
-                          RHS, E->getRHS()->getType(), E->getType());
-  case BinaryOperator::Shl:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitShl(LHS, RHS, E->getType());
-  case BinaryOperator::Shr:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitShr(LHS, RHS, E->getType());
-  case BinaryOperator::And:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitAnd(LHS, RHS, E->getType());
-  case BinaryOperator::Xor:
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitXor(LHS, RHS, E->getType());
-  case BinaryOperator::Or :
-    LHS = EmitExpr(E->getLHS());
-    RHS = EmitExpr(E->getRHS());
-    return EmitOr(LHS, RHS, E->getType());
-  case BinaryOperator::LAnd: return EmitBinaryLAnd(E);
-  case BinaryOperator::LOr: return EmitBinaryLOr(E);
-  case BinaryOperator::LT:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_ULT,
-                             llvm::ICmpInst::ICMP_SLT,
-                             llvm::FCmpInst::FCMP_OLT);
-  case BinaryOperator::GT:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_UGT,
-                             llvm::ICmpInst::ICMP_SGT,
-                             llvm::FCmpInst::FCMP_OGT);
-  case BinaryOperator::LE:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_ULE,
-                             llvm::ICmpInst::ICMP_SLE,
-                             llvm::FCmpInst::FCMP_OLE);
-  case BinaryOperator::GE:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_UGE,
-                             llvm::ICmpInst::ICMP_SGE,
-                             llvm::FCmpInst::FCMP_OGE);
-  case BinaryOperator::EQ:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_EQ,
-                             llvm::ICmpInst::ICMP_EQ,
-                             llvm::FCmpInst::FCMP_OEQ);
-  case BinaryOperator::NE:
-    return EmitBinaryCompare(E, llvm::ICmpInst::ICMP_NE,
-                             llvm::ICmpInst::ICMP_NE, 
-                             llvm::FCmpInst::FCMP_UNE);
   case BinaryOperator::Assign:
     return EmitBinaryAssign(E);
     
@@ -1059,327 +709,8 @@
     LHS = EmitSub(LHS, RHS, CAO->getComputationType());
     return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
   }
-  case BinaryOperator::ShlAssign: {
-    const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
-    LValue LHSLV;
-    EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
-    LHS = EmitShl(LHS, RHS, CAO->getComputationType());
-    return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
-  }
-  case BinaryOperator::ShrAssign: {
-    const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
-    LValue LHSLV;
-    EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
-    LHS = EmitShr(LHS, RHS, CAO->getComputationType());
-    return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
-  }
-  case BinaryOperator::AndAssign: {
-    const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
-    LValue LHSLV;
-    EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
-    LHS = EmitAnd(LHS, RHS, CAO->getComputationType());
-    return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
-  }
-  case BinaryOperator::OrAssign: {
-    const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
-    LValue LHSLV;
-    EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
-    LHS = EmitOr(LHS, RHS, CAO->getComputationType());
-    return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
-  }
-  case BinaryOperator::XorAssign: {
-    const CompoundAssignOperator *CAO = cast<CompoundAssignOperator>(E);
-    LValue LHSLV;
-    EmitCompoundAssignmentOperands(CAO, LHSLV, LHS, RHS);
-    LHS = EmitXor(LHS, RHS, CAO->getComputationType());
-    return EmitCompoundAssignmentResult(CAO, LHSLV, LHS);
-  }
-  case BinaryOperator::Comma: return EmitBinaryComma(E);
-  }
-}
-
-RValue CodeGenFunction::EmitMul(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateMul(LHS.getVal(), RHS.getVal(), "mul"));
-}
-
-RValue CodeGenFunction::EmitDiv(RValue LHS, RValue RHS, QualType ResTy) {
-  if (LHS.getVal()->getType()->isFloatingPoint())
-    return RValue::get(Builder.CreateFDiv(LHS.getVal(), RHS.getVal(), "div"));
-  else if (ResTy->isUnsignedIntegerType())
-    return RValue::get(Builder.CreateUDiv(LHS.getVal(), RHS.getVal(), "div"));
-  else
-    return RValue::get(Builder.CreateSDiv(LHS.getVal(), RHS.getVal(), "div"));
-}
-
-RValue CodeGenFunction::EmitRem(RValue LHS, RValue RHS, QualType ResTy) {
-  // Rem in C can't be a floating point type: C99 6.5.5p2.
-  if (ResTy->isUnsignedIntegerType())
-    return RValue::get(Builder.CreateURem(LHS.getVal(), RHS.getVal(), "rem"));
-  else
-    return RValue::get(Builder.CreateSRem(LHS.getVal(), RHS.getVal(), "rem"));
-}
-
-RValue CodeGenFunction::EmitAdd(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateAdd(LHS.getVal(), RHS.getVal(), "add"));
-}
-
-RValue CodeGenFunction::EmitPointerAdd(RValue LHS, QualType LHSTy,
-                                       RValue RHS, QualType RHSTy,
-                                       QualType ResTy) {
-  llvm::Value *LHSValue = LHS.getVal();
-  llvm::Value *RHSValue = RHS.getVal();
-  if (LHSTy->isPointerType()) {
-    // pointer + int
-    return RValue::get(Builder.CreateGEP(LHSValue, RHSValue, "add.ptr"));
-  } else {
-    // int + pointer
-    return RValue::get(Builder.CreateGEP(RHSValue, LHSValue, "add.ptr"));
   }
 }
 
-RValue CodeGenFunction::EmitSub(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateSub(LHS.getVal(), RHS.getVal(), "sub"));
-}
 
-RValue CodeGenFunction::EmitPointerSub(RValue LHS, QualType LHSTy,
-                                       RValue RHS, QualType RHSTy,
-                                       QualType ResTy) {
-  llvm::Value *LHSValue = LHS.getVal();
-  llvm::Value *RHSValue = RHS.getVal();
-  if (const PointerType *RHSPtrType =
-        dyn_cast<PointerType>(RHSTy.getTypePtr())) {
-    // pointer - pointer
-    const PointerType *LHSPtrType = cast<PointerType>(LHSTy.getTypePtr());
-    QualType LHSElementType = LHSPtrType->getPointeeType();
-    assert(LHSElementType == RHSPtrType->getPointeeType() &&
-      "can't subtract pointers with differing element types");
-    uint64_t ElementSize = getContext().getTypeSize(LHSElementType,
-                                                    SourceLocation()) / 8;
-    const llvm::Type *ResultType = ConvertType(ResTy);
-    llvm::Value *CastLHS = Builder.CreatePtrToInt(LHSValue, ResultType,
-                                                  "sub.ptr.lhs.cast");
-    llvm::Value *CastRHS = Builder.CreatePtrToInt(RHSValue, ResultType,
-                                                  "sub.ptr.rhs.cast");
-    llvm::Value *BytesBetween = Builder.CreateSub(CastLHS, CastRHS,
-                                                  "sub.ptr.sub");
-    
-    // HACK: LLVM doesn't have an divide instruction that 'knows' there is no
-    // remainder.  As such, we handle common power-of-two cases here to generate
-    // better code.
-    if (llvm::isPowerOf2_64(ElementSize)) {
-      llvm::Value *ShAmt =
-        llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
-      return RValue::get(Builder.CreateAShr(BytesBetween, ShAmt,"sub.ptr.shr"));
-    } else {
-      // Otherwise, do a full sdiv.
-      llvm::Value *BytesPerElement =
-        llvm::ConstantInt::get(ResultType, ElementSize);
-      return RValue::get(Builder.CreateSDiv(BytesBetween, BytesPerElement,
-                                            "sub.ptr.div"));
-    }
-  } else {
-    // pointer - int
-    llvm::Value *NegatedRHS = Builder.CreateNeg(RHSValue, "sub.ptr.neg");
-    return RValue::get(Builder.CreateGEP(LHSValue, NegatedRHS, "sub.ptr"));
-  }
-}
-
-RValue CodeGenFunction::EmitShl(RValue LHSV, RValue RHSV, QualType ResTy) {
-  llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
-  
-  // LLVM requires the LHS and RHS to be the same type, promote or truncate the
-  // RHS to the same size as the LHS.
-  if (LHS->getType() != RHS->getType())
-    RHS = Builder.CreateIntCast(RHS, LHS->getType(), false, "sh_prom");
-  
-  return RValue::get(Builder.CreateShl(LHS, RHS, "shl"));
-}
-
-RValue CodeGenFunction::EmitShr(RValue LHSV, RValue RHSV, QualType ResTy) {
-  llvm::Value *LHS = LHSV.getVal(), *RHS = RHSV.getVal();
-  
-  // LLVM requires the LHS and RHS to be the same type, promote or truncate the
-  // RHS to the same size as the LHS.
-  if (LHS->getType() != RHS->getType())
-    RHS = Builder.CreateIntCast(RHS, LHS->getType(), false, "sh_prom");
-  
-  if (ResTy->isUnsignedIntegerType())
-    return RValue::get(Builder.CreateLShr(LHS, RHS, "shr"));
-  else
-    return RValue::get(Builder.CreateAShr(LHS, RHS, "shr"));
-}
-
-RValue CodeGenFunction::EmitBinaryCompare(const BinaryOperator *E,
-                                          unsigned UICmpOpc, unsigned SICmpOpc,
-                                          unsigned FCmpOpc) {
-  llvm::Value *Result;
-  QualType LHSTy = E->getLHS()->getType();
-  if (!LHSTy->isComplexType()) {
-    RValue LHS = EmitExpr(E->getLHS());
-    RValue RHS = EmitExpr(E->getRHS());
-    
-    if (LHSTy->isRealFloatingType()) {
-      Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
-                                  LHS.getVal(), RHS.getVal(), "cmp");
-    } else if (LHSTy->isUnsignedIntegerType()) {
-      // FIXME: This check isn't right for "unsigned short < int" where ushort
-      // promotes to int and does a signed compare.
-      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
-                                  LHS.getVal(), RHS.getVal(), "cmp");
-    } else {
-      // Signed integers and pointers.
-      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
-                                  LHS.getVal(), RHS.getVal(), "cmp");
-    }
-  } else {
-    // Complex Comparison: can only be an equality comparison.
-    ComplexPairTy LHS = EmitComplexExpr(E->getLHS());
-    ComplexPairTy RHS = EmitComplexExpr(E->getRHS());
-
-    QualType CETy = 
-      cast<ComplexType>(LHSTy.getCanonicalType())->getElementType();
-    
-    llvm::Value *ResultR, *ResultI;
-    if (CETy->isRealFloatingType()) {
-      ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
-                                   LHS.first, RHS.first, "cmp.r");
-      ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
-                                   LHS.second, RHS.second, "cmp.i");
-    } else {
-      // Complex comparisons can only be equality comparisons.  As such, signed
-      // and unsigned opcodes are the same.
-      ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
-                                   LHS.first, RHS.first, "cmp.r");
-      ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
-                                   LHS.second, RHS.second, "cmp.i");
-    }
-      
-    if (E->getOpcode() == BinaryOperator::EQ) {
-      Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
-    } else {
-      assert(E->getOpcode() == BinaryOperator::NE &&
-             "Complex comparison other than == or != ?");
-      Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
-    }
-  }
-
-  // ZExt result to int.
-  return RValue::get(Builder.CreateZExt(Result, LLVMIntTy, "cmp.ext"));
-}
-
-RValue CodeGenFunction::EmitAnd(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateAnd(LHS.getVal(), RHS.getVal(), "and"));
-}
-
-RValue CodeGenFunction::EmitXor(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateXor(LHS.getVal(), RHS.getVal(), "xor"));
-}
-
-RValue CodeGenFunction::EmitOr(RValue LHS, RValue RHS, QualType ResTy) {
-  return RValue::get(Builder.CreateOr(LHS.getVal(), RHS.getVal(), "or"));
-}
-
-RValue CodeGenFunction::EmitBinaryLAnd(const BinaryOperator *E) {
-  llvm::Value *LHSCond = EvaluateExprAsBool(E->getLHS());
-  
-  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("land_cont");
-  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("land_rhs");
-
-  llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
-  Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock);
-  
-  EmitBlock(RHSBlock);
-  llvm::Value *RHSCond = EvaluateExprAsBool(E->getRHS());
-  
-  // Reaquire the RHS block, as there may be subblocks inserted.
-  RHSBlock = Builder.GetInsertBlock();
-  EmitBlock(ContBlock);
-  
-  // Create a PHI node.  If we just evaluted the LHS condition, the result is
-  // false.  If we evaluated both, the result is the RHS condition.
-  llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "land");
-  PN->reserveOperandSpace(2);
-  PN->addIncoming(llvm::ConstantInt::getFalse(), OrigBlock);
-  PN->addIncoming(RHSCond, RHSBlock);
-  
-  // ZExt result to int.
-  return RValue::get(Builder.CreateZExt(PN, LLVMIntTy, "land.ext"));
-}
-
-RValue CodeGenFunction::EmitBinaryLOr(const BinaryOperator *E) {
-  llvm::Value *LHSCond = EvaluateExprAsBool(E->getLHS());
-  
-  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("lor_cont");
-  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("lor_rhs");
-  
-  llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
-  Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock);
-  
-  EmitBlock(RHSBlock);
-  llvm::Value *RHSCond = EvaluateExprAsBool(E->getRHS());
-  
-  // Reaquire the RHS block, as there may be subblocks inserted.
-  RHSBlock = Builder.GetInsertBlock();
-  EmitBlock(ContBlock);
-  
-  // Create a PHI node.  If we just evaluted the LHS condition, the result is
-  // true.  If we evaluated both, the result is the RHS condition.
-  llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "lor");
-  PN->reserveOperandSpace(2);
-  PN->addIncoming(llvm::ConstantInt::getTrue(), OrigBlock);
-  PN->addIncoming(RHSCond, RHSBlock);
-  
-  // ZExt result to int.
-  return RValue::get(Builder.CreateZExt(PN, LLVMIntTy, "lor.ext"));
-}
-
-RValue CodeGenFunction::EmitBinaryAssign(const BinaryOperator *E) {
-  assert(E->getLHS()->getType().getCanonicalType() ==
-         E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
-  LValue LHS = EmitLValue(E->getLHS());
-  RValue RHS = EmitExpr(E->getRHS());
-  
-  // Store the value into the LHS.
-  EmitStoreThroughLValue(RHS, LHS, E->getType());
-
-  // Return the RHS.
-  return RHS;
-}
-
-
-RValue CodeGenFunction::EmitBinaryComma(const BinaryOperator *E) {
-  EmitStmt(E->getLHS());
-  return EmitExpr(E->getRHS());
-}
-
-RValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator *E) {
-  llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
-  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
-  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
-  
-  llvm::Value *Cond = EvaluateExprAsBool(E->getCond());
-  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
-  
-  EmitBlock(LHSBlock);
-  // Handle the GNU extension for missing LHS.
-  llvm::Value *LHSValue = E->getLHS() ? EmitExpr(E->getLHS()).getVal() : Cond;
-  Builder.CreateBr(ContBlock);
-  LHSBlock = Builder.GetInsertBlock();
-  
-  EmitBlock(RHSBlock);
-
-  llvm::Value *RHSValue = EmitExpr(E->getRHS()).getVal();
-  Builder.CreateBr(ContBlock);
-  RHSBlock = Builder.GetInsertBlock();
-  
-  const llvm::Type *LHSType = LHSValue->getType();
-  assert(LHSType == RHSValue->getType() && "?: LHS & RHS must have same type");
-  
-  EmitBlock(ContBlock);
-  llvm::PHINode *PN = Builder.CreatePHI(LHSType, "cond");
-  PN->reserveOperandSpace(2);
-  PN->addIncoming(LHSValue, LHSBlock);
-  PN->addIncoming(RHSValue, RHSBlock);
-  
-  return RValue::get(PN);
-}
+#endif

Modified: cfe/trunk/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprComplex.cpp?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/CodeGen/CGExprComplex.cpp Fri Aug 24 00:35:26 2007
@@ -119,7 +119,6 @@
   
   ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
   ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
-  //  case Expr::ChooseExprClass:
 };
 }  // end anonymous namespace.
 

Added: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=41355&view=auto

==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (added)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Fri Aug 24 00:35:26 2007
@@ -0,0 +1,648 @@
+//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Expr nodes with scalar LLVM types as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/AST.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Support/Compiler.h"
+using namespace clang;
+using namespace CodeGen;
+using llvm::Value;
+
+//===----------------------------------------------------------------------===//
+//                         Scalar Expression Emitter
+//===----------------------------------------------------------------------===//
+
+struct BinOpInfo {
+  Value *LHS;
+  Value *RHS;
+  const BinaryOperator *E;
+};
+
+namespace {
+class VISIBILITY_HIDDEN ScalarExprEmitter
+  : public StmtVisitor<ScalarExprEmitter, Value*> {
+  CodeGenFunction &CGF;
+  llvm::LLVMBuilder &Builder;
+public:
+
+  ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
+  }
+
+  
+  //===--------------------------------------------------------------------===//
+  //                               Utilities
+  //===--------------------------------------------------------------------===//
+
+  const llvm::Type *ConvertType(QualType T) { return CGF.ConvertType(T); }
+  LValue EmitLValue(const Expr *E) { return CGF.EmitLValue(E); }
+
+  Value *EmitLoadOfLValue(LValue LV, QualType T) {
+    return CGF.EmitLoadOfLValue(LV, T).getVal();
+  }
+    
+  /// EmitLoadOfLValue - Given an expression with complex type that represents a
+  /// value l-value, this method emits the address of the l-value, then loads
+  /// and returns the result.
+  Value *EmitLoadOfLValue(const Expr *E) {
+    // FIXME: Volatile
+    return EmitLoadOfLValue(EmitLValue(E), E->getType());
+  }
+    
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  Value *VisitStmt(Stmt *S) {
+    S->dump();
+    assert(0 && "Stmt can't have complex result type!");
+    return 0;
+  }
+  Value *VisitExpr(Expr *S);
+  Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }
+
+  // Leaves.
+  Value *VisitIntegerLiteral(const IntegerLiteral *E) {
+    return llvm::ConstantInt::get(E->getValue());
+  }
+  Value *VisitFloatingLiteral(const FloatingLiteral *E) {
+    return llvm::ConstantFP::get(ConvertType(E->getType()), E->getValue());
+  }
+  Value *VisitCharacterLiteral(const CharacterLiteral *E) {
+    return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
+  }
+  Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
+    return llvm::ConstantInt::get(ConvertType(E->getType()),
+                                  E->typesAreCompatible());
+  }
+  Value *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
+    return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
+  }
+    
+  // l-values.
+  Value *VisitDeclRefExpr(DeclRefExpr *E) {
+    if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(E->getDecl()))
+      return llvm::ConstantInt::get(EC->getInitVal());
+    return EmitLoadOfLValue(E);
+  }
+  Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+  Value *VisitMemberExpr(Expr *E)           { return EmitLoadOfLValue(E); }
+  Value *VisitOCUVectorElementExpr(Expr *E) { return EmitLoadOfLValue(E); }
+  Value *VisitStringLiteral(Expr *E)  { return EmitLValue(E).getAddress(); }
+  Value *VisitPreDefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); }
+  
+  // FIXME: CompoundLiteralExpr
+  Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
+  Value *VisitCastExpr(const CastExpr *E) { 
+    return EmitCastExpr(E->getSubExpr(), E->getType());
+  }
+  Value *EmitCastExpr(const Expr *E, QualType T);
+
+  Value *VisitCallExpr(const CallExpr *E) {
+    return CGF.EmitCallExpr(E).getVal();
+  }
+  
+  // Unary Operators.
+  Value *VisitPrePostIncDec(const UnaryOperator *E, bool isInc, bool isPre);
+  Value *VisitUnaryPostDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, false);
+  }
+  Value *VisitUnaryPostInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, false);
+  }
+  Value *VisitUnaryPreDec(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, false, true);
+  }
+  Value *VisitUnaryPreInc(const UnaryOperator *E) {
+    return VisitPrePostIncDec(E, true, true);
+  }
+  Value *VisitUnaryAddrOf(const UnaryOperator *E) {
+    return EmitLValue(E->getSubExpr()).getAddress();
+  }
+  Value *VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
+  Value *VisitUnaryPlus(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+  Value *VisitUnaryMinus    (const UnaryOperator *E);
+  Value *VisitUnaryNot      (const UnaryOperator *E);
+  Value *VisitUnaryLNot     (const UnaryOperator *E);
+  Value *VisitUnarySizeOf   (const UnaryOperator *E) {
+    return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
+  }
+  Value *VisitUnaryAlignOf  (const UnaryOperator *E) {
+    return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
+  }
+  Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType,
+                               bool isSizeOf);
+  // FIXME: Real,Imag.
+  Value *VisitUnaryExtension(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+  
+  // Binary Operators.
+  BinOpInfo EmitBinOps(const BinaryOperator *E);
+  Value *VisitBinMul(const BinaryOperator *E) { return EmitMul(EmitBinOps(E)); }
+  Value *VisitBinDiv(const BinaryOperator *E) { return EmitDiv(EmitBinOps(E)); }
+  Value *VisitBinRem(const BinaryOperator *E) { return EmitRem(EmitBinOps(E)); }
+  Value *VisitBinAdd(const BinaryOperator *E) { return EmitAdd(EmitBinOps(E)); }
+  Value *VisitBinSub(const BinaryOperator *E) { return EmitSub(EmitBinOps(E)); }
+  Value *VisitBinShl(const BinaryOperator *E) { return EmitShl(EmitBinOps(E)); }
+  Value *VisitBinShr(const BinaryOperator *E) { return EmitShr(EmitBinOps(E)); }
+  Value *VisitBinAnd(const BinaryOperator *E) { return EmitAnd(EmitBinOps(E)); }
+  Value *VisitBinXor(const BinaryOperator *E) { return EmitXor(EmitBinOps(E)); }
+  Value *VisitBinOr (const BinaryOperator *E) { return EmitOr (EmitBinOps(E)); }
+
+  Value *EmitMul(const BinOpInfo &Ops) {
+    return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
+  }
+  Value *EmitDiv(const BinOpInfo &Ops);
+  Value *EmitRem(const BinOpInfo &Ops);
+  Value *EmitAdd(const BinOpInfo &Ops);
+  Value *EmitSub(const BinOpInfo &Ops);
+  Value *EmitShl(const BinOpInfo &Ops);
+  Value *EmitShr(const BinOpInfo &Ops);
+  Value *EmitAnd(const BinOpInfo &Ops) {
+    return Builder.CreateAnd(Ops.LHS, Ops.RHS, "and");
+  }
+  Value *EmitXor(const BinOpInfo &Ops) {
+    return Builder.CreateXor(Ops.LHS, Ops.RHS, "xor");
+  }
+  Value *EmitOr (const BinOpInfo &Ops) {
+    return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
+  }
+
+  // Comparisons.
+  Value *EmitCompare(const BinaryOperator *E, unsigned UICmpOpc,
+                     unsigned SICmpOpc, unsigned FCmpOpc);
+#define VISITCOMP(CODE, UI, SI, FP) \
+    Value *VisitBin##CODE(const BinaryOperator *E) { \
+      return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
+                         llvm::FCmpInst::FP); }
+  VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT);
+  VISITCOMP(GT, ICMP_UGT, ICMP_SGT, FCMP_OGT);
+  VISITCOMP(LE, ICMP_ULE, ICMP_SLE, FCMP_OLE);
+  VISITCOMP(GE, ICMP_UGE, ICMP_SGE, FCMP_OGE);
+  VISITCOMP(EQ, ICMP_EQ , ICMP_EQ , FCMP_OEQ);
+  VISITCOMP(NE, ICMP_NE , ICMP_NE , FCMP_UNE);
+#undef VISITCOMP
+  
+  Value *VisitBinAssign     (const BinaryOperator *E);
+
+  Value *VisitBinLAnd       (const BinaryOperator *E);
+  Value *VisitBinLOr        (const BinaryOperator *E);
+
+  // FIXME: Compound assignment operators.
+  Value *VisitBinComma      (const BinaryOperator *E);
+
+  // Other Operators.
+  Value *VisitConditionalOperator(const ConditionalOperator *CO);
+  Value *VisitChooseExpr(ChooseExpr *CE);
+  Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
+    return CGF.EmitObjCStringLiteral(E);
+  }
+};
+}  // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+//                                Utilities
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//                            Visitor Methods
+//===----------------------------------------------------------------------===//
+
+Value *ScalarExprEmitter::VisitExpr(Expr *E) {
+  fprintf(stderr, "Unimplemented scalar expr!\n");
+  E->dump();
+  if (E->getType()->isVoidType())
+    return 0;
+  return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
+}
+
+Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  // Emit subscript expressions in rvalue context's.  For most cases, this just
+  // loads the lvalue formed by the subscript expr.  However, we have to be
+  // careful, because the base of a vector subscript is occasionally an rvalue,
+  // so we can't get it as an lvalue.
+  if (!E->getBase()->getType()->isVectorType())
+    return EmitLoadOfLValue(E);
+  
+  // Handle the vector case.  The base must be a vector, the index must be an
+  // integer value.
+  Value *Base = Visit(E->getBase());
+  Value *Idx  = Visit(E->getIdx());
+  
+  // FIXME: Convert Idx to i32 type.
+  return Builder.CreateExtractElement(Base, Idx, "vecext");
+}
+
+/// VisitImplicitCastExpr - Implicit casts are the same as normal casts, but
+/// also handle things like function to pointer-to-function decay, and array to
+/// pointer decay.
+Value *ScalarExprEmitter::VisitImplicitCastExpr(const ImplicitCastExpr *E) {
+  const Expr *Op = E->getSubExpr();
+  
+  // If this is due to array->pointer conversion, emit the array expression as
+  // an l-value.
+  if (Op->getType()->isArrayType()) {
+    // FIXME: For now we assume that all source arrays map to LLVM arrays.  This
+    // will not true when we add support for VLAs.
+    llvm::Value *V = EmitLValue(Op).getAddress();  // Bitfields can't be arrays.
+    
+    assert(isa<llvm::PointerType>(V->getType()) &&
+           isa<llvm::ArrayType>(cast<llvm::PointerType>(V->getType())
+                                ->getElementType()) &&
+           "Doesn't support VLAs yet!");
+    llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+    return Builder.CreateGEP(V, Idx0, Idx0, "arraydecay");
+  }
+  
+  return EmitCastExpr(Op, E->getType());
+}
+
+
+// VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts
+// have to handle a more broad range of conversions than explicit casts, as they
+// handle things like function to ptr-to-function decay etc.
+Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy) {
+  RValue Src = CGF.EmitAnyExpr(E);
+  
+  // If the destination is void, just evaluate the source.
+  if (DestTy->isVoidType())
+    return 0;
+  
+  // FIXME: Refactor EmitConversion to not return an RValue.  Sink it into this
+  // method.
+  return CGF.EmitConversion(Src, E->getType(), DestTy).getVal();
+}
+
+//===----------------------------------------------------------------------===//
+//                             Unary Operators
+//===----------------------------------------------------------------------===//
+
+Value *ScalarExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
+                                                    bool isInc, bool isPre) {
+  LValue LV = EmitLValue(E->getSubExpr());
+  // FIXME: Handle volatile!
+  Value *InVal = CGF.EmitLoadOfLValue(LV/* false*/,
+                                           E->getSubExpr()->getType()).getVal();
+  
+  int AmountVal = isInc ? 1 : -1;
+  
+  Value *NextVal;
+  if (isa<llvm::IntegerType>(InVal->getType()))
+    NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
+  else
+    NextVal = llvm::ConstantFP::get(InVal->getType(), AmountVal);
+  
+  // Add the inc/dec to the real part.
+  NextVal = Builder.CreateAdd(InVal, NextVal, isInc ? "inc" : "dec");
+  
+  // Store the updated result through the lvalue.
+  CGF.EmitStoreThroughLValue(RValue::get(NextVal), LV, 
+                             E->getSubExpr()->getType());
+
+  // If this is a postinc, return the value read from memory, otherwise use the
+  // updated value.
+  return isPre ? NextVal : InVal;
+}
+
+
+Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
+  Value *Op = Visit(E->getSubExpr());
+  return Builder.CreateNeg(Op, "neg");
+}
+
+Value *ScalarExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
+  Value *Op = Visit(E->getSubExpr());
+  return Builder.CreateNot(Op, "neg");
+}
+
+Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
+  // Compare operand to zero.
+  Value *BoolVal = CGF.EvaluateExprAsBool(E->getSubExpr());
+  
+  // Invert value.
+  // TODO: Could dynamically modify easy computations here.  For example, if
+  // the operand is an icmp ne, turn into icmp eq.
+  BoolVal = Builder.CreateNot(BoolVal, "lnot");
+  
+  // ZExt result to int.
+  return Builder.CreateZExt(BoolVal, CGF.LLVMIntTy, "lnot.ext");
+}
+
+/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as
+/// an integer (RetType).
+Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize, 
+                                                QualType RetType,bool isSizeOf){
+  /// FIXME: This doesn't handle VLAs yet!
+  std::pair<uint64_t, unsigned> Info =
+    CGF.getContext().getTypeInfo(TypeToSize, SourceLocation());
+  
+  uint64_t Val = isSizeOf ? Info.first : Info.second;
+  Val /= 8;  // Return size in bytes, not bits.
+  
+  assert(RetType->isIntegerType() && "Result type must be an integer!");
+  
+  unsigned ResultWidth = CGF.getContext().getTypeSize(RetType,SourceLocation());
+  return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
+}
+
+//===----------------------------------------------------------------------===//
+//                           Binary Operators
+//===----------------------------------------------------------------------===//
+
+BinOpInfo ScalarExprEmitter::EmitBinOps(const BinaryOperator *E) {
+  BinOpInfo Result;
+  Result.LHS = Visit(E->getLHS());
+  Result.RHS = Visit(E->getRHS());
+  Result.E = E;
+  return Result;
+}
+
+Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
+  if (Ops.LHS->getType()->isFloatingPoint())
+    return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
+  else if (Ops.E->getType()->isUnsignedIntegerType())
+    return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
+  else
+    return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
+}
+
+Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
+  // Rem in C can't be a floating point type: C99 6.5.5p2.
+  if (Ops.E->getType()->isUnsignedIntegerType())
+    return Builder.CreateURem(Ops.LHS, Ops.RHS, "rem");
+  else
+    return Builder.CreateSRem(Ops.LHS, Ops.RHS, "rem");
+}
+
+
+Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
+  if (!Ops.E->getType()->isPointerType())
+    return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
+  if (isa<llvm::PointerType>(Ops.LHS->getType())) // pointer + int
+    return Builder.CreateGEP(Ops.LHS, Ops.RHS, "add.ptr");
+  // int + pointer
+  return Builder.CreateGEP(Ops.RHS, Ops.LHS, "add.ptr");
+}
+
+Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
+  if (!isa<llvm::PointerType>(Ops.LHS->getType()))
+    return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
+  
+  // FIXME: This isn't right for -=.
+  QualType LHSTy = Ops.E->getLHS()->getType();
+  QualType RHSTy = Ops.E->getRHS()->getType();
+  
+  const PointerType *RHSPtrType = dyn_cast<PointerType>(RHSTy.getTypePtr());
+  if (RHSPtrType == 0) {   // pointer - int
+    Value *NegatedRHS = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
+    return Builder.CreateGEP(Ops.LHS, NegatedRHS, "sub.ptr");
+  }
+  
+  // pointer - pointer
+  const PointerType *LHSPtrType = cast<PointerType>(LHSTy.getTypePtr());
+  QualType LHSElementType = LHSPtrType->getPointeeType();
+  assert(LHSElementType == RHSPtrType->getPointeeType() &&
+         "can't subtract pointers with differing element types");
+  uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType,
+                                                      SourceLocation()) / 8;
+  const llvm::Type *ResultType = ConvertType(Ops.E->getType());
+  Value *CastLHS = Builder.CreatePtrToInt(Ops.LHS, ResultType,
+                                                "sub.ptr.lhs.cast");
+  Value *CastRHS = Builder.CreatePtrToInt(Ops.RHS, ResultType,
+                                                "sub.ptr.rhs.cast");
+  Value *BytesBetween = Builder.CreateSub(CastLHS, CastRHS,
+                                                "sub.ptr.sub");
+  
+  // HACK: LLVM doesn't have an divide instruction that 'knows' there is no
+  // remainder.  As such, we handle common power-of-two cases here to generate
+  // better code.
+  if (llvm::isPowerOf2_64(ElementSize)) {
+    Value *ShAmt =
+    llvm::ConstantInt::get(ResultType, llvm::Log2_64(ElementSize));
+    return Builder.CreateAShr(BytesBetween, ShAmt, "sub.ptr.shr");
+  }
+  // Otherwise, do a full sdiv.
+  Value *BytesPerElt = llvm::ConstantInt::get(ResultType, ElementSize);
+  return Builder.CreateSDiv(BytesBetween, BytesPerElt, "sub.ptr.div");
+}
+
+Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
+  // LLVM requires the LHS and RHS to be the same type: promote or truncate the
+  // RHS to the same size as the LHS.
+  Value *RHS = Ops.RHS;
+  if (Ops.LHS->getType() != RHS->getType())
+    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
+  
+  return Builder.CreateShl(Ops.LHS, RHS, "shl");
+}
+
+Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
+  // LLVM requires the LHS and RHS to be the same type: promote or truncate the
+  // RHS to the same size as the LHS.
+  Value *RHS = Ops.RHS;
+  if (Ops.LHS->getType() != RHS->getType())
+    RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
+  
+  if (Ops.E->getType()->isUnsignedIntegerType())
+    return Builder.CreateLShr(Ops.LHS, RHS, "shr");
+  return Builder.CreateAShr(Ops.LHS, RHS, "shr");
+}
+
+Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
+                                      unsigned SICmpOpc, unsigned FCmpOpc) {
+  llvm::Value *Result;
+  QualType LHSTy = E->getLHS()->getType();
+  if (!LHSTy->isComplexType()) {
+    Value *LHS = Visit(E->getLHS());
+    Value *RHS = Visit(E->getRHS());
+    
+    if (LHS->getType()->isFloatingPoint()) {
+      Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
+                                  LHS, RHS, "cmp");
+    } else if (LHSTy->isUnsignedIntegerType()) {
+      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                  LHS, RHS, "cmp");
+    } else {
+      // Signed integers and pointers.
+      Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
+                                  LHS, RHS, "cmp");
+    }
+  } else {
+    // Complex Comparison: can only be an equality comparison.
+    CodeGenFunction::ComplexPairTy LHS = CGF.EmitComplexExpr(E->getLHS());
+    CodeGenFunction::ComplexPairTy RHS = CGF.EmitComplexExpr(E->getRHS());
+    
+    QualType CETy = 
+      cast<ComplexType>(LHSTy.getCanonicalType())->getElementType();
+    
+    llvm::Value *ResultR, *ResultI;
+    if (CETy->isRealFloatingType()) {
+      ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
+                                   LHS.first, RHS.first, "cmp.r");
+      ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc,
+                                   LHS.second, RHS.second, "cmp.i");
+    } else {
+      // Complex comparisons can only be equality comparisons.  As such, signed
+      // and unsigned opcodes are the same.
+      ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                   LHS.first, RHS.first, "cmp.r");
+      ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc,
+                                   LHS.second, RHS.second, "cmp.i");
+    }
+    
+    if (E->getOpcode() == BinaryOperator::EQ) {
+      Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
+    } else {
+      assert(E->getOpcode() == BinaryOperator::NE &&
+             "Complex comparison other than == or != ?");
+      Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
+    }
+  }
+  
+  // ZExt result to int.
+  return Builder.CreateZExt(Result, CGF.LLVMIntTy, "cmp.ext");
+}
+
+Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+  LValue LHS = EmitLValue(E->getLHS());
+  Value *RHS = Visit(E->getRHS());
+  
+  // Store the value into the LHS.
+  // FIXME: Volatility!
+  CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType());
+  
+  // Return the RHS.
+  return RHS;
+}
+
+Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
+  Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
+  
+  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("land_cont");
+  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("land_rhs");
+  
+  llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
+  Builder.CreateCondBr(LHSCond, RHSBlock, ContBlock);
+  
+  CGF.EmitBlock(RHSBlock);
+  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+  
+  // Reaquire the RHS block, as there may be subblocks inserted.
+  RHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBlock(ContBlock);
+  
+  // Create a PHI node.  If we just evaluted the LHS condition, the result is
+  // false.  If we evaluated both, the result is the RHS condition.
+  llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "land");
+  PN->reserveOperandSpace(2);
+  PN->addIncoming(llvm::ConstantInt::getFalse(), OrigBlock);
+  PN->addIncoming(RHSCond, RHSBlock);
+  
+  // ZExt result to int.
+  return Builder.CreateZExt(PN, CGF.LLVMIntTy, "land.ext");
+}
+
+Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
+  Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
+  
+  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("lor_cont");
+  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("lor_rhs");
+  
+  llvm::BasicBlock *OrigBlock = Builder.GetInsertBlock();
+  Builder.CreateCondBr(LHSCond, ContBlock, RHSBlock);
+  
+  CGF.EmitBlock(RHSBlock);
+  Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+  
+  // Reaquire the RHS block, as there may be subblocks inserted.
+  RHSBlock = Builder.GetInsertBlock();
+  CGF.EmitBlock(ContBlock);
+  
+  // Create a PHI node.  If we just evaluted the LHS condition, the result is
+  // true.  If we evaluated both, the result is the RHS condition.
+  llvm::PHINode *PN = Builder.CreatePHI(llvm::Type::Int1Ty, "lor");
+  PN->reserveOperandSpace(2);
+  PN->addIncoming(llvm::ConstantInt::getTrue(), OrigBlock);
+  PN->addIncoming(RHSCond, RHSBlock);
+  
+  // ZExt result to int.
+  return Builder.CreateZExt(PN, CGF.LLVMIntTy, "lor.ext");
+}
+
+Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
+  CGF.EmitStmt(E->getLHS());
+  return Visit(E->getRHS());
+}
+
+//===----------------------------------------------------------------------===//
+//                             Other Operators
+//===----------------------------------------------------------------------===//
+
+Value *ScalarExprEmitter::
+VisitConditionalOperator(const ConditionalOperator *E) {
+  llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
+  llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
+  llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
+  
+  Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
+  Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
+  
+  CGF.EmitBlock(LHSBlock);
+  
+  // Handle the GNU extension for missing LHS.
+  Value *LHS = E->getLHS() ? Visit(E->getLHS()) : Cond;
+  Builder.CreateBr(ContBlock);
+  LHSBlock = Builder.GetInsertBlock();
+  
+  CGF.EmitBlock(RHSBlock);
+  
+  Value *RHS = Visit(E->getRHS());
+  Builder.CreateBr(ContBlock);
+  RHSBlock = Builder.GetInsertBlock();
+  
+  CGF.EmitBlock(ContBlock);
+  
+  // Create a PHI node for the real part.
+  llvm::PHINode *PN = Builder.CreatePHI(LHS->getType(), "cond");
+  PN->reserveOperandSpace(2);
+  PN->addIncoming(LHS, LHSBlock);
+  PN->addIncoming(RHS, RHSBlock);
+  return PN;
+}
+
+Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
+  llvm::APSInt CondVal(32);
+  bool IsConst = E->getCond()->isIntegerConstantExpr(CondVal, CGF.getContext());
+  assert(IsConst && "Condition of choose expr must be i-c-e"); IsConst=IsConst;
+  
+  // Emit the LHS or RHS as appropriate.
+  return Visit(CondVal != 0 ? E->getLHS() : E->getRHS());
+}
+
+//===----------------------------------------------------------------------===//
+//                         Entry Point into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitComplexExpr - Emit the computation of the specified expression of
+/// complex type, ignoring the result.
+Value *CodeGenFunction::EmitScalarExpr(const Expr *E) {
+  assert(E && !hasAggregateLLVMType(E->getType()) &&
+         "Invalid scalar expression to emit");
+  
+  return ScalarExprEmitter(*this).Visit(const_cast<Expr*>(E));
+}

Modified: cfe/trunk/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGObjC.cpp?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/CodeGen/CGObjC.cpp Fri Aug 24 00:35:26 2007
@@ -15,14 +15,11 @@
 #include "CodeGenModule.h"
 #include "clang/AST/Expr.h"
 #include "llvm/Constant.h"
-
 using namespace clang;
 using namespace CodeGen;
 
-RValue CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral* E)
-{
+llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
   std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
-  
-  return RValue::get(CGM.GetAddrOfConstantCFString(S));
+  return CGM.GetAddrOfConstantCFString(S);
 }
 

Modified: cfe/trunk/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGStmt.cpp?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/CodeGen/CGStmt.cpp Fri Aug 24 00:35:26 2007
@@ -275,8 +275,9 @@
   // Emit the result value, even if unused, to evalute the side effects.
   const Expr *RV = S.getRetValue();
   // FIXME: Handle return of an aggregate!
-  if (RV)
-    RetVal = EmitExpr(RV);
+  if (RV) 
+    // FIXME: This could be much better for return of aggregate: return inplace.
+    RetVal = EmitAnyExpr(RV);
   else  // Silence a bogus GCC warning. 
     RetVal = RValue::get(0);
   

Modified: cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.h?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.h Fri Aug 24 00:35:26 2007
@@ -185,7 +185,6 @@
 public:
   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
   llvm::LLVMBuilder Builder;
-private:
   
   const FunctionDecl *CurFuncDecl;
   llvm::Function *CurFn;
@@ -197,6 +196,7 @@
   const llvm::Type *LLVMIntTy;
   unsigned LLVMPointerWidth;
   
+private:
   /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
   /// decls.
   llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
@@ -345,29 +345,12 @@
   /// result of the expression doesn't need to be generated into memory.
   RValue EmitAnyExpr(const Expr *E, bool NeedResult = true);
   
-  RValue EmitExpr(const Expr *E);
-  RValue EmitIntegerLiteral(const IntegerLiteral *E);
-  RValue EmitFloatingLiteral(const FloatingLiteral *E);
-  RValue EmitCharacterLiteral(const CharacterLiteral *E);
-  RValue EmitTypesCompatibleExpr(const TypesCompatibleExpr *E);
-   
-  RValue EmitImplicitCastExpr(const ImplicitCastExpr *Op);
-  RValue EmitCastExpr(const Expr *Op, QualType DestTy);
   RValue EmitCallExpr(const CallExpr *E);
   RValue EmitBuiltinExpr(unsigned builtinID, const CallExpr *E);
-  RValue EmitArraySubscriptExprRV(const ArraySubscriptExpr *E);
 
-  // Unary Operators.
-  RValue EmitUnaryOperator(const UnaryOperator *E);
-  RValue EmitUnaryIncDec  (const UnaryOperator *E);
-  RValue EmitUnaryAddrOf  (const UnaryOperator *E);
-  RValue EmitUnaryPlus    (const UnaryOperator *E);
-  RValue EmitUnaryMinus   (const UnaryOperator *E);
-  RValue EmitUnaryNot     (const UnaryOperator *E);
-  RValue EmitUnaryLNot    (const UnaryOperator *E);
-  RValue EmitSizeAlignOf  (QualType TypeToSize, QualType RetType,bool isSizeOf);
-  // FIXME: real/imag
-  
+#if 0
+  RValue EmitExpr(const Expr *E);
+   
   // Binary Operators.
   RValue EmitBinaryOperator(const BinaryOperator *E);
   RValue EmitBinaryMul(const BinaryOperator *E);
@@ -398,8 +381,9 @@
   // Conditional Operator.
   RValue EmitConditionalOperator(const ConditionalOperator *E);
   RValue EmitChooseExpr(const ChooseExpr *E);
+#endif
   
-  RValue EmitObjCStringLiteral(const ObjCStringLiteral* E);
+  llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
 
   //===--------------------------------------------------------------------===//
   //                       Aggregate Expression Emission
@@ -408,6 +392,10 @@
   void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
                          QualType EltTy);
   
+  /// EmitScalarExpr - Emit the computation of the specified expression of
+  /// LLVM scalar type, returning the result.
+  llvm::Value *EmitScalarExpr(const Expr *E);
+  
   /// EmitAggExpr - Emit the computation of the specified expression of
   /// aggregate type.  The result is computed into DestPtr.  Note that if
   /// DestPtr is null, the value of the aggregate expression is not needed.

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=41355&r1=41354&r2=41355&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Fri Aug 24 00:35:26 2007
@@ -27,6 +27,7 @@
 		DE1733700B068DC60080B521 /* DeclSpec.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE17336F0B068DC60080B521 /* DeclSpec.h */; };
 		DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
 		DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */; };
+		DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */; };
 		DE344AB80AE5DF6D00DBC861 /* HeaderSearch.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */; };
 		DE344B540AE5E46C00DBC861 /* HeaderSearch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */; };
 		DE3450D70AEB543100DBC861 /* DirectoryLookup.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE3450D60AEB543100DBC861 /* DirectoryLookup.h */; };
@@ -220,6 +221,7 @@
 		DE17336F0B068DC60080B521 /* DeclSpec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeclSpec.h; path = clang/Parse/DeclSpec.h; sourceTree = "<group>"; };
 		DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
 		DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprComplex.cpp; path = CodeGen/CGExprComplex.cpp; sourceTree = "<group>"; };
+		DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExprScalar.cpp; path = CodeGen/CGExprScalar.cpp; sourceTree = "<group>"; };
 		DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HeaderSearch.h; sourceTree = "<group>"; };
 		DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HeaderSearch.cpp; sourceTree = "<group>"; };
 		DE3450D60AEB543100DBC861 /* DirectoryLookup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DirectoryLookup.h; sourceTree = "<group>"; };
@@ -444,6 +446,7 @@
 				DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
 				DEF2EFF20C6CDD74000C4259 /* CGExprAgg.cpp */,
 				DE224FF70C7AA98800D370A5 /* CGExprComplex.cpp */,
+				DE22526F0C7E82D000D370A5 /* CGExprScalar.cpp */,
 				1A7342470C7B57D500122F56 /* CGObjC.cpp */,
 				DE4772F90C10EAE5002239E8 /* CGStmt.cpp */,
 				DE928B120C05659200231DA4 /* ModuleBuilder.cpp */,
@@ -704,6 +707,7 @@
 				DE224FF80C7AA98800D370A5 /* CGExprComplex.cpp in Sources */,
 				1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */,
 				DEC63B1A0C7B940200DBF169 /* CFG.cpp in Sources */,
+				DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};





More information about the cfe-commits mailing list