CodeGenFunction.cpp revision ddf7cac45d85b73127adbbd91a2b28fc7291c57e
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This coordinates the per-function state used while generating code.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenFunction.h"
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "CodeGenModule.h"
163f2af1002249c8acc9ce17f1fc50324864feb8e1Eli Friedman#include "CGDebugInfo.h"
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TargetInfo.h"
18de7fb8413b13651fd85b7125d08b3c9ac2816d9dDaniel Dunbar#include "clang/AST/ASTContext.h"
19c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/Decl.h"
20d9363c3a80168283b3da518b4e17f545a6246857Devang Patel#include "llvm/Support/CFG.h"
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang;
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace CodeGen;
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerCodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
25c049e4f406a7f7179eba98659044a32508e53289Devang Patel  : CGM(cgm), Target(CGM.getContext().Target), SwitchInsn(NULL),
264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    CaseRangeBlock(NULL) {
274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    LLVMIntTy = ConvertType(getContext().IntTy);
284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    LLVMPointerWidth = Target.getPointerWidth(0);
294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerASTContext &CodeGenFunction::getContext() const {
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return CGM.getContext();
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerllvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) {
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::BasicBlock *&BB = LabelMap[S];
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (BB) return BB;
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Create, but don't insert, the new block.
41984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif  return BB = llvm::BasicBlock::Create(S->getName());
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
44813733577d33ec56479667b49e1bff42dc6bba90Lauro Ramos Venanciollvm::Constant *
45248a753f6b670692523c99afaeb8fe98f7ae3ca7Steve NaroffCodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
46813733577d33ec56479667b49e1bff42dc6bba90Lauro Ramos Venancio  return cast<llvm::Constant>(LocalDeclMap[BVD]);
47813733577d33ec56479667b49e1bff42dc6bba90Lauro Ramos Venancio}
485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
49dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlssonllvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD)
50dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson{
51dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson  return LocalDeclMap[VD];
52dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson}
53dde0a94120915fa925d1ffcdb997c7b44dc9fa21Anders Carlsson
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst llvm::Type *CodeGenFunction::ConvertType(QualType T) {
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return CGM.getTypes().ConvertType(T);
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
584111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattnerbool CodeGenFunction::isObjCPointerType(QualType T) {
594111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // All Objective-C types are pointers.
604111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  return T->isObjCInterfaceType() ||
614111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    T->isObjCQualifiedInterfaceType() || T->isObjCQualifiedIdType();
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
644111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattnerbool CodeGenFunction::hasAggregateLLVMType(QualType T) {
654111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  return !isObjCPointerType(T) &&!T->isRealType() && !T->isPointerLikeType() &&
664111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    !T->isVoidType() && !T->isVectorType() && !T->isFunctionType();
674111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
68391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner
69af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
700ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  // Finish emission of indirect switches.
710ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  EmitIndirectSwitches();
720ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar
73af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta  // Emit debug descriptor for function end.
745ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar  if (CGDebugInfo *DI = CGM.getDebugInfo()) {
7566031a5594bc9a7dc0dc5137c3e7955f835e4639Daniel Dunbar    DI->setLocation(EndLoc);
76af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta    DI->EmitRegionEnd(CurFn, Builder);
77af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta  }
78af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta
79391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner  assert(BreakContinueStack.empty() &&
80391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner         "mismatched push/pop in break/continue stack!");
815ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar
82b01d191a25f92884855117ee7113a1bd3b59cdbcDaniel Dunbar  // Emit function epilog (to return). This has the nice side effect
83b01d191a25f92884855117ee7113a1bd3b59cdbcDaniel Dunbar  // of also automatically handling code that falls off the end.
84b01d191a25f92884855117ee7113a1bd3b59cdbcDaniel Dunbar  EmitBlock(ReturnBlock);
8517b708d61827cd86278e9580b041dd6cbadf07d3Daniel Dunbar  EmitFunctionEpilog(FnRetTy, ReturnValue);
865ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar
87391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner  // Remove the AllocaInsertPt instruction, which is just a convenience for us.
88391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner  AllocaInsertPt->eraseFromParent();
89391d77a26382dddf25da73e29fc1fa5aaaea4c6fChris Lattner  AllocaInsertPt = 0;
90c8aa5f1f264fb230c38182adab944232bb160c2bChris Lattner}
91c8aa5f1f264fb230c38182adab944232bb160c2bChris Lattner
927c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbarvoid CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
937c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar                                    llvm::Function *Fn,
942284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar                                    const FunctionArgList &Args,
952284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar                                    SourceLocation StartLoc) {
967c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar  CurFuncDecl = D;
977c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar  FnRetTy = RetTy;
98bd012ff1fa088181646a784f385b28867372d434Daniel Dunbar  CurFn = Fn;
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(CurFn->isDeclaration() && "Function already has body?");
100ddee4231e9bdfbac1e1f5385ff1a17fd0e0b0e39Chris Lattner
101984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif  llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
1025ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Create a marker to make it easy to insert allocas into the entryblock
10455352a2d616cf9fbb621d10faf8b960b4b268bd8Chris Lattner  // later.  Don't create this with the builder, because we don't want it
10555352a2d616cf9fbb621d10faf8b960b4b268bd8Chris Lattner  // folded.
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
10755352a2d616cf9fbb621d10faf8b960b4b268bd8Chris Lattner  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
10855352a2d616cf9fbb621d10faf8b960b4b268bd8Chris Lattner                                         EntryBB);
1095ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar
110b01d191a25f92884855117ee7113a1bd3b59cdbcDaniel Dunbar  ReturnBlock = llvm::BasicBlock::Create("return");
1115ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar  ReturnValue = 0;
1127c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar  if (!RetTy->isVoidType())
1137c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar    ReturnValue = CreateTempAlloca(ConvertType(RetTy), "retval");
1145ca2084cf9b529563209429857f01fdae9dcdfa5Daniel Dunbar
11555352a2d616cf9fbb621d10faf8b960b4b268bd8Chris Lattner  Builder.SetInsertPoint(EntryBB);
1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
117af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta  // Emit subprogram debug descriptor.
1187c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar  // FIXME: The cast here is a huge hack.
1192284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar  if (CGDebugInfo *DI = CGM.getDebugInfo()) {
1202284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar    DI->setLocation(StartLoc);
1212284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1222284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar      DI->EmitFunctionStart(FD->getName(), RetTy, CurFn, Builder);
1232284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar    } else {
1242284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar      // Just use LLVM function name.
1252284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar      DI->EmitFunctionStart(Fn->getName().c_str(),
1262284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar                            RetTy, CurFn, Builder);
127af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta    }
128af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta  }
129af99417156c652a6f04dff643925036dc3241d60Sanjiv Gupta
13017b708d61827cd86278e9580b041dd6cbadf07d3Daniel Dunbar  EmitFunctionProlog(CurFn, FnRetTy, Args);
1317c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar}
132eb4b7051a596560ef4a1846e3714707f44e9dc30Eli Friedman
1337c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbarvoid CodeGenFunction::GenerateCode(const FunctionDecl *FD,
1347c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar                                   llvm::Function *Fn) {
1357c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar  FunctionArgList Args;
136eb4b7051a596560ef4a1846e3714707f44e9dc30Eli Friedman  if (FD->getNumParams()) {
137eb4b7051a596560ef4a1846e3714707f44e9dc30Eli Friedman    const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto();
138eb4b7051a596560ef4a1846e3714707f44e9dc30Eli Friedman    assert(FProto && "Function def must have prototype!");
1397c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar
1407c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
1417c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar      Args.push_back(std::make_pair(FD->getParamDecl(i),
1427c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar                                    FProto->getArgType(i)));
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
144af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
1452284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar  StartFunction(FD, FD->getResultType(), Fn, Args,
1462284ac9ec80299fcdefae9a2787cf85105a0f203Daniel Dunbar                cast<CompoundStmt>(FD->getBody())->getLBracLoc());
1477c086516f3cc9fba2733b1919973206c6ba4b171Daniel Dunbar
148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(FD->getBody());
149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const CompoundStmt *S = dyn_cast<CompoundStmt>(FD->getBody());
151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  if (S) {
152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction(S->getRBracLoc());
153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  } else {
154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction();
155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
158d9363c3a80168283b3da518b4e17f545a6246857Devang Patel/// isDummyBlock - Return true if BB is an empty basic block
159d9363c3a80168283b3da518b4e17f545a6246857Devang Patel/// with no predecessors.
160d9363c3a80168283b3da518b4e17f545a6246857Devang Patelbool CodeGenFunction::isDummyBlock(const llvm::BasicBlock *BB) {
1611e9660e1fb11efb7e65799bc145c0e2b6f3562beChris Lattner  if (BB->empty() && pred_begin(BB) == pred_end(BB) && !BB->hasName())
162d9363c3a80168283b3da518b4e17f545a6246857Devang Patel    return true;
163d9363c3a80168283b3da518b4e17f545a6246857Devang Patel  return false;
164d9363c3a80168283b3da518b4e17f545a6246857Devang Patel}
165d9363c3a80168283b3da518b4e17f545a6246857Devang Patel
16651b09f2c528c8460b5465c676173324e44176d62Devang Patel/// StartBlock - Start new block named N. If insert block is a dummy block
16751b09f2c528c8460b5465c676173324e44176d62Devang Patel/// then reuse it.
16851b09f2c528c8460b5465c676173324e44176d62Devang Patelvoid CodeGenFunction::StartBlock(const char *N) {
16951b09f2c528c8460b5465c676173324e44176d62Devang Patel  llvm::BasicBlock *BB = Builder.GetInsertBlock();
17051b09f2c528c8460b5465c676173324e44176d62Devang Patel  if (!isDummyBlock(BB))
171984d0b414bc76d3530b9bc55a5a55834ba76c607Gabor Greif    EmitBlock(llvm::BasicBlock::Create(N));
17251b09f2c528c8460b5465c676173324e44176d62Devang Patel  else
17351b09f2c528c8460b5465c676173324e44176d62Devang Patel    BB->setName(N);
17451b09f2c528c8460b5465c676173324e44176d62Devang Patel}
17551b09f2c528c8460b5465c676173324e44176d62Devang Patel
17688a981b47c7face1b1fdaa9074256245107b9ca9Devang Patel/// getCGRecordLayout - Return record layout info.
17788a981b47c7face1b1fdaa9074256245107b9ca9Devang Patelconst CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
178af31913e48c96fddb45a0fd33f25617546502cbbChris Lattner                                                         QualType Ty) {
179af31913e48c96fddb45a0fd33f25617546502cbbChris Lattner  const RecordType *RTy = Ty->getAsRecordType();
180af31913e48c96fddb45a0fd33f25617546502cbbChris Lattner  assert (RTy && "Unexpected type. RecordType expected here.");
181b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel
182af31913e48c96fddb45a0fd33f25617546502cbbChris Lattner  return CGT.getCGRecordLayout(RTy->getDecl());
183b84a06e68ffd71da22e3c75b6e4bbdba37816413Devang Patel}
184dc5e8268292046114ffe02e48773572a91a310f1Chris Lattner
185488e993a135ce700b982bf099c3d6b856301d642Daniel Dunbar/// ErrorUnsupported - Print out an error that codegen doesn't support the
186dc5e8268292046114ffe02e48773572a91a310f1Chris Lattner/// specified stmt yet.
18790df4b6661968a84bf64baee489bb2f6d948fcc1Daniel Dunbarvoid CodeGenFunction::ErrorUnsupported(const Stmt *S, const char *Type,
18890df4b6661968a84bf64baee489bb2f6d948fcc1Daniel Dunbar                                       bool OmitOnError) {
18990df4b6661968a84bf64baee489bb2f6d948fcc1Daniel Dunbar  CGM.ErrorUnsupported(S, Type, OmitOnError);
190dc5e8268292046114ffe02e48773572a91a310f1Chris Lattner}
191dc5e8268292046114ffe02e48773572a91a310f1Chris Lattner
1920ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarunsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
1930ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  // Use LabelIDs.size() as the new ID if one hasn't been assigned.
1940ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  return LabelIDs.insert(std::make_pair(L, LabelIDs.size())).first->second;
1950ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar}
1960ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar
1973d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlssonvoid CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty)
1983d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson{
1993d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
2003d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  if (DestPtr->getType() != BP)
2013d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson    DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
2023d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
2033d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  // Get size and alignment info for this aggregate.
2043d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
2053d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
2063d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  // FIXME: Handle variable sized types.
2073d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
2083d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
2093d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson  Builder.CreateCall4(CGM.getMemSetFn(), DestPtr,
2103d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson                      llvm::ConstantInt::getNullValue(llvm::Type::Int8Ty),
2113d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson                      // TypeInfo.first describes size in bits.
2123d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson                      llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
2133d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson                      llvm::ConstantInt::get(llvm::Type::Int32Ty,
2143d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson                                             TypeInfo.second/8));
2153d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
2163d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
2170ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbarvoid CodeGenFunction::EmitIndirectSwitches() {
2180ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  llvm::BasicBlock *Default;
2190ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar
22076526a5245ec2283b0c85fcef507d4c2dec90715Daniel Dunbar  if (IndirectSwitches.empty())
22176526a5245ec2283b0c85fcef507d4c2dec90715Daniel Dunbar    return;
22276526a5245ec2283b0c85fcef507d4c2dec90715Daniel Dunbar
2230ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  if (!LabelIDs.empty()) {
2240ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    Default = getBasicBlockForLabel(LabelIDs.begin()->first);
2250ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  } else {
2260ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    // No possible targets for indirect goto, just emit an infinite
2270ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    // loop.
2280ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    Default = llvm::BasicBlock::Create("indirectgoto.loop", CurFn);
2290ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    llvm::BranchInst::Create(Default, Default);
2300ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  }
2310ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar
2320ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  for (std::vector<llvm::SwitchInst*>::iterator i = IndirectSwitches.begin(),
2330ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar         e = IndirectSwitches.end(); i != e; ++i) {
2340ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    llvm::SwitchInst *I = *i;
2350ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar
2360ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    I->setSuccessor(0, Default);
2370ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    for (std::map<const LabelStmt*,unsigned>::iterator LI = LabelIDs.begin(),
2380ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar           LE = LabelIDs.end(); LI != LE; ++LI) {
2390ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar      I->addCase(llvm::ConstantInt::get(llvm::Type::Int32Ty,
2400ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar                                        LI->second),
2410ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar                 getBasicBlockForLabel(LI->first));
2420ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar    }
2430ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar  }
2440ffb125996336fc7602b162c0a9e392f1a93060fDaniel Dunbar}
245ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
246ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlssonllvm::Value *CodeGenFunction::EmitVAArg(llvm::Value *VAListAddr, QualType Ty)
247ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson{
248ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  // FIXME: This entire method is hardcoded for 32-bit X86.
249ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
250ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  const char *TargetPrefix = getContext().Target.getTargetPrefix();
251ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
252ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  if (strcmp(TargetPrefix, "x86") != 0 ||
253ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson      getContext().Target.getPointerWidth(0) != 32)
254ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    return 0;
255ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
256ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
257ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
258ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
259ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,
260ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson                                                       "ap");
261ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
262ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *AddrTyped =
263ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    Builder.CreateBitCast(Addr,
264ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson                          llvm::PointerType::getUnqual(ConvertType(Ty)));
265ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
266ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  uint64_t SizeInBytes = getContext().getTypeSize(Ty) / 8;
267ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  const unsigned ArgumentSizeInBytes = 4;
268ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  if (SizeInBytes < ArgumentSizeInBytes)
269ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    SizeInBytes = ArgumentSizeInBytes;
270ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
271ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  llvm::Value *NextAddr =
272ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson    Builder.CreateGEP(Addr,
273ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson                      llvm::ConstantInt::get(llvm::Type::Int32Ty, SizeInBytes),
274ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson                      "ap.next");
275ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
276ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
277ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson  return AddrTyped;
278ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson}
279ddf7cac45d85b73127adbbd91a2b28fc7291c57eAnders Carlsson
280