diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp
index 407812f..ee84f95 100644
--- a/CodeGen/CodeGenModule.cpp
+++ b/CodeGen/CodeGenModule.cpp
@@ -190,349 +190,8 @@
     CodeGenFunction(*this).GenerateCode(FD);
 }
 
-static llvm::Constant *GenerateConstantExpr(const Expr *Expression, 
-                                            CodeGenModule &CGM);
-
-/// GenerateConversionToBool - Generate comparison to zero for conversion to 
-/// bool
-static llvm::Constant *GenerateConversionToBool(llvm::Constant *Expression, 
-                                            QualType Source) {
-  if (Source->isRealFloatingType()) {
-    // Compare against 0.0 for fp scalars.
-    llvm::Constant *Zero = llvm::Constant::getNullValue(Expression->getType());
-    return llvm::ConstantExpr::getFCmp(llvm::FCmpInst::FCMP_UNE, Expression, 
-                                       Zero);
-  }
-
-  assert((Source->isIntegerType() || Source->isPointerType()) &&
-         "Unknown scalar type to convert");
-
-  // Compare against an integer or pointer null.
-  llvm::Constant *Zero = llvm::Constant::getNullValue(Expression->getType());
-  return llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, Expression, Zero);
-}
-
-/// GenerateConstantCast - Generates a constant cast to convert the Expression
-/// into the Target type.
-static llvm::Constant *GenerateConstantCast(const Expr *Expression, 
-                                            QualType Target, 
-                                            CodeGenModule &CGM) {
-  CodeGenTypes& Types = CGM.getTypes(); 
-  QualType Source = Expression->getType().getCanonicalType();
-  Target = Target.getCanonicalType();
-
-  assert (!Target->isVoidType());
-
-  llvm::Constant *SubExpr = GenerateConstantExpr(Expression, CGM);
-
-  if (Source == Target)
-      return SubExpr;
-
-  // Handle conversions to bool first, they are special: comparisons against 0.
-  if (Target->isBooleanType())
-    return GenerateConversionToBool(SubExpr, Source);
-    
-  const llvm::Type *SourceType = Types.ConvertType(Source);
-  const llvm::Type *TargetType = Types.ConvertType(Target);
-
-  // Ignore conversions like int -> uint.
-  if (SubExpr->getType() == TargetType)
-    return SubExpr;
-
-  // Handle pointer conversions next: pointers can only be converted to/from
-  // other pointers and integers.
-  if (isa<llvm::PointerType>(TargetType)) {
-    // The source value may be an integer, or a pointer.
-    if (isa<llvm::PointerType>(SubExpr->getType()))
-      return llvm::ConstantExpr::getBitCast(SubExpr, TargetType);
-    assert(Source->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
-    return llvm::ConstantExpr::getIntToPtr(SubExpr, TargetType);
-  }
-
-  if (isa<llvm::PointerType>(SourceType)) {
-    // Must be an ptr to int cast.
-    assert(isa<llvm::IntegerType>(TargetType) && "not ptr->int?");
-    return llvm::ConstantExpr::getPtrToInt(SubExpr, TargetType);
-  }
-
-  if (Source->isRealFloatingType() && Target->isRealFloatingType()) {
-    return llvm::ConstantExpr::getFPCast(SubExpr, TargetType);
-  }
-
-  // Finally, we have the arithmetic types: real int/float.
-  if (isa<llvm::IntegerType>(SourceType)) {
-    bool InputSigned = Source->isSignedIntegerType();
-    if (isa<llvm::IntegerType>(TargetType))
-      return llvm::ConstantExpr::getIntegerCast(SubExpr, TargetType, 
-                                                InputSigned);
-    else if (InputSigned)
-      return llvm::ConstantExpr::getSIToFP(SubExpr, TargetType);
-    else
-      return llvm::ConstantExpr::getUIToFP(SubExpr, TargetType);
-  }
-
-  assert(SubExpr->getType()->isFloatingPoint() && "Unknown real conversion");
-  if (isa<llvm::IntegerType>(TargetType)) {
-    if (Target->isSignedIntegerType())
-      return llvm::ConstantExpr::getFPToSI(SubExpr, TargetType);
-    else
-      return llvm::ConstantExpr::getFPToUI(SubExpr, TargetType);
-  }
-
-  assert(TargetType->isFloatingPoint() && "Unknown real conversion");
-  if (TargetType->getTypeID() < SubExpr->getType()->getTypeID())
-    return llvm::ConstantExpr::getFPTrunc(SubExpr, TargetType);
-  else
-    return llvm::ConstantExpr::getFPExtend(SubExpr, TargetType);
-
-  assert (!"Unsupported cast type in global intialiser.");
-  return 0;
-}
-
-/// GenerateAggregateInit - Generate a Constant initaliser for global array or
-/// struct typed variables.
-static llvm::Constant *GenerateAggregateInit(const InitListExpr *ILE, 
-                                             CodeGenModule &CGM) {
-  if (ILE->getType()->isVoidType()) {
-    // FIXME: Remove this when sema of initializers is finished (and the code
-    // below).
-    CGM.WarnUnsupported(ILE, "initializer");
-    return 0;
-  }
-  
-  assert((ILE->getType()->isArrayType() || ILE->getType()->isStructureType() ||
-          ILE->getType()->isVectorType()) &&
-         "Bad type for init list!");
-  CodeGenTypes& Types = CGM.getTypes();
-
-  unsigned NumInitElements = ILE->getNumInits();
-  unsigned NumInitableElts = NumInitElements;
-
-  const llvm::CompositeType *CType = 
-    cast<llvm::CompositeType>(Types.ConvertType(ILE->getType()));
-  assert(CType);
-  std::vector<llvm::Constant*> Elts;    
-    
-  // Initialising an array requires us to automatically initialise any 
-  // elements that have not been initialised explicitly
-  const llvm::ArrayType *AType = 0; 
-  const llvm::Type *AElemTy = 0;
-  unsigned NumArrayElements = 0;
-  
-  // If this is an array, we may have to truncate the initializer
-  if ((AType = dyn_cast<llvm::ArrayType>(CType))) {
-    NumArrayElements = AType->getNumElements();
-    AElemTy = AType->getElementType();
-    NumInitableElts = std::min(NumInitableElts, NumArrayElements);
-  }
-    
-  // Copy initializer elements.
-  unsigned i = 0;
-  for (i = 0; i < NumInitableElts; ++i) {
-    llvm::Constant *C = GenerateConstantExpr(ILE->getInit(i), CGM);
-    // FIXME: Remove this when sema of initializers is finished (and the code
-    // above).
-    if (C == 0 && ILE->getInit(i)->getType()->isVoidType()) {
-      if (ILE->getType()->isVoidType()) return 0;
-      return llvm::UndefValue::get(CType);
-    }
-    assert (C && "Failed to create initialiser expression");
-    Elts.push_back(C);
-  }
-
-  if (ILE->getType()->isStructureType())
-    return llvm::ConstantStruct::get(cast<llvm::StructType>(CType), Elts);
-
-  if (ILE->getType()->isVectorType())
-    return llvm::ConstantVector::get(cast<llvm::VectorType>(CType), Elts);
-
-  // Make sure we have an array at this point
-  assert(AType);
-
-  // Initialize remaining array elements.
-  for (; i < NumArrayElements; ++i)
-    Elts.push_back(llvm::Constant::getNullValue(AElemTy));
-    
-  return llvm::ConstantArray::get(AType, Elts);    
-}
-
-/// GenerateConstantExpr - Recursively builds a constant initialiser for the
-/// given expression.
-static llvm::Constant *GenerateConstantExpr(const Expr *Expression, 
-                                            CodeGenModule &CGM) {
-  CodeGenTypes& Types = CGM.getTypes(); 
-  ASTContext& Context = CGM.getContext();
-  assert ((Expression->isConstantExpr(Context, 0) ||
-           Expression->getStmtClass() == Stmt::InitListExprClass) &&
-          "Only constant global initialisers are supported.");
-
-  QualType type = Expression->getType().getCanonicalType();
-
-  if (type->isIntegerType()) {
-    llvm::APSInt
-      Value(static_cast<uint32_t>(Context.getTypeSize(type, SourceLocation())));
-    if (Expression->isIntegerConstantExpr(Value, Context)) {
-      return llvm::ConstantInt::get(Value);
-    } 
-  }
-
-  switch (Expression->getStmtClass()) {
-  default: break; // default emits a warning and returns bogus value.
-  case Stmt::DeclRefExprClass:  {
-    const ValueDecl *Decl = cast<DeclRefExpr>(Expression)->getDecl();
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
-      return CGM.GetAddrOfFunctionDecl(FD, false);
-    break;
-  }
-      
-  // Generate constant for floating point literal values.
-  case Stmt::FloatingLiteralClass: {
-    const FloatingLiteral *FLiteral = cast<FloatingLiteral>(Expression);
-    return llvm::ConstantFP::get(Types.ConvertType(type), FLiteral->getValue());
-  }
-
-  // Generate constant for string literal values.
-  case Stmt::StringLiteralClass: {
-    const StringLiteral *String = cast<StringLiteral>(Expression);
-    const char *StrData = String->getStrData();
-    unsigned Len = String->getByteLength();
-
-    // If the string has a pointer type, emit it as a global and use the pointer
-    // to the global as its value.
-    if (String->getType()->isPointerType()) 
-      return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
-
-    // Otherwise this must be a string initializing an array in a static
-    // initializer.  Don't emit it as the address of the string, emit the string
-    // data itself as an inline array.
-    const ConstantArrayType *CAT = String->getType()->getAsConstantArrayType();
-    assert(CAT && "String isn't pointer or array!");
-    
-    std::string Str(StrData, StrData + Len);
-    // Null terminate the string before potentially truncating it.
-    // FIXME: What about wchar_t strings?
-    Str.push_back(0);
-          
-    uint64_t RealLen = CAT->getSize().getZExtValue();
-    // String or grow the initializer to the required size.
-    if (RealLen != Str.size())
-      Str.resize(RealLen);
-    
-    return llvm::ConstantArray::get(Str, false);
-  }
-
-  // Generate initializer for the CompoundLiteral
-  case Stmt::CompoundLiteralExprClass: {
-    const CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(Expression);
-    return GenerateConstantExpr(CLE->getInitializer(), CGM);
-  }
-
-  // Elide parenthesis.
-  case Stmt::ParenExprClass:
-    return GenerateConstantExpr(cast<ParenExpr>(Expression)->getSubExpr(), CGM);
-        
-  // Generate constant for sizeof operator.
-  // FIXME: Need to support AlignOf
-  case Stmt::SizeOfAlignOfTypeExprClass: {
-    const SizeOfAlignOfTypeExpr *SOExpr = 
-      cast<SizeOfAlignOfTypeExpr>(Expression);
-    assert (SOExpr->isSizeOf());
-    return llvm::ConstantExpr::getSizeOf(Types.ConvertType(type));
-  }
-
-  // Generate constant cast expressions.
-  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);
-    
-    // If this is due to array->pointer conversion, emit the array expression as
-    // an l-value.
-    if (ICExpr->getSubExpr()->getType()->isArrayType()) {
-      // Note that VLAs can't exist for global variables.
-      // The only thing that can have array type like this is a
-      // DeclRefExpr(FileVarDecl)?
-      const DeclRefExpr *DRE = cast<DeclRefExpr>(ICExpr->getSubExpr());
-      const VarDecl *VD = cast<VarDecl>(DRE->getDecl());
-      llvm::Constant *C = CGM.GetAddrOfGlobalVar(VD, false);
-      assert(isa<llvm::PointerType>(C->getType()) &&
-             isa<llvm::ArrayType>(cast<llvm::PointerType>(C->getType())
-                                  ->getElementType()));
-      llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
-      
-      llvm::Constant *Ops[] = {Idx0, Idx0};
-      C = llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
-      
-      // The resultant pointer type can be implicitly casted to other pointer
-      // types as well, for example void*.
-      const llvm::Type *DestPTy = Types.ConvertType(type);
-      assert(isa<llvm::PointerType>(DestPTy) &&
-             "Only expect implicit cast to pointer");
-      return llvm::ConstantExpr::getBitCast(C, DestPTy);
-    }
-    
-    return GenerateConstantCast(ICExpr->getSubExpr(), type, CGM);
-  }
-
-  // Generate a constant array access expression
-  // FIXME: Clang's semantic analysis incorrectly prevents array access in 
-  // global initialisers, preventing us from testing this.
-  case Stmt::ArraySubscriptExprClass: {
-    const ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(Expression);
-    llvm::Constant *Base = GenerateConstantExpr(ASExpr->getBase(), CGM);
-    llvm::Constant *Index = GenerateConstantExpr(ASExpr->getIdx(), CGM);
-    return llvm::ConstantExpr::getExtractElement(Base, Index);
-  }
-
-  // Generate a constant expression to initialise an aggregate type, such as 
-  // an array or struct.
-  case Stmt::InitListExprClass: 
-    return GenerateAggregateInit(cast<InitListExpr>(Expression), CGM);
-  }
-        
-  CGM.WarnUnsupported(Expression, "initializer");
-  return llvm::UndefValue::get(Types.ConvertType(type));
-}
-
-llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expression) {
-  return GenerateConstantExpr(Expression, *this);
+llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
+  return EmitConstantExpr(Expr);
 }
 
 void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
