r182870 - [ms-cxxabi] Implement MSVC virtual base adjustment

Reid Kleckner rnk at google.com
Tue Jun 4 14:33:32 PDT 2013


Thanks, done in r183251.


On Tue, Jun 4, 2013 at 1:45 PM, John McCall <rjmccall at apple.com> wrote:

> On May 29, 2013, at 11:02 AM, Reid Kleckner <reid at kleckner.net> wrote:
> > Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=182870&r1=182869&r2=182870&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed May 29 13:02:47 2013
> > @@ -48,6 +48,11 @@ public:
> >                                       llvm::Value *ptr,
> >                                       QualType type);
> >
> > +  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
> > +                                         llvm::Value *This,
> > +                                         const CXXRecordDecl *ClassDecl,
> > +                                         const CXXRecordDecl
> *BaseClassDecl);
> > +
> >   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
> >                                  CXXCtorType Type,
> >                                  CanQualType &ResTy,
> > @@ -142,6 +147,22 @@ private:
> >   GetNullMemberPointerFields(const MemberPointerType *MPT,
> >                              llvm::SmallVectorImpl<llvm::Constant *>
> &fields);
> >
> > +  /// \brief Finds the offset from the base of RD to the vbptr it uses,
> even if
> > +  /// it is reusing a vbptr from a non-virtual base.  RD must have
> morally
> > +  /// virtual bases.
> > +  CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD);
> > +
> > +  /// \brief Shared code for virtual base adjustment.  Returns the
> offset from
> > +  /// the vbptr to the virtual base.  Optionally returns the address of
> the
> > +  /// vbptr itself.
> > +  llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
> > +                                       llvm::Value *Base,
> > +                                       llvm::Value *VBPtrOffset,
> > +                                       llvm::Value *VBTableOffset,
> > +                                       llvm::Value **VBPtr = 0);
> > +
> > +  /// \brief Performs a full virtual base adjustment.  Used to
> dereference
> > +  /// pointers to members of virtual bases.
> >   llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const
> CXXRecordDecl *RD,
> >                                  llvm::Value *Base,
> >                                  llvm::Value
> *VirtualBaseAdjustmentOffset,
> > @@ -212,6 +233,68 @@ llvm::Value *MicrosoftCXXABI::adjustToCo
> >   return ptr;
> > }
> >
> > +CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl
> *RD) {
> > +  assert(RD->getNumVBases());
> > +  CharUnits Total = CharUnits::Zero();
> > +  while (RD) {
> > +    const ASTRecordLayout &RDLayout =
> getContext().getASTRecordLayout(RD);
> > +    CharUnits VBPtrOffset = RDLayout.getVBPtrOffset();
> > +    // -1 is the sentinel for no vbptr.
> > +    if (VBPtrOffset != CharUnits::fromQuantity(-1)) {
> > +      Total += VBPtrOffset;
> > +      break;
> > +    }
> > +
> > +    // RD is reusing the vbptr of a non-virtual base.  Find it and
> continue.
> > +    const CXXRecordDecl *FirstNVBaseWithVBases = 0;
> > +    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
> > +         E = RD->bases_end(); I != E; ++I) {
> > +      const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
> > +      if (!I->isVirtual() && Base->getNumVBases() > 0) {
> > +        FirstNVBaseWithVBases = Base;
> > +        break;
> > +      }
> > +    }
> > +    assert(FirstNVBaseWithVBases);
>
> Please break this out into a function and use llvm_unreachable in the
> fall-out case.
>
> > +    Total += RDLayout.getBaseClassOffset(FirstNVBaseWithVBases);
> > +    RD = FirstNVBaseWithVBases;
> > +  }
> > +  return Total;
> > +}
> > +
> > +llvm::Value *
> > +MicrosoftCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
> > +                                           llvm::Value *This,
> > +                                           const CXXRecordDecl
> *ClassDecl,
> > +                                           const CXXRecordDecl
> *BaseClassDecl) {
> > +  int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity();
> > +  llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy,
> VBPtrChars);
> > +
> > +  // The vbtable is an array of i32 offsets.  The first entry is a self
> entry,
> > +  // and the rest are offsets from the vbptr to virtual bases.  The
> bases are
> > +  // ordered the same way our vbases are ordered: as they appear in a
> > +  // left-to-right depth-first search of the hierarchy.
> > +  unsigned VBTableIndex = 1;  // Start with one to skip the self entry.
> > +  for (CXXRecordDecl::base_class_const_iterator I =
> ClassDecl->vbases_begin(),
> > +       E = ClassDecl->vbases_end(); I != E; ++I) {
> > +    if (I->getType()->getAsCXXRecordDecl() == BaseClassDecl)
> > +      break;
> > +    VBTableIndex++;
> > +  }
> > +  assert(VBTableIndex != 1 + ClassDecl->getNumVBases() &&
> > +         "BaseClassDecl must be a vbase of ClassDecl");
>
> Same.
>
> Otherwise looks fine.
>
> John.
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130604/e6eda777/attachment.html>


More information about the cfe-commits mailing list