From: Anders Carlsson Date: Thu, 26 Nov 2009 19:54:33 +0000 (+0000) Subject: Lazily create the __cxa_pure_virtual reference. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d4ccb729c8073731439eafd272d257dac51f69a;p=clang Lazily create the __cxa_pure_virtual reference. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89965 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 527228fe2a..fb3e6be3e6 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -53,6 +53,9 @@ private: llvm::DenseMap NonVirtualOffset; llvm::DenseMap VBIndex; + /// PureVirtualFunction - Points to __cxa_pure_virtual. + llvm::Constant *PureVirtualFn; + /// Thunk - Represents a single thunk. struct Thunk { Thunk() @@ -113,7 +116,6 @@ private: const uint32_t LLVMPointerWidth; Index_t extra; typedef std::vector > Path_t; - llvm::Constant *cxa_pure; static llvm::DenseMap& AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l, const CXXRecordDecl *c) { @@ -126,23 +128,29 @@ private: ref = new llvm::DenseMap; return *ref; } + + /// getPureVirtualFn - Return the __cxa_pure_virtual function. + llvm::Constant* getPureVirtualFn() { + if (!PureVirtualFn) { + const llvm::FunctionType *Ty = + llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), + /*isVarArg=*/false); + PureVirtualFn = wrap(CGM.CreateRuntimeFunction(Ty, "__cxa_pure_virtual")); + } + + return PureVirtualFn; + } + public: VtableBuilder(std::vector &meth, const CXXRecordDecl *c, const CXXRecordDecl *l, uint64_t lo, CodeGenModule &cgm) : methods(meth), Class(c), LayoutClass(l), LayoutOffset(lo), BLayout(cgm.getContext().getASTRecordLayout(l)), rtti(cgm.GenerateRttiRef(c)), VMContext(cgm.getModule().getContext()), - CGM(cgm), subAddressPoints(AllocAddressPoint(cgm, l, c)), + CGM(cgm), PureVirtualFn(0),subAddressPoints(AllocAddressPoint(cgm, l, c)), Extern(!l->isInAnonymousNamespace()), - LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) { + LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) { Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); - - // Calculate pointer for ___cxa_pure_virtual. - const llvm::FunctionType *FTy; - std::vector ArgTys; - const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); - FTy = llvm::FunctionType::get(ResultType, ArgTys, false); - cxa_pure = wrap(CGM.CreateRuntimeFunction(FTy, "__cxa_pure_virtual")); } llvm::DenseMap &getIndex() { return Index; } @@ -399,7 +407,7 @@ public: for (PureVirtualMethodsSetTy::iterator i = PureVirtualMethods.begin(), e = PureVirtualMethods.end(); i != e; ++i) { GlobalDecl GD = *i; - submethods[Index[GD]] = cxa_pure; + submethods[Index[GD]] = getPureVirtualFn(); } PureVirtualMethods.clear(); }