summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/CodeGen')
-rw-r--r--clang/CodeGen/CGBuiltin.cpp486
-rw-r--r--clang/CodeGen/CGDecl.cpp163
-rw-r--r--clang/CodeGen/CGExpr.cpp615
-rw-r--r--clang/CodeGen/CGExprAgg.cpp337
-rw-r--r--clang/CodeGen/CGExprComplex.cpp542
-rw-r--r--clang/CodeGen/CGExprConstant.cpp627
-rw-r--r--clang/CodeGen/CGExprScalar.cpp1185
-rw-r--r--clang/CodeGen/CGObjC.cpp25
-rw-r--r--clang/CodeGen/CGObjCGNU.cpp97
-rw-r--r--clang/CodeGen/CGObjCRuntime.h47
-rw-r--r--clang/CodeGen/CGStmt.cpp776
-rw-r--r--clang/CodeGen/CodeGenFunction.cpp182
-rw-r--r--clang/CodeGen/CodeGenFunction.h486
-rw-r--r--clang/CodeGen/CodeGenModule.cpp509
-rw-r--r--clang/CodeGen/CodeGenModule.h129
-rw-r--r--clang/CodeGen/CodeGenTypes.cpp580
-rw-r--r--clang/CodeGen/CodeGenTypes.h165
-rw-r--r--clang/CodeGen/Makefile23
-rw-r--r--clang/CodeGen/ModuleBuilder.cpp104
19 files changed, 0 insertions, 7078 deletions
diff --git a/clang/CodeGen/CGBuiltin.cpp b/clang/CodeGen/CGBuiltin.cpp
deleted file mode 100644
index 83c5e60475c..00000000000
--- a/clang/CodeGen/CGBuiltin.cpp
+++ /dev/null
@@ -1,486 +0,0 @@
-//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Builtin calls as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Builtins.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/TargetBuiltins.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Intrinsics.h"
-using namespace clang;
-using namespace CodeGen;
-using namespace llvm;
-
-RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
- switch (BuiltinID) {
- default: {
- if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
- return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID),
- E->getCallee()->getType(), E->arg_begin(),
- E->getNumArgs());
-
- // See if we have a target specific intrinsic.
- Intrinsic::ID IntrinsicID;
- const char *TargetPrefix = Target.getTargetPrefix();
- const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID);
-#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-#include "llvm/Intrinsics.gen"
-#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
-
- if (IntrinsicID != Intrinsic::not_intrinsic) {
- SmallVector<Value*, 16> Args;
-
- Function *F = CGM.getIntrinsic(IntrinsicID);
- const llvm::FunctionType *FTy = F->getFunctionType();
-
- for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
- Value *ArgValue = EmitScalarExpr(E->getArg(i));
-
- // If the intrinsic arg type is different from the builtin arg type
- // we need to do a bit cast.
- const llvm::Type *PTy = FTy->getParamType(i);
- if (PTy != ArgValue->getType()) {
- assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
- "Must be able to losslessly bit cast to param");
- ArgValue = Builder.CreateBitCast(ArgValue, PTy);
- }
-
- Args.push_back(ArgValue);
- }
-
- Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size());
- QualType BuiltinRetType = E->getType();
-
- const llvm::Type *RetTy = llvm::Type::VoidTy;
- if (!BuiltinRetType->isVoidType()) RetTy = ConvertType(BuiltinRetType);
-
- if (RetTy != V->getType()) {
- assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
- "Must be able to losslessly bit cast result type");
- V = Builder.CreateBitCast(V, RetTy);
- }
-
- return RValue::get(V);
- }
-
- // See if we have a target specific builtin that needs to be lowered.
- Value *V = 0;
-
- if (strcmp(TargetPrefix, "x86") == 0)
- V = EmitX86BuiltinExpr(BuiltinID, E);
- else if (strcmp(TargetPrefix, "ppc") == 0)
- V = EmitPPCBuiltinExpr(BuiltinID, E);
-
- if (V)
- return RValue::get(V);
-
- WarnUnsupported(E, "builtin function");
-
- // Unknown builtin, for now just dump it out and return undef.
- if (hasAggregateLLVMType(E->getType()))
- return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType())));
- return RValue::get(UndefValue::get(ConvertType(E->getType())));
- }
- case Builtin::BI__builtin___CFStringMakeConstantString: {
- const Expr *Arg = E->getArg(0);
-
- while (1) {
- if (const ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
- Arg = PE->getSubExpr();
- else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = CE->getSubExpr();
- else
- break;
- }
-
- const StringLiteral *Literal = cast<StringLiteral>(Arg);
- std::string S(Literal->getStrData(), Literal->getByteLength());
-
- return RValue::get(CGM.GetAddrOfConstantCFString(S));
- }
- case Builtin::BI__builtin_va_start:
- case Builtin::BI__builtin_va_end: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
- const llvm::Type *DestType =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (ArgValue->getType() != DestType)
- ArgValue = Builder.CreateBitCast(ArgValue, DestType,
- ArgValue->getNameStart());
-
- Intrinsic::ID inst = (BuiltinID == Builtin::BI__builtin_va_start) ?
- Intrinsic::vastart : Intrinsic::vaend;
- return RValue::get(Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue));
- }
- case Builtin::BI__builtin_va_copy: {
- // FIXME: This does not yet handle architectures where va_list is a struct.
- Value *DstPtr = EmitScalarExpr(E->getArg(0));
- Value *SrcValue = EmitScalarExpr(E->getArg(1));
-
- Value *SrcPtr = CreateTempAlloca(SrcValue->getType(), "dst_ptr");
-
- // FIXME: Volatile
- Builder.CreateStore(SrcValue, SrcPtr, false);
-
- const llvm::Type *Type =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-
- DstPtr = Builder.CreateBitCast(DstPtr, Type);
- SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
- Value *Args[] = { DstPtr, SrcPtr };
- return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
- &Args[0], &Args[2]));
- }
- case Builtin::BI__builtin_classify_type: {
- APSInt Result(32);
- if (!E->isBuiltinClassifyType(Result))
- assert(0 && "Expr not __builtin_classify_type!");
- return RValue::get(ConstantInt::get(Result));
- }
- case Builtin::BI__builtin_constant_p: {
- APSInt Result(32);
- // FIXME: Analyze the parameter and check if it is a constant.
- Result = 0;
- return RValue::get(ConstantInt::get(Result));
- }
- case Builtin::BI__builtin_abs: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- llvm::BinaryOperator *NegOp =
- Builder.CreateNeg(ArgValue, (ArgValue->getName() + "neg").c_str());
- Value *CmpResult =
- Builder.CreateICmpSGE(ArgValue, NegOp->getOperand(0), "abscond");
- Value *Result =
- Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
-
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_ctz:
- case Builtin::BI__builtin_ctzl:
- case Builtin::BI__builtin_ctzll: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
-
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, &ArgType, 1);
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- Value *Result = Builder.CreateCall(F, ArgValue, "tmp");
- if (Result->getType() != ResultType)
- Result = Builder.CreateIntCast(Result, ResultType, "cast");
- return RValue::get(Result);
- }
- case Builtin::BI__builtin_expect:
- return RValue::get(EmitScalarExpr(E->getArg(0)));
- case Builtin::BI__builtin_bswap32:
- case Builtin::BI__builtin_bswap64: {
- Value *ArgValue = EmitScalarExpr(E->getArg(0));
- const llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
- return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
- }
- case Builtin::BI__builtin_inff: {
- APFloat f(APFloat::IEEEsingle, APFloat::fcInfinity, false);
- return RValue::get(ConstantFP::get(llvm::Type::FloatTy, f));
- }
- case Builtin::BI__builtin_huge_val:
- case Builtin::BI__builtin_inf:
- // FIXME: mapping long double onto double.
- case Builtin::BI__builtin_infl: {
- APFloat f(APFloat::IEEEdouble, APFloat::fcInfinity, false);
- return RValue::get(ConstantFP::get(llvm::Type::DoubleTy, f));
- }
- case Builtin::BI__builtin_isgreater:
- case Builtin::BI__builtin_isgreaterequal:
- case Builtin::BI__builtin_isless:
- case Builtin::BI__builtin_islessequal:
- case Builtin::BI__builtin_islessgreater:
- case Builtin::BI__builtin_isunordered: {
- // Ordered comparisons: we know the arguments to these are matching scalar
- // floating point values.
- Value *LHS = EmitScalarExpr(E->getArg(0));
- Value *RHS = EmitScalarExpr(E->getArg(1));
-
- switch (BuiltinID) {
- default: assert(0 && "Unknown ordered comparison");
- case Builtin::BI__builtin_isgreater:
- LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isgreaterequal:
- LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isless:
- LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_islessequal:
- LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_islessgreater:
- LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
- break;
- case Builtin::BI__builtin_isunordered:
- LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
- break;
- }
- // ZExt bool to int type.
- return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()),
- "tmp"));
- }
- case Builtin::BI__builtin_alloca:
- return RValue::get(Builder.CreateAlloca(llvm::Type::Int8Ty,
- EmitScalarExpr(E->getArg(0)),
- "tmp"));
- }
- return RValue::get(0);
-}
-
-Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
-
- llvm::SmallVector<Value*, 4> Ops;
-
- for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
- Ops.push_back(EmitScalarExpr(E->getArg(i)));
-
- switch (BuiltinID) {
- default: return 0;
- case X86::BI__builtin_ia32_mulps:
- return Builder.CreateMul(Ops[0], Ops[1], "mulps");
- case X86::BI__builtin_ia32_pand:
- return Builder.CreateAnd(Ops[0], Ops[1], "pand");
- case X86::BI__builtin_ia32_por:
- return Builder.CreateAnd(Ops[0], Ops[1], "por");
- case X86::BI__builtin_ia32_pxor:
- return Builder.CreateAnd(Ops[0], Ops[1], "pxor");
- case X86::BI__builtin_ia32_pandn: {
- Ops[0] = Builder.CreateNot(Ops[0], "tmp");
- return Builder.CreateAnd(Ops[0], Ops[1], "pandn");
- }
- case X86::BI__builtin_ia32_paddb:
- case X86::BI__builtin_ia32_paddd:
- case X86::BI__builtin_ia32_paddq:
- case X86::BI__builtin_ia32_paddw:
- case X86::BI__builtin_ia32_addps:
- return Builder.CreateAdd(Ops[0], Ops[1], "add");
- case X86::BI__builtin_ia32_psubb:
- case X86::BI__builtin_ia32_psubd:
- case X86::BI__builtin_ia32_psubq:
- case X86::BI__builtin_ia32_psubw:
- case X86::BI__builtin_ia32_subps:
- return Builder.CreateSub(Ops[0], Ops[1], "sub");
- case X86::BI__builtin_ia32_divps:
- return Builder.CreateFDiv(Ops[0], Ops[1], "divps");
- case X86::BI__builtin_ia32_pmullw:
- return Builder.CreateMul(Ops[0], Ops[1], "pmul");
- case X86::BI__builtin_ia32_punpckhbw:
- return EmitShuffleVector(Ops[0], Ops[1], 4, 12, 5, 13, 6, 14, 7, 15,
- "punpckhbw");
- case X86::BI__builtin_ia32_punpckhwd:
- return EmitShuffleVector(Ops[0], Ops[1], 2, 6, 3, 7, "punpckhwd");
- case X86::BI__builtin_ia32_punpckhdq:
- return EmitShuffleVector(Ops[0], Ops[1], 1, 3, "punpckhdq");
- case X86::BI__builtin_ia32_punpcklbw:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 8, 1, 9, 2, 10, 3, 11,
- "punpcklbw");
- case X86::BI__builtin_ia32_punpcklwd:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 4, 1, 5, "punpcklwd");
- case X86::BI__builtin_ia32_punpckldq:
- return EmitShuffleVector(Ops[0], Ops[1], 0, 2, "punpckldq");
- case X86::BI__builtin_ia32_pslldi:
- case X86::BI__builtin_ia32_psllqi:
- case X86::BI__builtin_ia32_psllwi:
- case X86::BI__builtin_ia32_psradi:
- case X86::BI__builtin_ia32_psrawi:
- case X86::BI__builtin_ia32_psrldi:
- case X86::BI__builtin_ia32_psrlqi:
- case X86::BI__builtin_ia32_psrlwi: {
- Ops[1] = Builder.CreateZExt(Ops[1], llvm::Type::Int64Ty, "zext");
- const llvm::Type *Ty = llvm::VectorType::get(llvm::Type::Int64Ty, 1);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ty, "bitcast");
- const char *name = 0;
- Intrinsic::ID ID = Intrinsic::not_intrinsic;
-
- switch (BuiltinID) {
- default: assert(0 && "Unsupported shift intrinsic!");
- case X86::BI__builtin_ia32_pslldi:
- name = "pslldi";
- ID = Intrinsic::x86_mmx_psll_d;
- break;
- case X86::BI__builtin_ia32_psllqi:
- name = "psllqi";
- ID = Intrinsic::x86_mmx_psll_q;
- break;
- case X86::BI__builtin_ia32_psllwi:
- name = "psllwi";
- ID = Intrinsic::x86_mmx_psll_w;
- break;
- case X86::BI__builtin_ia32_psradi:
- name = "psradi";
- ID = Intrinsic::x86_mmx_psra_d;
- break;
- case X86::BI__builtin_ia32_psrawi:
- name = "psrawi";
- ID = Intrinsic::x86_mmx_psra_w;
- break;
- case X86::BI__builtin_ia32_psrldi:
- name = "psrldi";
- ID = Intrinsic::x86_mmx_psrl_d;
- break;
- case X86::BI__builtin_ia32_psrlqi:
- name = "psrlqi";
- ID = Intrinsic::x86_mmx_psrl_q;
- break;
- case X86::BI__builtin_ia32_psrlwi:
- name = "psrlwi";
- ID = Intrinsic::x86_mmx_psrl_w;
- break;
- }
- llvm::Function *F = CGM.getIntrinsic(ID);
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_pshufd: {
- unsigned i = cast<ConstantInt>(Ops[1])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[0],
- i & 0x3, (i & 0xc) >> 2,
- (i & 0x30) >> 4, (i & 0xc0) >> 6,
- "pshufd");
- }
- case X86::BI__builtin_ia32_vec_init_v4hi:
- case X86::BI__builtin_ia32_vec_init_v8qi:
- case X86::BI__builtin_ia32_vec_init_v2si:
- return EmitVector(&Ops[0], Ops.size());
- case X86::BI__builtin_ia32_vec_ext_v2si:
- return Builder.CreateExtractElement(Ops[0], Ops[1], "result");
- case X86::BI__builtin_ia32_cmpordss:
- case X86::BI__builtin_ia32_cmpunordss:
- case X86::BI__builtin_ia32_cmpeqss:
- case X86::BI__builtin_ia32_cmpltss:
- case X86::BI__builtin_ia32_cmpless:
- case X86::BI__builtin_ia32_cmpneqss:
- case X86::BI__builtin_ia32_cmpnltss:
- case X86::BI__builtin_ia32_cmpnless: {
- unsigned i = 0;
- const char *name = 0;
- switch (BuiltinID) {
- default: assert(0 && "Unknown compare builtin!");
- case X86::BI__builtin_ia32_cmpeqss:
- i = 0;
- name = "cmpeqss";
- break;
- case X86::BI__builtin_ia32_cmpltss:
- i = 1;
- name = "cmpltss";
- break;
- case X86::BI__builtin_ia32_cmpless:
- i = 2;
- name = "cmpless";
- break;
- case X86::BI__builtin_ia32_cmpunordss:
- i = 3;
- name = "cmpunordss";
- break;
- case X86::BI__builtin_ia32_cmpneqss:
- i = 4;
- name = "cmpneqss";
- break;
- case X86::BI__builtin_ia32_cmpnltss:
- i = 5;
- name = "cmpntlss";
- break;
- case X86::BI__builtin_ia32_cmpnless:
- i = 6;
- name = "cmpnless";
- break;
- case X86::BI__builtin_ia32_cmpordss:
- i = 7;
- name = "cmpordss";
- break;
- }
-
- Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
- llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ss);
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_cmpordps:
- case X86::BI__builtin_ia32_cmpunordps:
- case X86::BI__builtin_ia32_cmpeqps:
- case X86::BI__builtin_ia32_cmpltps:
- case X86::BI__builtin_ia32_cmpleps:
- case X86::BI__builtin_ia32_cmpneqps:
- case X86::BI__builtin_ia32_cmpngtps:
- case X86::BI__builtin_ia32_cmpnltps:
- case X86::BI__builtin_ia32_cmpgtps:
- case X86::BI__builtin_ia32_cmpgeps:
- case X86::BI__builtin_ia32_cmpngeps:
- case X86::BI__builtin_ia32_cmpnleps: {
- unsigned i = 0;
- const char *name = 0;
- bool ShouldSwap = false;
- switch (BuiltinID) {
- default: assert(0 && "Unknown compare builtin!");
- case X86::BI__builtin_ia32_cmpeqps: i = 0; name = "cmpeqps"; break;
- case X86::BI__builtin_ia32_cmpltps: i = 1; name = "cmpltps"; break;
- case X86::BI__builtin_ia32_cmpleps: i = 2; name = "cmpleps"; break;
- case X86::BI__builtin_ia32_cmpunordps: i = 3; name = "cmpunordps"; break;
- case X86::BI__builtin_ia32_cmpneqps: i = 4; name = "cmpneqps"; break;
- case X86::BI__builtin_ia32_cmpnltps: i = 5; name = "cmpntlps"; break;
- case X86::BI__builtin_ia32_cmpnleps: i = 6; name = "cmpnleps"; break;
- case X86::BI__builtin_ia32_cmpordps: i = 7; name = "cmpordps"; break;
- case X86::BI__builtin_ia32_cmpgtps:
- ShouldSwap = true;
- i = 1;
- name = "cmpgtps";
- break;
- case X86::BI__builtin_ia32_cmpgeps:
- i = 2;
- name = "cmpgeps";
- ShouldSwap = true;
- break;
- case X86::BI__builtin_ia32_cmpngtps:
- i = 5;
- name = "cmpngtps";
- ShouldSwap = true;
- break;
- case X86::BI__builtin_ia32_cmpngeps:
- i = 6;
- name = "cmpngeps";
- ShouldSwap = true;
- break;
- }
-
- if (ShouldSwap)
- std::swap(Ops[0], Ops[1]);
-
- Ops.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, i));
- llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_sse_cmp_ps);
- return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
- }
- case X86::BI__builtin_ia32_movss:
- return EmitShuffleVector(Ops[0], Ops[1], 4, 1, 2, 3, "movss");
- case X86::BI__builtin_ia32_shufps:
- unsigned i = cast<ConstantInt>(Ops[2])->getZExtValue();
- return EmitShuffleVector(Ops[0], Ops[1],
- i & 0x3, (i & 0xc) >> 2,
- ((i & 0x30) >> 4) + 4,
- ((i & 0x60) >> 6) + 4, "shufps");
- }
-}
-
-Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
- switch (BuiltinID) {
- default: return 0;
- }
-}
diff --git a/clang/CodeGen/CGDecl.cpp b/clang/CodeGen/CGDecl.cpp
deleted file mode 100644
index c80cecc76ee..00000000000
--- a/clang/CodeGen/CGDecl.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Decl nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/AST.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Type.h"
-using namespace clang;
-using namespace CodeGen;
-
-
-void CodeGenFunction::EmitDecl(const Decl &D) {
- switch (D.getKind()) {
- default: assert(0 && "Unknown decl kind!");
- case Decl::FileVar:
- assert(0 && "Should not see file-scope variables inside a function!");
- case Decl::ParmVar:
- assert(0 && "Parmdecls should not be in declstmts!");
- case Decl::Typedef: // typedef int X;
- case Decl::Function: // void X();
- case Decl::Struct: // struct X;
- case Decl::Union: // union X;
- case Decl::Class: // class X;
- case Decl::Enum: // enum X;
- // None of these decls require codegen support.
- return;
-
- case Decl::BlockVar:
- return EmitBlockVarDecl(cast<BlockVarDecl>(D));
- case Decl::EnumConstant:
- return EmitEnumConstantDecl(cast<EnumConstantDecl>(D));
- }
-}
-
-void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
- assert(0 && "FIXME: Enum constant decls not implemented yet!");
-}
-
-/// EmitBlockVarDecl - This method handles emission of any variable declaration
-/// inside a function, including static vars etc.
-void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
- switch (D.getStorageClass()) {
- case VarDecl::Static:
- return EmitStaticBlockVarDecl(D);
- case VarDecl::Extern:
- // Don't emit it now, allow it to be emitted lazily on its first use.
- return;
- default:
- assert((D.getStorageClass() == VarDecl::None ||
- D.getStorageClass() == VarDecl::Auto ||
- D.getStorageClass() == VarDecl::Register) &&
- "Unknown storage class");
- return EmitLocalBlockVarDecl(D);
- }
-}
-
-void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
- QualType Ty = D.getCanonicalType();
- assert(Ty->isConstantSizeType() && "VLAs can't be static");
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
-
- const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
- llvm::Constant *Init = 0;
- if (D.getInit() == 0) {
- Init = llvm::Constant::getNullValue(LTy);
- } else {
- Init = CGM.EmitConstantExpr(D.getInit(), this);
- }
-
- assert(Init && "Unable to create initialiser for static decl");
-
- std::string ContextName;
- if (CurFuncDecl)
- ContextName = CurFuncDecl->getName();
- else
- assert(0 && "Unknown context for block var decl"); // FIXME Handle objc.
-
- DMEntry =
- new llvm::GlobalVariable(LTy, false,
- llvm::GlobalValue::InternalLinkage,
- Init, ContextName + "." + D.getName(),
- &CGM.getModule(), 0,
- Ty.getAddressSpace());
-
-}
-
-/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
-/// variable declaration with auto, register, or no storage class specifier.
-/// These turn into simple stack objects.
-void CodeGenFunction::EmitLocalBlockVarDecl(const BlockVarDecl &D) {
- QualType Ty = D.getCanonicalType();
-
- llvm::Value *DeclPtr;
- if (Ty->isConstantSizeType()) {
- // A normal fixed sized variable becomes an alloca in the entry block.
- const llvm::Type *LTy = ConvertType(Ty);
- // TODO: Alignment
- DeclPtr = CreateTempAlloca(LTy, D.getName());
- } else {
- // TODO: Create a dynamic alloca.
- assert(0 && "FIXME: Local VLAs not implemented yet");
- }
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
- DMEntry = DeclPtr;
-
- // If this local has an initializer, emit it now.
- if (const Expr *Init = D.getInit()) {
- if (!hasAggregateLLVMType(Init->getType())) {
- llvm::Value *V = EmitScalarExpr(Init);
- Builder.CreateStore(V, DeclPtr, D.getType().isVolatileQualified());
- } else if (Init->getType()->isComplexType()) {
- EmitComplexExprIntoAddr(Init, DeclPtr, D.getType().isVolatileQualified());
- } else {
- EmitAggExpr(Init, DeclPtr, D.getType().isVolatileQualified());
- }
- }
-}
-
-/// Emit an alloca for the specified parameter and set up LocalDeclMap.
-void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
- QualType Ty = D.getCanonicalType();
-
- llvm::Value *DeclPtr;
- if (!Ty->isConstantSizeType()) {
- // Variable sized values always are passed by-reference.
- DeclPtr = Arg;
- } else {
- // A fixed sized first class variable becomes an alloca in the entry block.
- const llvm::Type *LTy = ConvertType(Ty);
- if (LTy->isFirstClassType()) {
- // TODO: Alignment
- DeclPtr = new llvm::AllocaInst(LTy, 0, std::string(D.getName())+".addr",
- AllocaInsertPt);
-
- // Store the initial value into the alloca.
- Builder.CreateStore(Arg, DeclPtr);
- } else {
- // Otherwise, if this is an aggregate, just use the input pointer.
- DeclPtr = Arg;
- }
- Arg->setName(D.getName());
- }
-
- llvm::Value *&DMEntry = LocalDeclMap[&D];
- assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
- DMEntry = DeclPtr;
-}
-
diff --git a/clang/CodeGen/CGExpr.cpp b/clang/CodeGen/CGExpr.cpp
deleted file mode 100644
index 932a5c5da8b..00000000000
--- a/clang/CodeGen/CGExpr.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/AST.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/MathExtras.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===--------------------------------------------------------------------===//
-// Miscellaneous Helper Methods
-//===--------------------------------------------------------------------===//
-
-/// CreateTempAlloca - This creates a alloca and inserts it into the entry
-/// block.
-llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
- const char *Name) {
- return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
-}
-
-/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
-/// expression and compare the result against zero, returning an Int1Ty value.
-llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
- QualType BoolTy = getContext().BoolTy;
- if (!E->getType()->isComplexType())
- return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
-
- return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
-}
-
-/// EmitAnyExpr - Emit code to compute the specified expression which can have
-/// any type. The result is returned as an RValue struct. If this is an
-/// aggregate expression, the aggloc/agglocvolatile arguments indicate where
-/// the result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
- bool isAggLocVolatile) {
- if (!hasAggregateLLVMType(E->getType()))
- return RValue::get(EmitScalarExpr(E));
- else if (E->getType()->isComplexType())
- return RValue::getComplex(EmitComplexExpr(E));
-
- EmitAggExpr(E, AggLoc, isAggLocVolatile);
- return RValue::getAggregate(AggLoc);
-}
-
-
-//===----------------------------------------------------------------------===//
-// LValue Expression Emission
-//===----------------------------------------------------------------------===//
-
-/// EmitLValue - Emit code to compute a designator that specifies the location
-/// of the expression.
-///
-/// This can return one of two things: a simple address or a bitfield
-/// reference. In either case, the LLVM Value* in the LValue structure is
-/// guaranteed to be an LLVM pointer type.
-///
-/// If this returns a bitfield reference, nothing about the pointee type of
-/// the LLVM value is known: For example, it may not be a pointer to an
-/// integer.
-///
-/// If this returns a normal address, and if the lvalue's C type is fixed
-/// size, this method guarantees that the returned pointer type will point to
-/// an LLVM type of the same size of the lvalue's type. If the lvalue has a
-/// variable length type, this is not possible.
-///
-LValue CodeGenFunction::EmitLValue(const Expr *E) {
- switch (E->getStmtClass()) {
- default: {
- WarnUnsupported(E, "l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return LValue::MakeAddr(llvm::UndefValue::get(Ty));
- }
-
- case Expr::CallExprClass: return EmitCallExprLValue(cast<CallExpr>(E));
- case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
- case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
- case Expr::PreDefinedExprClass:
- return EmitPreDefinedLValue(cast<PreDefinedExpr>(E));
- case Expr::StringLiteralClass:
- return EmitStringLiteralLValue(cast<StringLiteral>(E));
-
- case Expr::UnaryOperatorClass:
- return EmitUnaryOpLValue(cast<UnaryOperator>(E));
- case Expr::ArraySubscriptExprClass:
- return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
- case Expr::OCUVectorElementExprClass:
- return EmitOCUVectorElementExpr(cast<OCUVectorElementExpr>(E));
- case Expr::MemberExprClass: return EmitMemberExpr(cast<MemberExpr>(E));
- }
-}
-
-/// EmitLoadOfLValue - Given an expression that represents a value lvalue,
-/// this method emits the address of the lvalue, then loads the result as an
-/// rvalue, returning the rvalue.
-RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
- if (LV.isSimple()) {
- llvm::Value *Ptr = LV.getAddress();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
-
- // Simple scalar l-value.
- if (EltTy->isFirstClassType()) {
- llvm::Value *V = Builder.CreateLoad(Ptr, "tmp");
-
- // Bool can have different representation in memory than in registers.
- if (ExprType->isBooleanType()) {
- if (V->getType() != llvm::Type::Int1Ty)
- V = Builder.CreateTrunc(V, llvm::Type::Int1Ty, "tobool");
- }
-
- return RValue::get(V);
- }
-
- assert(ExprType->isFunctionType() && "Unknown scalar value");
- return RValue::get(Ptr);
- }
-
- if (LV.isVectorElt()) {
- llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(), "tmp");
- return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
- "vecext"));
- }
-
- // If this is a reference to a subset of the elements of a vector, either
- // shuffle the input or extract/insert them as appropriate.
- if (LV.isOCUVectorElt())
- return EmitLoadOfOCUElementLValue(LV, ExprType);
-
- if (LV.isBitfield())
- return EmitLoadOfBitfieldLValue(LV, ExprType);
-
- assert(0 && "Unknown LValue type!");
- //an invalid RValue, but the assert will
- //ensure that this point is never reached
- return RValue();
-}
-
-RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
- QualType ExprType) {
- llvm::Value *Ptr = LV.getBitfieldAddr();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
- unsigned short BitfieldSize = LV.getBitfieldSize();
- unsigned short EndBit = LV.getBitfieldStartBit() + BitfieldSize;
-
- llvm::Value *V = Builder.CreateLoad(Ptr, "tmp");
-
- llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - EndBit);
- V = Builder.CreateShl(V, ShAmt, "tmp");
-
- ShAmt = llvm::ConstantInt::get(EltTy, EltTySize - BitfieldSize);
- V = LV.isBitfieldSigned() ?
- Builder.CreateAShr(V, ShAmt, "tmp") :
- Builder.CreateLShr(V, ShAmt, "tmp");
- return RValue::get(V);
-}
-
-// If this is a reference to a subset of the elements of a vector, either
-// shuffle the input or extract/insert them as appropriate.
-RValue CodeGenFunction::EmitLoadOfOCUElementLValue(LValue LV,
- QualType ExprType) {
- llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp");
-
- unsigned EncFields = LV.getOCUVectorElts();
-
- // If the result of the expression is a non-vector type, we must be
- // extracting a single element. Just codegen as an extractelement.
- const VectorType *ExprVT = ExprType->getAsVectorType();
- if (!ExprVT) {
- unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(0, EncFields);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
- }
-
- // If the source and destination have the same number of elements, use a
- // vector shuffle instead of insert/extracts.
- unsigned NumResultElts = ExprVT->getNumElements();
- unsigned NumSourceElts =
- cast<llvm::VectorType>(Vec->getType())->getNumElements();
-
- if (NumResultElts == NumSourceElts) {
- llvm::SmallVector<llvm::Constant*, 4> Mask;
- for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
- Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
- }
-
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
- Vec = Builder.CreateShuffleVector(Vec,
- llvm::UndefValue::get(Vec->getType()),
- MaskV, "tmp");
- return RValue::get(Vec);
- }
-
- // Start out with an undef of the result type.
- llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
-
- // Extract/Insert each element of the result.
- for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
-
- llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
- }
-
- return RValue::get(Result);
-}
-
-
-
-/// EmitStoreThroughLValue - Store the specified rvalue into the specified
-/// lvalue, where both are guaranteed to the have the same type, and that type
-/// is 'Ty'.
-void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
- QualType Ty) {
- if (!Dst.isSimple()) {
- if (Dst.isVectorElt()) {
- // Read/modify/write the vector, inserting the new element.
- // FIXME: Volatility.
- llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), "tmp");
- Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
- Dst.getVectorIdx(), "vecins");
- Builder.CreateStore(Vec, Dst.getVectorAddr());
- return;
- }
-
- // If this is an update of elements of a vector, insert them as appropriate.
- if (Dst.isOCUVectorElt())
- return EmitStoreThroughOCUComponentLValue(Src, Dst, Ty);
-
- if (Dst.isBitfield())
- return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
-
- assert(0 && "Unknown LValue type");
- }
-
- llvm::Value *DstAddr = Dst.getAddress();
- assert(Src.isScalar() && "Can't emit an agg store with this method");
- // FIXME: Handle volatility etc.
- const llvm::Type *SrcTy = Src.getScalarVal()->getType();
- const llvm::PointerType *DstPtr = cast<llvm::PointerType>(DstAddr->getType());
- const llvm::Type *AddrTy = DstPtr->getElementType();
- unsigned AS = DstPtr->getAddressSpace();
-
- if (AddrTy != SrcTy)
- DstAddr = Builder.CreateBitCast(DstAddr,
- llvm::PointerType::get(SrcTy, AS),
- "storetmp");
- Builder.CreateStore(Src.getScalarVal(), DstAddr);
-}
-
-void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
- QualType Ty) {
- unsigned short StartBit = Dst.getBitfieldStartBit();
- unsigned short BitfieldSize = Dst.getBitfieldSize();
- llvm::Value *Ptr = Dst.getBitfieldAddr();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
-
- llvm::Value *NewVal = Src.getScalarVal();
- llvm::Value *OldVal = Builder.CreateLoad(Ptr, "tmp");
-
- llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, StartBit);
- NewVal = Builder.CreateShl(NewVal, ShAmt, "tmp");
-
- llvm::Constant *Mask = llvm::ConstantInt::get(
- llvm::APInt::getBitsSet(EltTySize, StartBit,
- StartBit + BitfieldSize));
-
- // Mask out any bits that shouldn't be set in the result.
- NewVal = Builder.CreateAnd(NewVal, Mask, "tmp");
-
- // Next, mask out the bits this bit-field should include from the old value.
- Mask = llvm::ConstantExpr::getNot(Mask);
- OldVal = Builder.CreateAnd(OldVal, Mask, "tmp");
-
- // Finally, merge the two together and store it.
- NewVal = Builder.CreateOr(OldVal, NewVal, "tmp");
-
- Builder.CreateStore(NewVal, Ptr);
-}
-
-void CodeGenFunction::EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst,
- QualType Ty) {
- // This access turns into a read/modify/write of the vector. Load the input
- // value now.
- llvm::Value *Vec = Builder.CreateLoad(Dst.getOCUVectorAddr(), "tmp");
- // FIXME: Volatility.
- unsigned EncFields = Dst.getOCUVectorElts();
-
- llvm::Value *SrcVal = Src.getScalarVal();
-
- if (const VectorType *VTy = Ty->getAsVectorType()) {
- unsigned NumSrcElts = VTy->getNumElements();
-
- // Extract/Insert each element.
- for (unsigned i = 0; i != NumSrcElts; ++i) {
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
-
- unsigned Idx = OCUVectorElementExpr::getAccessedFieldNo(i, EncFields);
- llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
- Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
- }
- } else {
- // If the Src is a scalar (not a vector) it must be updating one element.
- unsigned InIdx = OCUVectorElementExpr::getAccessedFieldNo(0, EncFields);
- llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
- Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
- }
-
- Builder.CreateStore(Vec, Dst.getOCUVectorAddr());
-}
-
-
-LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
- const ValueDecl *D = E->getDecl();
- if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
- const VarDecl *VD = cast<VarDecl>(D);
- if (VD->getStorageClass() == VarDecl::Extern)
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
- else {
- llvm::Value *V = LocalDeclMap[D];
- assert(V && "BlockVarDecl not entered in LocalDeclMap?");
- return LValue::MakeAddr(V);
- }
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- return LValue::MakeAddr(CGM.GetAddrOfFunctionDecl(FD, false));
- } else if (const FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
- return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(FVD, false));
- }
- assert(0 && "Unimp declref");
- //an invalid LValue, but the assert will
- //ensure that this point is never reached.
- return LValue();
-}
-
-LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
- // __extension__ doesn't affect lvalue-ness.
- if (E->getOpcode() == UnaryOperator::Extension)
- return EmitLValue(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) {
- assert(!E->isWide() && "FIXME: Wide strings not supported yet!");
- const char *StrData = E->getStrData();
- unsigned Len = E->getByteLength();
- std::string StringLiteral(StrData, StrData+Len);
- return LValue::MakeAddr(CGM.GetAddrOfConstantString(StringLiteral));
-}
-
-LValue CodeGenFunction::EmitPreDefinedLValue(const PreDefinedExpr *E) {
- std::string FunctionName(CurFuncDecl->getName());
- std::string GlobalVarName;
-
- switch (E->getIdentType()) {
- default:
- assert(0 && "unknown pre-defined ident type");
- case PreDefinedExpr::Func:
- GlobalVarName = "__func__.";
- break;
- case PreDefinedExpr::Function:
- GlobalVarName = "__FUNCTION__.";
- break;
- case PreDefinedExpr::PrettyFunction:
- // FIXME:: Demangle C++ method names
- GlobalVarName = "__PRETTY_FUNCTION__.";
- break;
- }
-
- GlobalVarName += CurFuncDecl->getName();
-
- // FIXME: Can cache/reuse these within the module.
- llvm::Constant *C=llvm::ConstantArray::get(FunctionName);
-
- // Create a global variable for this.
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, GlobalVarName, CurFn->getParent());
- return LValue::MakeAddr(C);
-}
-
-LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
- // The index must always be an integer, which is not an aggregate. Emit it.
- llvm::Value *Idx = EmitScalarExpr(E->getIdx());
-
- // If the base is a vector type, then we are forming a vector element lvalue
- // with this subscript.
- if (E->getLHS()->getType()->isVectorType()) {
- // Emit the vector as an lvalue to get its address.
- LValue LHS = EmitLValue(E->getLHS());
- assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
- // FIXME: This should properly sign/zero/extend or truncate Idx to i32.
- return LValue::MakeVectorElt(LHS.getAddress(), Idx);
- }
-
- // The base must be a pointer, which is not an aggregate. Emit it.
- llvm::Value *Base = EmitScalarExpr(E->getBase());
-
- // Extend or truncate the index type to 32 or 64-bits.
- QualType IdxTy = E->getIdx()->getType();
- bool IdxSigned = IdxTy->isSignedIntegerType();
- unsigned IdxBitwidth = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (IdxBitwidth != LLVMPointerWidth)
- Idx = Builder.CreateIntCast(Idx, llvm::IntegerType::get(LLVMPointerWidth),
- IdxSigned, "idxprom");
-
- // We know that the pointer points to a type of the correct size, unless the
- // size is a VLA.
- if (!E->getType()->isConstantSizeType())
- assert(0 && "VLA idx not implemented");
- return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
-}
-
-LValue CodeGenFunction::
-EmitOCUVectorElementExpr(const OCUVectorElementExpr *E) {
- // Emit the base vector as an l-value.
- LValue Base = EmitLValue(E->getBase());
- assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
-
- return LValue::MakeOCUVectorElt(Base.getAddress(),
- E->getEncodedElementAccess());
-}
-
-LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
- bool isUnion = false;
- Expr *BaseExpr = E->getBase();
- llvm::Value *BaseValue = NULL;
-
- // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
- if (E->isArrow()) {
- BaseValue = EmitScalarExpr(BaseExpr);
- const PointerType *PTy =
- cast<PointerType>(BaseExpr->getType().getCanonicalType());
- if (PTy->getPointeeType()->isUnionType())
- isUnion = true;
- }
- else {
- LValue BaseLV = EmitLValue(BaseExpr);
- // FIXME: this isn't right for bitfields.
- BaseValue = BaseLV.getAddress();
- if (BaseExpr->getType()->isUnionType())
- isUnion = true;
- }
-
- FieldDecl *Field = E->getMemberDecl();
- return EmitLValueForField(BaseValue, Field, isUnion);
-}
-
-LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
- FieldDecl* Field,
- bool isUnion)
-{
- llvm::Value *V;
- unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
-
- if (Field->isBitField()) {
- const llvm::Type * FieldTy = ConvertType(Field->getType());
- const llvm::PointerType * BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- unsigned AS = BaseTy->getAddressSpace();
- BaseValue = Builder.CreateBitCast(BaseValue,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
- V = Builder.CreateGEP(BaseValue,
- llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
- "tmp");
- } else {
- llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
- V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
- }
- // Match union field type.
- if (isUnion) {
- const llvm::Type * FieldTy = ConvertType(Field->getType());
- const llvm::PointerType * BaseTy =
- cast<llvm::PointerType>(BaseValue->getType());
- if (FieldTy != BaseTy->getElementType()) {
- unsigned AS = BaseTy->getAddressSpace();
- V = Builder.CreateBitCast(V,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
- }
- }
-
- if (Field->isBitField()) {
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
- Field->getType()->isSignedIntegerType());
- } else
- return LValue::MakeAddr(V);
-}
-
-//===--------------------------------------------------------------------===//
-// Expression Emission
-//===--------------------------------------------------------------------===//
-
-
-RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
- if (const ImplicitCastExpr *IcExpr =
- dyn_cast<const ImplicitCastExpr>(E->getCallee()))
- if (const DeclRefExpr *DRExpr =
- dyn_cast<const DeclRefExpr>(IcExpr->getSubExpr()))
- if (const FunctionDecl *FDecl =
- dyn_cast<const FunctionDecl>(DRExpr->getDecl()))
- if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID())
- return EmitBuiltinExpr(builtinID, E);
-
- llvm::Value *Callee = EmitScalarExpr(E->getCallee());
- return EmitCallExpr(Callee, E->getCallee()->getType(),
- E->arg_begin(), E->getNumArgs());
-}
-
-RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr, Expr *const *Args,
- unsigned NumArgs) {
- llvm::Value *Callee = EmitScalarExpr(FnExpr);
- return EmitCallExpr(Callee, FnExpr->getType(), Args, NumArgs);
-}
-
-LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
- // Can only get l-value for call expression returning aggregate type
- RValue RV = EmitCallExpr(E);
- return LValue::MakeAddr(RV.getAggregateAddr());
-}
-
-RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType,
- Expr *const *ArgExprs, unsigned NumArgs) {
- // The callee type will always be a pointer to function type, get the function
- // type.
- FnType = cast<PointerType>(FnType.getCanonicalType())->getPointeeType();
- QualType ResultType = cast<FunctionType>(FnType)->getResultType();
-
- llvm::SmallVector<llvm::Value*, 16> Args;
-
- // Handle struct-return functions by passing a pointer to the location that
- // we would like to return into.
- if (hasAggregateLLVMType(ResultType)) {
- // Create a temporary alloca to hold the result of the call. :(
- Args.push_back(CreateTempAlloca(ConvertType(ResultType)));
- // FIXME: set the stret attribute on the argument.
- }
-
- for (unsigned i = 0, e = NumArgs; i != e; ++i) {
- QualType ArgTy = ArgExprs[i]->getType();
-
- if (!hasAggregateLLVMType(ArgTy)) {
- // Scalar argument is passed by-value.
- Args.push_back(EmitScalarExpr(ArgExprs[i]));
- } else if (ArgTy->isComplexType()) {
- // Make a temporary alloca to pass the argument.
- llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
- EmitComplexExprIntoAddr(ArgExprs[i], DestMem, false);
- Args.push_back(DestMem);
- } else {
- llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
- EmitAggExpr(ArgExprs[i], DestMem, false);
- Args.push_back(DestMem);
- }
- }
-
- llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
- if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
- CI->setCallingConv(F->getCallingConv());
- if (CI->getType() != llvm::Type::VoidTy)
- CI->setName("call");
- else if (ResultType->isComplexType())
- return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
- else if (hasAggregateLLVMType(ResultType))
- // Struct return.
- return RValue::getAggregate(Args[0]);
- else {
- // void return.
- assert(ResultType->isVoidType() && "Should only have a void expr here");
- CI = 0;
- }
-
- return RValue::get(CI);
-}
diff --git a/clang/CodeGen/CGExprAgg.cpp b/clang/CodeGen/CGExprAgg.cpp
deleted file mode 100644
index 325ac2109eb..00000000000
--- a/clang/CodeGen/CGExprAgg.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Aggregate Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/AST.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/Compiler.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Aggregate Expression Emitter
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
- CodeGenFunction &CGF;
- llvm::LLVMFoldingBuilder &Builder;
- llvm::Value *DestPtr;
- bool VolatileDest;
-public:
- AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
- : CGF(cgf), Builder(CGF.Builder),
- DestPtr(destPtr), VolatileDest(volatileDest) {
- }
-
- //===--------------------------------------------------------------------===//
- // Utilities
- //===--------------------------------------------------------------------===//
-
- /// EmitAggLoadOfLValue - Given an expression with aggregate type that
- /// represents a value lvalue, this method emits the address of the lvalue,
- /// then loads the result into DestPtr.
- void EmitAggLoadOfLValue(const Expr *E);
-
- void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
- QualType EltTy);
-
- void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
-
- void EmitNonConstInit(InitListExpr *E);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- void VisitStmt(Stmt *S) {
- CGF.WarnUnsupported(S, "aggregate expression");
- }
- void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
-
- // l-values.
- void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
- void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
- void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
- void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
-
- void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- EmitAggLoadOfLValue(E);
- }
-
- // Operators.
- // case Expr::UnaryOperatorClass:
- // case Expr::CastExprClass:
- void VisitImplicitCastExpr(ImplicitCastExpr *E);
- void VisitCallExpr(const CallExpr *E);
- void VisitStmtExpr(const StmtExpr *E);
- void VisitBinaryOperator(const BinaryOperator *BO);
- void VisitBinAssign(const BinaryOperator *E);
- void VisitOverloadExpr(const OverloadExpr *E);
-
-
- void VisitConditionalOperator(const ConditionalOperator *CO);
- void VisitInitListExpr(InitListExpr *E);
- // case Expr::ChooseExprClass:
-
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-void AggExprEmitter::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
- assert(!Ty->isComplexType() && "Shouldn't happen for complex");
-
- // Aggregate assignment turns into llvm.memset.
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (DestPtr->getType() != BP)
- DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
-
- // Get size and alignment info for this aggregate.
- std::pair<uint64_t, unsigned> TypeInfo = CGF.getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
-
- llvm::Value *MemSetOps[4] = {
- DestPtr,
- llvm::ConstantInt::getNullValue(llvm::Type::Int8Ty),
- // TypeInfo.first describes size in bits.
- llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second/8)
- };
-
- Builder.CreateCall(CGF.CGM.getMemSetFn(), MemSetOps, MemSetOps+4);
-}
-
-void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
- llvm::Value *SrcPtr, QualType Ty) {
- assert(!Ty->isComplexType() && "Shouldn't happen for complex");
-
- // Aggregate assignment turns into llvm.memcpy.
- const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- if (DestPtr->getType() != BP)
- DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
- if (SrcPtr->getType() != BP)
- SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
-
- // Get size and alignment info for this aggregate.
- std::pair<uint64_t, unsigned> TypeInfo = CGF.getContext().getTypeInfo(Ty);
-
- // FIXME: Handle variable sized types.
- const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
-
- llvm::Value *MemCpyOps[4] = {
- DestPtr, SrcPtr,
- // TypeInfo.first describes size in bits.
- llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second/8)
- };
-
- Builder.CreateCall(CGF.CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
-}
-
-
-/// EmitAggLoadOfLValue - Given an expression with aggregate type that
-/// represents a value lvalue, this method emits the address of the lvalue,
-/// then loads the result into DestPtr.
-void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
- LValue LV = CGF.EmitLValue(E);
- assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
- llvm::Value *SrcPtr = LV.getAddress();
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
-}
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-void AggExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *E)
-{
- QualType STy = E->getSubExpr()->getType().getCanonicalType();
- QualType Ty = E->getType().getCanonicalType();
-
- assert(CGF.getContext().typesAreCompatible(
- STy.getUnqualifiedType(), Ty.getUnqualifiedType())
- && "Implicit cast types must be compatible");
-
- Visit(E->getSubExpr());
-}
-
-void AggExprEmitter::VisitCallExpr(const CallExpr *E)
-{
- RValue RV = CGF.EmitCallExpr(E);
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitOverloadExpr(const OverloadExpr *E)
-{
- RValue RV = CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->getNumArgs(CGF.getContext()));
- assert(RV.isAggregate() && "Return value must be aggregate value!");
-
- // If the result is ignored, don't copy from the value.
- if (DestPtr == 0)
- // FIXME: If the source is volatile, we must read from it.
- return;
-
- EmitAggregateCopy(DestPtr, RV.getAggregateAddr(), E->getType());
-}
-
-void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
-}
-
-void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
- CGF.WarnUnsupported(E, "aggregate binary expression");
-}
-
-void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
- // For an assignment to work, the value on the right has
- // to be compatible with the value on the left.
- assert(CGF.getContext().typesAreCompatible(
- E->getLHS()->getType().getUnqualifiedType(),
- E->getRHS()->getType().getUnqualifiedType())
- && "Invalid assignment");
- LValue LHS = CGF.EmitLValue(E->getLHS());
-
- // Codegen the RHS so that it stores directly into the LHS.
- CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
-
- if (DestPtr == 0)
- return;
-
- // If the result of the assignment is used, copy the RHS there also.
- EmitAggregateCopy(DestPtr, LHS.getAddress(), E->getType());
-}
-
-void AggExprEmitter::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");
-
- llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
- Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- assert(E->getLHS() && "Must have LHS for aggregate value");
-
- Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-}
-
-void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
-
- const llvm::PointerType *APType =
- cast<llvm::PointerType>(DestPtr->getType());
- const llvm::Type *DestType = APType->getElementType();
-
- if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(DestType)) {
- unsigned NumInitElements = E->getNumInits();
-
- llvm::Value *Idxs[] = {
- llvm::Constant::getNullValue(llvm::Type::Int32Ty),
- NULL
- };
- llvm::Value *NextVal = NULL;
- unsigned i;
- for (i = 0; i != NumInitElements; ++i) {
- Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
- Expr *Init = E->getInit(i);
- if (isa<InitListExpr>(Init))
- CGF.EmitAggExpr(Init, NextVal, VolatileDest);
- else
- Builder.CreateStore(CGF.EmitScalarExpr(Init), NextVal);
- }
-
- // Emit remaining default initializers
- unsigned NumArrayElements = AType->getNumElements();
- QualType QType = E->getInit(0)->getType();
- const llvm::Type *EType = AType->getElementType();
- for (/*Do not initialize i*/; i < NumArrayElements; ++i) {
- Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
- if (EType->isFirstClassType())
- Builder.CreateStore(llvm::Constant::getNullValue(EType), NextVal);
- else
- EmitAggregateClear(NextVal, QType);
- }
- } else
- assert(false && "Invalid initializer");
-}
-
-void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
-
- if (E->isConstantExpr(CGF.CGM.getContext(), NULL)) {
- llvm::Constant *V = CGF.CGM.EmitConstantExpr(E);
- // Create global value to hold this array.
- V = new llvm::GlobalVariable(V->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- V, ".array",
- &CGF.CGM.getModule());
-
- EmitAggregateCopy(DestPtr, V , E->getType());
- return;
- } else {
- if (!E->getType()->isArrayType()) {
- CGF.WarnUnsupported(E, "aggregate init-list expression");
- return;
- }
- EmitNonConstInit(E);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Entry Points into this File
-//===----------------------------------------------------------------------===//
-
-/// 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.
-void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
- bool VolatileDest) {
- assert(E && hasAggregateLLVMType(E->getType()) &&
- "Invalid aggregate expression to emit");
-
- AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
-}
diff --git a/clang/CodeGen/CGExprComplex.cpp b/clang/CodeGen/CGExprComplex.cpp
deleted file mode 100644
index b1de93570d9..00000000000
--- a/clang/CodeGen/CGExprComplex.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Expr nodes with complex 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/ADT/SmallString.h"
-#include "llvm/Support/Compiler.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Complex Expression Emitter
-//===----------------------------------------------------------------------===//
-
-typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
-
-namespace {
-class VISIBILITY_HIDDEN ComplexExprEmitter
- : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
- CodeGenFunction &CGF;
- llvm::LLVMFoldingBuilder &Builder;
-public:
- ComplexExprEmitter(CodeGenFunction &cgf) : CGF(cgf), Builder(CGF.Builder) {
- }
-
-
- //===--------------------------------------------------------------------===//
- // Utilities
- //===--------------------------------------------------------------------===//
-
- /// 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.
- ComplexPairTy EmitLoadOfLValue(const Expr *E) {
- LValue LV = CGF.EmitLValue(E);
- // FIXME: Volatile
- return EmitLoadOfComplex(LV.getAddress(), false);
- }
-
- /// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
- /// the real and imaginary pieces.
- ComplexPairTy EmitLoadOfComplex(llvm::Value *SrcPtr, bool isVolatile);
-
- /// EmitStoreOfComplex - Store the specified real/imag parts into the
- /// specified value pointer.
- void EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *ResPtr, bool isVol);
-
- /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
- ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
- QualType DestType);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- ComplexPairTy VisitStmt(Stmt *S) {
- S->dump(CGF.getContext().getSourceManager());
- assert(0 && "Stmt can't have complex result type!");
- return ComplexPairTy();
- }
- ComplexPairTy VisitExpr(Expr *S);
- ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
- ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
-
- // l-values.
- ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
-
- // FIXME: CompoundLiteralExpr
-
- ComplexPairTy EmitCast(Expr *Op, QualType DestTy);
- ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
- // Unlike for scalars, we don't have to worry about function->ptr demotion
- // here.
- return EmitCast(E->getSubExpr(), E->getType());
- }
- ComplexPairTy VisitCastExpr(CastExpr *E) {
- return EmitCast(E->getSubExpr(), E->getType());
- }
- ComplexPairTy VisitCallExpr(const CallExpr *E);
- ComplexPairTy VisitStmtExpr(const StmtExpr *E);
- ComplexPairTy VisitOverloadExpr(const OverloadExpr *OE);
-
- // Operators.
- ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
- bool isInc, bool isPre);
- ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, false);
- }
- ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, false);
- }
- ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, false, true);
- }
- ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
- return VisitPrePostIncDec(E, true, true);
- }
- ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitUnaryPlus (const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- ComplexPairTy VisitUnaryMinus (const UnaryOperator *E);
- ComplexPairTy VisitUnaryNot (const UnaryOperator *E);
- // LNot,SizeOf,AlignOf,Real,Imag never return complex.
- ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
-
- struct BinOpInfo {
- ComplexPairTy LHS;
- ComplexPairTy RHS;
- QualType Ty; // Computation Type.
- };
-
- BinOpInfo EmitBinOps(const BinaryOperator *E);
- ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)
- (const BinOpInfo &));
-
- ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
- ComplexPairTy EmitBinSub(const BinOpInfo &Op);
- ComplexPairTy EmitBinMul(const BinOpInfo &Op);
- ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
-
- ComplexPairTy VisitBinMul(const BinaryOperator *E) {
- return EmitBinMul(EmitBinOps(E));
- }
- ComplexPairTy VisitBinAdd(const BinaryOperator *E) {
- return EmitBinAdd(EmitBinOps(E));
- }
- ComplexPairTy VisitBinSub(const BinaryOperator *E) {
- return EmitBinSub(EmitBinOps(E));
- }
- ComplexPairTy VisitBinDiv(const BinaryOperator *E) {
- return EmitBinDiv(EmitBinOps(E));
- }
-
- // Compound assignments.
- ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
- }
- ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
- }
- ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
- }
- ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
- }
-
- // GCC rejects rem/and/or/xor for integer complex.
- // Logical and/or always return int, never complex.
-
- // No comparisons produce a complex result.
- ComplexPairTy VisitBinAssign (const BinaryOperator *E);
- ComplexPairTy VisitBinComma (const BinaryOperator *E);
-
-
- ComplexPairTy VisitConditionalOperator(const ConditionalOperator *CO);
- ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-/// EmitLoadOfComplex - Given an RValue reference for a complex, emit code to
-/// load the real and imaginary pieces, returning them as Real/Imag.
-ComplexPairTy ComplexExprEmitter::EmitLoadOfComplex(llvm::Value *SrcPtr,
- bool isVolatile) {
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
-
- llvm::SmallString<64> Name(SrcPtr->getNameStart(),
- SrcPtr->getNameStart()+SrcPtr->getNameLen());
-
- Name += ".realp";
- llvm::Value *Ops[] = {Zero, Zero};
- llvm::Value *RealPtr = Builder.CreateGEP(SrcPtr, Ops, Ops+2, Name.c_str());
-
- Name.pop_back(); // .realp -> .real
- llvm::Value *Real = Builder.CreateLoad(RealPtr, isVolatile, Name.c_str());
-
- Name.resize(Name.size()-4); // .real -> .imagp
- Name += "imagp";
-
- Ops[1] = One; // { Ops = { Zero, One }
- llvm::Value *ImagPtr = Builder.CreateGEP(SrcPtr, Ops, Ops+2, Name.c_str());
-
- Name.pop_back(); // .imagp -> .imag
- llvm::Value *Imag = Builder.CreateLoad(ImagPtr, isVolatile, Name.c_str());
- return ComplexPairTy(Real, Imag);
-}
-
-/// EmitStoreOfComplex - Store the specified real/imag parts into the
-/// specified value pointer.
-void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, llvm::Value *Ptr,
- bool isVolatile) {
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *One = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1);
-
- llvm::Value *Ops[] = {Zero, Zero};
- llvm::Value *RealPtr = Builder.CreateGEP(Ptr, Ops, Ops+2, "real");
-
- Ops[1] = One; // { Ops = { Zero, One }
- llvm::Value *ImagPtr = Builder.CreateGEP(Ptr, Ops, Ops+2, "imag");
-
- Builder.CreateStore(Val.first, RealPtr, isVolatile);
- Builder.CreateStore(Val.second, ImagPtr, isVolatile);
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
- CGF.WarnUnsupported(E, "complex expression");
- const llvm::Type *EltTy =
- CGF.ConvertType(E->getType()->getAsComplexType()->getElementType());
- llvm::Value *U = llvm::UndefValue::get(EltTy);
- return ComplexPairTy(U, U);
-}
-
-ComplexPairTy ComplexExprEmitter::
-VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
- llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
- return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
-}
-
-
-ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
- return CGF.EmitCallExpr(E).getComplexVal();
-}
-
-ComplexPairTy ComplexExprEmitter::VisitOverloadExpr(const OverloadExpr *E) {
- return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->getNumArgs(CGF.getContext())).getComplexVal();
-}
-
-ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal();
-}
-
-/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
-ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
- QualType SrcType,
- QualType DestType) {
- // Get the src/dest element type.
- SrcType = cast<ComplexType>(SrcType.getCanonicalType())->getElementType();
- DestType = cast<ComplexType>(DestType.getCanonicalType())->getElementType();
-
- // C99 6.3.1.6: When a value of complextype is converted to another
- // complex type, both the real and imaginary parts followthe conversion
- // rules for the corresponding real types.
- Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
- Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType);
- return Val;
-}
-
-ComplexPairTy ComplexExprEmitter::EmitCast(Expr *Op, QualType DestTy) {
- // Two cases here: cast from (complex to complex) and (scalar to complex).
- if (Op->getType()->isComplexType())
- return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy);
-
- // C99 6.3.1.7: When a value of real type is converted to a complex type, the
- // real part of the complex result value is determined by the rules of
- // conversion to the corresponding real type and the imaginary part of the
- // complex result value is a positive zero or an unsigned zero.
- llvm::Value *Elt = CGF.EmitScalarExpr(Op);
-
- // Convert the input element to the element type of the complex.
- DestTy = cast<ComplexType>(DestTy.getCanonicalType())->getElementType();
- Elt = CGF.EmitScalarConversion(Elt, Op->getType(), DestTy);
-
- // Return (realval, 0).
- return ComplexPairTy(Elt, llvm::Constant::getNullValue(Elt->getType()));
-}
-
-ComplexPairTy ComplexExprEmitter::VisitPrePostIncDec(const UnaryOperator *E,
- bool isInc, bool isPre) {
- LValue LV = CGF.EmitLValue(E->getSubExpr());
- // FIXME: Handle volatile!
- ComplexPairTy InVal = EmitLoadOfComplex(LV.getAddress(), false);
-
- uint64_t AmountVal = isInc ? 1 : -1;
-
- llvm::Value *NextVal;
- if (isa<llvm::IntegerType>(InVal.first->getType()))
- NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal);
- else if (InVal.first->getType() == llvm::Type::FloatTy)
- // FIXME: Handle long double.
- NextVal =
- llvm::ConstantFP::get(InVal.first->getType(),
- llvm::APFloat(static_cast<float>(AmountVal)));
- else {
- // FIXME: Handle long double.
- assert(InVal.first->getType() == llvm::Type::DoubleTy);
- NextVal =
- llvm::ConstantFP::get(InVal.first->getType(),
- llvm::APFloat(static_cast<double>(AmountVal)));
- }
-
- // Add the inc/dec to the real part.
- NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
-
- ComplexPairTy IncVal(NextVal, InVal.second);
-
- // Store the updated result through the lvalue.
- EmitStoreOfComplex(IncVal, LV.getAddress(), false); /* FIXME: Volatile */
-
- // If this is a postinc, return the value read from memory, otherwise use the
- // updated value.
- return isPre ? IncVal : InVal;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E) {
- ComplexPairTy Op = Visit(E->getSubExpr());
- llvm::Value *ResR = Builder.CreateNeg(Op.first, "neg.r");
- llvm::Value *ResI = Builder.CreateNeg(Op.second, "neg.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
- // ~(a+ib) = a + i*-b
- ComplexPairTy Op = Visit(E->getSubExpr());
- llvm::Value *ResI = Builder.CreateNeg(Op.second, "conj.i");
- return ComplexPairTy(Op.first, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
- llvm::Value *ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r");
- llvm::Value *ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
- llvm::Value *ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
- llvm::Value *ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-
-ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
- llvm::Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
- llvm::Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,"mul.rr");
- llvm::Value *ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
-
- llvm::Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
- llvm::Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
- llvm::Value *ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
- return ComplexPairTy(ResR, ResI);
-}
-
-ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
- llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
- llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
-
- // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
- llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr, "tmp"); // a*c
- llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi, "tmp"); // b*d
- llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2, "tmp"); // ac+bd
-
- llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr, "tmp"); // c*c
- llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi, "tmp"); // d*d
- llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5, "tmp"); // cc+dd
-
- llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr, "tmp"); // b*c
- llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi, "tmp"); // a*d
- llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8, "tmp"); // bc-ad
-
- llvm::Value *DSTr, *DSTi;
- if (Tmp3->getType()->isFloatingPoint()) {
- DSTr = Builder.CreateFDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateFDiv(Tmp9, Tmp6, "tmp");
- } else {
- if (Op.Ty->getAsComplexType()->getElementType()->isUnsignedIntegerType()) {
- DSTr = Builder.CreateUDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateUDiv(Tmp9, Tmp6, "tmp");
- } else {
- DSTr = Builder.CreateSDiv(Tmp3, Tmp6, "tmp");
- DSTi = Builder.CreateSDiv(Tmp9, Tmp6, "tmp");
- }
- }
-
- return ComplexPairTy(DSTr, DSTi);
-}
-
-ComplexExprEmitter::BinOpInfo
-ComplexExprEmitter::EmitBinOps(const BinaryOperator *E) {
- BinOpInfo Ops;
- Ops.LHS = Visit(E->getLHS());
- Ops.RHS = Visit(E->getRHS());
- Ops.Ty = E->getType();
- return Ops;
-}
-
-
-// Compound assignments.
-ComplexPairTy ComplexExprEmitter::
-EmitCompoundAssign(const CompoundAssignOperator *E,
- ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
- QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
-
- // Load the LHS and RHS operands.
- LValue LHSLV = CGF.EmitLValue(E->getLHS());
-
- BinOpInfo OpInfo;
- OpInfo.Ty = E->getComputationType();
-
- // We know the LHS is a complex lvalue.
- OpInfo.LHS = EmitLoadOfComplex(LHSLV.getAddress(), false);// FIXME: Volatile.
- OpInfo.LHS = EmitComplexToComplexCast(OpInfo.LHS, LHSTy, OpInfo.Ty);
-
- // It is possible for the RHS to be complex or scalar.
- OpInfo.RHS = EmitCast(E->getRHS(), OpInfo.Ty);
-
- // Expand the binary operator.
- ComplexPairTy Result = (this->*Func)(OpInfo);
-
- // Truncate the result back to the LHS type.
- Result = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
-
- // Store the result value into the LHS lvalue.
- EmitStoreOfComplex(Result, LHSLV.getAddress(), false); // FIXME: VOLATILE
- return Result;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
- assert(E->getLHS()->getType().getCanonicalType() ==
- E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
- // Emit the RHS.
- ComplexPairTy Val = Visit(E->getRHS());
-
- // Compute the address to store into.
- LValue LHS = CGF.EmitLValue(E->getLHS());
-
- // Store into it.
- // FIXME: Volatility!
- EmitStoreOfComplex(Val, LHS.getAddress(), false);
- return Val;
-}
-
-ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
- CGF.EmitStmt(E->getLHS());
- return Visit(E->getRHS());
-}
-
-ComplexPairTy ComplexExprEmitter::
-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");
-
- llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
- Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- assert(E->getLHS() && "Must have LHS for complex value");
-
- ComplexPairTy LHS = Visit(E->getLHS());
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- ComplexPairTy RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-
- // Create a PHI node for the real part.
- llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), "cond.r");
- RealPN->reserveOperandSpace(2);
- RealPN->addIncoming(LHS.first, LHSBlock);
- RealPN->addIncoming(RHS.first, RHSBlock);
-
- // Create a PHI node for the imaginary part.
- llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), "cond.i");
- ImagPN->reserveOperandSpace(2);
- ImagPN->addIncoming(LHS.second, LHSBlock);
- ImagPN->addIncoming(RHS.second, RHSBlock);
-
- return ComplexPairTy(RealPN, ImagPN);
-}
-
-ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
- // Emit the LHS or RHS as appropriate.
- return Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() :E->getRHS());
-}
-
-//===----------------------------------------------------------------------===//
-// Entry Point into this File
-//===----------------------------------------------------------------------===//
-
-/// EmitComplexExpr - Emit the computation of the specified expression of
-/// complex type, ignoring the result.
-ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) {
- assert(E && E->getType()->isComplexType() &&
- "Invalid complex expression to emit");
-
- return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E));
-}
-
-/// EmitComplexExprIntoAddr - Emit the computation of the specified expression
-/// of complex type, storing into the specified Value*.
-void CodeGenFunction::EmitComplexExprIntoAddr(const Expr *E,
- llvm::Value *DestAddr,
- bool DestIsVolatile) {
- assert(E && E->getType()->isComplexType() &&
- "Invalid complex expression to emit");
- ComplexExprEmitter Emitter(*this);
- ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
- Emitter.EmitStoreOfComplex(Val, DestAddr, DestIsVolatile);
-}
-
-/// LoadComplexFromAddr - Load a complex number from the specified address.
-ComplexPairTy CodeGenFunction::LoadComplexFromAddr(llvm::Value *SrcAddr,
- bool SrcIsVolatile) {
- return ComplexExprEmitter(*this).EmitLoadOfComplex(SrcAddr, SrcIsVolatile);
-}
diff --git a/clang/CodeGen/CGExprConstant.cpp b/clang/CodeGen/CGExprConstant.cpp
deleted file mode 100644
index e2405b88f37..00000000000
--- a/clang/CodeGen/CGExprConstant.cpp
+++ /dev/null
@@ -1,627 +0,0 @@
-//===--- CGExprConstant.cpp - Emit LLVM Code from Constant Expressions ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Constant Expr nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/AST.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Support/Compiler.h"
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class VISIBILITY_HIDDEN ConstExprEmitter :
- public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
- CodeGenModule &CGM;
- CodeGenFunction *CGF;
-public:
- ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
- : CGM(cgm), CGF(cgf) {
- }
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- llvm::Constant *VisitStmt(Stmt *S) {
- CGM.WarnUnsupported(S, "constant expression");
- QualType T = cast<Expr>(S)->getType();
- return llvm::UndefValue::get(CGM.getTypes().ConvertType(T));
- }
-
- llvm::Constant *VisitParenExpr(ParenExpr *PE) {
- return Visit(PE->getSubExpr());
- }
-
- // Leaves
- llvm::Constant *VisitIntegerLiteral(const IntegerLiteral *E) {
- return llvm::ConstantInt::get(E->getValue());
- }
- llvm::Constant *VisitFloatingLiteral(const FloatingLiteral *E) {
- return llvm::ConstantFP::get(ConvertType(E->getType()), E->getValue());
- }
- llvm::Constant *VisitCharacterLiteral(const CharacterLiteral *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- llvm::Constant *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
-
- llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- return Visit(E->getInitializer());
- }
-
- llvm::Constant *VisitCastExpr(const CastExpr* E) {
- llvm::Constant *C = Visit(E->getSubExpr());
-
- return EmitConversion(C, E->getSubExpr()->getType(), E->getType());
- }
-
- llvm::Constant *EmitArrayInitialization(InitListExpr *ILE,
- const llvm::ArrayType *AType) {
- std::vector<llvm::Constant*> Elts;
- unsigned NumInitElements = ILE->getNumInits();
- // FIXME: Check for wide strings
- if (NumInitElements > 0 && isa<StringLiteral>(ILE->getInit(0)) &&
- ILE->getType()->getAsArrayType()->getElementType()->isCharType())
- return Visit(ILE->getInit(0));
- const llvm::Type *ElemTy = AType->getElementType();
- unsigned NumElements = AType->getNumElements();
-
- // Initialising an array requires us to automatically
- // initialise any elements that have not been initialised explicitly
- unsigned NumInitableElts = std::min(NumInitElements, NumElements);
-
- // Copy initializer elements.
- unsigned i = 0;
- for (; i < NumInitableElts; ++i) {
-
- llvm::Constant *C = Visit(ILE->getInit(i));
- // 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(AType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- }
-
- // Initialize remaining array elements.
- for (; i < NumElements; ++i)
- Elts.push_back(llvm::Constant::getNullValue(ElemTy));
-
- return llvm::ConstantArray::get(AType, Elts);
- }
-
- llvm::Constant *EmitStructInitialization(InitListExpr *ILE,
- const llvm::StructType *SType) {
-
- TagDecl *TD = ILE->getType()->getAsRecordType()->getDecl();
- std::vector<llvm::Constant*> Elts;
- const CGRecordLayout *CGR = CGM.getTypes().getCGRecordLayout(TD);
- unsigned NumInitElements = ILE->getNumInits();
- unsigned NumElements = SType->getNumElements();
-
- // Initialising an structure requires us to automatically
- // initialise any elements that have not been initialised explicitly
- unsigned NumInitableElts = std::min(NumInitElements, NumElements);
-
- // Copy initializer elements. Skip padding fields.
- unsigned EltNo = 0; // Element no in ILE
- unsigned FieldNo = 0; // Field no in SType
- while (EltNo < NumInitableElts) {
-
- // Zero initialize padding field.
- if (CGR->isPaddingField(FieldNo)) {
- const llvm::Type *FieldTy = SType->getElementType(FieldNo);
- Elts.push_back(llvm::Constant::getNullValue(FieldTy));
- FieldNo++;
- continue;
- }
-
- llvm::Constant *C = Visit(ILE->getInit(EltNo));
- // FIXME: Remove this when sema of initializers is finished (and the code
- // above).
- if (C == 0 && ILE->getInit(EltNo)->getType()->isVoidType()) {
- if (ILE->getType()->isVoidType()) return 0;
- return llvm::UndefValue::get(SType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- EltNo++;
- FieldNo++;
- }
-
- // Initialize remaining structure elements.
- for (unsigned i = Elts.size(); i < NumElements; ++i) {
- const llvm::Type *FieldTy = SType->getElementType(i);
- Elts.push_back(llvm::Constant::getNullValue(FieldTy));
- }
-
- return llvm::ConstantStruct::get(SType, Elts);
- }
-
- llvm::Constant *EmitVectorInitialization(InitListExpr *ILE,
- const llvm::VectorType *VType) {
-
- std::vector<llvm::Constant*> Elts;
- unsigned NumInitElements = ILE->getNumInits();
- unsigned NumElements = VType->getNumElements();
-
- assert (NumInitElements == NumElements
- && "Unsufficient vector init elelments");
- // Copy initializer elements.
- unsigned i = 0;
- for (; i < NumElements; ++i) {
-
- llvm::Constant *C = Visit(ILE->getInit(i));
- // 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(VType);
- }
- assert (C && "Failed to create initializer expression");
- Elts.push_back(C);
- }
-
- return llvm::ConstantVector::get(VType, Elts);
- }
-
- llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
- const llvm::CompositeType *CType =
- dyn_cast<llvm::CompositeType>(ConvertType(ILE->getType()));
-
- if (!CType) {
- // We have a scalar in braces. Just use the first element.
- return Visit(ILE->getInit(0));
- }
-
- if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(CType))
- return EmitArrayInitialization(ILE, AType);
-
- if (const llvm::StructType *SType = dyn_cast<llvm::StructType>(CType))
- return EmitStructInitialization(ILE, SType);
-
- if (const llvm::VectorType *VType = dyn_cast<llvm::VectorType>(CType))
- return EmitVectorInitialization(ILE, VType);
-
- // Make sure we have an array at this point
- assert(0 && "Unable to handle InitListExpr");
- // Get rid of control reaches end of void function warning.
- // Not reached.
- return 0;
- }
-
- llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) {
- Expr* SExpr = ICExpr->getSubExpr();
- QualType SType = SExpr->getType();
- llvm::Constant *C; // the intermediate expression
- QualType T; // the type of the intermediate expression
- if (SType->isArrayType()) {
- // Arrays decay to a pointer to the first element
- // VLAs would require special handling, but they can't occur here
- C = EmitLValue(SExpr);
- llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Ops[] = {Idx0, Idx0};
- C = llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
-
- QualType ElemType = SType->getAsArrayType()->getElementType();
- T = CGM.getContext().getPointerType(ElemType);
- } else if (SType->isFunctionType()) {
- // Function types decay to a pointer to the function
- C = EmitLValue(SExpr);
- T = CGM.getContext().getPointerType(SType);
- } else {
- C = Visit(SExpr);
- T = SType;
- }
-
- // Perform the conversion; note that an implicit cast can both promote
- // and convert an array/function
- return EmitConversion(C, T, ICExpr->getType());
- }
-
- llvm::Constant *VisitStringLiteral(StringLiteral *E) {
- const char *StrData = E->getStrData();
- unsigned Len = E->getByteLength();
- assert(!E->getType()->isPointerType() && "Strings are always arrays");
-
- // 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 = E->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);
- }
-
- llvm::Constant *VisitDeclRefExpr(DeclRefExpr *E) {
- const ValueDecl *Decl = E->getDecl();
- if (const EnumConstantDecl *EC = dyn_cast<EnumConstantDecl>(Decl))
- return llvm::ConstantInt::get(EC->getInitVal());
- assert(0 && "Unsupported decl ref type!");
- return 0;
- }
-
- llvm::Constant *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) {
- return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf());
- }
-
- // Unary operators
- llvm::Constant *VisitUnaryPlus(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- llvm::Constant *VisitUnaryMinus(const UnaryOperator *E) {
- return llvm::ConstantExpr::getNeg(Visit(E->getSubExpr()));
- }
- llvm::Constant *VisitUnaryNot(const UnaryOperator *E) {
- return llvm::ConstantExpr::getNot(Visit(E->getSubExpr()));
- }
- llvm::Constant *VisitUnaryLNot(const UnaryOperator *E) {
- llvm::Constant *SubExpr = Visit(E->getSubExpr());
-
- if (E->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_UEQ, SubExpr,
- Zero);
- } else {
- assert((E->getSubExpr()->getType()->isIntegerType() ||
- E->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_EQ, SubExpr,
- Zero);
- }
-
- return llvm::ConstantExpr::getZExt(SubExpr, ConvertType(E->getType()));
- }
- llvm::Constant *VisitUnarySizeOf(const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true);
- }
- llvm::Constant *VisitUnaryAlignOf(const UnaryOperator *E) {
- return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
- }
- llvm::Constant *VisitUnaryAddrOf(const UnaryOperator *E) {
- return EmitLValue(E->getSubExpr());
- }
- llvm::Constant *VisitUnaryOffsetOf(const UnaryOperator *E) {
- int64_t Val = E->evaluateOffsetOf(CGM.getContext());
-
- assert(E->getType()->isIntegerType() && "Result type must be an integer!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGM.getContext().getTypeSize(E->getType()));
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
- }
-
- // Binary operators
- llvm::Constant *VisitBinOr(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getOr(LHS, RHS);
- }
- llvm::Constant *VisitBinSub(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (!isa<llvm::PointerType>(RHS->getType())) {
- // pointer - int
- if (isa<llvm::PointerType>(LHS->getType())) {
- llvm::Constant *Idx = llvm::ConstantExpr::getNeg(RHS);
-
- return llvm::ConstantExpr::getGetElementPtr(LHS, &Idx, 1);
- }
-
- // int - int
- return llvm::ConstantExpr::getSub(LHS, RHS);
- }
-
- assert(0 && "Unhandled bin sub case!");
- return 0;
- }
-
- llvm::Constant *VisitBinShl(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- // 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 = llvm::ConstantExpr::getIntegerCast(RHS, LHS->getType(), false);
-
- return llvm::ConstantExpr::getShl(LHS, RHS);
- }
-
- llvm::Constant *VisitBinMul(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getMul(LHS, RHS);
- }
-
- llvm::Constant *VisitBinDiv(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (LHS->getType()->isFPOrFPVector())
- return llvm::ConstantExpr::getFDiv(LHS, RHS);
- else if (E->getType()->isUnsignedIntegerType())
- return llvm::ConstantExpr::getUDiv(LHS, RHS);
- else
- return llvm::ConstantExpr::getSDiv(LHS, RHS);
- }
-
- llvm::Constant *VisitBinAdd(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- if (!E->getType()->isPointerType())
- return llvm::ConstantExpr::getAdd(LHS, RHS);
-
- llvm::Constant *Ptr, *Idx;
- if (isa<llvm::PointerType>(LHS->getType())) { // pointer + int
- Ptr = LHS;
- Idx = RHS;
- } else { // int + pointer
- Ptr = RHS;
- Idx = LHS;
- }
-
- return llvm::ConstantExpr::getGetElementPtr(Ptr, &Idx, 1);
- }
-
- llvm::Constant *VisitBinAnd(const BinaryOperator *E) {
- llvm::Constant *LHS = Visit(E->getLHS());
- llvm::Constant *RHS = Visit(E->getRHS());
-
- return llvm::ConstantExpr::getAnd(LHS, RHS);
- }
-
- // Utility methods
- const llvm::Type *ConvertType(QualType T) {
- return CGM.getTypes().ConvertType(T);
- }
-
- llvm::Constant *EmitConversionToBool(llvm::Constant *Src, QualType SrcType) {
- assert(SrcType->isCanonical() && "EmitConversion strips typedefs");
-
- if (SrcType->isRealFloatingType()) {
- // Compare against 0.0 for fp scalars.
- llvm::Constant *Zero = llvm::Constant::getNullValue(Src->getType());
- return llvm::ConstantExpr::getFCmp(llvm::FCmpInst::FCMP_UNE, Src, Zero);
- }
-
- assert((SrcType->isIntegerType() || SrcType->isPointerType()) &&
- "Unknown scalar type to convert");
-
- // Compare against an integer or pointer null.
- llvm::Constant *Zero = llvm::Constant::getNullValue(Src->getType());
- return llvm::ConstantExpr::getICmp(llvm::ICmpInst::ICMP_NE, Src, Zero);
- }
-
- llvm::Constant *EmitConversion(llvm::Constant *Src, QualType SrcType,
- QualType DstType) {
- SrcType = SrcType.getCanonicalType();
- DstType = DstType.getCanonicalType();
- if (SrcType == DstType) return Src;
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstType->isBooleanType())
- return EmitConversionToBool(Src, SrcType);
-
- const llvm::Type *DstTy = ConvertType(DstType);
-
- // Ignore conversions like int -> uint.
- if (Src->getType() == DstTy)
- return Src;
-
- // Handle pointer conversions next: pointers can only be converted to/from
- // other pointers and integers.
- if (isa<PointerType>(DstType)) {
- // The source value may be an integer, or a pointer.
- if (isa<llvm::PointerType>(Src->getType()))
- return llvm::ConstantExpr::getBitCast(Src, DstTy);
- assert(SrcType->isIntegerType() &&"Not ptr->ptr or int->ptr conversion?");
- return llvm::ConstantExpr::getIntToPtr(Src, DstTy);
- }
-
- if (isa<PointerType>(SrcType)) {
- // Must be an ptr to int cast.
- assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
- return llvm::ConstantExpr::getPtrToInt(Src, DstTy);
- }
-
- // A scalar source can be splatted to a vector of the same element type
- if (isa<llvm::VectorType>(DstTy) && !isa<VectorType>(SrcType)) {
- const llvm::VectorType *VT = cast<llvm::VectorType>(DstTy);
- assert((VT->getElementType() == Src->getType()) &&
- "Vector element type must match scalar type to splat.");
- unsigned NumElements = DstType->getAsVectorType()->getNumElements();
- llvm::SmallVector<llvm::Constant*, 16> Elements;
- for (unsigned i = 0; i < NumElements; i++)
- Elements.push_back(Src);
-
- return llvm::ConstantVector::get(&Elements[0], NumElements);
- }
-
- if (isa<llvm::VectorType>(Src->getType()) ||
- isa<llvm::VectorType>(DstTy)) {
- return llvm::ConstantExpr::getBitCast(Src, DstTy);
- }
-
- // Finally, we have the arithmetic types: real int/float.
- if (isa<llvm::IntegerType>(Src->getType())) {
- bool InputSigned = SrcType->isSignedIntegerType();
- if (isa<llvm::IntegerType>(DstTy))
- return llvm::ConstantExpr::getIntegerCast(Src, DstTy, InputSigned);
- else if (InputSigned)
- return llvm::ConstantExpr::getSIToFP(Src, DstTy);
- else
- return llvm::ConstantExpr::getUIToFP(Src, DstTy);
- }
-
- assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
- if (isa<llvm::IntegerType>(DstTy)) {
- if (DstType->isSignedIntegerType())
- return llvm::ConstantExpr::getFPToSI(Src, DstTy);
- else
- return llvm::ConstantExpr::getFPToUI(Src, DstTy);
- }
-
- assert(DstTy->isFloatingPoint() && "Unknown real conversion");
- if (DstTy->getTypeID() < Src->getType()->getTypeID())
- return llvm::ConstantExpr::getFPTrunc(Src, DstTy);
- else
- return llvm::ConstantExpr::getFPExtend(Src, DstTy);
- }
-
- llvm::Constant *EmitSizeAlignOf(QualType TypeToSize,
- QualType RetType, bool isSizeOf) {
- std::pair<uint64_t, unsigned> Info =
- CGM.getContext().getTypeInfo(TypeToSize);
-
- 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!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGM.getContext().getTypeSize(RetType));
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
- }
-
- llvm::Constant *EmitLValue(Expr *E) {
- switch (E->getStmtClass()) {
- default: break;
- case Expr::ParenExprClass:
- // Elide parenthesis
- return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
- case Expr::CompoundLiteralExprClass: {
- // Note that due to the nature of compound literals, this is guaranteed
- // to be the only use of the variable, so we just generate it here.
- CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
- llvm::Constant* C = Visit(CLE->getInitializer());
- C = new llvm::GlobalVariable(C->getType(),E->getType().isConstQualified(),
- llvm::GlobalValue::InternalLinkage,
- C, ".compoundliteral", &CGM.getModule());
- return C;
- }
- case Expr::DeclRefExprClass: {
- ValueDecl *Decl = cast<DeclRefExpr>(E)->getDecl();
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
- return CGM.GetAddrOfFunctionDecl(FD, false);
- if (const FileVarDecl* VD = dyn_cast<FileVarDecl>(Decl))
- return CGM.GetAddrOfGlobalVar(VD, false);
- if (const BlockVarDecl* BVD = dyn_cast<BlockVarDecl>(Decl)) {
- assert(CGF && "Can't access static local vars without CGF");
- return CGF->GetAddrOfStaticLocalVar(BVD);
- }
- break;
- }
- case Expr::MemberExprClass: {
- MemberExpr* ME = cast<MemberExpr>(E);
- llvm::Constant *Base;
- if (ME->isArrow())
- Base = Visit(ME->getBase());
- else
- Base = EmitLValue(ME->getBase());
-
- unsigned FieldNumber = CGM.getTypes().getLLVMFieldNo(ME->getMemberDecl());
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
- FieldNumber);
- llvm::Value *Ops[] = {Zero, Idx};
- return llvm::ConstantExpr::getGetElementPtr(Base, Ops, 2);
- }
- case Expr::ArraySubscriptExprClass: {
- ArraySubscriptExpr* ASExpr = cast<ArraySubscriptExpr>(E);
- llvm::Constant *Base = Visit(ASExpr->getBase());
- llvm::Constant *Index = Visit(ASExpr->getIdx());
- assert(!ASExpr->getBase()->getType()->isVectorType() &&
- "Taking the address of a vector component is illegal!");
- return llvm::ConstantExpr::getGetElementPtr(Base, &Index, 1);
- }
- case Expr::StringLiteralClass: {
- StringLiteral *String = cast<StringLiteral>(E);
- assert(!String->isWide() && "Cannot codegen wide strings yet");
- const char *StrData = String->getStrData();
- unsigned Len = String->getByteLength();
-
- return CGM.GetAddrOfConstantString(std::string(StrData, StrData + Len));
- }
- case Expr::UnaryOperatorClass: {
- UnaryOperator *Exp = cast<UnaryOperator>(E);
- switch (Exp->getOpcode()) {
- default: break;
- case UnaryOperator::Extension:
- // Extension is just a wrapper for expressions
- return EmitLValue(Exp->getSubExpr());
- case UnaryOperator::Real:
- case UnaryOperator::Imag: {
- // The address of __real or __imag is just a GEP off the address
- // of the internal expression
- llvm::Constant* C = EmitLValue(Exp->getSubExpr());
- llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty,
- Exp->getOpcode() == UnaryOperator::Imag);
- llvm::Value *Ops[] = {Zero, Idx};
- return llvm::ConstantExpr::getGetElementPtr(C, Ops, 2);
- }
- case UnaryOperator::Deref:
- // The address of a deref is just the value of the expression
- return Visit(Exp->getSubExpr());
- }
- break;
- }
- }
- CGM.WarnUnsupported(E, "constant l-value expression");
- llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
- return llvm::UndefValue::get(Ty);
- }
-
-};
-
-} // end anonymous namespace.
-
-
-llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
- CodeGenFunction *CGF)
-{
- QualType type = E->getType().getCanonicalType();
-
- if (type->isIntegerType()) {
- llvm::APSInt Value(static_cast<uint32_t>(Context.getTypeSize(type)));
- if (E->isIntegerConstantExpr(Value, Context)) {
- return llvm::ConstantInt::get(Value);
- }
- }
-
- return ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-}
diff --git a/clang/CodeGen/CGExprScalar.cpp b/clang/CodeGen/CGExprScalar.cpp
deleted file mode 100644
index 892712a0d4c..00000000000
--- a/clang/CodeGen/CGExprScalar.cpp
+++ /dev/null
@@ -1,1185 +0,0 @@
-//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file 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/GlobalVariable.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Support/Compiler.h"
-#include <cstdarg>
-
-using namespace clang;
-using namespace CodeGen;
-using llvm::Value;
-
-//===----------------------------------------------------------------------===//
-// Scalar Expression Emitter
-//===----------------------------------------------------------------------===//
-
-struct BinOpInfo {
- Value *LHS;
- Value *RHS;
- QualType Ty; // Computation Type.
- const BinaryOperator *E;
-};
-
-namespace {
-class VISIBILITY_HIDDEN ScalarExprEmitter
- : public StmtVisitor<ScalarExprEmitter, Value*> {
- CodeGenFunction &CGF;
- llvm::LLVMFoldingBuilder &Builder;
- CGObjCRuntime *Runtime;
-
-
-public:
-
- ScalarExprEmitter(CodeGenFunction &cgf) : CGF(cgf),
- Builder(CGF.Builder),
- Runtime(CGF.CGM.getObjCRuntime()) {
- }
-
-
- //===--------------------------------------------------------------------===//
- // 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).getScalarVal();
- }
-
- /// 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());
- }
-
- /// EmitConversionToBool - Convert the specified expression value to a
- /// boolean (i1) truth value. This is equivalent to "Val != 0".
- Value *EmitConversionToBool(Value *Src, QualType DstTy);
-
- /// EmitScalarConversion - Emit a conversion from the specified type to the
- /// specified destination type, both of which are LLVM scalar types.
- Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy);
-
- /// EmitComplexToScalarConversion - Emit a conversion from the specified
- /// complex type to the specified destination type, where the destination
- /// type is an LLVM scalar type.
- Value *EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
- QualType SrcTy, QualType DstTy);
-
- //===--------------------------------------------------------------------===//
- // Visitor Methods
- //===--------------------------------------------------------------------===//
-
- Value *VisitStmt(Stmt *S) {
- S->dump(CGF.getContext().getSourceManager());
- 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 *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
- }
- Value *VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
- return llvm::ConstantInt::get(ConvertType(E->getType()),
- CGF.getContext().typesAreCompatible(
- E->getArgType1(), E->getArgType2()));
- }
- 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 *VisitObjCMessageExpr(ObjCMessageExpr *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(); }
-
- Value *VisitInitListExpr(InitListExpr *E) {
- unsigned NumInitElements = E->getNumInits();
-
- const llvm::VectorType *VType =
- dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
-
- // We have a scalar in braces. Just use the first element.
- if (!VType)
- return Visit(E->getInit(0));
-
- unsigned NumVectorElements = VType->getNumElements();
- const llvm::Type *ElementType = VType->getElementType();
-
- // Emit individual vector element stores.
- llvm::Value *V = llvm::UndefValue::get(VType);
-
- // Emit initializers
- unsigned i;
- for (i = 0; i < NumInitElements; ++i) {
- Value *NewV = Visit(E->getInit(i));
- Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- V = Builder.CreateInsertElement(V, NewV, Idx);
- }
-
- // Emit remaining default initializers
- for (/* Do not initialize i*/; i < NumVectorElements; ++i) {
- Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- llvm::Value *NewV = llvm::Constant::getNullValue(ElementType);
- V = Builder.CreateInsertElement(V, NewV, Idx);
- }
-
- return V;
- }
-
- Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- return Visit(E->getInitializer());
- }
-
- 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).getScalarVal();
- }
-
- Value *VisitStmtExpr(const StmtExpr *E);
-
- // 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);
- Value *VisitUnaryReal (const UnaryOperator *E);
- Value *VisitUnaryImag (const UnaryOperator *E);
- Value *VisitUnaryExtension(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
- Value *VisitUnaryOffsetOf(const UnaryOperator *E);
-
- // Binary Operators.
- 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");
- }
-
- BinOpInfo EmitBinOps(const BinaryOperator *E);
- Value *EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*F)(const BinOpInfo &));
-
- // Binary operators and binary compound assignment operators.
-#define HANDLEBINOP(OP) \
- Value *VisitBin ## OP(const BinaryOperator *E) { \
- return Emit ## OP(EmitBinOps(E)); \
- } \
- Value *VisitBin ## OP ## Assign(const CompoundAssignOperator *E) { \
- return EmitCompoundAssign(E, &ScalarExprEmitter::Emit ## OP); \
- }
- HANDLEBINOP(Mul);
- HANDLEBINOP(Div);
- HANDLEBINOP(Rem);
- HANDLEBINOP(Add);
- // (Sub) - Sub is handled specially below for ptr-ptr subtract.
- HANDLEBINOP(Shl);
- HANDLEBINOP(Shr);
- HANDLEBINOP(And);
- HANDLEBINOP(Xor);
- HANDLEBINOP(Or);
-#undef HANDLEBINOP
- Value *VisitBinSub(const BinaryOperator *E);
- Value *VisitBinSubAssign(const CompoundAssignOperator *E) {
- return EmitCompoundAssign(E, &ScalarExprEmitter::EmitSub);
- }
-
- // 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);
- Value *VisitBinComma (const BinaryOperator *E);
-
- // Other Operators.
- Value *VisitConditionalOperator(const ConditionalOperator *CO);
- Value *VisitChooseExpr(ChooseExpr *CE);
- Value *VisitOverloadExpr(OverloadExpr *OE);
- Value *VisitVAArgExpr(VAArgExpr *VE);
- Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
- return CGF.EmitObjCStringLiteral(E);
- }
- Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
-};
-} // end anonymous namespace.
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-/// EmitConversionToBool - Convert the specified expression value to a
-/// boolean (i1) truth value. This is equivalent to "Val != 0".
-Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
- assert(SrcType->isCanonical() && "EmitScalarConversion strips typedefs");
-
- if (SrcType->isRealFloatingType()) {
- // Compare against 0.0 for fp scalars.
- llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
- return Builder.CreateFCmpUNE(Src, Zero, "tobool");
- }
-
- assert((SrcType->isIntegerType() || SrcType->isPointerType()) &&
- "Unknown scalar type to convert");
-
- // Because of the type rules of C, we often end up computing a logical value,
- // then zero extending it to int, then wanting it as a logical value again.
- // Optimize this common case.
- if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(Src)) {
- if (ZI->getOperand(0)->getType() == llvm::Type::Int1Ty) {
- Value *Result = ZI->getOperand(0);
- // If there aren't any more uses, zap the instruction to save space.
- // Note that there can be more uses, for example if this
- // is the result of an assignment.
- if (ZI->use_empty())
- ZI->eraseFromParent();
- return Result;
- }
- }
-
- // Compare against an integer or pointer null.
- llvm::Value *Zero = llvm::Constant::getNullValue(Src->getType());
- return Builder.CreateICmpNE(Src, Zero, "tobool");
-}
-
-/// EmitScalarConversion - Emit a conversion from the specified type to the
-/// specified destination type, both of which are LLVM scalar types.
-Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
- QualType DstType) {
- SrcType = SrcType.getCanonicalType();
- DstType = DstType.getCanonicalType();
- if (SrcType == DstType) return Src;
-
- if (DstType->isVoidType()) return 0;
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstType->isBooleanType())
- return EmitConversionToBool(Src, SrcType);
-
- const llvm::Type *DstTy = ConvertType(DstType);
-
- // Ignore conversions like int -> uint.
- if (Src->getType() == DstTy)
- return Src;
-
- // Handle pointer conversions next: pointers can only be converted to/from
- // other pointers and integers.
- if (isa<PointerType>(DstType)) {
- // The source value may be an integer, or a pointer.
- if (isa<llvm::PointerType>(Src->getType()))
- return Builder.CreateBitCast(Src, DstTy, "conv");
- assert(SrcType->isIntegerType() && "Not ptr->ptr or int->ptr conversion?");
- return Builder.CreateIntToPtr(Src, DstTy, "conv");
- }
-
- if (isa<PointerType>(SrcType)) {
- // Must be an ptr to int cast.
- assert(isa<llvm::IntegerType>(DstTy) && "not ptr->int?");
- return Builder.CreatePtrToInt(Src, DstTy, "conv");
- }
-
- // A scalar source can be splatted to an OCU vector of the same element type
- if (DstType->isOCUVectorType() && !isa<VectorType>(SrcType) &&
- cast<llvm::VectorType>(DstTy)->getElementType() == Src->getType())
- return CGF.EmitVector(&Src, DstType->getAsVectorType()->getNumElements(),
- true);
-
- // Allow bitcast from vector to integer/fp of the same size.
- if (isa<llvm::VectorType>(Src->getType()) ||
- isa<llvm::VectorType>(DstTy))
- return Builder.CreateBitCast(Src, DstTy, "conv");
-
- // Finally, we have the arithmetic types: real int/float.
- if (isa<llvm::IntegerType>(Src->getType())) {
- bool InputSigned = SrcType->isSignedIntegerType();
- if (isa<llvm::IntegerType>(DstTy))
- return Builder.CreateIntCast(Src, DstTy, InputSigned, "conv");
- else if (InputSigned)
- return Builder.CreateSIToFP(Src, DstTy, "conv");
- else
- return Builder.CreateUIToFP(Src, DstTy, "conv");
- }
-
- assert(Src->getType()->isFloatingPoint() && "Unknown real conversion");
- if (isa<llvm::IntegerType>(DstTy)) {
- if (DstType->isSignedIntegerType())
- return Builder.CreateFPToSI(Src, DstTy, "conv");
- else
- return Builder.CreateFPToUI(Src, DstTy, "conv");
- }
-
- assert(DstTy->isFloatingPoint() && "Unknown real conversion");
- if (DstTy->getTypeID() < Src->getType()->getTypeID())
- return Builder.CreateFPTrunc(Src, DstTy, "conv");
- else
- return Builder.CreateFPExt(Src, DstTy, "conv");
-}
-
-/// EmitComplexToScalarConversion - Emit a conversion from the specified
-/// complex type to the specified destination type, where the destination
-/// type is an LLVM scalar type.
-Value *ScalarExprEmitter::
-EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
- QualType SrcTy, QualType DstTy) {
- // Get the source element type.
- SrcTy = cast<ComplexType>(SrcTy.getCanonicalType())->getElementType();
-
- // Handle conversions to bool first, they are special: comparisons against 0.
- if (DstTy->isBooleanType()) {
- // Complex != 0 -> (Real != 0) | (Imag != 0)
- Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy);
- Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy);
- return Builder.CreateOr(Src.first, Src.second, "tobool");
- }
-
- // C99 6.3.1.7p2: "When a value of complex type is converted to a real type,
- // the imaginary part of the complex value is discarded and the value of the
- // real part is converted according to the conversion rules for the
- // corresponding real type.
- return EmitScalarConversion(Src.first, SrcTy, DstTy);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Visitor Methods
-//===----------------------------------------------------------------------===//
-
-Value *ScalarExprEmitter::VisitExpr(Expr *E) {
- CGF.WarnUnsupported(E, "scalar expression");
- if (E->getType()->isVoidType())
- return 0;
- return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
-}
-
-Value *ScalarExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- // Only the lookup mechanism and first two arguments of the method
- // implementation vary between runtimes. We can get the receiver and
- // arguments in generic code.
-
- // Find the receiver
- llvm::Value * Receiver = CGF.EmitScalarExpr(E->getReceiver());
-
- // Process the arguments
- unsigned int ArgC = E->getNumArgs();
- llvm::SmallVector<llvm::Value*, 16> Args;
- for(unsigned i=0 ; i<ArgC ; i++) {
- Expr *ArgExpr = E->getArg(i);
- QualType ArgTy = ArgExpr->getType();
- if (!CGF.hasAggregateLLVMType(ArgTy)) {
- // Scalar argument is passed by-value.
- Args.push_back(CGF.EmitScalarExpr(ArgExpr));
- } else if (ArgTy->isComplexType()) {
- // Make a temporary alloca to pass the argument.
- llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
- CGF.EmitComplexExprIntoAddr(ArgExpr, DestMem, false);
- Args.push_back(DestMem);
- } else {
- llvm::Value *DestMem = CGF.CreateTempAlloca(ConvertType(ArgTy));
- CGF.EmitAggExpr(ArgExpr, DestMem, false);
- Args.push_back(DestMem);
- }
- }
-
- // Get the selector string
- std::string SelStr = E->getSelector().getName();
- llvm::Constant *Selector = CGF.CGM.GetAddrOfConstantString(SelStr);
- ConvertType(E->getType());
- return Runtime->generateMessageSend(Builder,
- ConvertType(E->getType()),
- Receiver,
- Selector,
- &Args[0],
- Args.size());
-}
-
-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.
- 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);
-
- llvm::Value *Ops[] = {Idx0, Idx0};
- V = Builder.CreateGEP(V, Ops, Ops+2, "arraydecay");
-
- // The resultant pointer type can be implicitly casted to other pointer
- // types as well, for example void*.
- const llvm::Type *DestPTy = ConvertType(E->getType());
- assert(isa<llvm::PointerType>(DestPTy) &&
- "Only expect implicit cast to pointer");
- if (V->getType() != DestPTy)
- V = Builder.CreateBitCast(V, DestPTy, "ptrconv");
- return V;
-
- } else if (E->getType()->isReferenceType()) {
- assert(cast<ReferenceType>(E->getType().getCanonicalType())->
- getReferenceeType() ==
- Op->getType().getCanonicalType() && "Incompatible types!");
-
- return EmitLValue(Op).getAddress();
- }
-
- 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) {
- // Handle cases where the source is an non-complex type.
-
- if (!CGF.hasAggregateLLVMType(E->getType())) {
- Value *Src = Visit(const_cast<Expr*>(E));
-
- // Use EmitScalarConversion to perform the conversion.
- return EmitScalarConversion(Src, E->getType(), DestTy);
- }
-
- if (E->getType()->isComplexType()) {
- // Handle cases where the source is a complex type.
- return EmitComplexToScalarConversion(CGF.EmitComplexExpr(E), E->getType(),
- DestTy);
- }
-
- // Okay, this is a cast from an aggregate. It must be a cast to void. Just
- // evaluate the result and return.
- CGF.EmitAggExpr(E, 0, false);
- return 0;
-}
-
-Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) {
- return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getScalarVal();
-}
-
-
-//===----------------------------------------------------------------------===//
-// 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()).getScalarVal();
-
- int AmountVal = isInc ? 1 : -1;
-
- Value *NextVal;
- if (isa<llvm::PointerType>(InVal->getType())) {
- // FIXME: This isn't right for VLAs.
- NextVal = llvm::ConstantInt::get(llvm::Type::Int32Ty, AmountVal);
- NextVal = Builder.CreateGEP(InVal, NextVal);
- } else {
- // Add the inc/dec to the real part.
- if (isa<llvm::IntegerType>(InVal->getType()))
- NextVal = llvm::ConstantInt::get(InVal->getType(), AmountVal);
- else if (InVal->getType() == llvm::Type::FloatTy)
- // FIXME: Handle long double.
- NextVal =
- llvm::ConstantFP::get(InVal->getType(),
- llvm::APFloat(static_cast<float>(AmountVal)));
- else {
- // FIXME: Handle long double.
- assert(InVal->getType() == llvm::Type::DoubleTy);
- NextVal =
- llvm::ConstantFP::get(InVal->getType(),
- llvm::APFloat(static_cast<double>(AmountVal)));
- }
- 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){
- assert(RetType->isIntegerType() && "Result type must be an integer!");
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGF.getContext().getTypeSize(RetType));
-
- // sizeof(void) and __alignof__(void) = 1 as a gcc extension.
- if (TypeToSize->isVoidType())
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1));
-
- /// FIXME: This doesn't handle VLAs yet!
- std::pair<uint64_t, unsigned> Info = CGF.getContext().getTypeInfo(TypeToSize);
-
- uint64_t Val = isSizeOf ? Info.first : Info.second;
- Val /= 8; // Return size in bytes, not bits.
-
- return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val));
-}
-
-Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) {
- Expr *Op = E->getSubExpr();
- if (Op->getType()->isComplexType())
- return CGF.EmitComplexExpr(Op).first;
- return Visit(Op);
-}
-Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) {
- Expr *Op = E->getSubExpr();
- if (Op->getType()->isComplexType())
- return CGF.EmitComplexExpr(Op).second;
-
- // __imag on a scalar returns zero. Emit it the subexpr to ensure side
- // effects are evaluated.
- CGF.EmitScalarExpr(Op);
- return llvm::Constant::getNullValue(ConvertType(E->getType()));
-}
-
-Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E)
-{
- int64_t Val = E->evaluateOffsetOf(CGF.getContext());
-
- assert(E->getType()->isIntegerType() && "Result type must be an integer!");
-
- uint32_t ResultWidth =
- static_cast<uint32_t>(CGF.getContext().getTypeSize(E->getType()));
- 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.Ty = E->getType();
- Result.E = E;
- return Result;
-}
-
-Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
- Value *(ScalarExprEmitter::*Func)(const BinOpInfo &)) {
- QualType LHSTy = E->getLHS()->getType(), RHSTy = E->getRHS()->getType();
-
- BinOpInfo OpInfo;
-
- // Load the LHS and RHS operands.
- LValue LHSLV = EmitLValue(E->getLHS());
- OpInfo.LHS = EmitLoadOfLValue(LHSLV, LHSTy);
-
- // Determine the computation type. If the RHS is complex, then this is one of
- // the add/sub/mul/div operators. All of these operators can be computed in
- // with just their real component even though the computation domain really is
- // complex.
- QualType ComputeType = E->getComputationType();
-
- // If the computation type is complex, then the RHS is complex. Emit the RHS.
- if (const ComplexType *CT = ComputeType->getAsComplexType()) {
- ComputeType = CT->getElementType();
-
- // Emit the RHS, only keeping the real component.
- OpInfo.RHS = CGF.EmitComplexExpr(E->getRHS()).first;
- RHSTy = RHSTy->getAsComplexType()->getElementType();
- } else {
- // Otherwise the RHS is a simple scalar value.
- OpInfo.RHS = Visit(E->getRHS());
- }
-
- // Convert the LHS/RHS values to the computation type.
- OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, ComputeType);
-
- // Do not merge types for -= or += where the LHS is a pointer.
- if (!(E->getOpcode() == BinaryOperator::SubAssign ||
- E->getOpcode() == BinaryOperator::AddAssign) ||
- !E->getLHS()->getType()->isPointerType()) {
- OpInfo.RHS = EmitScalarConversion(OpInfo.RHS, RHSTy, ComputeType);
- }
- OpInfo.Ty = ComputeType;
- OpInfo.E = E;
-
- // Expand the binary operator.
- Value *Result = (this->*Func)(OpInfo);
-
- // Truncate the result back to the LHS type.
- Result = EmitScalarConversion(Result, ComputeType, LHSTy);
-
- // Store the result value into the LHS lvalue.
- CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, E->getType());
-
- return Result;
-}
-
-
-Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
- if (Ops.LHS->getType()->isFPOrFPVector())
- return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
- else if (Ops.Ty->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.Ty->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.Ty->isPointerType())
- return Builder.CreateAdd(Ops.LHS, Ops.RHS, "add");
-
- // FIXME: What about a pointer to a VLA?
- Value *Ptr, *Idx;
- Expr *IdxExp;
- if (isa<llvm::PointerType>(Ops.LHS->getType())) { // pointer + int
- Ptr = Ops.LHS;
- Idx = Ops.RHS;
- IdxExp = Ops.E->getRHS();
- } else { // int + pointer
- Ptr = Ops.RHS;
- Idx = Ops.LHS;
- IdxExp = Ops.E->getLHS();
- }
-
- unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (Width < CGF.LLVMPointerWidth) {
- // Zero or sign extend the pointer value based on whether the index is
- // signed or not.
- const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
- if (IdxExp->getType().getCanonicalType()->isSignedIntegerType())
- Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
- else
- Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
- }
-
- return Builder.CreateGEP(Ptr, Idx, "add.ptr");
-}
-
-Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
- if (!isa<llvm::PointerType>(Ops.LHS->getType()))
- return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub");
-
- // pointer - int
- assert(!isa<llvm::PointerType>(Ops.RHS->getType()) &&
- "ptr-ptr shouldn't get here");
- // FIXME: The pointer could point to a VLA.
- Value *Idx = Builder.CreateNeg(Ops.RHS, "sub.ptr.neg");
-
- unsigned Width = cast<llvm::IntegerType>(Idx->getType())->getBitWidth();
- if (Width < CGF.LLVMPointerWidth) {
- // Zero or sign extend the pointer value based on whether the index is
- // signed or not.
- const llvm::Type *IdxType = llvm::IntegerType::get(CGF.LLVMPointerWidth);
- if (Ops.E->getRHS()->getType().getCanonicalType()->isSignedIntegerType())
- Idx = Builder.CreateSExt(Idx, IdxType, "idx.ext");
- else
- Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext");
- }
-
- return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr");
-}
-
-Value *ScalarExprEmitter::VisitBinSub(const BinaryOperator *E) {
- // "X - Y" is different from "X -= Y" in one case: when Y is a pointer. In
- // the compound assignment case it is invalid, so just handle it here.
- if (!E->getRHS()->getType()->isPointerType())
- return EmitSub(EmitBinOps(E));
-
- // pointer - pointer
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
-
- const QualType LHSType = E->getLHS()->getType().getCanonicalType();
- const QualType LHSElementType = cast<PointerType>(LHSType)->getPointeeType();
- uint64_t ElementSize = CGF.getContext().getTypeSize(LHSElementType) / 8;
-
- const llvm::Type *ResultType = ConvertType(E->getType());
- LHS = Builder.CreatePtrToInt(LHS, ResultType, "sub.ptr.lhs.cast");
- RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
- Value *BytesBetween = Builder.CreateSub(LHS, RHS, "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.Ty->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) {
- 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();
-
- 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");
-
- // Evaluate the conditional, then convert it to bool. We do this explicitly
- // because we need the unconverted value if this is a GNU ?: expression with
- // missing middle value.
- Value *CondVal = CGF.EmitScalarExpr(E->getCond());
- Value *CondBoolVal =CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
- CGF.getContext().BoolTy);
- Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);
-
- CGF.EmitBlock(LHSBlock);
-
- // Handle the GNU extension for missing LHS.
- Value *LHS;
- if (E->getLHS())
- LHS = Visit(E->getLHS());
- else // Perform promotions, to handle cases like "short ?: int"
- LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType());
-
- Builder.CreateBr(ContBlock);
- LHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(RHSBlock);
-
- Value *RHS = Visit(E->getRHS());
- Builder.CreateBr(ContBlock);
- RHSBlock = Builder.GetInsertBlock();
-
- CGF.EmitBlock(ContBlock);
-
- if (!LHS) {
- assert(E->getType()->isVoidType() && "Non-void value should have a value");
- return 0;
- }
-
- // 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) {
- // Emit the LHS or RHS as appropriate.
- return
- Visit(E->isConditionTrue(CGF.getContext()) ? E->getLHS() : E->getRHS());
-}
-
-Value *ScalarExprEmitter::VisitOverloadExpr(OverloadExpr *E) {
- return CGF.EmitCallExpr(E->getFn(), E->arg_begin(),
- E->getNumArgs(CGF.getContext())).getScalarVal();
-}
-
-Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
- llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
-
- llvm::Value *V = Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
- return V;
-}
-
-Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
- std::string str;
- llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
- CGF.getContext().getObjCEncodingForType(E->getEncodedType(), str,
- EncodingRecordTypes);
-
- llvm::Constant *C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGF.CGM.getModule());
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
- C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-
- return C;
-}
-
-//===----------------------------------------------------------------------===//
-// 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));
-}
-
-/// EmitScalarConversion - Emit a conversion from the specified type to the
-/// specified destination type, both of which are LLVM scalar types.
-Value *CodeGenFunction::EmitScalarConversion(Value *Src, QualType SrcTy,
- QualType DstTy) {
- assert(!hasAggregateLLVMType(SrcTy) && !hasAggregateLLVMType(DstTy) &&
- "Invalid scalar expression to emit");
- return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy);
-}
-
-/// EmitComplexToScalarConversion - Emit a conversion from the specified
-/// complex type to the specified destination type, where the destination
-/// type is an LLVM scalar type.
-Value *CodeGenFunction::EmitComplexToScalarConversion(ComplexPairTy Src,
- QualType SrcTy,
- QualType DstTy) {
- assert(SrcTy->isComplexType() && !hasAggregateLLVMType(DstTy) &&
- "Invalid complex -> scalar conversion");
- return ScalarExprEmitter(*this).EmitComplexToScalarConversion(Src, SrcTy,
- DstTy);
-}
-
-Value *CodeGenFunction::EmitShuffleVector(Value* V1, Value *V2, ...) {
- assert(V1->getType() == V2->getType() &&
- "Vector operands must be of the same type");
-
- unsigned NumElements =
- cast<llvm::VectorType>(V1->getType())->getNumElements();
-
- va_list va;
- va_start(va, V2);
-
- llvm::SmallVector<llvm::Constant*, 16> Args;
-
- for (unsigned i = 0; i < NumElements; i++) {
- int n = va_arg(va, int);
-
- assert(n >= 0 && n < (int)NumElements * 2 &&
- "Vector shuffle index out of bounds!");
-
- Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, n));
- }
-
- const char *Name = va_arg(va, const char *);
- va_end(va);
-
- llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], NumElements);
-
- return Builder.CreateShuffleVector(V1, V2, Mask, Name);
-}
-
-llvm::Value *CodeGenFunction::EmitVector(llvm::Value * const *Vals,
- unsigned NumVals, bool isSplat)
-{
- llvm::Value *Vec
- = llvm::UndefValue::get(llvm::VectorType::get(Vals[0]->getType(), NumVals));
-
- for (unsigned i = 0, e = NumVals ; i != e; ++i) {
- llvm::Value *Val = isSplat ? Vals[0] : Vals[i];
- llvm::Value *Idx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
- Vec = Builder.CreateInsertElement(Vec, Val, Idx, "tmp");
- }
-
- return Vec;
-}
diff --git a/clang/CodeGen/CGObjC.cpp b/clang/CodeGen/CGObjC.cpp
deleted file mode 100644
index 33419a3d51d..00000000000
--- a/clang/CodeGen/CGObjC.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Objective-C code as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/AST/Expr.h"
-#include "llvm/Constant.h"
-using namespace clang;
-using namespace CodeGen;
-
-llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E){
- std::string S(E->getString()->getStrData(), E->getString()->getByteLength());
- return CGM.GetAddrOfConstantCFString(S);
-}
-
diff --git a/clang/CodeGen/CGObjCGNU.cpp b/clang/CodeGen/CGObjCGNU.cpp
deleted file mode 100644
index f0d6f554d55..00000000000
--- a/clang/CodeGen/CGObjCGNU.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides Objective-C code generation targetting the GNU runtime.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CGObjCRuntime.h"
-#include "llvm/Module.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/LLVMBuilder.h"
-#include "llvm/ADT/SmallVector.h"
-
-using namespace clang::CodeGen;
-using namespace clang;
-
-CGObjCRuntime::~CGObjCRuntime() {}
-
-namespace {
-class CGObjCGNU : public CGObjCRuntime {
-private:
- llvm::Module &TheModule;
-public:
- CGObjCGNU(llvm::Module &M) : TheModule(M) {};
- virtual llvm::Value *generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Receiver,
- llvm::Constant *Selector,
- llvm::Value** ArgV,
- unsigned ArgC);
-};
-} // end anonymous namespace
-
-// Generate code for a message send expression on the GNU runtime.
-// BIG FAT WARNING: Much of this code will need factoring out later.
-// FIXME: This currently only handles id returns. Other return types
-// need some explicit casting.
-llvm::Value *CGObjCGNU::generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Receiver,
- llvm::Constant *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) {
- // Get the selector Type.
- const llvm::Type *PtrToInt8Ty =
- llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- std::vector<const llvm::Type*> Str2(2, PtrToInt8Ty);
- const llvm::Type *SelStructTy = llvm::StructType::get(Str2);
- const llvm::Type *SelTy = llvm::PointerType::getUnqual(SelStructTy);
-
- // Look up the selector.
- // If we haven't got the selector lookup function, look it up now.
- // TODO: Factor this out and use it to implement @selector() too.
- llvm::Constant *SelFunction =
- TheModule.getOrInsertFunction("sel_get_uid", SelTy, PtrToInt8Ty, NULL);
- // FIXME: Selectors should be statically cached, not looked up on every call.
-
- // TODO: Pull this out into the caller.
- llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
- llvm::Constant *Ops[] = {Idx0, Idx0};
- llvm::Value *SelStr = llvm::ConstantExpr::getGetElementPtr(Selector, Ops, 2);
- llvm::Value *cmd = Builder.CreateCall(SelFunction, &SelStr, &SelStr+1);
-
- // Look up the method implementation.
- std::vector<const llvm::Type*> impArgTypes;
- impArgTypes.push_back(Receiver->getType());
- impArgTypes.push_back(SelTy);
-
- // Avoid an explicit cast on the IMP by getting a version that has the right
- // return type.
- llvm::FunctionType *impType = llvm::FunctionType::get(ReturnTy, impArgTypes,
- true);
-
- llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup",
- llvm::PointerType::get(impType, 0),
- Receiver->getType(), SelTy, NULL);
- llvm::SmallVector<llvm::Value*, 16> lookupArgs;
- lookupArgs.push_back(Receiver);
- lookupArgs.push_back(cmd);
- llvm::Value *imp = Builder.CreateCall(lookupFunction,
- lookupArgs.begin(), lookupArgs.end());
-
- // Call the method.
- lookupArgs.insert(lookupArgs.end(), ArgV, ArgV+ArgC);
- return Builder.CreateCall(imp, lookupArgs.begin(), lookupArgs.end());
-}
-
-CGObjCRuntime * clang::CodeGen::CreateObjCRuntime(llvm::Module &M) {
- return new CGObjCGNU(M);
-}
diff --git a/clang/CodeGen/CGObjCRuntime.h b/clang/CodeGen/CGObjCRuntime.h
deleted file mode 100644
index d8fc60f99c0..00000000000
--- a/clang/CodeGen/CGObjCRuntime.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===----- CGObjCRuntime.h - Emit LLVM Code from ASTs for a Module --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This provides an abstract class for Objective-C code generation. Concrete
-// subclasses of this implement code generation for specific Objective-C
-// runtime libraries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_OBCJRUNTIME_H
-#define CLANG_CODEGEN_OBCJRUNTIME_H
-
-namespace llvm {
- class LLVMFoldingBuilder;
- class Constant;
- class Type;
- class Value;
- class Module;
-}
-
-namespace clang {
-namespace CodeGen {
-
-// Implements runtime-specific code generation functions
-class CGObjCRuntime {
-public:
- virtual ~CGObjCRuntime();
-
- // Generate an Objective-C message send operation
- virtual llvm::Value *generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
- const llvm::Type *ReturnTy,
- llvm::Value *Receiver,
- llvm::Constant *Selector,
- llvm::Value** ArgV,
- unsigned ArgC) = 0;
-};
-
-CGObjCRuntime *CreateObjCRuntime(llvm::Module &M);
-}
-}
-#endif
diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp
deleted file mode 100644
index 5fdc61b46f8..00000000000
--- a/clang/CodeGen/CGStmt.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code to emit Stmt nodes as LLVM code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "clang/AST/AST.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/ADT/StringExtras.h"
-using namespace clang;
-using namespace CodeGen;
-
-//===----------------------------------------------------------------------===//
-// Statement Emission
-//===----------------------------------------------------------------------===//
-
-void CodeGenFunction::EmitStmt(const Stmt *S) {
- assert(S && "Null statement?");
-
- switch (S->getStmtClass()) {
- default:
- // Must be an expression in a stmt context. Emit the value (to get
- // side-effects) and ignore the result.
- if (const Expr *E = dyn_cast<Expr>(S)) {
- if (!hasAggregateLLVMType(E->getType()))
- EmitScalarExpr(E);
- else if (E->getType()->isComplexType())
- EmitComplexExpr(E);
- else
- EmitAggExpr(E, 0, false);
- } else {
- WarnUnsupported(S, "statement");
- }
- break;
- case Stmt::NullStmtClass: break;
- case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
- case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
- case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
-
- case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
- case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
- case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S)); break;
- case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S)); break;
-
- case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
- case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
-
- case Stmt::BreakStmtClass: EmitBreakStmt(); break;
- case Stmt::ContinueStmtClass: EmitContinueStmt(); break;
- case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
- case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
- case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break;
- case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
- }
-}
-
-/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
-/// this captures the expression result of the last sub-statement and returns it
-/// (for use by the statement expression extension).
-RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
- llvm::Value *AggLoc, bool isAggVol) {
- // FIXME: handle vla's etc.
- if (S.body_empty() || !isa<Expr>(S.body_back())) GetLast = false;
-
- for (CompoundStmt::const_body_iterator I = S.body_begin(),
- E = S.body_end()-GetLast; I != E; ++I)
- EmitStmt(*I);
-
-
- if (!GetLast)
- return RValue::get(0);
-
- return EmitAnyExpr(cast<Expr>(S.body_back()), AggLoc);
-}
-
-void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) {
- // Emit a branch from this block to the next one if this was a real block. If
- // this was just a fall-through block after a terminator, don't emit it.
- llvm::BasicBlock *LastBB = Builder.GetInsertBlock();
-
- if (LastBB->getTerminator()) {
- // If the previous block is already terminated, don't touch it.
- } else if (LastBB->empty() && LastBB->getValueName() == 0) {
- // If the last block was an empty placeholder, remove it now.
- // TODO: cache and reuse these.
- Builder.GetInsertBlock()->eraseFromParent();
- } else {
- // Otherwise, create a fall-through branch.
- Builder.CreateBr(BB);
- }
- CurFn->getBasicBlockList().push_back(BB);
- Builder.SetInsertPoint(BB);
-}
-
-void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
- llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
-
- EmitBlock(NextBB);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
- Builder.CreateBr(getBasicBlockForLabel(S.getLabel()));
-
- // Emit a block after the branch so that dead code after a goto has some place
- // to go.
- Builder.SetInsertPoint(new llvm::BasicBlock("", CurFn));
-}
-
-void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
- // C99 6.8.4.1: The first substatement is executed if the expression compares
- // unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- llvm::BasicBlock *ContBlock = new llvm::BasicBlock("ifend");
- llvm::BasicBlock *ThenBlock = new llvm::BasicBlock("ifthen");
- llvm::BasicBlock *ElseBlock = ContBlock;
-
- if (S.getElse())
- ElseBlock = new llvm::BasicBlock("ifelse");
-
- // Insert the conditional branch.
- Builder.CreateCondBr(BoolCondVal, ThenBlock, ElseBlock);
-
- // Emit the 'then' code.
- EmitBlock(ThenBlock);
- EmitStmt(S.getThen());
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ThenBlock);
- }
- else
- Builder.CreateBr(ContBlock);
-
- // Emit the 'else' code if present.
- if (const Stmt *Else = S.getElse()) {
- EmitBlock(ElseBlock);
- EmitStmt(Else);
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB)) {
- BB->eraseFromParent();
- Builder.SetInsertPoint(ElseBlock);
- }
- else
- Builder.CreateBr(ContBlock);
- }
-
- // Emit the continuation block for code after the if.
- EmitBlock(ContBlock);
-}
-
-void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
- // Emit the header for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopHeader = new llvm::BasicBlock("whilecond");
- EmitBlock(LoopHeader);
-
- // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
- // of the controlling expression takes place before each execution of the loop
- // body.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // while(1) is common, avoid extra exit blocks. Be sure
- // to correctly handle break/continue though.
- bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
- if (C->isOne())
- EmitBoolCondBranch = false;
-
- // Create an exit block for when the condition fails, create a block for the
- // body of the loop.
- llvm::BasicBlock *ExitBlock = new llvm::BasicBlock("whileexit");
- llvm::BasicBlock *LoopBody = new llvm::BasicBlock("whilebody");
-
- // As long as the condition is true, go to the loop body.
- if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
-
- // Emit the loop body.
- EmitBlock(LoopBody);
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- // Cycle to the condition.
- Builder.CreateBr(LoopHeader);
-
- // Emit the exit block.
- EmitBlock(ExitBlock);
-
- // If LoopHeader is a simple forwarding block then eliminate it.
- if (!EmitBoolCondBranch
- && &LoopHeader->front() == LoopHeader->getTerminator()) {
- LoopHeader->replaceAllUsesWith(LoopBody);
- LoopHeader->getTerminator()->eraseFromParent();
- LoopHeader->eraseFromParent();
- }
-}
-
-void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
- // Emit the body for the loop, insert it, which will create an uncond br to
- // it.
- llvm::BasicBlock *LoopBody = new llvm::BasicBlock("dobody");
- llvm::BasicBlock *AfterDo = new llvm::BasicBlock("afterdo");
- EmitBlock(LoopBody);
-
- llvm::BasicBlock *DoCond = new llvm::BasicBlock("docond");
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond));
-
- // Emit the body of the loop into the block.
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- EmitBlock(DoCond);
-
- // C99 6.8.5.2: "The evaluation of the controlling expression takes place
- // after each execution of the loop body."
-
- // Evaluate the conditional in the while header.
- // C99 6.8.5p2/p4: The first substatement is executed if the expression
- // compares unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // "do {} while (0)" is common in macros, avoid extra blocks. Be sure
- // to correctly handle break/continue though.
- bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
- if (C->isZero())
- EmitBoolCondBranch = false;
-
- // As long as the condition is true, iterate the loop.
- if (EmitBoolCondBranch)
- Builder.CreateCondBr(BoolCondVal, LoopBody, AfterDo);
-
- // Emit the exit block.
- EmitBlock(AfterDo);
-
- // If DoCond is a simple forwarding block then eliminate it.
- if (!EmitBoolCondBranch && &DoCond->front() == DoCond->getTerminator()) {
- DoCond->replaceAllUsesWith(AfterDo);
- DoCond->getTerminator()->eraseFromParent();
- DoCond->eraseFromParent();
- }
-}
-
-void CodeGenFunction::EmitForStmt(const ForStmt &S) {
- // FIXME: What do we do if the increment (f.e.) contains a stmt expression,
- // which contains a continue/break?
- // TODO: We could keep track of whether the loop body contains any
- // break/continue statements and not create unnecessary blocks (like
- // "afterfor" for a condless loop) if it doesn't.
-
- // Evaluate the first part before the loop.
- if (S.getInit())
- EmitStmt(S.getInit());
-
- // Start the loop with a block that tests the condition.
- llvm::BasicBlock *CondBlock = new llvm::BasicBlock("forcond");
- llvm::BasicBlock *AfterFor = new llvm::BasicBlock("afterfor");
-
- EmitBlock(CondBlock);
-
- // Evaluate the condition if present. If not, treat it as a non-zero-constant
- // according to 6.8.5.3p2, aka, true.
- if (S.getCond()) {
- // C99 6.8.5p2/p4: The first substatement is executed if the expression
- // compares unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
-
- // As long as the condition is true, iterate the loop.
- llvm::BasicBlock *ForBody = new llvm::BasicBlock("forbody");
- Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
- EmitBlock(ForBody);
- } else {
- // Treat it as a non-zero constant. Don't even create a new block for the
- // body, just fall into it.
- }
-
- // If the for loop doesn't have an increment we can just use the
- // condition as the continue block.
- llvm::BasicBlock *ContinueBlock;
- if (S.getInc())
- ContinueBlock = new llvm::BasicBlock("forinc");
- else
- ContinueBlock = CondBlock;
-
- // Store the blocks to use for break and continue.
- BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock));
-
- // If the condition is true, execute the body of the for stmt.
- EmitStmt(S.getBody());
-
- BreakContinueStack.pop_back();
-
- if (S.getInc())
- EmitBlock(ContinueBlock);
-
- // If there is an increment, emit it next.
- if (S.getInc())
- EmitStmt(S.getInc());
-
- // Finally, branch back up to the condition for the next iteration.
- Builder.CreateBr(CondBlock);
-
- // Emit the fall-through block.
- EmitBlock(AfterFor);
-}
-
-/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
-/// if the function returns void, or may be missing one if the function returns
-/// non-void. Fun stuff :).
-void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
- // Emit the result value, even if unused, to evalute the side effects.
- const Expr *RV = S.getRetValue();
-
- QualType FnRetTy = CurFuncDecl->getType().getCanonicalType();
- FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();
-
- if (FnRetTy->isVoidType()) {
- // If the function returns void, emit ret void.
- Builder.CreateRetVoid();
- } else if (RV == 0) {
- // Handle "return;" in a function that returns a value.
- const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType();
- if (RetTy == llvm::Type::VoidTy)
- Builder.CreateRetVoid(); // struct return etc.
- else
- Builder.CreateRet(llvm::UndefValue::get(RetTy));
- } else if (!hasAggregateLLVMType(RV->getType())) {
- Builder.CreateRet(EmitScalarExpr(RV));
- } else if (RV->getType()->isComplexType()) {
- llvm::Value *SRetPtr = CurFn->arg_begin();
- EmitComplexExprIntoAddr(RV, SRetPtr, false);
- } else {
- llvm::Value *SRetPtr = CurFn->arg_begin();
- EmitAggExpr(RV, SRetPtr, false);
- }
-
- // Emit a block after the branch so that dead code after a return has some
- // place to go.
- EmitBlock(new llvm::BasicBlock());
-}
-
-void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
- for (const ScopedDecl *Decl = S.getDecl(); Decl;
- Decl = Decl->getNextDeclarator())
- EmitDecl(*Decl);
-}
-
-void CodeGenFunction::EmitBreakStmt() {
- assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
-
- llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
- Builder.CreateBr(Block);
- EmitBlock(new llvm::BasicBlock());
-}
-
-void CodeGenFunction::EmitContinueStmt() {
- assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
-
- llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
- Builder.CreateBr(Block);
- EmitBlock(new llvm::BasicBlock());
-}
-
-/// EmitCaseStmtRange - If case statement range is not too big then
-/// add multiple cases to switch instruction, one for each value within
-/// the range. If range is too big then emit "if" condition check.
-void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
- assert (S.getRHS() && "Unexpected RHS value in CaseStmt");
-
- const Expr *L = S.getLHS();
- const Expr *R = S.getRHS();
- llvm::ConstantInt *LV = cast<llvm::ConstantInt>(EmitScalarExpr(L));
- llvm::ConstantInt *RV = cast<llvm::ConstantInt>(EmitScalarExpr(R));
- llvm::APInt LHS = LV->getValue();
- const llvm::APInt &RHS = RV->getValue();
-
- llvm::APInt Range = RHS - LHS;
- if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
- // Range is small enough to add multiple switch instruction cases.
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- SwitchInsn->addCase(LV, CaseDest);
- LHS++;
- while (LHS != RHS) {
- SwitchInsn->addCase(llvm::ConstantInt::get(LHS), CaseDest);
- LHS++;
- }
- SwitchInsn->addCase(RV, CaseDest);
- EmitStmt(S.getSubStmt());
- return;
- }
-
- // The range is too big. Emit "if" condition.
- llvm::BasicBlock *FalseDest = NULL;
- llvm::BasicBlock *CaseDest = new llvm::BasicBlock("sw.bb");
-
- // If we have already seen one case statement range for this switch
- // instruction then piggy-back otherwise use default block as false
- // destination.
- if (CaseRangeBlock)
- FalseDest = CaseRangeBlock;
- else
- FalseDest = SwitchInsn->getDefaultDest();
-
- // Start new block to hold case statement range check instructions.
- StartBlock("case.range");
- CaseRangeBlock = Builder.GetInsertBlock();
-
- // Emit range check.
- llvm::Value *Diff =
- Builder.CreateSub(SwitchInsn->getCondition(), LV, "tmp");
- llvm::Value *Cond =
- Builder.CreateICmpULE(Diff, llvm::ConstantInt::get(Range), "tmp");
- Builder.CreateCondBr(Cond, CaseDest, FalseDest);
-
- // Now emit case statement body.
- EmitBlock(CaseDest);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
- if (S.getRHS()) {
- EmitCaseStmtRange(S);
- return;
- }
-
- StartBlock("sw.bb");
- llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
- llvm::APSInt CaseVal(32);
- S.getLHS()->isIntegerConstantExpr(CaseVal, getContext());
- llvm::ConstantInt *LV = llvm::ConstantInt::get(CaseVal);
- SwitchInsn->addCase(LV, CaseDest);
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitDefaultStmt(const DefaultStmt &S) {
- StartBlock("sw.default");
- // Current insert block is the default destination.
- SwitchInsn->setSuccessor(0, Builder.GetInsertBlock());
- EmitStmt(S.getSubStmt());
-}
-
-void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
- llvm::Value *CondV = EmitScalarExpr(S.getCond());
-
- // Handle nested switch statements.
- llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
- llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
- CaseRangeBlock = NULL;
-
- // Create basic block to hold stuff that comes after switch statement.
- // Initially use it to hold DefaultStmt.
- llvm::BasicBlock *NextBlock = new llvm::BasicBlock("after.sw");
- SwitchInsn = Builder.CreateSwitch(CondV, NextBlock);
-
- // All break statements jump to NextBlock. If BreakContinueStack is non empty
- // then reuse last ContinueBlock.
- llvm::BasicBlock *ContinueBlock = NULL;
- if (!BreakContinueStack.empty())
- ContinueBlock = BreakContinueStack.back().ContinueBlock;
- BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
-
- // Emit switch body.
- EmitStmt(S.getBody());
- BreakContinueStack.pop_back();
-
- // If one or more case statement range is seen then use CaseRangeBlock
- // as the default block. False edge of CaseRangeBlock will lead to
- // original default block.
- if (CaseRangeBlock)
- SwitchInsn->setSuccessor(0, CaseRangeBlock);
-
- // Prune insert block if it is dummy.
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
- BB->eraseFromParent();
- else // Otherwise, branch to continuation.
- Builder.CreateBr(NextBlock);
-
- // Place NextBlock as the new insert point.
- CurFn->getBasicBlockList().push_back(NextBlock);
- Builder.SetInsertPoint(NextBlock);
- SwitchInsn = SavedSwitchInsn;
- CaseRangeBlock = SavedCRBlock;
-}
-
-static inline std::string ConvertAsmString(const char *Start,
- unsigned NumOperands,
- bool IsSimple)
-{
- static unsigned AsmCounter = 0;
-
- AsmCounter++;
-
- std::string Result;
- if (IsSimple) {
- while (*Start) {
- switch (*Start) {
- default:
- Result += *Start;
- break;
- case '$':
- Result += "$$";
- break;
- }
-
- Start++;
- }
-
- return Result;
- }
-
- while (*Start) {
- switch (*Start) {
- default:
- Result += *Start;
- break;
- case '$':
- Result += "$$";
- break;
- case '%':
- // Escaped character
- Start++;
- if (!*Start) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Trailing '%' in asm string.");
- }
-
- char EscapedChar = *Start;
- if (EscapedChar == '%') {
- // Escaped percentage sign.
- Result += '%';
- }
- else if (EscapedChar == '=') {
- // Generate an unique ID.
- Result += llvm::utostr(AsmCounter);
- } else if (isdigit(EscapedChar)) {
- // %n - Assembler operand n
- char *End;
-
- unsigned long n = strtoul(Start, &End, 10);
- if (Start == End) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Missing operand!");
- } else if (n >= NumOperands) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Operand number out of range!");
- }
-
- Result += '$' + llvm::utostr(n);
- Start = End - 1;
- } else if (isalpha(EscapedChar)) {
- char *End;
-
- unsigned long n = strtoul(Start + 1, &End, 10);
- if (Start == End) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Missing operand!");
- } else if (n >= NumOperands) {
- // FIXME: This should be caught during Sema.
- assert(0 && "Operand number out of range!");
- }
-
- Result += "${" + llvm::utostr(n) + ':' + EscapedChar + '}';
- Start = End - 1;
- } else {
- assert(0 && "Unhandled asm escaped character!");
- }
- }
- Start++;
- }
-
- return Result;
-}
-
-static std::string SimplifyConstraint(const char* Constraint,
- TargetInfo &Target) {
- std::string Result;
-
- while (*Constraint) {
- switch (*Constraint) {
- default:
- Result += Target.convertConstraint(*Constraint);
- break;
- // Ignore these
- case '*':
- case '?':
- case '!':
- break;
- case 'g':
- Result += "imr";
- break;
- }
-
- Constraint++;
- }
-
- return Result;
-}
-
-void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
- std::string AsmString =
- ConvertAsmString(std::string(S.getAsmString()->getStrData(),
- S.getAsmString()->getByteLength()).c_str(),
- S.getNumOutputs() + S.getNumInputs(), S.isSimple());
-
- std::string Constraints;
-
- llvm::Value *ResultAddr = 0;
- const llvm::Type *ResultType = llvm::Type::VoidTy;
-
- std::vector<const llvm::Type*> ArgTypes;
- std::vector<llvm::Value*> Args;
-
- // Keep track of inout constraints.
- std::string InOutConstraints;
- std::vector<llvm::Value*> InOutArgs;
- std::vector<const llvm::Type*> InOutArgTypes;
-
- for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) {
- std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(),
- S.getOutputConstraint(i)->getByteLength());
-
- TargetInfo::ConstraintInfo Info;
- bool result = Target.validateOutputConstraint(OutputConstraint.c_str(),
- Info);
- assert(result && "Failed to parse output constraint");
-
- // Simplify the output constraint.
- OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target);
-
- LValue Dest = EmitLValue(S.getOutputExpr(i));
- const llvm::Type *DestValueType =
- cast<llvm::PointerType>(Dest.getAddress()->getType())->getElementType();
-
- // If the first output operand is not a memory dest, we'll
- // make it the return value.
- if (i == 0 && !(Info & TargetInfo::CI_AllowsMemory) &&
- DestValueType->isFirstClassType()) {
- ResultAddr = Dest.getAddress();
- ResultType = DestValueType;
- Constraints += "=" + OutputConstraint;
- } else {
- ArgTypes.push_back(Dest.getAddress()->getType());
- Args.push_back(Dest.getAddress());
- if (i != 0)
- Constraints += ',';
- Constraints += "=*";
- Constraints += OutputConstraint;
- }
-
- if (Info & TargetInfo::CI_ReadWrite) {
- // FIXME: This code should be shared with the code that handles inputs.
- InOutConstraints += ',';
-
- const Expr *InputExpr = S.getOutputExpr(i);
- llvm::Value *Arg;
- if ((Info & TargetInfo::CI_AllowsRegister) ||
- !(Info & TargetInfo::CI_AllowsMemory)) {
- if (ConvertType(InputExpr->getType())->isFirstClassType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- assert(0 && "FIXME: Implement passing non first class types as inputs");
- }
- } else {
- LValue Dest = EmitLValue(InputExpr);
- Arg = Dest.getAddress();
- InOutConstraints += '*';
- }
-
- InOutArgTypes.push_back(Arg->getType());
- InOutArgs.push_back(Arg);
- InOutConstraints += OutputConstraint;
- }
- }
-
- unsigned NumConstraints = S.getNumOutputs() + S.getNumInputs();
-
- for (unsigned i = 0, e = S.getNumInputs(); i != e; i++) {
- const Expr *InputExpr = S.getInputExpr(i);
-
- std::string InputConstraint(S.getInputConstraint(i)->getStrData(),
- S.getInputConstraint(i)->getByteLength());
-
- TargetInfo::ConstraintInfo Info;
- bool result = Target.validateInputConstraint(InputConstraint.c_str(),
- NumConstraints,
- Info);
- assert(result && "Failed to parse input constraint");
-
- if (i != 0 || S.getNumOutputs() > 0)
- Constraints += ',';
-
- // Simplify the input constraint.
- InputConstraint = SimplifyConstraint(InputConstraint.c_str(), Target);
-
- llvm::Value *Arg;
-
- if ((Info & TargetInfo::CI_AllowsRegister) ||
- !(Info & TargetInfo::CI_AllowsMemory)) {
- if (ConvertType(InputExpr->getType())->isFirstClassType()) {
- Arg = EmitScalarExpr(InputExpr);
- } else {
- assert(0 && "FIXME: Implement passing non first class types as inputs");
- }
- } else {
- LValue Dest = EmitLValue(InputExpr);
- Arg = Dest.getAddress();
- Constraints += '*';
- }
-
- ArgTypes.push_back(Arg->getType());
- Args.push_back(Arg);
- Constraints += InputConstraint;
- }
-
- // Append the "input" part of inout constraints last.
- for (unsigned i = 0, e = InOutArgs.size(); i != e; i++) {
- ArgTypes.push_back(InOutArgTypes[i]);
- Args.push_back(InOutArgs[i]);
- }
- Constraints += InOutConstraints;
-
- // Clobbers
- for (unsigned i = 0, e = S.getNumClobbers(); i != e; i++) {
- std::string Clobber(S.getClobber(i)->getStrData(),
- S.getClobber(i)->getByteLength());
-
- Clobber = Target.getNormalizedGCCRegisterName(Clobber.c_str());
-
- if (i != 0 || NumConstraints != 0)
- Constraints += ',';
-
- Constraints += "~{";
- Constraints += Clobber;
- Constraints += '}';
- }
-
- // Add machine specific clobbers
- if (const char *C = Target.getClobbers()) {
- if (!Constraints.empty())
- Constraints += ',';
- Constraints += C;
- }
-
- const llvm::FunctionType *FTy =
- llvm::FunctionType::get(ResultType, ArgTypes, false);
-
- llvm::InlineAsm *IA =
- llvm::InlineAsm::get(FTy, AsmString, Constraints,
- S.isVolatile() || S.getNumOutputs() == 0);
- llvm::Value *Result = Builder.CreateCall(IA, Args.begin(), Args.end(), "");
- if (ResultAddr)
- Builder.CreateStore(Result, ResultAddr);
-}
diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp
deleted file mode 100644
index 49f23f27c34..00000000000
--- a/clang/CodeGen/CodeGenFunction.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the per-function state used while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenFunction.h"
-#include "CodeGenModule.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/AST/AST.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Support/CFG.h"
-using namespace clang;
-using namespace CodeGen;
-
-CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
- : CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
- CaseRangeBlock(NULL) {}
-
-ASTContext &CodeGenFunction::getContext() const {
- return CGM.getContext();
-}
-
-
-llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
- llvm::BasicBlock *&BB = LabelMap[S];
- if (BB) return BB;
-
- // Create, but don't insert, the new block.
- return BB = new llvm::BasicBlock(S->getName());
-}
-
-llvm::Constant *
-CodeGenFunction::GetAddrOfStaticLocalVar(const BlockVarDecl *BVD) {
- return cast<llvm::Constant>(LocalDeclMap[BVD]);
-}
-
-const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
- return CGM.getTypes().ConvertType(T);
-}
-
-bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
- return !T->isRealType() && !T->isPointerType() && !T->isReferenceType() &&
- !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
-}
-
-
-void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
- LLVMIntTy = ConvertType(getContext().IntTy);
- LLVMPointerWidth = static_cast<unsigned>(
- getContext().getTypeSize(getContext().getPointerType(getContext().VoidTy)));
-
- CurFuncDecl = FD;
- CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true));
- assert(CurFn->isDeclaration() && "Function already has body?");
-
- // TODO: Set up linkage and many other things. Note, this is a simple
- // approximation of what we really want.
- if (FD->getAttr<DLLImportAttr>())
- CurFn->setLinkage(llvm::Function::DLLImportLinkage);
- else if (FD->getAttr<DLLExportAttr>())
- CurFn->setLinkage(llvm::Function::DLLExportLinkage);
- else if (FD->getAttr<WeakAttr>() || FD->isInline())
- CurFn->setLinkage(llvm::Function::WeakLinkage);
- else if (FD->getStorageClass() == FunctionDecl::Static)
- CurFn->setLinkage(llvm::Function::InternalLinkage);
-
- if (FD->getAttr<FastCallAttr>())
- CurFn->setCallingConv(llvm::CallingConv::Fast);
-
- if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>())
- CurFn->setVisibility(attr->getVisibility());
- // FIXME: else handle -fvisibility
-
-
- unsigned FuncAttrs = 0;
- if (FD->getAttr<NoThrowAttr>())
- FuncAttrs |= llvm::ParamAttr::NoUnwind;
- if (FD->getAttr<NoReturnAttr>())
- FuncAttrs |= llvm::ParamAttr::NoReturn;
-
- if (FuncAttrs) {
- llvm::ParamAttrsWithIndex PAWI =
- llvm::ParamAttrsWithIndex::get(0, FuncAttrs);
- CurFn->setParamAttrs(llvm::PAListPtr::get(&PAWI, 1));
- }
-
- llvm::BasicBlock *EntryBB = new llvm::BasicBlock("entry", CurFn);
-
- // Create a marker to make it easy to insert allocas into the entryblock
- // later. Don't create this with the builder, because we don't want it
- // folded.
- llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
- AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
- EntryBB);
-
- Builder.SetInsertPoint(EntryBB);
-
- // Emit allocs for param decls. Give the LLVM Argument nodes names.
- llvm::Function::arg_iterator AI = CurFn->arg_begin();
-
- // Name the struct return argument.
- if (hasAggregateLLVMType(FD->getResultType())) {
- AI->setName("agg.result");
- ++AI;
- }
-
- for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
- assert(AI != CurFn->arg_end() && "Argument mismatch!");
- EmitParmDecl(*FD->getParamDecl(i), AI);
- }
-
- // Emit the function body.
- EmitStmt(FD->getBody());
-
- // Emit a return for code that falls off the end. If insert point
- // is a dummy block with no predecessors then remove the block itself.
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
- BB->eraseFromParent();
- else {
- // FIXME: if this is C++ main, this should return 0.
- if (CurFn->getReturnType() == llvm::Type::VoidTy)
- Builder.CreateRetVoid();
- else
- Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
- }
- assert(BreakContinueStack.empty() &&
- "mismatched push/pop in break/continue stack!");
-
- // Remove the AllocaInsertPt instruction, which is just a convenience for us.
- AllocaInsertPt->eraseFromParent();
- AllocaInsertPt = 0;
-
- // Verify that the function is well formed.
- assert(!verifyFunction(*CurFn));
-}
-
-/// isDummyBlock - Return true if BB is an empty basic block
-/// with no predecessors.
-bool CodeGenFunction::isDummyBlock(const llvm::BasicBlock *BB) {
- if (BB->empty() && pred_begin(BB) == pred_end(BB))
- return true;
- return false;
-}
-
-/// StartBlock - Start new block named N. If insert block is a dummy block
-/// then reuse it.
-void CodeGenFunction::StartBlock(const char *N) {
- llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (!isDummyBlock(BB))
- EmitBlock(new llvm::BasicBlock(N));
- else
- BB->setName(N);
-}
-
-/// getCGRecordLayout - Return record layout info.
-const CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
- QualType Ty) {
- const RecordType *RTy = Ty->getAsRecordType();
- assert (RTy && "Unexpected type. RecordType expected here.");
-
- return CGT.getCGRecordLayout(RTy->getDecl());
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenFunction::WarnUnsupported(const Stmt *S, const char *Type) {
- CGM.WarnUnsupported(S, Type);
-}
-
diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h
deleted file mode 100644
index 509e8296d20..00000000000
--- a/clang/CodeGen/CodeGenFunction.h
+++ /dev/null
@@ -1,486 +0,0 @@
-//===--- CodeGenFunction.h - Per-Function state for LLVM CodeGen ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the internal per-function state used for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENFUNCTION_H
-#define CLANG_CODEGEN_CODEGENFUNCTION_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/LLVMBuilder.h"
-#include <vector>
-
-namespace llvm {
- class Module;
-}
-
-namespace clang {
- class ASTContext;
- class Decl;
- class FunctionDecl;
- class TargetInfo;
- class QualType;
- class FunctionTypeProto;
-
- class Stmt;
- class CompoundStmt;
- class LabelStmt;
- class GotoStmt;
- class IfStmt;
- class WhileStmt;
- class DoStmt;
- class ForStmt;
- class ReturnStmt;
- class DeclStmt;
- class CaseStmt;
- class DefaultStmt;
- class SwitchStmt;
- class AsmStmt;
-
- class Expr;
- class DeclRefExpr;
- class StringLiteral;
- class IntegerLiteral;
- class FloatingLiteral;
- class CharacterLiteral;
- class TypesCompatibleExpr;
-
- class ImplicitCastExpr;
- class CastExpr;
- class CallExpr;
- class UnaryOperator;
- class BinaryOperator;
- class CompoundAssignOperator;
- class ArraySubscriptExpr;
- class OCUVectorElementExpr;
- class ConditionalOperator;
- class ChooseExpr;
- class PreDefinedExpr;
- class ObjCStringLiteral;
- class MemberExpr;
-
- class BlockVarDecl;
- class EnumConstantDecl;
- class ParmVarDecl;
- class FieldDecl;
-namespace CodeGen {
- class CodeGenModule;
- class CodeGenTypes;
- class CGRecordLayout;
-
-/// RValue - This trivial value class is used to represent the result of an
-/// expression that is evaluated. It can be one of three things: either a
-/// simple LLVM SSA value, a pair of SSA values for complex numbers, or the
-/// address of an aggregate value in memory.
-class RValue {
- llvm::Value *V1, *V2;
- // TODO: Encode this into the low bit of pointer for more efficient
- // return-by-value.
- enum { Scalar, Complex, Aggregate } Flavor;
-
- // FIXME: Aggregate rvalues need to retain information about whether they are
- // volatile or not.
-public:
-
- bool isScalar() const { return Flavor == Scalar; }
- bool isComplex() const { return Flavor == Complex; }
- bool isAggregate() const { return Flavor == Aggregate; }
-
- /// getScalar() - Return the Value* of this scalar value.
- llvm::Value *getScalarVal() const {
- assert(isScalar() && "Not a scalar!");
- return V1;
- }
-
- /// getComplexVal - Return the real/imag components of this complex value.
- ///
- std::pair<llvm::Value *, llvm::Value *> getComplexVal() const {
- return std::pair<llvm::Value *, llvm::Value *>(V1, V2);
- }
-
- /// getAggregateAddr() - Return the Value* of the address of the aggregate.
- llvm::Value *getAggregateAddr() const {
- assert(isAggregate() && "Not an aggregate!");
- return V1;
- }
-
- static RValue get(llvm::Value *V) {
- RValue ER;
- ER.V1 = V;
- ER.Flavor = Scalar;
- return ER;
- }
- static RValue getComplex(llvm::Value *V1, llvm::Value *V2) {
- RValue ER;
- ER.V1 = V1;
- ER.V2 = V2;
- ER.Flavor = Complex;
- return ER;
- }
- static RValue getComplex(const std::pair<llvm::Value *, llvm::Value *> &C) {
- RValue ER;
- ER.V1 = C.first;
- ER.V2 = C.second;
- ER.Flavor = Complex;
- return ER;
- }
- static RValue getAggregate(llvm::Value *V) {
- RValue ER;
- ER.V1 = V;
- ER.Flavor = Aggregate;
- return ER;
- }
-};
-
-
-/// LValue - This represents an lvalue references. Because C/C++ allow
-/// bitfields, this is not a simple LLVM pointer, it may be a pointer plus a
-/// bitrange.
-class LValue {
- // FIXME: Volatility. Restrict?
- // alignment?
-
- enum {
- Simple, // This is a normal l-value, use getAddress().
- VectorElt, // This is a vector element l-value (V[i]), use getVector*
- BitField, // This is a bitfield l-value, use getBitfield*.
- OCUVectorElt // This is an ocu vector subset, use getOCUVectorComp
- } LVType;
-
- llvm::Value *V;
-
- union {
- llvm::Value *VectorIdx; // Index into a vector subscript: V[i]
- unsigned VectorElts; // Encoded OCUVector element subset: V.xyx
- struct {
- unsigned short StartBit;
- unsigned short Size;
- bool IsSigned;
- } BitfieldData; // BitField start bit and size
- };
-public:
- bool isSimple() const { return LVType == Simple; }
- bool isVectorElt() const { return LVType == VectorElt; }
- bool isBitfield() const { return LVType == BitField; }
- bool isOCUVectorElt() const { return LVType == OCUVectorElt; }
-
- // simple lvalue
- llvm::Value *getAddress() const { assert(isSimple()); return V; }
- // vector elt lvalue
- llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
- llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
- // ocu vector elements.
- llvm::Value *getOCUVectorAddr() const { assert(isOCUVectorElt()); return V; }
- unsigned getOCUVectorElts() const {
- assert(isOCUVectorElt());
- return VectorElts;
- }
- // bitfield lvalue
- llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
- unsigned short getBitfieldStartBit() const {
- assert(isBitfield());
- return BitfieldData.StartBit;
- }
- unsigned short getBitfieldSize() const {
- assert(isBitfield());
- return BitfieldData.Size;
- }
- bool isBitfieldSigned() const {
- assert(isBitfield());
- return BitfieldData.IsSigned;
- }
-
- static LValue MakeAddr(llvm::Value *V) {
- LValue R;
- R.LVType = Simple;
- R.V = V;
- return R;
- }
-
- static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx) {
- LValue R;
- R.LVType = VectorElt;
- R.V = Vec;
- R.VectorIdx = Idx;
- return R;
- }
-
- static LValue MakeOCUVectorElt(llvm::Value *Vec, unsigned Elements) {
- LValue R;
- R.LVType = OCUVectorElt;
- R.V = Vec;
- R.VectorElts = Elements;
- return R;
- }
-
- static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
- unsigned short Size, bool IsSigned) {
- LValue R;
- R.LVType = BitField;
- R.V = V;
- R.BitfieldData.StartBit = StartBit;
- R.BitfieldData.Size = Size;
- R.BitfieldData.IsSigned = IsSigned;
- return R;
- }
-};
-
-/// CodeGenFunction - This class organizes the per-function state that is used
-/// while generating LLVM code.
-class CodeGenFunction {
-public:
- CodeGenModule &CGM; // Per-module state.
- TargetInfo &Target;
-
- typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
- llvm::LLVMFoldingBuilder Builder;
-
- const FunctionDecl *CurFuncDecl;
- llvm::Function *CurFn;
-
- /// AllocaInsertPoint - This is an instruction in the entry block before which
- /// we prefer to insert allocas.
- llvm::Instruction *AllocaInsertPt;
-
- const llvm::Type *LLVMIntTy;
- uint32_t LLVMPointerWidth;
-
-private:
- /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
- /// decls.
- llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
-
- /// LabelMap - This keeps track of the LLVM basic block for each C label.
- llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
-
- // BreakContinueStack - This keeps track of where break and continue
- // statements should jump to.
- struct BreakContinue {
- BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb)
- : BreakBlock(bb), ContinueBlock(cb) {}
-
- llvm::BasicBlock *BreakBlock;
- llvm::BasicBlock *ContinueBlock;
- };
- llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
-
- /// SwitchInsn - This is nearest current switch instruction. It is null if
- /// if current context is not in a switch.
- llvm::SwitchInst *SwitchInsn;
-
- /// CaseRangeBlock - This block holds if condition check for last case
- /// statement range in current switch instruction.
- llvm::BasicBlock *CaseRangeBlock;
-
-public:
- CodeGenFunction(CodeGenModule &cgm);
-
- ASTContext &getContext() const;
-
- void GenerateCode(const FunctionDecl *FD);
-
- const llvm::Type *ConvertType(QualType T);
-
- /// hasAggregateLLVMType - Return true if the specified AST type will map into
- /// an aggregate LLVM type or is void.
- static bool hasAggregateLLVMType(QualType T);
-
- /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
- /// label maps to.
- llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
-
-
- void EmitBlock(llvm::BasicBlock *BB);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified stmt yet.
- void WarnUnsupported(const Stmt *S, const char *Type);
-
- //===--------------------------------------------------------------------===//
- // Helpers
- //===--------------------------------------------------------------------===//
-
- /// CreateTempAlloca - This creates a alloca and inserts it into the entry
- /// block.
- llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty,
- const char *Name = "tmp");
-
- /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
- /// expression and compare the result against zero, returning an Int1Ty value.
- llvm::Value *EvaluateExprAsBool(const Expr *E);
-
- /// EmitAnyExpr - Emit code to compute the specified expression which can have
- /// any type. The result is returned as an RValue struct. If this is an
- /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
- /// the result should be returned.
- RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false);
-
- /// isDummyBlock - Return true if BB is an empty basic block
- /// with no predecessors.
- static bool isDummyBlock(const llvm::BasicBlock *BB);
-
- /// StartBlock - Start new block named N. If insert block is a dummy block
- /// then reuse it.
- void StartBlock(const char *N);
-
- /// getCGRecordLayout - Return record layout info.
- const CGRecordLayout *getCGRecordLayout(CodeGenTypes &CGT, QualType RTy);
-
- /// GetAddrOfStaticLocalVar - Return the address of a static local variable.
- llvm::Constant *GetAddrOfStaticLocalVar(const BlockVarDecl *BVD);
- //===--------------------------------------------------------------------===//
- // Declaration Emission
- //===--------------------------------------------------------------------===//
-
- void EmitDecl(const Decl &D);
- void EmitEnumConstantDecl(const EnumConstantDecl &D);
- void EmitBlockVarDecl(const BlockVarDecl &D);
- void EmitLocalBlockVarDecl(const BlockVarDecl &D);
- void EmitStaticBlockVarDecl(const BlockVarDecl &D);
- void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
-
- //===--------------------------------------------------------------------===//
- // Statement Emission
- //===--------------------------------------------------------------------===//
-
- void EmitStmt(const Stmt *S);
- RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
- llvm::Value *AggLoc = 0, bool isAggVol = false);
- void EmitLabelStmt(const LabelStmt &S);
- void EmitGotoStmt(const GotoStmt &S);
- void EmitIfStmt(const IfStmt &S);
- void EmitWhileStmt(const WhileStmt &S);
- void EmitDoStmt(const DoStmt &S);
- void EmitForStmt(const ForStmt &S);
- void EmitReturnStmt(const ReturnStmt &S);
- void EmitDeclStmt(const DeclStmt &S);
- void EmitBreakStmt();
- void EmitContinueStmt();
- void EmitSwitchStmt(const SwitchStmt &S);
- void EmitDefaultStmt(const DefaultStmt &S);
- void EmitCaseStmt(const CaseStmt &S);
- void EmitCaseStmtRange(const CaseStmt &S);
- void EmitAsmStmt(const AsmStmt &S);
-
- //===--------------------------------------------------------------------===//
- // LValue Expression Emission
- //===--------------------------------------------------------------------===//
-
- /// EmitLValue - Emit code to compute a designator that specifies the location
- /// of the expression.
- ///
- /// This can return one of two things: a simple address or a bitfield
- /// reference. In either case, the LLVM Value* in the LValue structure is
- /// guaranteed to be an LLVM pointer type.
- ///
- /// If this returns a bitfield reference, nothing about the pointee type of
- /// the LLVM value is known: For example, it may not be a pointer to an
- /// integer.
- ///
- /// If this returns a normal address, and if the lvalue's C type is fixed
- /// size, this method guarantees that the returned pointer type will point to
- /// an LLVM type of the same size of the lvalue's type. If the lvalue has a
- /// variable length type, this is not possible.
- ///
- LValue EmitLValue(const Expr *E);
-
- /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
- /// this method emits the address of the lvalue, then loads the result as an
- /// rvalue, returning the rvalue.
- RValue EmitLoadOfLValue(LValue V, QualType LVType);
- RValue EmitLoadOfOCUElementLValue(LValue V, QualType LVType);
- RValue EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType);
-
-
- /// EmitStoreThroughLValue - Store the specified rvalue into the specified
- /// lvalue, where both are guaranteed to the have the same type, and that type
- /// is 'Ty'.
- void EmitStoreThroughLValue(RValue Src, LValue Dst, QualType Ty);
- void EmitStoreThroughOCUComponentLValue(RValue Src, LValue Dst, QualType Ty);
- void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty);
-
- // Note: only availabe for agg return types
- LValue EmitCallExprLValue(const CallExpr *E);
-
- LValue EmitDeclRefLValue(const DeclRefExpr *E);
- LValue EmitStringLiteralLValue(const StringLiteral *E);
- LValue EmitPreDefinedLValue(const PreDefinedExpr *E);
- LValue EmitUnaryOpLValue(const UnaryOperator *E);
- LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
- LValue EmitOCUVectorElementExpr(const OCUVectorElementExpr *E);
- LValue EmitMemberExpr(const MemberExpr *E);
-
- LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field,
- bool isUnion);
-
- //===--------------------------------------------------------------------===//
- // Scalar Expression Emission
- //===--------------------------------------------------------------------===//
-
- RValue EmitCallExpr(const CallExpr *E);
- RValue EmitCallExpr(Expr *FnExpr, Expr *const *Args, unsigned NumArgs);
- RValue EmitCallExpr(llvm::Value *Callee, QualType FnType,
- Expr *const *Args, unsigned NumArgs);
- RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
-
- llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
- llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
-
- llvm::Value *EmitShuffleVector(llvm::Value* V1, llvm::Value *V2, ...);
- llvm::Value *EmitVector(llvm::Value * const *Vals, unsigned NumVals,
- bool isSplat = false);
-
- llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
-
- //===--------------------------------------------------------------------===//
- // Expression Emission
- //===--------------------------------------------------------------------===//
-
- // Expressions are broken into three classes: scalar, complex, aggregate.
-
- /// EmitScalarExpr - Emit the computation of the specified expression of
- /// LLVM scalar type, returning the result.
- llvm::Value *EmitScalarExpr(const Expr *E);
-
- /// EmitScalarConversion - Emit a conversion from the specified type to the
- /// specified destination type, both of which are LLVM scalar types.
- llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
- QualType DstTy);
-
- /// EmitComplexToScalarConversion - Emit a conversion from the specified
- /// complex type to the specified destination type, where the destination
- /// type is an LLVM scalar type.
- llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
- QualType DstTy);
-
-
- /// 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.
- void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest);
-
- /// EmitComplexExpr - Emit the computation of the specified expression of
- /// complex type, returning the result.
- ComplexPairTy EmitComplexExpr(const Expr *E);
-
- /// EmitComplexExprIntoAddr - Emit the computation of the specified expression
- /// of complex type, storing into the specified Value*.
- void EmitComplexExprIntoAddr(const Expr *E, llvm::Value *DestAddr,
- bool DestIsVolatile);
- /// LoadComplexFromAddr - Load a complex number from the specified address.
- ComplexPairTy LoadComplexFromAddr(llvm::Value *SrcAddr, bool SrcIsVolatile);
-};
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/CodeGen/CodeGenModule.cpp b/clang/CodeGen/CodeGenModule.cpp
deleted file mode 100644
index 43f399a61f2..00000000000
--- a/clang/CodeGen/CodeGenModule.cpp
+++ /dev/null
@@ -1,509 +0,0 @@
-//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This coordinates the per-module state used while generating code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CodeGenFunction.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Intrinsics.h"
-#include <algorithm>
-using namespace clang;
-using namespace CodeGen;
-
-
-CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO,
- llvm::Module &M, const llvm::TargetData &TD,
- Diagnostic &diags)
- : Context(C), Features(LO), TheModule(M), TheTargetData(TD), Diags(diags),
- Types(C, M, TD), MemCpyFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
- //TODO: Make this selectable at runtime
- Runtime = CreateObjCRuntime(M);
-}
-
-CodeGenModule::~CodeGenModule() {
- EmitGlobalCtors();
- delete Runtime;
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified stmt yet.
-void CodeGenModule::WarnUnsupported(const Stmt *S, const char *Type) {
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
- "cannot codegen this %0 yet");
- SourceRange Range = S->getSourceRange();
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID,
- &Msg, 1, &Range, 1);
-}
-
-/// WarnUnsupported - Print out a warning that codegen doesn't support the
-/// specified decl yet.
-void CodeGenModule::WarnUnsupported(const Decl *D, const char *Type) {
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Warning,
- "cannot codegen this %0 yet");
- std::string Msg = Type;
- getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID,
- &Msg, 1);
-}
-
-/// AddGlobalCtor - Add a function to the list that will be called before
-/// main() runs.
-void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor) {
- // TODO: Type coercion of void()* types.
- GlobalCtors.push_back(Ctor);
-}
-
-void CodeGenModule::EmitGlobalCtors() {
- // Get the type of @llvm.global_ctors
- std::vector<const llvm::Type*> CtorFields;
- CtorFields.push_back(llvm::IntegerType::get(32));
- // Constructor function type
- std::vector<const llvm::Type*> VoidArgs;
- llvm::FunctionType* CtorFuncTy = llvm::FunctionType::get(
- llvm::Type::VoidTy,
- VoidArgs,
- false);
- // i32, function type pair
- CtorFields.push_back(llvm::PointerType::getUnqual(CtorFuncTy));
- llvm::StructType* CtorStructTy = llvm::StructType::get(CtorFields, false);
- // Array of fields
- llvm::ArrayType* GlobalCtorsTy = llvm::ArrayType::get(CtorStructTy,
- GlobalCtors.size());
-
- const std::string GlobalCtorsVar = std::string("llvm.global_ctors");
- // Define the global variable
- llvm::GlobalVariable *GlobalCtorsVal = new llvm::GlobalVariable(
- GlobalCtorsTy,
- false,
- llvm::GlobalValue::AppendingLinkage,
- (llvm::Constant*)0,
- GlobalCtorsVar,
- &TheModule);
-
- // Populate the array
- std::vector<llvm::Constant*> CtorValues;
- llvm::Constant *MagicNumber = llvm::ConstantInt::get(llvm::IntegerType::Int32Ty,
- 65535,
- false);
- for (std::vector<llvm::Constant*>::iterator I = GlobalCtors.begin(),
- E = GlobalCtors.end(); I != E; ++I) {
- std::vector<llvm::Constant*> StructValues;
- StructValues.push_back(MagicNumber);
- StructValues.push_back(*I);
-
- llvm::Constant* CtorEntry = llvm::ConstantStruct::get(CtorStructTy, StructValues);
- CtorValues.push_back(CtorEntry);
- }
- llvm::Constant* CtorArray = llvm::ConstantArray::get(GlobalCtorsTy, CtorValues);
- GlobalCtorsVal->setInitializer(CtorArray);
-
-}
-
-/// ReplaceMapValuesWith - This is a really slow and bad function that
-/// searches for any entries in GlobalDeclMap that point to OldVal, changing
-/// them to point to NewVal. This is badbadbad, FIXME!
-void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal,
- llvm::Constant *NewVal) {
- for (llvm::DenseMap<const Decl*, llvm::Constant*>::iterator
- I = GlobalDeclMap.begin(), E = GlobalDeclMap.end(); I != E; ++I)
- if (I->second == OldVal) I->second = NewVal;
-}
-
-
-llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D,
- bool isDefinition) {
- // See if it is already in the map. If so, just return it.
- llvm::Constant *&Entry = GlobalDeclMap[D];
- if (Entry) return Entry;
-
- const llvm::Type *Ty = getTypes().ConvertType(D->getType());
-
- // Check to see if the function already exists.
- llvm::Function *F = getModule().getFunction(D->getName());
- const llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-
- // If it doesn't already exist, just create and return an entry.
- if (F == 0) {
- // FIXME: param attributes for sext/zext etc.
- F = new llvm::Function(FTy, llvm::Function::ExternalLinkage, D->getName(),
- &getModule());
-
- // Set the appropriate calling convention for the Function.
- if (D->getAttr<FastCallAttr>())
- F->setCallingConv(llvm::CallingConv::Fast);
- return Entry = F;
- }
-
- // If the pointer type matches, just return it.
- llvm::Type *PFTy = llvm::PointerType::getUnqual(Ty);
- if (PFTy == F->getType()) return Entry = F;
-
- // If this isn't a definition, just return it casted to the right type.
- if (!isDefinition)
- return Entry = llvm::ConstantExpr::getBitCast(F, PFTy);
-
- // Otherwise, we have a definition after a prototype with the wrong type.
- // F is the Function* for the one with the wrong type, we must make a new
- // Function* and update everything that used F (a declaration) with the new
- // Function* (which will be a definition).
- //
- // This happens if there is a prototype for a function (e.g. "int f()") and
- // then a definition of a different type (e.g. "int f(int x)"). Start by
- // making a new function of the correct type, RAUW, then steal the name.
- llvm::Function *NewFn = new llvm::Function(FTy,
- llvm::Function::ExternalLinkage,
- "", &getModule());
- NewFn->takeName(F);
-
- // Replace uses of F with the Function we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewFn, F->getType());
- F->replaceAllUsesWith(NewPtrForOldDecl);
-
- // FIXME: Update the globaldeclmap for the previous decl of this name. We
- // really want a way to walk all of these, but we don't have it yet. This
- // is incredibly slow!
- ReplaceMapValuesWith(F, NewPtrForOldDecl);
-
- // Ok, delete the old function now, which is dead.
- assert(F->isDeclaration() && "Shouldn't replace non-declaration");
- F->eraseFromParent();
-
- // Return the new function which has the right type.
- return Entry = NewFn;
-}
-
-static bool IsZeroElementArray(const llvm::Type *Ty) {
- if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(Ty))
- return ATy->getNumElements() == 0;
- return false;
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
- bool isDefinition) {
- assert(D->hasGlobalStorage() && "Not a global variable");
-
- // See if it is already in the map.
- llvm::Constant *&Entry = GlobalDeclMap[D];
- if (Entry) return Entry;
-
- QualType ASTTy = D->getType();
- const llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
-
- // Check to see if the global already exists.
- llvm::GlobalVariable *GV = getModule().getGlobalVariable(D->getName(), true);
-
- // If it doesn't already exist, just create and return an entry.
- if (GV == 0) {
- return Entry = new llvm::GlobalVariable(Ty, false,
- llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- }
-
- // If the pointer type matches, just return it.
- llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
- if (PTy == GV->getType()) return Entry = GV;
-
- // If this isn't a definition, just return it casted to the right type.
- if (!isDefinition)
- return Entry = llvm::ConstantExpr::getBitCast(GV, PTy);
-
-
- // Otherwise, we have a definition after a prototype with the wrong type.
- // GV is the GlobalVariable* for the one with the wrong type, we must make a
- /// new GlobalVariable* and update everything that used GV (a declaration)
- // with the new GlobalVariable* (which will be a definition).
- //
- // This happens if there is a prototype for a global (e.g. "extern int x[];")
- // and then a definition of a different type (e.g. "int x[10];"). Start by
- // making a new global of the correct type, RAUW, then steal the name.
- llvm::GlobalVariable *NewGV =
- new llvm::GlobalVariable(Ty, false, llvm::GlobalValue::ExternalLinkage,
- 0, D->getName(), &getModule(), 0,
- ASTTy.getAddressSpace());
- NewGV->takeName(GV);
-
- // Replace uses of GV with the globalvalue we will endow with a body.
- llvm::Constant *NewPtrForOldDecl =
- llvm::ConstantExpr::getBitCast(NewGV, GV->getType());
- GV->replaceAllUsesWith(NewPtrForOldDecl);
-
- // FIXME: Update the globaldeclmap for the previous decl of this name. We
- // really want a way to walk all of these, but we don't have it yet. This
- // is incredibly slow!
- ReplaceMapValuesWith(GV, NewPtrForOldDecl);
-
- // Verify that GV was a declaration or something like x[] which turns into
- // [0 x type].
- assert((GV->isDeclaration() ||
- IsZeroElementArray(GV->getType()->getElementType())) &&
- "Shouldn't replace non-declaration");
-
- // Ok, delete the old global now, which is dead.
- GV->eraseFromParent();
-
- // Return the new global which has the right type.
- return Entry = NewGV;
-}
-
-
-void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
- // If this is not a prototype, emit the body.
- if (FD->getBody())
- CodeGenFunction(*this).GenerateCode(FD);
-}
-
-llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
- return EmitConstantExpr(Expr);
-}
-
-void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
- // If this is just a forward declaration of the variable, don't emit it now,
- // allow it to be emitted lazily on its first use.
- if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
- return;
-
- // Get the global, forcing it to be a direct reference.
- llvm::GlobalVariable *GV =
- cast<llvm::GlobalVariable>(GetAddrOfGlobalVar(D, true));
-
- // Convert the initializer, or use zero if appropriate.
- llvm::Constant *Init = 0;
- if (D->getInit() == 0) {
- Init = llvm::Constant::getNullValue(GV->getType()->getElementType());
- } else if (D->getType()->isIntegerType()) {
- llvm::APSInt Value(static_cast<uint32_t>(
- getContext().getTypeSize(D->getInit()->getType())));
- if (D->getInit()->isIntegerConstantExpr(Value, Context))
- Init = llvm::ConstantInt::get(Value);
- }
-
- if (!Init)
- Init = EmitGlobalInit(D->getInit());
-
- assert(GV->getType()->getElementType() == Init->getType() &&
- "Initializer codegen type mismatch!");
- GV->setInitializer(Init);
-
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>())
- GV->setVisibility(attr->getVisibility());
- // FIXME: else handle -fvisibility
-
- // Set the llvm linkage type as appropriate.
- if (D->getAttr<DLLImportAttr>())
- GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->getAttr<DLLExportAttr>())
- GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->getAttr<WeakAttr>()) {
- GV->setLinkage(llvm::GlobalVariable::WeakLinkage);
-
- } else {
- // FIXME: This isn't right. This should handle common linkage and other
- // stuff.
- switch (D->getStorageClass()) {
- case VarDecl::Auto:
- case VarDecl::Register:
- assert(0 && "Can't have auto or register globals");
- case VarDecl::None:
- if (!D->getInit())
- GV->setLinkage(llvm::GlobalVariable::WeakLinkage);
- break;
- case VarDecl::Extern:
- case VarDecl::PrivateExtern:
- // todo: common
- break;
- case VarDecl::Static:
- GV->setLinkage(llvm::GlobalVariable::InternalLinkage);
- break;
- }
- }
-}
-
-/// EmitGlobalVarDeclarator - Emit all the global vars attached to the specified
-/// declarator chain.
-void CodeGenModule::EmitGlobalVarDeclarator(const FileVarDecl *D) {
- for (; D; D = cast_or_null<FileVarDecl>(D->getNextDeclarator()))
- EmitGlobalVar(D);
-}
-
-void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
- // Make sure that this type is translated.
- Types.UpdateCompletedType(TD);
-}
-
-
-/// getBuiltinLibFunction
-llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
- if (BuiltinID > BuiltinFunctions.size())
- BuiltinFunctions.resize(BuiltinID);
-
- // Cache looked up functions. Since builtin id #0 is invalid we don't reserve
- // a slot for it.
- assert(BuiltinID && "Invalid Builtin ID");
- llvm::Function *&FunctionSlot = BuiltinFunctions[BuiltinID-1];
- if (FunctionSlot)
- return FunctionSlot;
-
- assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a lib fn");
-
- // Get the name, skip over the __builtin_ prefix.
- const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10;
-
- // Get the type for the builtin.
- QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context);
- const llvm::FunctionType *Ty =
- cast<llvm::FunctionType>(getTypes().ConvertType(Type));
-
- // FIXME: This has a serious problem with code like this:
- // void abs() {}
- // ... __builtin_abs(x);
- // The two versions of abs will collide. The fix is for the builtin to win,
- // and for the existing one to be turned into a constantexpr cast of the
- // builtin. In the case where the existing one is a static function, it
- // should just be renamed.
- if (llvm::Function *Existing = getModule().getFunction(Name)) {
- if (Existing->getFunctionType() == Ty && Existing->hasExternalLinkage())
- return FunctionSlot = Existing;
- assert(Existing == 0 && "FIXME: Name collision");
- }
-
- // FIXME: param attributes for sext/zext etc.
- return FunctionSlot = new llvm::Function(Ty, llvm::Function::ExternalLinkage,
- Name, &getModule());
-}
-
-llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
- unsigned NumTys) {
- return llvm::Intrinsic::getDeclaration(&getModule(),
- (llvm::Intrinsic::ID)IID, Tys, NumTys);
-}
-
-llvm::Function *CodeGenModule::getMemCpyFn() {
- if (MemCpyFn) return MemCpyFn;
- llvm::Intrinsic::ID IID;
- switch (Context.Target.getPointerWidth(0)) {
- default: assert(0 && "Unknown ptr width");
- case 32: IID = llvm::Intrinsic::memcpy_i32; break;
- case 64: IID = llvm::Intrinsic::memcpy_i64; break;
- }
- return MemCpyFn = getIntrinsic(IID);
-}
-
-llvm::Function *CodeGenModule::getMemSetFn() {
- if (MemSetFn) return MemSetFn;
- llvm::Intrinsic::ID IID;
- switch (Context.Target.getPointerWidth(0)) {
- default: assert(0 && "Unknown ptr width");
- case 32: IID = llvm::Intrinsic::memset_i32; break;
- case 64: IID = llvm::Intrinsic::memset_i64; break;
- }
- return MemSetFn = getIntrinsic(IID);
-}
-
-llvm::Constant *CodeGenModule::
-GetAddrOfConstantCFString(const std::string &str) {
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
-
- if (Entry.getValue())
- return Entry.getValue();
-
- std::vector<llvm::Constant*> Fields;
-
- if (!CFConstantStringClassRef) {
- const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Ty = llvm::ArrayType::get(Ty, 0);
-
- CFConstantStringClassRef =
- new llvm::GlobalVariable(Ty, false,
- llvm::GlobalVariable::ExternalLinkage, 0,
- "__CFConstantStringClassReference",
- &getModule());
- }
-
- // Class pointer.
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
- llvm::Constant *C =
- llvm::ConstantExpr::getGetElementPtr(CFConstantStringClassRef, Zeros, 2);
- Fields.push_back(C);
-
- // Flags.
- const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
- Fields.push_back(llvm::ConstantInt::get(Ty, 1992));
-
- // String pointer.
- C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &getModule());
-
- C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
- Fields.push_back(C);
-
- // String length.
- Ty = getTypes().ConvertType(getContext().LongTy);
- Fields.push_back(llvm::ConstantInt::get(Ty, str.length()));
-
- // The struct.
- Ty = getTypes().ConvertType(getContext().getCFConstantStringType());
- C = llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Fields);
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalVariable::InternalLinkage,
- C, "", &getModule());
- GV->setSection("__DATA,__cfstring");
- Entry.setValue(GV);
- return GV;
-}
-
-/// GenerateWritableString -- Creates storage for a string literal.
-static llvm::Constant *GenerateStringLiteral(const std::string &str,
- bool constant,
- CodeGenModule &CGM) {
- // Create Constant for this string literal
- llvm::Constant *C=llvm::ConstantArray::get(str);
-
- // Create a global variable for this string
- C = new llvm::GlobalVariable(C->getType(), constant,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGM.getModule());
- return C;
-}
-
-/// CodeGenModule::GetAddrOfConstantString -- returns a pointer to the character
-/// array containing the literal. The result is pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str) {
- // Don't share any string literals if writable-strings is turned on.
- if (Features.WritableStrings)
- return GenerateStringLiteral(str, false, *this);
-
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
-
- if (Entry.getValue())
- return Entry.getValue();
-
- // Create a global variable for this.
- llvm::Constant *C = GenerateStringLiteral(str, true, *this);
- Entry.setValue(C);
- return C;
-}
diff --git a/clang/CodeGen/CodeGenModule.h b/clang/CodeGen/CodeGenModule.h
deleted file mode 100644
index cbea09fd3ec..00000000000
--- a/clang/CodeGen/CodeGenModule.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the internal per-translation-unit state used for llvm translation.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENMODULE_H
-#define CLANG_CODEGEN_CODEGENMODULE_H
-
-#include "CodeGenTypes.h"
-#include "CGObjCRuntime.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace llvm {
- class Module;
- class Constant;
- class Function;
- class GlobalVariable;
- class TargetData;
-}
-
-namespace clang {
- class ASTContext;
- class FunctionDecl;
- class Decl;
- class Expr;
- class Stmt;
- class ValueDecl;
- class VarDecl;
- class TypeDecl;
- class FileVarDecl;
- struct LangOptions;
- class Diagnostic;
-
-namespace CodeGen {
-
- class CodeGenFunction;
-
-/// CodeGenModule - This class organizes the cross-module state that is used
-/// while generating LLVM code.
-class CodeGenModule {
- ASTContext &Context;
- const LangOptions &Features;
- llvm::Module &TheModule;
- const llvm::TargetData &TheTargetData;
- Diagnostic &Diags;
- CodeGenTypes Types;
- CGObjCRuntime *Runtime;
-
- llvm::Function *MemCpyFn;
- llvm::Function *MemSetFn;
- llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
- std::vector<llvm::Constant*> GlobalCtors;
-
- llvm::StringMap<llvm::Constant*> CFConstantStringMap;
- llvm::StringMap<llvm::Constant*> ConstantStringMap;
- llvm::Constant *CFConstantStringClassRef;
-
- std::vector<llvm::Function *> BuiltinFunctions;
-public:
- CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M,
- const llvm::TargetData &TD, Diagnostic &Diags);
- ~CodeGenModule();
-
- CGObjCRuntime *getObjCRuntime() { return Runtime; }
- ASTContext &getContext() const { return Context; }
- const LangOptions &getLangOptions() const { return Features; }
- llvm::Module &getModule() const { return TheModule; }
- CodeGenTypes &getTypes() { return Types; }
- Diagnostic &getDiags() const { return Diags; }
- const llvm::TargetData &getTargetData() const { return TheTargetData; }
-
- llvm::Constant *GetAddrOfFunctionDecl(const FunctionDecl *D,
- bool isDefinition);
- llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, bool isDefinition);
-
-
- /// getBuiltinLibFunction - Given a builtin id for a function like
- /// "__builtin_fabsf", return a Function* for "fabsf".
- ///
- llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
- llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
-
- /// GetAddrOfConstantString -- returns a pointer to the character
- /// array containing the literal. The result is pointer to array type.
- llvm::Constant *GetAddrOfConstantString(const std::string& str);
- llvm::Function *getMemCpyFn();
- llvm::Function *getMemSetFn();
- llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
- unsigned NumTys = 0);
-
- void AddGlobalCtor(llvm::Function * Ctor);
- void EmitGlobalCtors(void);
-
- void EmitFunction(const FunctionDecl *FD);
- void EmitGlobalVar(const FileVarDecl *D);
- void EmitGlobalVarDeclarator(const FileVarDecl *D);
- void UpdateCompletedType(const TagDecl *D);
- llvm::Constant *EmitGlobalInit(const Expr *E);
- llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified stmt yet.
-
- void WarnUnsupported(const Stmt *S, const char *Type);
-
- /// WarnUnsupported - Print out a warning that codegen doesn't support the
- /// specified decl yet.
- void WarnUnsupported(const Decl *D, const char *Type);
-
-private:
- /// ReplaceMapValuesWith - This is a really slow and bad function that
- /// searches for any entries in GlobalDeclMap that point to OldVal, changing
- /// them to point to NewVal. This is badbadbad, FIXME!
- void ReplaceMapValuesWith(llvm::Constant *OldVal, llvm::Constant *NewVal);
-
-};
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/CodeGen/CodeGenTypes.cpp b/clang/CodeGen/CodeGenTypes.cpp
deleted file mode 100644
index 9a669e87056..00000000000
--- a/clang/CodeGen/CodeGenTypes.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the code that handles AST -> LLVM type lowering.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenTypes.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/AST/AST.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
- /// RecordOrganizer - This helper class, used by CGRecordLayout, layouts
- /// structs and unions. It manages transient information used during layout.
- /// FIXME : Handle field aligments. Handle packed structs.
- class RecordOrganizer {
- public:
- explicit RecordOrganizer(CodeGenTypes &Types) :
- CGT(Types), STy(NULL), llvmFieldNo(0), Cursor(0),
- llvmSize(0) {}
-
- /// addField - Add new field.
- void addField(const FieldDecl *FD);
-
- /// addLLVMField - Add llvm struct field that corresponds to llvm type Ty.
- /// Increment field count.
- void addLLVMField(const llvm::Type *Ty, bool isPaddingField = false);
-
- /// addPaddingFields - Current cursor is not suitable place to add next
- /// field. Add required padding fields.
- void addPaddingFields(unsigned WaterMark);
-
- /// layoutStructFields - Do the actual work and lay out all fields. Create
- /// corresponding llvm struct type. This should be invoked only after
- /// all fields are added.
- void layoutStructFields(const ASTRecordLayout &RL);
-
- /// layoutUnionFields - Do the actual work and lay out all fields. Create
- /// corresponding llvm struct type. This should be invoked only after
- /// all fields are added.
- void layoutUnionFields();
-
- /// getLLVMType - Return associated llvm struct type. This may be NULL
- /// if fields are not laid out.
- llvm::Type *getLLVMType() const {
- return STy;
- }
-
- /// placeBitField - Find a place for FD, which is a bit-field.
- void placeBitField(const FieldDecl *FD);
-
- llvm::SmallSet<unsigned, 8> &getPaddingFields() {
- return PaddingFields;
- }
-
- private:
- CodeGenTypes &CGT;
- llvm::Type *STy;
- unsigned llvmFieldNo;
- uint64_t Cursor;
- uint64_t llvmSize;
- llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
- std::vector<const llvm::Type*> LLVMFields;
- llvm::SmallSet<unsigned, 8> PaddingFields;
- };
-}
-
-CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
- const llvm::TargetData &TD)
- : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD) {
-}
-
-CodeGenTypes::~CodeGenTypes() {
- for(llvm::DenseMap<const TagDecl *, CGRecordLayout *>::iterator
- I = CGRecordLayouts.begin(), E = CGRecordLayouts.end();
- I != E; ++I)
- delete I->second;
- CGRecordLayouts.clear();
-}
-
-/// ConvertType - Convert the specified type to its LLVM form.
-const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
- // See if type is already cached.
- llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator
- I = TypeCache.find(T.getCanonicalType().getTypePtr());
- // If type is found in map and this is not a definition for a opaque
- // place holder type then use it. Otherwise, convert type T.
- if (I != TypeCache.end())
- return I->second.get();
-
- const llvm::Type *ResultType = ConvertNewType(T);
- TypeCache.insert(std::make_pair(T.getCanonicalType().getTypePtr(),
- llvm::PATypeHolder(ResultType)));
- return ResultType;
-}
-
-/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
-/// ConvertType in that it is used to convert to the memory representation for
-/// a type. For example, the scalar representation for _Bool is i1, but the
-/// memory representation is usually i8 or i32, depending on the target.
-const llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
- const llvm::Type *R = ConvertType(T);
-
- // If this is a non-bool type, don't map it.
- if (R != llvm::Type::Int1Ty)
- return R;
-
- // Otherwise, return an integer of the target-specified size.
- return llvm::IntegerType::get((unsigned)Context.getTypeSize(T));
-
-}
-
-/// UpdateCompletedType - When we find the full definition for a TagDecl,
-/// replace the 'opaque' type we previously made for it if applicable.
-void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
- llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(TD);
- if (TDTI == TagDeclTypes.end()) return;
-
- // Remember the opaque LLVM type for this tagdecl.
- llvm::PATypeHolder OpaqueHolder = TDTI->second;
- assert(isa<llvm::OpaqueType>(OpaqueHolder.get()) &&
- "Updating compilation of an already non-opaque type?");
-
- // Remove it from TagDeclTypes so that it will be regenerated.
- TagDeclTypes.erase(TDTI);
-
- // Generate the new type.
- const llvm::Type *NT = ConvertTagDeclType(TD);
-
- // Refine the old opaque type to its new definition.
- cast<llvm::OpaqueType>(OpaqueHolder.get())->refineAbstractTypeTo(NT);
-}
-
-
-
-const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
- const clang::Type &Ty = *T.getCanonicalType();
-
- switch (Ty.getTypeClass()) {
- case Type::TypeName: // typedef isn't canonical.
- case Type::TypeOfExp: // typeof isn't canonical.
- case Type::TypeOfTyp: // typeof isn't canonical.
- assert(0 && "Non-canonical type, shouldn't happen");
- case Type::Builtin: {
- switch (cast<BuiltinType>(Ty).getKind()) {
- case BuiltinType::Void:
- // LLVM void type can only be used as the result of a function call. Just
- // map to the same as char.
- return llvm::IntegerType::get(8);
-
- case BuiltinType::Bool:
- // Note that we always return bool as i1 for use as a scalar type.
- return llvm::Type::Int1Ty;
-
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- case BuiltinType::Short:
- case BuiltinType::UShort:
- case BuiltinType::Int:
- case BuiltinType::UInt:
- case BuiltinType::Long:
- case BuiltinType::ULong:
- case BuiltinType::LongLong:
- case BuiltinType::ULongLong:
- return llvm::IntegerType::get(
- static_cast<unsigned>(Context.getTypeSize(T)));
-
- case BuiltinType::Float: return llvm::Type::FloatTy;
- case BuiltinType::Double: return llvm::Type::DoubleTy;
- case BuiltinType::LongDouble:
- // FIXME: mapping long double onto double.
- return llvm::Type::DoubleTy;
- }
- break;
- }
- case Type::Complex: {
- std::vector<const llvm::Type*> Elts;
- Elts.push_back(ConvertType(cast<ComplexType>(Ty).getElementType()));
- Elts.push_back(Elts[0]);
- return llvm::StructType::get(Elts);
- }
- case Type::Pointer: {
- const PointerType &P = cast<PointerType>(Ty);
- QualType ETy = P.getPointeeType();
- return llvm::PointerType::get(ConvertType(ETy), ETy.getAddressSpace());
- }
- case Type::Reference: {
- const ReferenceType &R = cast<ReferenceType>(Ty);
- return llvm::PointerType::getUnqual(ConvertType(R.getReferenceeType()));
- }
-
- case Type::VariableArray: {
- const VariableArrayType &A = cast<VariableArrayType>(Ty);
- assert(A.getIndexTypeQualifier() == 0 &&
- "FIXME: We only handle trivial array types so far!");
- // VLAs resolve to the innermost element type; this matches
- // the return of alloca, and there isn't any obviously better choice.
- return ConvertType(A.getElementType());
- }
- case Type::IncompleteArray: {
- const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
- assert(A.getIndexTypeQualifier() == 0 &&
- "FIXME: We only handle trivial array types so far!");
- // int X[] -> [0 x int]
- return llvm::ArrayType::get(ConvertType(A.getElementType()), 0);
- }
- case Type::ConstantArray: {
- const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
- const llvm::Type *EltTy = ConvertType(A.getElementType());
- return llvm::ArrayType::get(EltTy, A.getSize().getZExtValue());
- }
- case Type::OCUVector:
- case Type::Vector: {
- const VectorType &VT = cast<VectorType>(Ty);
- return llvm::VectorType::get(ConvertType(VT.getElementType()),
- VT.getNumElements());
- }
- case Type::FunctionNoProto:
- case Type::FunctionProto: {
- const FunctionType &FP = cast<FunctionType>(Ty);
- const llvm::Type *ResultType;
-
- if (FP.getResultType()->isVoidType())
- ResultType = llvm::Type::VoidTy; // Result of function uses llvm void.
- else
- ResultType = ConvertType(FP.getResultType());
-
- // FIXME: Convert argument types.
- bool isVarArg;
- std::vector<const llvm::Type*> ArgTys;
-
- // Struct return passes the struct byref.
- if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
- ArgTys.push_back(llvm::PointerType::get(ResultType,
- FP.getResultType().getAddressSpace()));
- ResultType = llvm::Type::VoidTy;
- }
-
- if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) {
- DecodeArgumentTypes(*FTP, ArgTys);
- isVarArg = FTP->isVariadic();
- } else {
- isVarArg = true;
- }
-
- return llvm::FunctionType::get(ResultType, ArgTys, isVarArg);
- }
-
- case Type::ASQual:
- return ConvertType(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
-
- case Type::ObjCInterface:
- assert(0 && "FIXME: add missing functionality here");
- break;
-
- case Type::ObjCQualifiedInterface:
- assert(0 && "FIXME: add missing functionality here");
- break;
-
- case Type::ObjCQualifiedId:
- assert(0 && "FIXME: add missing functionality here");
- break;
-
- case Type::Tagged: {
- const TagDecl *TD = cast<TagType>(Ty).getDecl();
- const llvm::Type *Res = ConvertTagDeclType(TD);
-
- std::string TypeName(TD->getKindName());
- TypeName += '.';
-
- // Name the codegen type after the typedef name
- // if there is no tag type name available
- if (TD->getIdentifier())
- TypeName += TD->getName();
- else if (const TypedefType *TdT = dyn_cast<TypedefType>(T))
- TypeName += TdT->getDecl()->getName();
- else
- TypeName += "anon";
-
- TheModule.addTypeName(TypeName, Res);
- return Res;
- }
- }
-
- // FIXME: implement.
- return llvm::OpaqueType::get();
-}
-
-void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
- std::vector<const llvm::Type*> &ArgTys) {
- for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
- const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
- if (Ty->isFirstClassType())
- ArgTys.push_back(Ty);
- else
- // byval arguments are always on the stack, which is addr space #0.
- ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
- }
-}
-
-/// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
-/// enum.
-const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
- llvm::DenseMap<const TagDecl*, llvm::PATypeHolder>::iterator TDTI =
- TagDeclTypes.find(TD);
-
- // If we've already compiled this tag type, use the previous definition.
- if (TDTI != TagDeclTypes.end())
- return TDTI->second;
-
- // If this is still a forward definition, just define an opaque type to use
- // for this tagged decl.
- if (!TD->isDefinition()) {
- llvm::Type *ResultType = llvm::OpaqueType::get();
- TagDeclTypes.insert(std::make_pair(TD, ResultType));
- return ResultType;
- }
-
- // Okay, this is a definition of a type. Compile the implementation now.
-
- if (TD->getKind() == Decl::Enum) {
- // Don't bother storing enums in TagDeclTypes.
- return ConvertType(cast<EnumDecl>(TD)->getIntegerType());
- }
-
- // This decl could well be recursive. In this case, insert an opaque
- // definition of this type, which the recursive uses will get. We will then
- // refine this opaque version later.
-
- // Create new OpaqueType now for later use in case this is a recursive
- // type. This will later be refined to the actual type.
- llvm::PATypeHolder ResultHolder = llvm::OpaqueType::get();
- TagDeclTypes.insert(std::make_pair(TD, ResultHolder));
-
- const llvm::Type *ResultType;
- const RecordDecl *RD = cast<const RecordDecl>(TD);
- if (TD->getKind() == Decl::Struct || TD->getKind() == Decl::Class) {
- // Layout fields.
- RecordOrganizer RO(*this);
- for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
- RO.addField(RD->getMember(i));
-
- RO.layoutStructFields(Context.getASTRecordLayout(RD));
-
- // Get llvm::StructType.
- CGRecordLayouts[TD] = new CGRecordLayout(RO.getLLVMType(),
- RO.getPaddingFields());
- ResultType = RO.getLLVMType();
-
- } else if (TD->getKind() == Decl::Union) {
- // Just use the largest element of the union, breaking ties with the
- // highest aligned member.
- if (RD->getNumMembers() != 0) {
- RecordOrganizer RO(*this);
- for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
- RO.addField(RD->getMember(i));
-
- RO.layoutUnionFields();
-
- // Get llvm::StructType.
- CGRecordLayouts[TD] = new CGRecordLayout(RO.getLLVMType(),
- RO.getPaddingFields());
- ResultType = RO.getLLVMType();
- } else {
- ResultType = llvm::StructType::get(std::vector<const llvm::Type*>());
- }
- } else {
- assert(0 && "FIXME: Unknown tag decl kind!");
- }
-
- // Refine our Opaque type to ResultType. This can invalidate ResultType, so
- // make sure to read the result out of the holder.
- cast<llvm::OpaqueType>(ResultHolder.get())
- ->refineAbstractTypeTo(ResultType);
-
- return ResultHolder.get();
-}
-
-/// getLLVMFieldNo - Return llvm::StructType element number
-/// that corresponds to the field FD.
-unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
- llvm::DenseMap<const FieldDecl *, unsigned>::iterator
- I = FieldInfo.find(FD);
- assert (I != FieldInfo.end() && "Unable to find field info");
- return I->second;
-}
-
-/// addFieldInfo - Assign field number to field FD.
-void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
- FieldInfo[FD] = No;
-}
-
-/// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field FD.
-CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) {
- llvm::DenseMap<const FieldDecl *, BitFieldInfo>::iterator
- I = BitFields.find(FD);
- assert (I != BitFields.end() && "Unable to find bitfield info");
- return I->second;
-}
-
-/// addBitFieldInfo - Assign a start bit and a size to field FD.
-void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned Begin,
- unsigned Size) {
- BitFields.insert(std::make_pair(FD, BitFieldInfo(Begin, Size)));
-}
-
-/// getCGRecordLayout - Return record layout info for the given llvm::Type.
-const CGRecordLayout *
-CodeGenTypes::getCGRecordLayout(const TagDecl *TD) const {
- llvm::DenseMap<const TagDecl*, CGRecordLayout *>::iterator I
- = CGRecordLayouts.find(TD);
- assert (I != CGRecordLayouts.end()
- && "Unable to find record layout information for type");
- return I->second;
-}
-
-/// addField - Add new field.
-void RecordOrganizer::addField(const FieldDecl *FD) {
- assert (!STy && "Record fields are already laid out");
- FieldDecls.push_back(FD);
-}
-
-/// layoutStructFields - Do the actual work and lay out all fields. Create
-/// corresponding llvm struct type. This should be invoked only after
-/// all fields are added.
-/// FIXME : At the moment assume
-/// - one to one mapping between AST FieldDecls and
-/// llvm::StructType elements.
-/// - Ignore bit fields
-/// - Ignore field aligments
-/// - Ignore packed structs
-void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
- // FIXME : Use SmallVector
- llvmSize = 0;
- llvmFieldNo = 0;
- Cursor = 0;
- LLVMFields.clear();
-
- for (llvm::SmallVector<const FieldDecl *, 8>::iterator I = FieldDecls.begin(),
- E = FieldDecls.end(); I != E; ++I) {
- const FieldDecl *FD = *I;
-
- if (FD->isBitField())
- placeBitField(FD);
- else {
- const llvm::Type *Ty = CGT.ConvertType(FD->getType());
- addLLVMField(Ty);
- CGT.addFieldInfo(FD, llvmFieldNo - 1);
- Cursor = llvmSize;
- }
- }
-
- unsigned StructAlign = RL.getAlignment();
- if (llvmSize % StructAlign) {
- unsigned StructPadding = StructAlign - (llvmSize % StructAlign);
- addPaddingFields(llvmSize + StructPadding);
- }
-
- STy = llvm::StructType::get(LLVMFields);
-}
-
-/// addPaddingFields - Current cursor is not suitable place to add next field.
-/// Add required padding fields.
-void RecordOrganizer::addPaddingFields(unsigned WaterMark) {
- assert(WaterMark >= llvmSize && "Invalid padding Field");
- unsigned RequiredBits = WaterMark - llvmSize;
- unsigned RequiredBytes = (RequiredBits + 7) / 8;
- for (unsigned i = 0; i != RequiredBytes; ++i)
- addLLVMField(llvm::Type::Int8Ty, true);
-}
-
-/// addLLVMField - Add llvm struct field that corresponds to llvm type Ty.
-/// Increment field count.
-void RecordOrganizer::addLLVMField(const llvm::Type *Ty, bool isPaddingField) {
-
- unsigned AlignmentInBits = CGT.getTargetData().getABITypeAlignment(Ty) * 8;
- if (llvmSize % AlignmentInBits) {
- // At the moment, insert padding fields even if target specific llvm
- // type alignment enforces implict padding fields for FD. Later on,
- // optimize llvm fields by removing implicit padding fields and
- // combining consequetive padding fields.
- unsigned Padding = AlignmentInBits - (llvmSize % AlignmentInBits);
- addPaddingFields(llvmSize + Padding);
- }
-
- unsigned TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- llvmSize += TySize;
- if (isPaddingField)
- PaddingFields.insert(llvmFieldNo);
- LLVMFields.push_back(Ty);
- ++llvmFieldNo;
-}
-
-/// layoutUnionFields - Do the actual work and lay out all fields. Create
-/// corresponding llvm struct type. This should be invoked only after
-/// all fields are added.
-void RecordOrganizer::layoutUnionFields() {
-
- unsigned PrimaryEltNo = 0;
- std::pair<uint64_t, unsigned> PrimaryElt =
- CGT.getContext().getTypeInfo(FieldDecls[0]->getType());
- CGT.addFieldInfo(FieldDecls[0], 0);
-
- unsigned Size = FieldDecls.size();
- for(unsigned i = 1; i != Size; ++i) {
- const FieldDecl *FD = FieldDecls[i];
- assert (!FD->isBitField() && "Bit fields are not yet supported");
- std::pair<uint64_t, unsigned> EltInfo =
- CGT.getContext().getTypeInfo(FD->getType());
-
- // Use largest element, breaking ties with the hightest aligned member.
- if (EltInfo.first > PrimaryElt.first ||
- (EltInfo.first == PrimaryElt.first &&
- EltInfo.second > PrimaryElt.second)) {
- PrimaryElt = EltInfo;
- PrimaryEltNo = i;
- }
-
- // In union, each field gets first slot.
- CGT.addFieldInfo(FD, 0);
- }
-
- std::vector<const llvm::Type*> Fields;
- const llvm::Type *Ty = CGT.ConvertType(FieldDecls[PrimaryEltNo]->getType());
- Fields.push_back(Ty);
- STy = llvm::StructType::get(Fields);
-}
-
-/// placeBitField - Find a place for FD, which is a bit-field.
-/// This function searches for the last aligned field. If the bit-field fits in
-/// it, it is reused. Otherwise, the bit-field is placed in a new field.
-void RecordOrganizer::placeBitField(const FieldDecl *FD) {
-
- assert (FD->isBitField() && "FD is not a bit-field");
- Expr *BitWidth = FD->getBitWidth();
- llvm::APSInt FieldSize(32);
- bool isBitField =
- BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
- assert (isBitField && "Invalid BitField size expression");
- uint64_t BitFieldSize = FieldSize.getZExtValue();
-
- const llvm::Type *Ty = CGT.ConvertType(FD->getType());
- uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-
- unsigned Idx = Cursor / TySize;
- unsigned BitsLeft = TySize - (Cursor % TySize);
-
- if (BitsLeft >= BitFieldSize) {
- // The bitfield fits in the last aligned field.
- // This is : struct { char a; int CurrentField:10;};
- // where 'CurrentField' shares first field with 'a'.
- CGT.addFieldInfo(FD, Idx);
- CGT.addBitFieldInfo(FD, TySize - BitsLeft, BitFieldSize);
- Cursor += BitFieldSize;
- } else {
- // Place the bitfield in a new LLVM field.
- // This is : struct { char a; short CurrentField:10;};
- // where 'CurrentField' needs a new llvm field.
- CGT.addFieldInfo(FD, Idx + 1);
- CGT.addBitFieldInfo(FD, 0, BitFieldSize);
- Cursor = (Idx + 1) * TySize + BitFieldSize;
- }
- if (Cursor > llvmSize)
- addPaddingFields(Cursor);
-}
diff --git a/clang/CodeGen/CodeGenTypes.h b/clang/CodeGen/CodeGenTypes.h
deleted file mode 100644
index 08a2467106a..00000000000
--- a/clang/CodeGen/CodeGenTypes.h
+++ /dev/null
@@ -1,165 +0,0 @@
-//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is the code that handles AST -> LLVM type lowering.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_CODEGEN_CODEGENTYPES_H
-#define CLANG_CODEGEN_CODEGENTYPES_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include <vector>
-
-namespace llvm {
- class Module;
- class Type;
- class PATypeHolder;
- class TargetData;
-}
-
-namespace clang {
- class ASTContext;
- class TagDecl;
- class TargetInfo;
- class QualType;
- class Type;
- class FunctionTypeProto;
- class FieldDecl;
- class RecordDecl;
-
-namespace CodeGen {
- class CodeGenTypes;
-
- /// CGRecordLayout - This class handles struct and union layout info while
- /// lowering AST types to LLVM types.
- class CGRecordLayout {
- CGRecordLayout(); // DO NOT IMPLEMENT
- public:
- CGRecordLayout(llvm::Type *T, llvm::SmallSet<unsigned, 8> &PF)
- : STy(T), PaddingFields(PF) {
- // FIXME : Collect info about fields that requires adjustments
- // (i.e. fields that do not directly map to llvm struct fields.)
- }
-
- /// getLLVMType - Return llvm type associated with this record.
- llvm::Type *getLLVMType() const {
- return STy;
- }
-
- bool isPaddingField(unsigned No) const {
- return PaddingFields.count(No) != 0;
- }
-
- unsigned getNumPaddingFields() {
- return PaddingFields.size();
- }
-
- private:
- llvm::Type *STy;
- llvm::SmallSet<unsigned, 8> PaddingFields;
- };
-
-/// CodeGenTypes - This class organizes the cross-module state that is used
-/// while lowering AST types to LLVM types.
-class CodeGenTypes {
- ASTContext &Context;
- TargetInfo &Target;
- llvm::Module& TheModule;
- const llvm::TargetData& TheTargetData;
-
- llvm::DenseMap<const TagDecl*, llvm::PATypeHolder> TagDeclTypes;
-
- /// CGRecordLayouts - This maps llvm struct type with corresponding
- /// record layout info.
- /// FIXME : If CGRecordLayout is less than 16 bytes then use
- /// inline it in the map.
- llvm::DenseMap<const TagDecl*, CGRecordLayout *> CGRecordLayouts;
-
- /// FieldInfo - This maps struct field with corresponding llvm struct type
- /// field no. This info is populated by record organizer.
- llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
-
-public:
- class BitFieldInfo {
- public:
- explicit BitFieldInfo(unsigned short B, unsigned short S)
- : Begin(B), Size(S) {}
-
- unsigned short Begin;
- unsigned short Size;
- };
-
-private:
- llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
-
- /// TypeCache - This map keeps cache of llvm::Types (through PATypeHolder)
- /// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is
- /// used instead of llvm::Type because it allows us to bypass potential
- /// dangling type pointers due to type refinement on llvm side.
- llvm::DenseMap<Type *, llvm::PATypeHolder> TypeCache;
-
- /// ConvertNewType - Convert type T into a llvm::Type. Do not use this
- /// method directly because it does not do any type caching. This method
- /// is available only for ConvertType(). CovertType() is preferred
- /// interface to convert type T into a llvm::Type.
- const llvm::Type *ConvertNewType(QualType T);
-public:
- CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD);
- ~CodeGenTypes();
-
- const llvm::TargetData &getTargetData() const { return TheTargetData; }
- TargetInfo &getTarget() const { return Target; }
- ASTContext &getContext() const { return Context; }
-
- /// ConvertType - Convert type T into a llvm::Type.
- const llvm::Type *ConvertType(QualType T);
-
- /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
- /// ConvertType in that it is used to convert to the memory representation for
- /// a type. For example, the scalar representation for _Bool is i1, but the
- /// memory representation is usually i8 or i32, depending on the target.
- const llvm::Type *ConvertTypeForMem(QualType T);
-
-
- const CGRecordLayout *getCGRecordLayout(const TagDecl*) const;
-
- /// getLLVMFieldNo - Return llvm::StructType element number
- /// that corresponds to the field FD.
- unsigned getLLVMFieldNo(const FieldDecl *FD);
-
-
- /// UpdateCompletedType - When we find the full definition for a TagDecl,
- /// replace the 'opaque' type we previously made for it if applicable.
- void UpdateCompletedType(const TagDecl *TD);
-
-public: // These are internal details of CGT that shouldn't be used externally.
- void DecodeArgumentTypes(const FunctionTypeProto &FTP,
- std::vector<const llvm::Type*> &ArgTys);
-
- /// addFieldInfo - Assign field number to field FD.
- void addFieldInfo(const FieldDecl *FD, unsigned No);
-
- /// addBitFieldInfo - Assign a start bit and a size to field FD.
- void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size);
-
- /// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field
- /// FD.
- BitFieldInfo getBitFieldInfo(const FieldDecl *FD);
-
- /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or
- /// enum.
- const llvm::Type *ConvertTagDeclType(const TagDecl *TD);
-};
-
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
diff --git a/clang/CodeGen/Makefile b/clang/CodeGen/Makefile
deleted file mode 100644
index 87bc646424a..00000000000
--- a/clang/CodeGen/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- clang/CodeGen/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-#
-# This implements the AST -> LLVM code generation library for the
-# C-Language front-end.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME := clangCodeGen
-BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
-
-CPPFLAGS += -I$(PROJ_SRC_DIR)/../include
-
-include $(LEVEL)/Makefile.common
-
diff --git a/clang/CodeGen/ModuleBuilder.cpp b/clang/CodeGen/ModuleBuilder.cpp
deleted file mode 100644
index 06467488a5e..00000000000
--- a/clang/CodeGen/ModuleBuilder.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This builds an AST and converts it to LLVM Code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "CodeGenModule.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// LLVM Emitter
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-
-namespace {
- class CodeGenerator : public ASTConsumer {
- Diagnostic &Diags;
- const llvm::TargetData *TD;
- ASTContext *Ctx;
- const LangOptions &Features;
- protected:
- llvm::Module *&M;
- CodeGen::CodeGenModule *Builder;
- public:
- CodeGenerator(Diagnostic &diags, const LangOptions &LO,
- llvm::Module *&DestModule)
- : Diags(diags), Features(LO), M(DestModule) {}
-
- ~CodeGenerator() {
- delete Builder;
- }
-
- virtual void Initialize(ASTContext &Context) {
- Ctx = &Context;
-
- M->setTargetTriple(Ctx->Target.getTargetTriple());
- M->setDataLayout(Ctx->Target.getTargetDescription());
- TD = new llvm::TargetData(Ctx->Target.getTargetDescription());
- Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags);
- }
-
- virtual void HandleTopLevelDecl(Decl *D) {
- // If an error occurred, stop code generation, but continue parsing and
- // semantic analysis (to ensure all warnings and errors are emitted).
- if (Diags.hasErrorOccurred())
- return;
-
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- Builder->EmitFunction(FD);
- } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
- Builder->EmitGlobalVarDeclarator(FVD);
- } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
- if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx)
- Builder->WarnUnsupported(LSD, "linkage spec");
- // FIXME: implement C++ linkage, C linkage works mostly by C
- // language reuse already.
- } else if (FileScopeAsmDecl *AD = dyn_cast<FileScopeAsmDecl>(D)) {
- std::string AsmString(AD->getAsmString()->getStrData(),
- AD->getAsmString()->getByteLength());
-
- const std::string &S = Builder->getModule().getModuleInlineAsm();
- if (S.empty())
- Builder->getModule().setModuleInlineAsm(AsmString);
- else
- Builder->getModule().setModuleInlineAsm(S + '\n' + AsmString);
- } else {
- assert(isa<TypeDecl>(D) && "Unknown top level decl");
- // TODO: handle debug info?
- }
- }
-
- /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
- /// (e.g. struct, union, enum, class) is completed. This allows the client to
- /// hack on the type, which can occur at any point in the file (because these
- /// can be defined in declspecs).
- virtual void HandleTagDeclDefinition(TagDecl *D) {
- Builder->UpdateCompletedType(D);
- }
-
- };
-}
-
-ASTConsumer *clang::CreateLLVMCodeGen(Diagnostic &Diags,
- const LangOptions &Features,
- llvm::Module *&DestModule) {
- return new CodeGenerator(Diags, Features, DestModule);
-}
-
OpenPOWER on IntegriCloud