]> granicus.if.org Git - clang/commitdiff
Lazily create the __cxa_pure_virtual reference.
authorAnders Carlsson <andersca@mac.com>
Thu, 26 Nov 2009 19:54:33 +0000 (19:54 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 26 Nov 2009 19:54:33 +0000 (19:54 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89965 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp

index 527228fe2a53255d718ac1843f5aa67b6e4cc5c1..fb3e6be3e6b233e7d0e249dd73099b9a8c8fa8e8 100644 (file)
@@ -53,6 +53,9 @@ private:
   llvm::DenseMap<GlobalDecl, Index_t> NonVirtualOffset;
   llvm::DenseMap<const CXXRecordDecl *, Index_t> 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<std::pair<const CXXRecordDecl *, int64_t> > Path_t;
-  llvm::Constant *cxa_pure;
   static llvm::DenseMap<CtorVtable_t, int64_t>&
   AllocAddressPoint(CodeGenModule &cgm, const CXXRecordDecl *l,
                     const CXXRecordDecl *c) {
@@ -126,23 +128,29 @@ private:
       ref = new llvm::DenseMap<CtorVtable_t, int64_t>;
     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<llvm::Constant *> &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<const llvm::Type*> 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<GlobalDecl, Index_t> &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();
   }