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