<div dir="ltr">Thanks, done in r183251.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jun 4, 2013 at 1:45 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On May 29, 2013, at 11:02 AM, Reid Kleckner <<a href="mailto:reid@kleckner.net">reid@kleckner.net</a>> wrote:<br>

> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=182870&r1=182869&r2=182870&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=182870&r1=182869&r2=182870&view=diff</a><br>

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