[cfe-commits] r92409 - in /cfe/trunk: lib/CodeGen/CGClass.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGVtable.cpp lib/CodeGen/CGVtable.h lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/constructor-template.cpp test/CodeGenCXX/default-constructor-default-argument.cpp test/CodeGenCXX/virtual-destructor-calls.cpp

Anders Carlsson andersca at mac.com
Fri Jan 1 17:01:18 PST 2010


Author: andersca
Date: Fri Jan  1 19:01:18 2010
New Revision: 92409

URL: http://llvm.org/viewvc/llvm-project?rev=92409&view=rev
Log:
Correctly pass VTT parameters to constructors and destructors. The VTTs aren't yet used in the ctors/dtors, but that will follow.

Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CGVtable.h
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenCXX/constructor-template.cpp
    cfe/trunk/test/CodeGenCXX/default-constructor-default-argument.cpp
    cfe/trunk/test/CodeGenCXX/virtual-destructor-calls.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Fri Jan  1 19:01:18 2010
@@ -431,6 +431,37 @@
   EmitBlock(AfterFor, true);
 }
 
+/// GetVTTParameter - Return the VTT parameter that should be passed to a
+/// base constructor/destructor with virtual bases.
+static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD) {
+  if (!CGVtableInfo::needsVTTParameter(GD)) {
+    // This constructor/destructor does not need a VTT parameter.
+    return 0;
+  }
+  
+  const CXXRecordDecl *RD = cast<CXXMethodDecl>(CGF.CurFuncDecl)->getParent();
+  const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
+  
+  llvm::Value *VTT;
+
+  uint64_t SubVTTIndex = 
+    CGF.CGM.getVtableInfo().getSubVTTIndex(RD, Base);
+  assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
+  
+  if (CGVtableInfo::needsVTTParameter(CGF.CurGD)) {
+    // A VTT parameter was passed to the constructor, use it.
+    VTT = CGF.LoadCXXVTT();
+    VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
+  } else {
+    // We're the complete constructor, so get the VTT by name.
+    VTT = CGF.CGM.getVtableInfo().getVTT(RD);
+    VTT = CGF.Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
+  }
+
+  return VTT;
+}
+
+                                    
 /// EmitClassMemberwiseCopy - This routine generates code to copy a class
 /// object from SrcValue to DestValue. Copying can be either a bitwise copy
 /// or via a copy constructor call.
@@ -438,11 +469,16 @@
                         llvm::Value *Dest, llvm::Value *Src,
                         const CXXRecordDecl *ClassDecl,
                         const CXXRecordDecl *BaseClassDecl, QualType Ty) {
+  CXXCtorType CtorType = Ctor_Complete;
+  
   if (ClassDecl) {
     Dest = GetAddressOfBaseClass(Dest, ClassDecl, BaseClassDecl,
                                  /*NullCheckValue=*/false);
     Src = GetAddressOfBaseClass(Src, ClassDecl, BaseClassDecl,
                                 /*NullCheckValue=*/false);
+
+    // We want to call the base constructor.
+    CtorType = Ctor_Base;
   }
   if (BaseClassDecl->hasTrivialCopyConstructor()) {
     EmitAggregateCopy(Dest, Src, Ty);
@@ -451,13 +487,19 @@
 
   if (CXXConstructorDecl *BaseCopyCtor =
       BaseClassDecl->getCopyConstructor(getContext(), 0)) {
-    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor,
-                                                      Ctor_Complete);
+    llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(BaseCopyCtor, CtorType);
     CallArgList CallArgs;
     // Push the this (Dest) ptr.
     CallArgs.push_back(std::make_pair(RValue::get(Dest),
                                       BaseCopyCtor->getThisType(getContext())));
 
+    // Push the VTT parameter, if necessary.
+    if (llvm::Value *VTT = 
+          GetVTTParameter(*this, GlobalDecl(BaseCopyCtor, CtorType))) {
+      QualType T = getContext().getPointerType(getContext().VoidPtrTy);
+      CallArgs.push_back(std::make_pair(RValue::get(VTT), T));
+    }
+
     // Push the Src ptr.
     CallArgs.push_back(std::make_pair(RValue::get(Src),
                        BaseCopyCtor->getParamDecl(0)->getType()));
@@ -787,10 +829,8 @@
   V = CGF.Builder.CreateConstInBoundsGEP1_64(V, Offset/8);
   V = CGF.Builder.CreateBitCast(V, BaseClassType->getPointerTo());
 
-  // FIXME: This should always use Ctor_Base as the ctor type!  (But that
-  // causes crashes in tests.)
   CGF.EmitCXXConstructorCall(BaseInit->getConstructor(),
-                             CtorType, V,
+                             Ctor_Base, V,
                              BaseInit->const_arg_begin(),
                              BaseInit->const_arg_end());
 }
@@ -1248,6 +1288,7 @@
   return m;
 }
 
+
 void
 CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
                                         CXXCtorType Type,
@@ -1271,35 +1312,19 @@
     return;
   }
 
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type));
   llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
 
-  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, ArgBeg, ArgEnd);
+  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
 }
 
 void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
                                             CXXDtorType Type,
                                             llvm::Value *This) {
+  llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type));
   llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
   
-  CallArgList Args;
-
-  // Push the this ptr.
-  Args.push_back(std::make_pair(RValue::get(This),
-                                DD->getThisType(getContext())));
-  
-  // Add a VTT parameter if necessary.
-  // FIXME: This should not be a dummy null parameter!
-  if (Type == Dtor_Base && DD->getParent()->getNumVBases() != 0) {
-    QualType T = getContext().getPointerType(getContext().VoidPtrTy);
-    
-    Args.push_back(std::make_pair(RValue::get(CGM.EmitNullConstant(T)), T));
-  }
-
-  // FIXME: We should try to share this code with EmitCXXMemberCall.
-  
-  QualType ResultType = DD->getType()->getAs<FunctionType>()->getResultType();
-  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, 
-           ReturnValueSlot(), Args, DD);
+  EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
 }
 
 llvm::Value *
@@ -1395,3 +1420,11 @@
   // Store address point
   Builder.CreateStore(VtableAddressPoint, VtableField);
 }
+
+llvm::Value *CodeGenFunction::LoadCXXVTT() {
+  assert((isa<CXXConstructorDecl>(CurFuncDecl) ||
+          isa<CXXDestructorDecl>(CurFuncDecl)) &&
+         "Must be in a C++ ctor or dtor to load the vtt parameter");
+
+  return Builder.CreateLoad(LocalDeclMap[CXXVTTDecl], "vtt");
+}

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Fri Jan  1 19:01:18 2010
@@ -19,6 +19,7 @@
                                           llvm::Value *Callee,
                                           ReturnValueSlot ReturnValue,
                                           llvm::Value *This,
+                                          llvm::Value *VTT,
                                           CallExpr::const_arg_iterator ArgBeg,
                                           CallExpr::const_arg_iterator ArgEnd) {
   assert(MD->isInstance() &&
@@ -32,6 +33,12 @@
   Args.push_back(std::make_pair(RValue::get(This),
                                 MD->getThisType(getContext())));
 
+  // If there is a VTT parameter, emit it.
+  if (VTT) {
+    QualType T = getContext().getPointerType(getContext().VoidPtrTy);
+    Args.push_back(std::make_pair(RValue::get(VTT), T));
+  }
+  
   // And the rest of the call args
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
@@ -129,7 +136,7 @@
     Callee = CGM.GetAddrOfFunction(MD, Ty);
   }
 
-  return EmitCXXMemberCall(MD, Callee, ReturnValue, This,
+  return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
                            CE->arg_begin(), CE->arg_end());
 }
 
@@ -275,7 +282,7 @@
   else
     Callee = CGM.GetAddrOfFunction(MD, Ty);
 
-  return EmitCXXMemberCall(MD, Callee, ReturnValue, This, 
+  return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
                            E->arg_begin() + 1, E->arg_end());
 }
 
@@ -726,7 +733,8 @@
                                            /*isVariadic=*/false);
           
           llvm::Value *Callee = BuildVirtualCall(Dtor, Dtor_Deleting, Ptr, Ty);
-          EmitCXXMemberCall(Dtor, Callee, ReturnValueSlot(), Ptr, 0, 0);
+          EmitCXXMemberCall(Dtor, Callee, ReturnValueSlot(), Ptr, /*VTT=*/0,
+                            0, 0);
 
           // The dtor took care of deleting the object.
           ShouldCallDelete = false;

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Fri Jan  1 19:01:18 2010
@@ -211,7 +211,7 @@
     return VtableComponents;
   }
   
-  llvm::DenseMap<const CXXRecordDecl *, Index_t> &getVBIndex()
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getVBIndex()
     { return VBIndex; }
 
   SavedAdjustmentsVectorTy &getSavedAdjustments()
@@ -1209,6 +1209,10 @@
   llvm::Constant *ClassVtbl;
   llvm::LLVMContext &VMContext;
 
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t> SubVTTIndicies;
+  
+  bool GenerateDefinition;
+  
   /// BuildVtablePtr - Build up a referene to the given secondary vtable
   llvm::Constant *BuildVtablePtr(llvm::Constant *Vtable,
                                  const CXXRecordDecl *VtableClass,
@@ -1268,14 +1272,17 @@
         // FIXME: Slightly too many of these for __ZTT8test8_B2
         llvm::Constant *init;
         if (BaseMorallyVirtual)
-          init = BuildVtablePtr(vtbl, VtblClass, RD, Offset);
+          init = GenerateDefinition ? 
+            BuildVtablePtr(vtbl, VtblClass, RD, Offset) : 0;
         else {
-          init = CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset);
+          init = GenerateDefinition ?
+            CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset) : 0;
           
           subvtbl = init;
           subVtblClass = Base;
           
-          init = BuildVtablePtr(init, Class, Base, BaseOffset);
+          init = GenerateDefinition ?
+          BuildVtablePtr(init, Class, Base, BaseOffset) : 0;
         }
         Inits.push_back(init);
       }
@@ -1294,14 +1301,16 @@
 
     // First comes the primary virtual table pointer...
     if (MorallyVirtual) {
-      Vtable = ClassVtbl;
+      Vtable = GenerateDefinition ? ClassVtbl : 0;
       VtableClass = Class;
     } else {
-      Vtable = CGM.getVtableInfo().getCtorVtable(Class, RD, Offset);
+      Vtable = GenerateDefinition ? 
+        CGM.getVtableInfo().getCtorVtable(Class, RD, Offset) : 0;
       VtableClass = RD;
     }
     
-    llvm::Constant *Init = BuildVtablePtr(Vtable, VtableClass, RD, Offset);
+    llvm::Constant *Init = GenerateDefinition ?
+      BuildVtablePtr(Vtable, VtableClass, RD, Offset) : 0;
     Inits.push_back(Init);
 
     // then the secondary VTTs....
@@ -1324,6 +1333,10 @@
         continue;
       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
       uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base);
+      
+      // Remember the sub-VTT index.
+      SubVTTIndicies[Base] = Inits.size();
+
       BuildVTT(Base, BaseOffset, MorallyVirtual);
     }
   }
@@ -1336,6 +1349,9 @@
       const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       if (i->isVirtual() && !SeenVBase.count(Base)) {
+        // Remember the sub-VTT index.
+        SubVTTIndicies[Base] = Inits.size();
+
         SeenVBase.insert(Base);
         uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
         BuildVTT(Base, BaseOffset, true);
@@ -1346,15 +1362,18 @@
 
 public:
   VTTBuilder(std::vector<llvm::Constant *> &inits, const CXXRecordDecl *c,
-             CodeGenModule &cgm)
+             CodeGenModule &cgm, bool GenerateDefinition)
     : Inits(inits), Class(c), CGM(cgm),
       BLayout(cgm.getContext().getASTRecordLayout(c)),
       AddressPoints(*cgm.AddressPoints[c]),
-      VMContext(cgm.getModule().getContext()) {
+      VMContext(cgm.getModule().getContext()),
+      GenerateDefinition(GenerateDefinition) {
     
     // First comes the primary virtual table pointer for the complete class...
     ClassVtbl = CGM.getVtableInfo().getVtable(Class);
-    Inits.push_back(BuildVtablePtr(ClassVtbl, Class, Class, 0));
+    llvm::Constant *Init = GenerateDefinition ? 
+      BuildVtablePtr(ClassVtbl, Class, Class, 0) : 0;
+    Inits.push_back(Init);
     
     // then the secondary VTTs...
     SecondaryVTTs(Class);
@@ -1365,11 +1384,16 @@
     // and last, the virtual VTTs.
     VirtualVTTs(Class);
   }
+  
+  llvm::DenseMap<const CXXRecordDecl *, uint64_t> &getSubVTTIndicies() {
+    return SubVTTIndicies;
+  }
 };
 }
 
 llvm::GlobalVariable *
 CGVtableInfo::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
+                          bool GenerateDefinition,
                           const CXXRecordDecl *RD) {
   // Only classes that have virtual bases need a VTT.
   if (RD->getNumVBases() == 0)
@@ -1379,23 +1403,36 @@
   CGM.getMangleContext().mangleCXXVTT(RD, OutName);
   llvm::StringRef Name = OutName.str();
 
-
   D1(printf("vtt %s\n", RD->getNameAsCString()));
 
-  std::vector<llvm::Constant *> inits;
-  VTTBuilder b(inits, RD, CGM);
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  if (GV == 0 || GV->isDeclaration()) {
+    const llvm::Type *Int8PtrTy = 
+      llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
 
-  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-  const llvm::ArrayType *Type = llvm::ArrayType::get(Int8PtrTy, inits.size());
-  
-  llvm::Constant *Init = llvm::ConstantArray::get(Type, inits);
-  
-  llvm::GlobalVariable *VTT = 
-    new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
-                             Linkage, Init, Name);
-  CGM.setGlobalVisibility(VTT, RD);
+    std::vector<llvm::Constant *> inits;
+    VTTBuilder b(inits, RD, CGM, GenerateDefinition);
+
+    const llvm::ArrayType *Type = llvm::ArrayType::get(Int8PtrTy, inits.size());
+    llvm::Constant *Init = 0;
+    if (GenerateDefinition)
+      Init = llvm::ConstantArray::get(Type, inits);
+
+    llvm::GlobalVariable *OldGV = GV;
+    GV = new llvm::GlobalVariable(CGM.getModule(), Type, /*isConstant=*/true, 
+                                  Linkage, Init, Name);
+    CGM.setGlobalVisibility(GV, RD);
+    
+    if (OldGV) {
+      GV->takeName(OldGV);
+      llvm::Constant *NewPtr = 
+        llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+      OldGV->replaceAllUsesWith(NewPtr);
+      OldGV->eraseFromParent();
+    }
+  }
   
-  return VTT;
+  return GV;
 }
 
 void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
@@ -1407,7 +1444,7 @@
   }
   
   Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0);
-  GenerateVTT(Linkage, RD);  
+  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);  
 }
 
 llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
@@ -1428,6 +1465,13 @@
                         LayoutClass, RD, Offset);
 }
 
+llvm::GlobalVariable *CGVtableInfo::getVTT(const CXXRecordDecl *RD) {
+  return GenerateVTT(llvm::GlobalValue::ExternalLinkage, 
+                     /*GenerateDefinition=*/false, RD);
+  
+}
+
+
 void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
   const CXXRecordDecl *RD = MD->getParent();
@@ -1443,16 +1487,6 @@
     // We don't have the right key function.
     if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
       return;
-    
-    // If the key function is a destructor, we only want to emit the vtable 
-    // once, so do it for the complete destructor.
-    if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Complete)
-      return;
-  } else {
-    // If there is no key function, we only want to emit the vtable if we are
-    // emitting a constructor.
-    if (!isa<CXXConstructorDecl>(MD) || GD.getCtorType() != Ctor_Complete)
-      return;
   }
 
   llvm::GlobalVariable::LinkageTypes Linkage;
@@ -1479,3 +1513,47 @@
   }
 }
 
+bool CGVtableInfo::needsVTTParameter(GlobalDecl GD) {
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
+  
+  // We don't have any virtual bases, just return early.
+  if (!MD->getParent()->getNumVBases())
+    return false;
+  
+  // Check if we have a base constructor.
+  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
+    return true;
+
+  // Check if we have a base destructor.
+  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
+    return true;
+  
+  return false;
+}
+
+uint64_t CGVtableInfo::getSubVTTIndex(const CXXRecordDecl *RD, 
+                                      const CXXRecordDecl *Base) {
+  ClassPairTy ClassPair(RD, Base);
+
+  SubVTTIndiciesTy::iterator I = 
+    SubVTTIndicies.find(ClassPair);
+  if (I != SubVTTIndicies.end())
+    return I->second;
+  
+  std::vector<llvm::Constant *> inits;
+  VTTBuilder Builder(inits, RD, CGM, /*GenerateDefinition=*/false);
+
+  for (llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
+       Builder.getSubVTTIndicies().begin(), 
+       E = Builder.getSubVTTIndicies().end(); I != E; ++I) {
+    // Insert all indices.
+    ClassPairTy ClassPair(RD, I->first);
+    
+    SubVTTIndicies.insert(std::make_pair(ClassPair, I->second));
+  }
+    
+  I = SubVTTIndicies.find(ClassPair);
+  assert(I != SubVTTIndicies.end() && "Did not find index!");
+  
+  return I->second;
+}

Modified: cfe/trunk/lib/CodeGen/CGVtable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.h?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Fri Jan  1 19:01:18 2010
@@ -93,6 +93,9 @@
   SavedAdjustmentsTy SavedAdjustments;
   llvm::DenseSet<const CXXRecordDecl*> SavedAdjustmentRecords;
 
+  typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesTy;
+  SubVTTIndiciesTy SubVTTIndicies;
+
   /// getNumVirtualFunctionPointers - Return the number of virtual function
   /// pointers in the vtable for a given record decl.
   uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
@@ -113,12 +116,22 @@
                  const CXXRecordDecl *RD, uint64_t Offset);
 
   llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
+                                    bool GenerateDefinition,
                                     const CXXRecordDecl *RD);
 
 public:
   CGVtableInfo(CodeGenModule &CGM)
     : CGM(CGM) { }
 
+  /// needsVTTParameter - Return whether the given global decl needs a VTT
+  /// parameter, which it does if it's a base constructor or destructor with
+  /// virtual bases.
+  static bool needsVTTParameter(GlobalDecl GD);
+
+  /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
+  /// given record decl.
+  uint64_t getSubVTTIndex(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
+  
   /// getMethodVtableIndex - Return the index (relative to the vtable address
   /// point) where the function pointer for the given virtual function is
   /// stored.
@@ -144,6 +157,7 @@
                                       const CXXRecordDecl *Class, 
                                       uint64_t Offset);
   
+  llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
   
   void MaybeEmitVtable(GlobalDecl GD);
 };

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Jan  1 19:01:18 2010
@@ -230,26 +230,7 @@
   }
 }
 
-static bool NeedsVTTParameter(GlobalDecl GD) {
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
-  
-  // We don't have any virtual bases, just return early.
-  if (!MD->getParent()->getNumVBases())
-    return false;
-  
-  // Check if we have a base constructor.
-  if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
-    return true;
-
-  // Check if we have a base destructor.
-  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
-    return true;
-  
-  return false;
-}
-
-void CodeGenFunction::GenerateCode(GlobalDecl GD,
-                                   llvm::Function *Fn) {
+void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
   
   // Check if we should generate debug info for this function.
@@ -271,7 +252,7 @@
       Args.push_back(std::make_pair(CXXThisDecl, CXXThisDecl->getType()));
       
       // Check if we need a VTT parameter as well.
-      if (NeedsVTTParameter(GD)) {
+      if (CGVtableInfo::needsVTTParameter(GD)) {
         // FIXME: The comment about using a fake decl above applies here too.
         QualType T = getContext().getPointerType(getContext().VoidPtrTy);
         CXXVTTDecl = 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Jan  1 19:01:18 2010
@@ -728,6 +728,10 @@
   /// generating code for an C++ member function.
   llvm::Value *LoadCXXThis();
 
+  /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
+  /// virtual bases.
+  llvm::Value *LoadCXXVTT();
+  
   /// GetAddressOfBaseClass - This function will add the necessary delta to the
   /// load of 'this' and returns address of the base class.
   // FIXME. This currently only does a derived to non-virtual base conversion.
@@ -1057,6 +1061,7 @@
                            llvm::Value *Callee,
                            ReturnValueSlot ReturnValue,
                            llvm::Value *This,
+                           llvm::Value *VTT,
                            CallExpr::const_arg_iterator ArgBeg,
                            CallExpr::const_arg_iterator ArgEnd);
   RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,

Modified: cfe/trunk/test/CodeGenCXX/constructor-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructor-template.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/constructor-template.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/constructor-template.cpp Fri Jan  1 19:01:18 2010
@@ -44,10 +44,10 @@
   delete node;
 }
 
-// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
 // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
 // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev:
 
-// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev:
 // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
 // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev:

Modified: cfe/trunk/test/CodeGenCXX/default-constructor-default-argument.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/default-constructor-default-argument.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/default-constructor-default-argument.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/default-constructor-default-argument.cpp Fri Jan  1 19:01:18 2010
@@ -5,4 +5,4 @@
 struct B : public A {};
 B x;
 
-// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1AC2Ei

Modified: cfe/trunk/test/CodeGenCXX/virtual-destructor-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-destructor-calls.cpp?rev=92409&r1=92408&r2=92409&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/virtual-destructor-calls.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virtual-destructor-calls.cpp Fri Jan  1 19:01:18 2010
@@ -8,15 +8,15 @@
   virtual ~B();
 };
 
+// Complete dtor.
+// CHECK: define void @_ZN1BD1Ev
+// CHECK: call void @_ZN1AD2Ev
+
 // Deleting dtor.
 // CHECK: define void @_ZN1BD0Ev
 // CHECK: call void @_ZN1AD2Ev
 // check: call void @_ZdlPv
 
-// Complete dtor.
-// CHECK: define void @_ZN1BD1Ev
-// CHECK: call void @_ZN1AD2Ev
-
 // Base dtor.
 // CHECK: define void @_ZN1BD2Ev
 // CHECK: call void @_ZN1AD2Ev





More information about the cfe-commits mailing list