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); }
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; }
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; }
/// 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 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; }
static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD) { return CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCXXABI().canSpeculativelyEmitVTable(RD); }