CGDecl.cpp revision 6fba7464867180f672b6fa55894485dd8a093804
1e35fdd936d133bf8a48de140a3c666897588a05shiqian//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===// 2e35fdd936d133bf8a48de140a3c666897588a05shiqian// 3e35fdd936d133bf8a48de140a3c666897588a05shiqian// The LLVM Compiler Infrastructure 4e35fdd936d133bf8a48de140a3c666897588a05shiqian// 5e35fdd936d133bf8a48de140a3c666897588a05shiqian// This file is distributed under the University of Illinois Open Source 6e35fdd936d133bf8a48de140a3c666897588a05shiqian// License. See LICENSE.TXT for details. 7e35fdd936d133bf8a48de140a3c666897588a05shiqian// 8e35fdd936d133bf8a48de140a3c666897588a05shiqian//===----------------------------------------------------------------------===// 9e35fdd936d133bf8a48de140a3c666897588a05shiqian// 10e35fdd936d133bf8a48de140a3c666897588a05shiqian// This contains code to emit Decl nodes as LLVM code. 11e35fdd936d133bf8a48de140a3c666897588a05shiqian// 12e35fdd936d133bf8a48de140a3c666897588a05shiqian//===----------------------------------------------------------------------===// 13e35fdd936d133bf8a48de140a3c666897588a05shiqian 14e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "CGDebugInfo.h" 15e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "CodeGenFunction.h" 16e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "CodeGenModule.h" 17e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "clang/AST/ASTContext.h" 18e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "clang/AST/Decl.h" 19e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "clang/AST/DeclObjC.h" 20e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "clang/Basic/SourceManager.h" 21e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "clang/Basic/TargetInfo.h" 22e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "llvm/GlobalVariable.h" 23e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "llvm/Intrinsics.h" 24e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "llvm/Target/TargetData.h" 25e35fdd936d133bf8a48de140a3c666897588a05shiqian#include "llvm/Type.h" 26e35fdd936d133bf8a48de140a3c666897588a05shiqianusing namespace clang; 27e35fdd936d133bf8a48de140a3c666897588a05shiqianusing namespace CodeGen; 28e35fdd936d133bf8a48de140a3c666897588a05shiqian 29e35fdd936d133bf8a48de140a3c666897588a05shiqian 30e35fdd936d133bf8a48de140a3c666897588a05shiqianvoid CodeGenFunction::EmitDecl(const Decl &D) { 31e35fdd936d133bf8a48de140a3c666897588a05shiqian switch (D.getKind()) { 32e35fdd936d133bf8a48de140a3c666897588a05shiqian default: assert(0 && "Unknown decl kind!"); 33e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::ParmVar: 34e35fdd936d133bf8a48de140a3c666897588a05shiqian assert(0 && "Parmdecls should not be in declstmts!"); 35e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::Function: // void X(); 36e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::Record: // struct/union/class X; 37e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::Enum: // enum X; 38e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::EnumConstant: // enum ? { X = ? } 39df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan case Decl::CXXRecord: // struct/union/class X; [C++] 40df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan case Decl::UsingDirective: // using X; [C++] 41df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // None of these decls require codegen support. 42e35fdd936d133bf8a48de140a3c666897588a05shiqian return; 436c54a5e1f91e033fa937be5d647ce43dee597ad8vladlosev 44df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan case Decl::Var: { 45e35fdd936d133bf8a48de140a3c666897588a05shiqian const VarDecl &VD = cast<VarDecl>(D); 46e35fdd936d133bf8a48de140a3c666897588a05shiqian assert(VD.isBlockVarDecl() && 47df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan "Should not see file-scope variables inside a function!"); 48df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan return EmitBlockVarDecl(VD); 49df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 50df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 51e35fdd936d133bf8a48de140a3c666897588a05shiqian case Decl::Typedef: { // typedef int X; 52e35fdd936d133bf8a48de140a3c666897588a05shiqian const TypedefDecl &TD = cast<TypedefDecl>(D); 53e35fdd936d133bf8a48de140a3c666897588a05shiqian QualType Ty = TD.getUnderlyingType(); 54e35fdd936d133bf8a48de140a3c666897588a05shiqian 55e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty->isVariablyModifiedType()) 56e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitVLASize(Ty); 57e35fdd936d133bf8a48de140a3c666897588a05shiqian } 58e35fdd936d133bf8a48de140a3c666897588a05shiqian } 5932de5f53763125925e078498250f7e73a88de9edzhanyong.wan} 6032de5f53763125925e078498250f7e73a88de9edzhanyong.wan 6132de5f53763125925e078498250f7e73a88de9edzhanyong.wan/// EmitBlockVarDecl - This method handles emission of any variable declaration 6232de5f53763125925e078498250f7e73a88de9edzhanyong.wan/// inside a function, including static vars etc. 6332de5f53763125925e078498250f7e73a88de9edzhanyong.wanvoid CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) { 6432de5f53763125925e078498250f7e73a88de9edzhanyong.wan if (D.hasAttr<AsmLabelAttr>()) 65e35fdd936d133bf8a48de140a3c666897588a05shiqian CGM.ErrorUnsupported(&D, "__asm__"); 66e35fdd936d133bf8a48de140a3c666897588a05shiqian 67e35fdd936d133bf8a48de140a3c666897588a05shiqian switch (D.getStorageClass()) { 68e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::None: 69e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::Auto: 70e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::Register: 71e35fdd936d133bf8a48de140a3c666897588a05shiqian return EmitLocalBlockVarDecl(D); 72e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::Static: 73e35fdd936d133bf8a48de140a3c666897588a05shiqian return EmitStaticBlockVarDecl(D); 74e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::Extern: 75e35fdd936d133bf8a48de140a3c666897588a05shiqian case VarDecl::PrivateExtern: 7632de5f53763125925e078498250f7e73a88de9edzhanyong.wan // Don't emit it now, allow it to be emitted lazily on its first use. 77e35fdd936d133bf8a48de140a3c666897588a05shiqian return; 7832de5f53763125925e078498250f7e73a88de9edzhanyong.wan } 79e35fdd936d133bf8a48de140a3c666897588a05shiqian 80e35fdd936d133bf8a48de140a3c666897588a05shiqian assert(0 && "Unknown storage class"); 81e35fdd936d133bf8a48de140a3c666897588a05shiqian} 82e35fdd936d133bf8a48de140a3c666897588a05shiqian 83e35fdd936d133bf8a48de140a3c666897588a05shiqianllvm::GlobalVariable * 84e35fdd936d133bf8a48de140a3c666897588a05shiqianCodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D, 85e35fdd936d133bf8a48de140a3c666897588a05shiqian const char *Separator, 86e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::GlobalValue::LinkageTypes 87e35fdd936d133bf8a48de140a3c666897588a05shiqian Linkage) { 88e35fdd936d133bf8a48de140a3c666897588a05shiqian QualType Ty = D.getType(); 8941b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan assert(Ty->isConstantSizeType() && "VLAs can't be static"); 9041b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan 9141b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan std::string Name; 92e35fdd936d133bf8a48de140a3c666897588a05shiqian if (getContext().getLangOptions().CPlusPlus) { 93e35fdd936d133bf8a48de140a3c666897588a05shiqian Name = CGM.getMangledName(&D); 94e35fdd936d133bf8a48de140a3c666897588a05shiqian } else { 95e35fdd936d133bf8a48de140a3c666897588a05shiqian std::string ContextName; 96e35fdd936d133bf8a48de140a3c666897588a05shiqian if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) 97e35fdd936d133bf8a48de140a3c666897588a05shiqian ContextName = CGM.getMangledName(FD); 98e35fdd936d133bf8a48de140a3c666897588a05shiqian else if (isa<ObjCMethodDecl>(CurFuncDecl)) 99e35fdd936d133bf8a48de140a3c666897588a05shiqian ContextName = CurFn->getName(); 100e35fdd936d133bf8a48de140a3c666897588a05shiqian else 101e35fdd936d133bf8a48de140a3c666897588a05shiqian assert(0 && "Unknown context for block var decl"); 102e35fdd936d133bf8a48de140a3c666897588a05shiqian 103e35fdd936d133bf8a48de140a3c666897588a05shiqian Name = ContextName + Separator + D.getNameAsString(); 10441b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan } 105e35fdd936d133bf8a48de140a3c666897588a05shiqian 10641b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty); 10741b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan llvm::GlobalVariable *GV = 108e35fdd936d133bf8a48de140a3c666897588a05shiqian new llvm::GlobalVariable(CGM.getModule(), LTy, 109e35fdd936d133bf8a48de140a3c666897588a05shiqian Ty.isConstant(getContext()), Linkage, 110e35fdd936d133bf8a48de140a3c666897588a05shiqian CGM.EmitNullConstant(D.getType()), Name, 0, 111e35fdd936d133bf8a48de140a3c666897588a05shiqian D.isThreadSpecified(), Ty.getAddressSpace()); 112e35fdd936d133bf8a48de140a3c666897588a05shiqian GV->setAlignment(getContext().getDeclAlignInBytes(&D)); 113e35fdd936d133bf8a48de140a3c666897588a05shiqian return GV; 114e35fdd936d133bf8a48de140a3c666897588a05shiqian} 115e35fdd936d133bf8a48de140a3c666897588a05shiqian 11641b9b0b5614588d252d565646ae43e9607d46502zhanyong.wanvoid CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { 117e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *&DMEntry = LocalDeclMap[&D]; 11841b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); 119e35fdd936d133bf8a48de140a3c666897588a05shiqian 12041b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan llvm::GlobalVariable *GV = 121e35fdd936d133bf8a48de140a3c666897588a05shiqian CreateStaticBlockVarDecl(D, ".", llvm::GlobalValue::InternalLinkage); 122e35fdd936d133bf8a48de140a3c666897588a05shiqian 12341b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan // Store into LocalDeclMap before generating initializer to handle 12441b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan // circular references. 125e35fdd936d133bf8a48de140a3c666897588a05shiqian DMEntry = GV; 126e35fdd936d133bf8a48de140a3c666897588a05shiqian 127e35fdd936d133bf8a48de140a3c666897588a05shiqian // Make sure to evaluate VLA bounds now so that we have them for later. 128e35fdd936d133bf8a48de140a3c666897588a05shiqian // 129e35fdd936d133bf8a48de140a3c666897588a05shiqian // FIXME: Can this happen? 13041b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan if (D.getType()->isVariablyModifiedType()) 131e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitVLASize(D.getType()); 132e35fdd936d133bf8a48de140a3c666897588a05shiqian 133e35fdd936d133bf8a48de140a3c666897588a05shiqian if (D.getInit()) { 134e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), D.getType(), this); 135e35fdd936d133bf8a48de140a3c666897588a05shiqian 136e35fdd936d133bf8a48de140a3c666897588a05shiqian // If constant emission failed, then this should be a C++ static 137e35fdd936d133bf8a48de140a3c666897588a05shiqian // initializer. 138e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!Init) { 139e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!getContext().getLangOptions().CPlusPlus) 140e35fdd936d133bf8a48de140a3c666897588a05shiqian CGM.ErrorUnsupported(D.getInit(), "constant l-value expression"); 141e35fdd936d133bf8a48de140a3c666897588a05shiqian else 142e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitStaticCXXBlockVarDeclInit(D, GV); 143e35fdd936d133bf8a48de140a3c666897588a05shiqian } else { 1449413f2ff615ae1b933580576183d316c4cb6376czhanyong.wan // The initializer may differ in type from the global. Rewrite 145e35fdd936d133bf8a48de140a3c666897588a05shiqian // the global to match the initializer. (We have to do this 146e35fdd936d133bf8a48de140a3c666897588a05shiqian // because some types, like unions, can't be completely represented 1479413f2ff615ae1b933580576183d316c4cb6376czhanyong.wan // in the LLVM type system.) 148e35fdd936d133bf8a48de140a3c666897588a05shiqian if (GV->getType() != Init->getType()) { 149e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::GlobalVariable *OldGV = GV; 150e35fdd936d133bf8a48de140a3c666897588a05shiqian 151e35fdd936d133bf8a48de140a3c666897588a05shiqian GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 152e35fdd936d133bf8a48de140a3c666897588a05shiqian OldGV->isConstant(), 153e35fdd936d133bf8a48de140a3c666897588a05shiqian OldGV->getLinkage(), Init, "", 154e35fdd936d133bf8a48de140a3c666897588a05shiqian 0, D.isThreadSpecified(), 155e35fdd936d133bf8a48de140a3c666897588a05shiqian D.getType().getAddressSpace()); 156e35fdd936d133bf8a48de140a3c666897588a05shiqian 157e35fdd936d133bf8a48de140a3c666897588a05shiqian // Steal the name of the old global 158e35fdd936d133bf8a48de140a3c666897588a05shiqian GV->takeName(OldGV); 159e35fdd936d133bf8a48de140a3c666897588a05shiqian 160e35fdd936d133bf8a48de140a3c666897588a05shiqian // Replace all uses of the old global with the new global 161e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Constant *NewPtrForOldDecl = 162df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); 163df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan OldGV->replaceAllUsesWith(NewPtrForOldDecl); 164df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 165df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // Erase the old global, since it is no longer used. 166df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan OldGV->eraseFromParent(); 167df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 168df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 169df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan GV->setInitializer(Init); 170df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 171df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 172df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 173e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan // FIXME: Merge attribute handling. 174e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) { 175df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan SourceManager &SM = CGM.getContext().getSourceManager(); 176df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan llvm::Constant *Ann = 177df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CGM.EmitAnnotateAttr(GV, AA, 178df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan SM.getInstantiationLineNumber(D.getLocation())); 179df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CGM.AddAnnotation(Ann); 180df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 181df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 182df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (const SectionAttr *SA = D.getAttr<SectionAttr>()) 183df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan GV->setSection(SA->getName()); 184df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 185df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (D.hasAttr<UsedAttr>()) 186df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CGM.AddUsedGlobal(GV); 187df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 188df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // We may have to cast the constant because of the initializer 189df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // mismatch above. 190df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // 191df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // FIXME: It is really dangerous to store this in the map; if anyone 192df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // RAUW's the GV uses of this constant will be invalid. 1939571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); 1949571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan const llvm::Type *LPtrTy = 1959571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan llvm::PointerType::get(LTy, D.getType().getAddressSpace()); 196df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy); 197df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 198df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // Emit global variable debug descriptor for static vars. 199df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CGDebugInfo *DI = getDebugInfo(); 200df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (DI) { 201df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan DI->setLocation(D.getLocation()); 202df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D); 203df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 204df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan} 205df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 206df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wanunsigned CodeGenFunction::getByRefValueLLVMField(const ValueDecl *VD) const { 207df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan assert(ByRefValueInfo.count(VD) && "Did not find value!"); 2089571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan 209df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan return ByRefValueInfo.find(VD)->second.second; 210f5e1ce5b9237edbc2e524ae9ebcb2452dc842937zhanyong.wan} 211f5e1ce5b9237edbc2e524ae9ebcb2452dc842937zhanyong.wan 2129571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan/// BuildByRefType - This routine changes a __block variable declared as T x 213e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan/// into: 2149571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan/// 215e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan/// struct { 216e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan/// void *__isa; 2179571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan/// void *__forwarding; 218e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan/// int32_t __flags; 219df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan/// int32_t __size; 220df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan/// void *__copy_helper; // only if needed 221df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan/// void *__destroy_helper; // only if needed 2229571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan/// char padding[X]; // only if needed 223df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan/// T x; 224df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan/// } x 2259571b28675a5a602ed3c8a7acf270d03aca69c96zhanyong.wan/// 226df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wanconst llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) { 227df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan std::pair<const llvm::Type *, unsigned> &Info = ByRefValueInfo[D]; 228df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (Info.first) 229df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan return Info.first; 230df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 231df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan QualType Ty = D->getType(); 232df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 233df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan std::vector<const llvm::Type *> Types; 234df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 235df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan const llvm::PointerType *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 236df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 237df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext); 238df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 239df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // void *__isa; 240df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Types.push_back(Int8PtrTy); 241e35fdd936d133bf8a48de140a3c666897588a05shiqian 242e35fdd936d133bf8a48de140a3c666897588a05shiqian // void *__forwarding; 243e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(llvm::PointerType::getUnqual(ByRefTypeHolder)); 244e35fdd936d133bf8a48de140a3c666897588a05shiqian 245e35fdd936d133bf8a48de140a3c666897588a05shiqian // int32_t __flags; 246e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(llvm::Type::getInt32Ty(VMContext)); 247e35fdd936d133bf8a48de140a3c666897588a05shiqian 248e35fdd936d133bf8a48de140a3c666897588a05shiqian // int32_t __size; 249e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(llvm::Type::getInt32Ty(VMContext)); 250e35fdd936d133bf8a48de140a3c666897588a05shiqian 251e35fdd936d133bf8a48de140a3c666897588a05shiqian bool HasCopyAndDispose = BlockRequiresCopying(Ty); 252e35fdd936d133bf8a48de140a3c666897588a05shiqian if (HasCopyAndDispose) { 253e35fdd936d133bf8a48de140a3c666897588a05shiqian /// void *__copy_helper; 254e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(Int8PtrTy); 255e35fdd936d133bf8a48de140a3c666897588a05shiqian 256e35fdd936d133bf8a48de140a3c666897588a05shiqian /// void *__destroy_helper; 257e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(Int8PtrTy); 258e35fdd936d133bf8a48de140a3c666897588a05shiqian } 259e35fdd936d133bf8a48de140a3c666897588a05shiqian 260e35fdd936d133bf8a48de140a3c666897588a05shiqian bool Packed = false; 261e35fdd936d133bf8a48de140a3c666897588a05shiqian unsigned Align = getContext().getDeclAlignInBytes(D); 262e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Align > Target.getPointerAlign(0) / 8) { 263e35fdd936d133bf8a48de140a3c666897588a05shiqian // We have to insert padding. 264e35fdd936d133bf8a48de140a3c666897588a05shiqian 265e35fdd936d133bf8a48de140a3c666897588a05shiqian // The struct above has 2 32-bit integers. 266e35fdd936d133bf8a48de140a3c666897588a05shiqian unsigned CurrentOffsetInBytes = 4 * 2; 267e35fdd936d133bf8a48de140a3c666897588a05shiqian 268e35fdd936d133bf8a48de140a3c666897588a05shiqian // And either 2 or 4 pointers. 269e35fdd936d133bf8a48de140a3c666897588a05shiqian CurrentOffsetInBytes += (HasCopyAndDispose ? 4 : 2) * 270e35fdd936d133bf8a48de140a3c666897588a05shiqian CGM.getTargetData().getTypeAllocSize(Int8PtrTy); 271e35fdd936d133bf8a48de140a3c666897588a05shiqian 272e35fdd936d133bf8a48de140a3c666897588a05shiqian // Align the offset. 273e35fdd936d133bf8a48de140a3c666897588a05shiqian unsigned AlignedOffsetInBytes = 274e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::RoundUpToAlignment(CurrentOffsetInBytes, Align); 275e35fdd936d133bf8a48de140a3c666897588a05shiqian 276e35fdd936d133bf8a48de140a3c666897588a05shiqian unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes; 277e35fdd936d133bf8a48de140a3c666897588a05shiqian if (NumPaddingBytes > 0) { 278e35fdd936d133bf8a48de140a3c666897588a05shiqian const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext); 279e35fdd936d133bf8a48de140a3c666897588a05shiqian // FIXME: We need a sema error for alignment larger than the minimum of 280e35fdd936d133bf8a48de140a3c666897588a05shiqian // the maximal stack alignmint and the alignment of malloc on the system. 281e35fdd936d133bf8a48de140a3c666897588a05shiqian if (NumPaddingBytes > 1) 282e35fdd936d133bf8a48de140a3c666897588a05shiqian Ty = llvm::ArrayType::get(Ty, NumPaddingBytes); 283e35fdd936d133bf8a48de140a3c666897588a05shiqian 284e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(Ty); 285e35fdd936d133bf8a48de140a3c666897588a05shiqian 286e35fdd936d133bf8a48de140a3c666897588a05shiqian // We want a packed struct. 287e35fdd936d133bf8a48de140a3c666897588a05shiqian Packed = true; 288e35fdd936d133bf8a48de140a3c666897588a05shiqian } 289e35fdd936d133bf8a48de140a3c666897588a05shiqian } 290e35fdd936d133bf8a48de140a3c666897588a05shiqian 291e35fdd936d133bf8a48de140a3c666897588a05shiqian // T x; 292e35fdd936d133bf8a48de140a3c666897588a05shiqian Types.push_back(ConvertType(Ty)); 293e35fdd936d133bf8a48de140a3c666897588a05shiqian 294e35fdd936d133bf8a48de140a3c666897588a05shiqian const llvm::Type *T = llvm::StructType::get(VMContext, Types, Packed); 295e35fdd936d133bf8a48de140a3c666897588a05shiqian 296e35fdd936d133bf8a48de140a3c666897588a05shiqian cast<llvm::OpaqueType>(ByRefTypeHolder.get())->refineAbstractTypeTo(T); 297df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(), 298df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan ByRefTypeHolder.get()); 299df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 300df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Info.first = ByRefTypeHolder.get(); 301df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 302df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Info.second = Types.size() - 1; 303df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 304df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan return Info.first; 305e35fdd936d133bf8a48de140a3c666897588a05shiqian} 306e35fdd936d133bf8a48de140a3c666897588a05shiqian 307e35fdd936d133bf8a48de140a3c666897588a05shiqian/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a 308e35fdd936d133bf8a48de140a3c666897588a05shiqian/// variable declaration with auto, register, or no storage class specifier. 309e35fdd936d133bf8a48de140a3c666897588a05shiqian/// These turn into simple stack objects, or GlobalValues depending on target. 310e35fdd936d133bf8a48de140a3c666897588a05shiqianvoid CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { 311e35fdd936d133bf8a48de140a3c666897588a05shiqian QualType Ty = D.getType(); 312e35fdd936d133bf8a48de140a3c666897588a05shiqian bool isByRef = D.hasAttr<BlocksAttr>(); 313e35fdd936d133bf8a48de140a3c666897588a05shiqian bool needsDispose = false; 314e35fdd936d133bf8a48de140a3c666897588a05shiqian unsigned Align = 0; 315e35fdd936d133bf8a48de140a3c666897588a05shiqian 316e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *DeclPtr; 317e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty->isConstantSizeType()) { 318e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!Target.useGlobalsForAutomaticVariables()) { 319e35fdd936d133bf8a48de140a3c666897588a05shiqian // A normal fixed sized variable becomes an alloca in the entry block. 320e35fdd936d133bf8a48de140a3c666897588a05shiqian const llvm::Type *LTy = ConvertTypeForMem(Ty); 321e35fdd936d133bf8a48de140a3c666897588a05shiqian Align = getContext().getDeclAlignInBytes(&D); 322e35fdd936d133bf8a48de140a3c666897588a05shiqian if (isByRef) 323e35fdd936d133bf8a48de140a3c666897588a05shiqian LTy = BuildByRefType(&D); 324e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::AllocaInst *Alloc = CreateTempAlloca(LTy); 325e35fdd936d133bf8a48de140a3c666897588a05shiqian Alloc->setName(D.getNameAsString().c_str()); 326e35fdd936d133bf8a48de140a3c666897588a05shiqian 327e35fdd936d133bf8a48de140a3c666897588a05shiqian if (isByRef) 328e35fdd936d133bf8a48de140a3c666897588a05shiqian Align = std::max(Align, unsigned(Target.getPointerAlign(0) / 8)); 329e35fdd936d133bf8a48de140a3c666897588a05shiqian Alloc->setAlignment(Align); 330df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan DeclPtr = Alloc; 331e35fdd936d133bf8a48de140a3c666897588a05shiqian } else { 332e35fdd936d133bf8a48de140a3c666897588a05shiqian // Targets that don't support recursion emit locals as globals. 333e35fdd936d133bf8a48de140a3c666897588a05shiqian const char *Class = 334e35fdd936d133bf8a48de140a3c666897588a05shiqian D.getStorageClass() == VarDecl::Register ? ".reg." : ".auto."; 335e35fdd936d133bf8a48de140a3c666897588a05shiqian DeclPtr = CreateStaticBlockVarDecl(D, Class, 336e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::GlobalValue 337e35fdd936d133bf8a48de140a3c666897588a05shiqian ::InternalLinkage); 338df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 339df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 340e35fdd936d133bf8a48de140a3c666897588a05shiqian // FIXME: Can this happen? 341e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty->isVariablyModifiedType()) 342e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitVLASize(Ty); 343e35fdd936d133bf8a48de140a3c666897588a05shiqian } else { 344e35fdd936d133bf8a48de140a3c666897588a05shiqian EnsureInsertPoint(); 345e35fdd936d133bf8a48de140a3c666897588a05shiqian 346e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!DidCallStackSave) { 347e35fdd936d133bf8a48de140a3c666897588a05shiqian // Save the stack. 348e35fdd936d133bf8a48de140a3c666897588a05shiqian const llvm::Type *LTy = llvm::Type::getInt8PtrTy(VMContext); 349e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *Stack = CreateTempAlloca(LTy, "saved_stack"); 350e35fdd936d133bf8a48de140a3c666897588a05shiqian 351e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave); 352e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *V = Builder.CreateCall(F); 353e35fdd936d133bf8a48de140a3c666897588a05shiqian 354e35fdd936d133bf8a48de140a3c666897588a05shiqian Builder.CreateStore(V, Stack); 355e35fdd936d133bf8a48de140a3c666897588a05shiqian 356e35fdd936d133bf8a48de140a3c666897588a05shiqian DidCallStackSave = true; 357df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 358df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan { 359df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // Push a cleanup block and restore the stack there. 360df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan CleanupScope scope(*this); 361df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 362df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan V = Builder.CreateLoad(Stack, "tmp"); 363df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore); 364df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Builder.CreateCall(F, V); 365df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 366df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan } 367df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 368df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // Get the element type. 369df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan const llvm::Type *LElemTy = ConvertTypeForMem(Ty); 370df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan const llvm::Type *LElemPtrTy = 371e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan llvm::PointerType::get(LElemTy, D.getType().getAddressSpace()); 372e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan 373e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan llvm::Value *VLASize = EmitVLASize(Ty); 374e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan 375e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan // Downcast the VLA size expression 376e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan VLASize = Builder.CreateIntCast(VLASize, llvm::Type::getInt32Ty(VMContext), 377e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan false, "tmp"); 378e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan 379e7bb5ededa4df6ec430c1e84154bc01bf84d4ecczhanyong.wan // Allocate memory for the array. 380df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan llvm::AllocaInst *VLA = 381e35fdd936d133bf8a48de140a3c666897588a05shiqian Builder.CreateAlloca(llvm::Type::getInt8Ty(VMContext), VLASize, "vla"); 382e35fdd936d133bf8a48de140a3c666897588a05shiqian VLA->setAlignment(getContext().getDeclAlignInBytes(&D)); 383e35fdd936d133bf8a48de140a3c666897588a05shiqian 384e35fdd936d133bf8a48de140a3c666897588a05shiqian DeclPtr = Builder.CreateBitCast(VLA, LElemPtrTy, "tmp"); 385e35fdd936d133bf8a48de140a3c666897588a05shiqian } 386e35fdd936d133bf8a48de140a3c666897588a05shiqian 387e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *&DMEntry = LocalDeclMap[&D]; 388e35fdd936d133bf8a48de140a3c666897588a05shiqian assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); 389e35fdd936d133bf8a48de140a3c666897588a05shiqian DMEntry = DeclPtr; 390df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan 391df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan // Emit debug info for local var declaration. 392df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (CGDebugInfo *DI = getDebugInfo()) { 393df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan assert(HaveInsertPoint() && "Unexpected unreachable point!"); 394e35fdd936d133bf8a48de140a3c666897588a05shiqian 395e35fdd936d133bf8a48de140a3c666897588a05shiqian DI->setLocation(D.getLocation()); 396e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Target.useGlobalsForAutomaticVariables()) { 397df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(DeclPtr), &D); 398e35fdd936d133bf8a48de140a3c666897588a05shiqian } else 399e35fdd936d133bf8a48de140a3c666897588a05shiqian DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder); 400e35fdd936d133bf8a48de140a3c666897588a05shiqian } 401e35fdd936d133bf8a48de140a3c666897588a05shiqian 402e35fdd936d133bf8a48de140a3c666897588a05shiqian // If this local has an initializer, emit it now. 403e35fdd936d133bf8a48de140a3c666897588a05shiqian const Expr *Init = D.getInit(); 404e35fdd936d133bf8a48de140a3c666897588a05shiqian 405e35fdd936d133bf8a48de140a3c666897588a05shiqian // If we are at an unreachable point, we don't need to emit the initializer 406e35fdd936d133bf8a48de140a3c666897588a05shiqian // unless it contains a label. 407e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!HaveInsertPoint()) { 408e35fdd936d133bf8a48de140a3c666897588a05shiqian if (!ContainsLabel(Init)) 409df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Init = 0; 410e35fdd936d133bf8a48de140a3c666897588a05shiqian else 411e35fdd936d133bf8a48de140a3c666897588a05shiqian EnsureInsertPoint(); 412e35fdd936d133bf8a48de140a3c666897588a05shiqian } 413e35fdd936d133bf8a48de140a3c666897588a05shiqian 414e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Init) { 415e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *Loc = DeclPtr; 416df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan if (isByRef) 417df35a763b9d98d7040a00fc1e5cffe91a80ba9e0zhanyong.wan Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 418e35fdd936d133bf8a48de140a3c666897588a05shiqian D.getNameAsString()); 419e35fdd936d133bf8a48de140a3c666897588a05shiqian 420e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty->isReferenceType()) { 421e35fdd936d133bf8a48de140a3c666897588a05shiqian RValue RV = EmitReferenceBindingToExpr(Init, Ty, /*IsInitializer=*/true); 422e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty); 423e35fdd936d133bf8a48de140a3c666897588a05shiqian } else if (!hasAggregateLLVMType(Init->getType())) { 424e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *V = EmitScalarExpr(Init); 425e35fdd936d133bf8a48de140a3c666897588a05shiqian EmitStoreOfScalar(V, Loc, D.getType().isVolatileQualified(), 426e35fdd936d133bf8a48de140a3c666897588a05shiqian D.getType()); 4277c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan } else if (Init->getType()->isAnyComplexType()) { 4287c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan EmitComplexExprIntoAddr(Init, Loc, D.getType().isVolatileQualified()); 4297c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan } else { 43032de5f53763125925e078498250f7e73a88de9edzhanyong.wan EmitAggExpr(Init, Loc, D.getType().isVolatileQualified()); 43132de5f53763125925e078498250f7e73a88de9edzhanyong.wan } 4327c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan } 4337c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan 4347c95d8346e9c62e9d6d7e8202fbcfb34c4404db9zhanyong.wan if (isByRef) { 435e35fdd936d133bf8a48de140a3c666897588a05shiqian const llvm::PointerType *PtrToInt8Ty = llvm::Type::getInt8PtrTy(VMContext); 43641b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan 437e35fdd936d133bf8a48de140a3c666897588a05shiqian EnsureInsertPoint(); 43841b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan llvm::Value *isa_field = Builder.CreateStructGEP(DeclPtr, 0); 43941b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan llvm::Value *forwarding_field = Builder.CreateStructGEP(DeclPtr, 1); 44041b9b0b5614588d252d565646ae43e9607d46502zhanyong.wan llvm::Value *flags_field = Builder.CreateStructGEP(DeclPtr, 2); 441e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *size_field = Builder.CreateStructGEP(DeclPtr, 3); 442e35fdd936d133bf8a48de140a3c666897588a05shiqian llvm::Value *V; 443e35fdd936d133bf8a48de140a3c666897588a05shiqian int flag = 0; 444e35fdd936d133bf8a48de140a3c666897588a05shiqian int flags = 0; 445e35fdd936d133bf8a48de140a3c666897588a05shiqian 446e35fdd936d133bf8a48de140a3c666897588a05shiqian needsDispose = true; 447e35fdd936d133bf8a48de140a3c666897588a05shiqian 448e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty->isBlockPointerType()) { 449e35fdd936d133bf8a48de140a3c666897588a05shiqian flag |= BLOCK_FIELD_IS_BLOCK; 450e35fdd936d133bf8a48de140a3c666897588a05shiqian flags |= BLOCK_HAS_COPY_DISPOSE; 451e35fdd936d133bf8a48de140a3c666897588a05shiqian } else if (BlockRequiresCopying(Ty)) { 452e35fdd936d133bf8a48de140a3c666897588a05shiqian flag |= BLOCK_FIELD_IS_OBJECT; 453e35fdd936d133bf8a48de140a3c666897588a05shiqian flags |= BLOCK_HAS_COPY_DISPOSE; 454e35fdd936d133bf8a48de140a3c666897588a05shiqian } 455e35fdd936d133bf8a48de140a3c666897588a05shiqian 456e35fdd936d133bf8a48de140a3c666897588a05shiqian // FIXME: Someone double check this. 457e35fdd936d133bf8a48de140a3c666897588a05shiqian if (Ty.isObjCGCWeak()) 458e35fdd936d133bf8a48de140a3c666897588a05shiqian flag |= BLOCK_FIELD_IS_WEAK; 459e35fdd936d133bf8a48de140a3c666897588a05shiqian 460e35fdd936d133bf8a48de140a3c666897588a05shiqian int isa = 0; 461e35fdd936d133bf8a48de140a3c666897588a05shiqian if (flag&BLOCK_FIELD_IS_WEAK) 462e35fdd936d133bf8a48de140a3c666897588a05shiqian isa = 1; 463e35fdd936d133bf8a48de140a3c666897588a05shiqian V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), isa); 464e35fdd936d133bf8a48de140a3c666897588a05shiqian V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa"); 465e35fdd936d133bf8a48de140a3c666897588a05shiqian Builder.CreateStore(V, isa_field); 466 467 Builder.CreateStore(DeclPtr, forwarding_field); 468 469 V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags); 470 Builder.CreateStore(V, flags_field); 471 472 const llvm::Type *V1; 473 V1 = cast<llvm::PointerType>(DeclPtr->getType())->getElementType(); 474 V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 475 (CGM.getTargetData().getTypeStoreSizeInBits(V1) 476 / 8)); 477 Builder.CreateStore(V, size_field); 478 479 if (flags & BLOCK_HAS_COPY_DISPOSE) { 480 BlockHasCopyDispose = true; 481 llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4); 482 Builder.CreateStore(BuildbyrefCopyHelper(DeclPtr->getType(), flag, Align), 483 copy_helper); 484 485 llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5); 486 Builder.CreateStore(BuildbyrefDestroyHelper(DeclPtr->getType(), flag, 487 Align), 488 destroy_helper); 489 } 490 } 491 492 // Handle CXX destruction of variables. 493 QualType DtorTy(Ty); 494 if (const ArrayType *Array = DtorTy->getAs<ArrayType>()) 495 DtorTy = getContext().getBaseElementType(Array); 496 if (const RecordType *RT = DtorTy->getAs<RecordType>()) 497 if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 498 if (!ClassDecl->hasTrivialDestructor()) { 499 const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext()); 500 assert(D && "EmitLocalBlockVarDecl - destructor is nul"); 501 502 CleanupScope scope(*this); 503 if (const ConstantArrayType *Array = 504 getContext().getAsConstantArrayType(Ty)) { 505 QualType BaseElementTy = getContext().getBaseElementType(Array); 506 const llvm::Type *BasePtr = ConvertType(BaseElementTy); 507 BasePtr = llvm::PointerType::getUnqual(BasePtr); 508 llvm::Value *BaseAddrPtr = 509 Builder.CreateBitCast(DeclPtr, BasePtr); 510 EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 511 } 512 else 513 EmitCXXDestructorCall(D, Dtor_Complete, DeclPtr); 514 } 515 } 516 517 // Handle the cleanup attribute 518 if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) { 519 const FunctionDecl *FD = CA->getFunctionDecl(); 520 521 llvm::Constant* F = CGM.GetAddrOfFunction(FD); 522 assert(F && "Could not find function!"); 523 524 CleanupScope scope(*this); 525 526 const CGFunctionInfo &Info = CGM.getTypes().getFunctionInfo(FD); 527 528 // In some cases, the type of the function argument will be different from 529 // the type of the pointer. An example of this is 530 // void f(void* arg); 531 // __attribute__((cleanup(f))) void *g; 532 // 533 // To fix this we insert a bitcast here. 534 QualType ArgTy = Info.arg_begin()->type; 535 DeclPtr = Builder.CreateBitCast(DeclPtr, ConvertType(ArgTy)); 536 537 CallArgList Args; 538 Args.push_back(std::make_pair(RValue::get(DeclPtr), 539 getContext().getPointerType(D.getType()))); 540 541 EmitCall(Info, F, Args); 542 } 543 544 if (needsDispose && CGM.getLangOptions().getGCMode() != LangOptions::GCOnly) { 545 CleanupScope scope(*this); 546 llvm::Value *V = Builder.CreateStructGEP(DeclPtr, 1, "forwarding"); 547 V = Builder.CreateLoad(V, false); 548 BuildBlockRelease(V); 549 } 550} 551 552/// Emit an alloca (or GlobalValue depending on target) 553/// for the specified parameter and set up LocalDeclMap. 554void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) { 555 // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl? 556 assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) && 557 "Invalid argument to EmitParmDecl"); 558 QualType Ty = D.getType(); 559 560 llvm::Value *DeclPtr; 561 if (!Ty->isConstantSizeType()) { 562 // Variable sized values always are passed by-reference. 563 DeclPtr = Arg; 564 } else { 565 // A fixed sized single-value variable becomes an alloca in the entry block. 566 const llvm::Type *LTy = ConvertTypeForMem(Ty); 567 if (LTy->isSingleValueType()) { 568 // TODO: Alignment 569 std::string Name = D.getNameAsString(); 570 Name += ".addr"; 571 DeclPtr = CreateTempAlloca(LTy); 572 DeclPtr->setName(Name.c_str()); 573 574 // Store the initial value into the alloca. 575 EmitStoreOfScalar(Arg, DeclPtr, Ty.isVolatileQualified(), Ty); 576 } else { 577 // Otherwise, if this is an aggregate, just use the input pointer. 578 DeclPtr = Arg; 579 } 580 Arg->setName(D.getNameAsString()); 581 } 582 583 llvm::Value *&DMEntry = LocalDeclMap[&D]; 584 assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); 585 DMEntry = DeclPtr; 586 587 // Emit debug info for param declaration. 588 if (CGDebugInfo *DI = getDebugInfo()) { 589 DI->setLocation(D.getLocation()); 590 DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder); 591 } 592} 593 594