// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures // from available_externally to the correct linkage if necessary. An example of // this is: // // struct A { // virtual void f(); // }; // // const std::type_info &g() { // return typeid(A); // } // // void A::f() { } // // When we're generating the typeid(A) expression, we do not yet know that // A's key function is defined in this translation unit, so we will give the // typeinfo and typename structures available_externally linkage. When A::f // forces the vtable to be generated, we need to change the linkage of the // typeinfo and typename structs, otherwise we'll end up with undefined // externals when linking. static void maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV, QualType Ty) { // We're only interested in globals with available_externally linkage. if (!GV->hasAvailableExternallyLinkage()) return; // Get the real linkage for the type. llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty); // If variable is supposed to have available_externally linkage, we don't // need to do anything. if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage) return; // Update the typeinfo linkage. GV->setLinkage(Linkage); // Get the typename global. SmallString<256> OutName; llvm::raw_svector_ostream Out(OutName); CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out); Out.flush(); StringRef Name = OutName.str(); llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name); assert(TypeNameGV->hasAvailableExternallyLinkage() && "Type name has different linkage from type info!"); // And update its linkage. TypeNameGV->setLinkage(Linkage); }
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info, llvm::SmallVectorImpl<llvm::Type*> &elementTypes) { ASTContext &C = CGM.getContext(); // The header is basically a 'struct { void *; int; int; void *; void *; }'. CharUnits ptrSize, ptrAlign, intSize, intAlign; llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.UInt32Ty); llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.Int32Ty); // Are there crazy embedded platforms where this isn't true? assert(intSize <= ptrSize && "layout assumptions horribly violated"); CharUnits headerSize = ptrSize; if (2 * intSize < ptrAlign) headerSize += ptrSize; else headerSize += 2 * intSize; headerSize += 2 * ptrSize; info.BlockAlign = ptrAlign; info.BlockSize = headerSize; assert(elementTypes.empty()); llvm::Type *i8p = CGM.getTypes().ConvertType(C.UInt32Ty); llvm::Type *intTy = CGM.getTypes().ConvertType(C.Int32Ty); elementTypes.push_back(i8p); elementTypes.push_back(intTy); elementTypes.push_back(intTy); elementTypes.push_back(i8p); elementTypes.push_back(CGM.getBlockDescriptorType()); assert(elementTypes.size() == BlockHeaderSize); }
static bool CheckElementalArguments(CodeGenModule &CGM, const FunctionDecl *FD, llvm::Function *Fn, bool &HasThis) { // Check the return type. QualType RetTy = FD->getReturnType(); if (RetTy->isAggregateType()) { CGM.Error(FD->getLocation(), "the return type for this elemental " "function is not supported yet"); return false; } // Check each parameter type. for (unsigned I = 0, E = FD->param_size(); I < E; ++I) { const ParmVarDecl *VD = FD->getParamDecl(I); QualType Ty = VD->getType(); assert(!Ty->isIncompleteType() && "incomplete type"); if (Ty->isAggregateType()) { CGM.Error(VD->getLocation(), "the parameter type for this elemental " "function is not supported yet"); return false; } } HasThis = isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isInstance(); // At this point, no passing struct arguments by value. unsigned NumArgs = FD->param_size(); unsigned NumLLVMArgs = Fn->arg_size(); // There is a single implicit 'this' parameter. if (HasThis && (NumArgs + 1 == NumLLVMArgs)) return true; return NumArgs == NumLLVMArgs; }
CodeGenVTables::CodeGenVTables(CodeGenModule &CGM) : CGM(CGM), ItaniumVTContext(CGM.getContext()) { if (CGM.getTarget().getCXXABI().isMicrosoft()) { // FIXME: Eventually, we should only have one of V*TContexts available. // Today we use both in the Microsoft ABI as MicrosoftVFTableContext // is not completely supported in CodeGen yet. MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext())); } }
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) : CGCUDARuntime(CGM) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); IntTy = Types.ConvertType(Ctx.IntTy); SizeTy = Types.ConvertType(Ctx.getSizeType()); CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy)); VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy)); }
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) : CGCUDARuntime(CGM), Context(CGM.getLLVMContext()), TheModule(CGM.getModule()) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); IntTy = CGM.IntTy; SizeTy = CGM.SizeTy; VoidTy = CGM.VoidTy; CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy)); VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy)); VoidPtrPtrTy = VoidPtrTy->getPointerTo(); }
/// Given that we're currently at the end of the translation unit, and /// we've emitted a reference to the v-table for this class, should /// we define that v-table? static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD) { // If we're building with optimization, we always emit v-tables // since that allows for virtual function calls to be devirtualized. // If the v-table is defined strongly elsewhere, this definition // will be emitted available_externally. // // However, we don't want to do this in -fapple-kext mode, because // kext mode does not permit devirtualization. if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext) return true; return !CGM.getVTables().isVTableExternal(RD); }
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD) { CGM.setFunctionLinkage(GD, ThunkFn); CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, !Thunk.Return.isEmpty()); // Set the right visibility. const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); setThunkVisibility(CGM, MD, Thunk, ThunkFn); if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker()) ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); }
static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM, const OMPAlignedClause &Clause) { unsigned ClauseAlignment = 0; if (auto AlignmentExpr = Clause.getAlignment()) { auto AlignmentCI = cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue()); } for (auto E : Clause.varlists()) { unsigned Alignment = ClauseAlignment; if (Alignment == 0) { // OpenMP [2.8.1, Description] // If no optional parameter is specified, implementation-defined default // alignments for SIMD instructions on the target platforms are assumed. Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( E->getType()); } assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && "alignment is not power of 2"); if (Alignment != 0) { llvm::Value *PtrValue = CGF.EmitScalarExpr(E); CGF.EmitAlignmentAssumption(PtrValue, Alignment); } } }
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, const ThunkInfo &Thunk, llvm::Function *Fn) { CGM.setGlobalVisibility(Fn, MD); if (!CGM.getCodeGenOpts().HiddenWeakVTables) return; // If the thunk has weak/linkonce linkage, but the function must be // emitted in every translation unit that references it, then we can // emit its thunks with hidden visibility, since its thunks must be // emitted when the function is. // This follows CodeGenModule::setTypeVisibility; see the comments // there for explanation. if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage && Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) || Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility) return; if (MD->getExplicitVisibility()) return; switch (MD->getTemplateSpecializationKind()) { case TSK_ExplicitInstantiationDefinition: case TSK_ExplicitInstantiationDeclaration: return; case TSK_Undeclared: break; case TSK_ExplicitSpecialization: case TSK_ImplicitInstantiation: if (!CGM.getCodeGenOpts().HiddenWeakTemplateVTables) return; break; } // If there's an explicit definition, and that definition is // out-of-line, then we can't assume that all users will have a // definition to emit. const FunctionDecl *Def = 0; if (MD->hasBody(Def) && Def->isOutOfLine()) return; Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); }
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, bool IsUnprototyped, bool ForVTable) { // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to // provide thunks for us. if (CGM.getTarget().getCXXABI().isMicrosoft()) return true; // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide // definitions of the main method. Therefore, emitting thunks with the vtable // is purely an optimization. Emit the thunk if optimizations are enabled and // all of the parameter types are complete. if (ForVTable) return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped; // Always emit thunks along with the method definition. return true; }
/// Given that we're currently at the end of the translation unit, and /// we've emitted a reference to the vtable for this class, should /// we define that vtable? static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, const CXXRecordDecl *RD) { // If vtable is internal then it has to be done. if (!CGM.getVTables().isVTableExternal(RD)) return true; // If it's external then maybe we will need it as available_externally. return shouldEmitAvailableExternallyVTable(CGM, RD); }
void VBTableInfo::EmitVBTableDefinition( CodeGenModule &CGM, const CXXRecordDecl *RD, llvm::GlobalVariable::LinkageTypes Linkage) const { assert(RD->getNumVBases() && ReusingBase->getNumVBases() && "should only emit vbtables for classes with vbtables"); const ASTRecordLayout &BaseLayout = CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase()); const ASTRecordLayout &DerivedLayout = CGM.getContext().getASTRecordLayout(RD); SmallVector<llvm::Constant *, 4> Offsets; // The offset from ReusingBase's vbptr to itself always leads. CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset(); Offsets.push_back( llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity())); // These are laid out in the same order as in Itanium, which is the same as // the order of the vbase iterator. for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(), E = ReusingBase->vbases_end(); I != E; ++I) { const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl(); CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase); assert(!Offset.isNegative()); // Make it relative to the subobject vbptr. Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset; Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity())); } assert(Offsets.size() == cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType()) ->getElementType())->getNumElements()); llvm::ArrayType *VBTableType = llvm::ArrayType::get(CGM.IntTy, Offsets.size()); llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets); GV->setInitializer(Init); // Set the correct linkage. GV->setLinkage(Linkage); // Set the right visibility. CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable); }
CodeGenTypes::CodeGenTypes(CodeGenModule &cgm) : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()), TheDataLayout(cgm.getDataLayout()), Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()), CodeGenOpts(cgm.getCodeGenOpts()), TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) { SkippedLayout = false; }
CharUnits swiftcall::getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type) { // For Swift's purposes, this is always just the store size of the type // rounded up to a power of 2. auto size = (unsigned long long) getTypeStoreSize(CGM, type).getQuantity(); if (!isPowerOf2(size)) { size = 1ULL << (llvm::findLastSet(size, llvm::ZB_Undefined) + 1); } assert(size >= CGM.getDataLayout().getABITypeAlignment(type)); return CharUnits::fromQuantity(size); }
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for /// the given type exists somewhere else, and that we should not emit the type /// information in this translation unit. Assumes that it is not a /// standard-library type. static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) { ASTContext &Context = CGM.getContext(); // If RTTI is disabled, don't consider key functions. if (!Context.getLangOpts().RTTI) return false; if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); if (!RD->hasDefinition()) return false; if (!RD->isDynamicClass()) return false; return !CGM.getVTables().ShouldEmitVTableInThisTU(RD); } return false; }
/// getTypeInfoLinkage - Return the linkage that the type info and type info /// name constants should have for the given type. static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) { // Itanium C++ ABI 2.9.5p7: // In addition, it and all of the intermediate abi::__pointer_type_info // structs in the chain down to the abi::__class_type_info for the // incomplete class type must be prevented from resolving to the // corresponding type_info structs for the complete class type, possibly // by making them local static objects. Finally, a dummy class RTTI is // generated for the incomplete type that will not resolve to the final // complete class RTTI (because the latter need not exist), possibly by // making it a local static object. if (ContainsIncompleteClassType(Ty)) return llvm::GlobalValue::InternalLinkage; switch (Ty->getLinkage()) { case NoLinkage: case VisibleNoLinkage: case InternalLinkage: case UniqueExternalLinkage: return llvm::GlobalValue::InternalLinkage; case ExternalLinkage: if (!CGM.getLangOpts().RTTI) { // RTTI is not enabled, which means that this type info struct is going // to be used for exception handling. Give it linkonce_odr linkage. return llvm::GlobalValue::LinkOnceODRLinkage; } if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); if (RD->hasAttr<WeakAttr>()) return llvm::GlobalValue::WeakODRLinkage; if (RD->isDynamicClass()) return CGM.getVTableLinkage(RD); } return llvm::GlobalValue::LinkOnceODRLinkage; } llvm_unreachable("Invalid linkage!"); }
CodeGenTypes::CodeGenTypes(CodeGenModule &CGM) : Context(CGM.getContext()), Target(Context.getTargetInfo()), TheModule(CGM.getModule()), TheTargetData(CGM.getTargetData()), TheABIInfo(CGM.getTargetCodeGenInfo().getABIInfo()), TheCXXABI(CGM.getCXXABI()), CodeGenOpts(CGM.getCodeGenOpts()), CGM(CGM) { SkippedLayout = false; }
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) : BlockFunction(cgm, *this, Builder), CGM(cgm), Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()), DebugInfo(0), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0), CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), ConditionalBranchLevel(0), TerminateHandler(0), TrapBB(0), UniqueAggrDestructorCount(0) { LLVMIntTy = ConvertType(getContext().IntTy); LLVMPointerWidth = Target.getPointerWidth(0); Exceptions = getContext().getLangOptions().Exceptions; CatchUndefined = getContext().getLangOptions().CatchUndefined; }
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for /// the given type exists somewhere else, and that we should not emit the type /// information in this translation unit. Assumes that it is not a /// standard-library type. static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) { ASTContext &Context = CGM.getContext(); // If RTTI is disabled, assume it might be disabled in the // translation unit that defines any potential key function, too. if (!Context.getLangOpts().RTTI) return false; if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl()); if (!RD->hasDefinition()) return false; if (!RD->isDynamicClass()) return false; // FIXME: this may need to be reconsidered if the key function // changes. return CGM.getVTables().isVTableExternal(RD); } return false; }
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) : CodeGenTypeCache(cgm), CGM(cgm), Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()), AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1), ExceptionSlot(0), DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), ClassThisDefn(0), ClassThisValue(0), ClassVTTDefn(0), ClassVTTValue(0), OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0), TrapBB(0) { CatchUndefined = false/*getContext().getLangOptions().CatchUndefined*/; CGM.getOOPABI().getMangleContext().startNewFunction(); }
CGIdeasRuntime::CGIdeasRuntime(CodeGenModule& CGM) : module_(CGM.getModule()){ llvm::LLVMContext& C = module_.getContext(); Int1Ty = llvm::IntegerType::getInt1Ty(C); Int8Ty = llvm::IntegerType::getInt8Ty(C); Int32Ty = llvm::IntegerType::getInt32Ty(C); Int64Ty = llvm::IntegerType::getInt64Ty(C); FloatTy = llvm::Type::getFloatTy(C); DoubleTy = llvm::Type::getDoubleTy(C); VoidTy = llvm::Type::getVoidTy(C); VoidPtrTy = PointerTy(Int8Ty); StringTy = PointerTy(Int8Ty); TypeVec params = {VoidPtrTy}; QueueFuncTy = llvm::FunctionType::get(VoidTy, params, false); }
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) : CodeGenTypeCache(cgm), CGM(cgm), Target(CGM.getContext().getTargetInfo()), Builder(cgm.getModule().getContext()), AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0), DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0), TrapBB(0) { CatchUndefined = getContext().getLangOpts().CatchUndefined; if (!suppressNewContext) CGM.getCXXABI().getMangleContext().startNewFunction(); }
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) : CGCUDARuntime(CGM), Context(CGM.getLLVMContext()), TheModule(CGM.getModule()), RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode), DeviceMC(CGM.getContext().createMangleContext( CGM.getContext().getAuxTargetInfo())) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); IntTy = CGM.IntTy; SizeTy = CGM.SizeTy; VoidTy = CGM.VoidTy; CharPtrTy = llvm::PointerType::getUnqual(Types.ConvertType(Ctx.CharTy)); VoidPtrTy = cast<llvm::PointerType>(Types.ConvertType(Ctx.VoidPtrTy)); VoidPtrPtrTy = VoidPtrTy->getPointerTo(); }
bool swiftcall::isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *intTy) { auto size = intTy->getBitWidth(); switch (size) { case 1: case 8: case 16: case 32: case 64: // Just assume that the above are always legal. return true; case 128: return CGM.getContext().getTargetInfo().hasInt128Type(); default: return false; } }
/// \brief Generates a properstep argument for each function parameter. /// Returns true if this is a non-linear and non-uniform variable. /// Otherwise returns false. static bool handleParameter(CodeGenModule &CGM, CilkElementalGroup &G, StringRef ParmName, SmallVectorImpl<llvm::Metadata *> &StepArgs, SmallVectorImpl<llvm::Metadata *> &AligArgs) { // Update the alignment args. unsigned Alignment; if (G.getAlignedAttr(ParmName, &Alignment)) { AligArgs.push_back(llvm::ConstantAsMetadata::get( llvm::ConstantInt::get(CGM.IntTy, Alignment))); } else { AligArgs.push_back(llvm::ConstantAsMetadata::get( llvm::UndefValue::get(CGM.IntTy))); } // Update the step args. std::pair<int,std::string> LinStep; if (G.getUniformAttr(ParmName)) { // If this is uniform, then use step 0 as placeholder. StepArgs.push_back(llvm::ConstantAsMetadata::get( llvm::ConstantInt::get(CGM.IntTy, 0))); return false; } else if (G.getLinearAttr(ParmName, &LinStep)) { if (LinStep.first != 0) { StepArgs.push_back(llvm::ConstantAsMetadata::get( llvm::ConstantInt::get(CGM.IntTy, LinStep.first))); } else { StepArgs.push_back(llvm::MDString::get(CGM.getLLVMContext(), LinStep.second)); } return false; } // If this is non-linear and non-uniform, use undefined step as placeholder. StepArgs.push_back(llvm::ConstantAsMetadata::get( llvm::UndefValue::get(CGM.IntTy))); return true; }
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) : BlockFunction(cgm, *this, Builder), CGM(cgm), Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()), NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1), ExceptionSlot(0), DebugInfo(0), IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), DidCallStackSave(false), UnreachableBlock(0), CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), ConditionalBranchLevel(0), TerminateLandingPad(0), TerminateHandler(0), TrapBB(0) { // Get some frequently used types. LLVMPointerWidth = Target.getPointerWidth(0); llvm::LLVMContext &LLVMContext = CGM.getLLVMContext(); IntPtrTy = llvm::IntegerType::get(LLVMContext, LLVMPointerWidth); Int32Ty = llvm::Type::getInt32Ty(LLVMContext); Int64Ty = llvm::Type::getInt64Ty(LLVMContext); Exceptions = getContext().getLangOptions().Exceptions; CatchUndefined = getContext().getLangOptions().CatchUndefined; CGM.getCXXABI().getMangleContext().startNewFunction(); }
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, llvm::Function *ThunkFn, bool ForVTable, GlobalDecl GD) { CGM.setFunctionLinkage(GD, ThunkFn); CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, !Thunk.Return.isEmpty()); // Set the right visibility. CGM.setGVProperties(ThunkFn, GD); if (!CGM.getCXXABI().exportThunk()) { ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); ThunkFn->setDSOLocal(true); } if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker()) ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); }
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD) { return CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCXXABI().canSpeculativelyEmitVTable(RD); }
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD, const ThunkInfo &Thunk, llvm::Function *Fn) { CGM.setGlobalVisibility(Fn, MD); }