// 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); }
CodeGenTypes::CodeGenTypes(CodeGenModule &cgm) : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()), TheDataLayout(cgm.getDataLayout()), Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()), TheABIInfo(cgm.getTargetCodeGenInfo().getABIInfo()) { SkippedLayout = false; }
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; }
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 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 bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, const CXXRecordDecl *RD) { return CGM.getCodeGenOpts().OptimizationLevel > 0 && CGM.getCXXABI().canSpeculativelyEmitVTable(RD); }