<div dir="ltr">On Thu, Mar 21, 2013 at 9:45 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="im"><div>On Mar 21, 2013, at 6:19 PM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:</div>
<blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">



+  // FIXME: Emit a pair of {vbtable offset, field offset} when we know vbtable<br>
+  // layout.<br>
+  return GetBogusMemberPointer(QualType(MPT, 0));<br>
<br>
I don't think this ever actually comes up here.  If it did, you'd need a<br>
totally different interface anyway.<br></blockquote><div><br></div><div>Yeah, we do need a different interface.  Testing this case hits assertions.</div></div></div></div></blockquote><div><br></div></div>Oh, sorry, this case *will* come up, but only with a "null" vbtable offset.</div>
<div>The trick is that &A::foo always has the type of the actual member;  the type</div><div>"A" only matters for lookup.</div><div><br></div><div>That is, if you have:</div><div>  struct A { int x, y; };</div>
<div>  struct B : virtual A { int z; };</div><div>then "&B::x" has type int A::*.  (This is supposed to ignore using decls, too.)</div><div><br></div><div>Therefore, when you're forming a member pointer constant from a field,</div>
<div>the constant itself will always refer to a direct member of the base type of the</div><div>member pointer type.  That doesn't mean you can't have member pointer</div><div>constants that have vbase-offset fields — case in point, &B::z — but it does</div>
<div>mean that those fields will always be the null value.</div><div><br></div><div>That's assuming that MSVC follows the language rules about the type of a</div><div>member pointer constant, of course.</div><div><br>
</div><div><div class="im"><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+  // For member data pointers, this is just a check against -1 or 0.<br>
+  if (MPT->isMemberDataPointer()) {<br>
+    assert(MemPtr->getType() == getPtrDiffTy());<br>
+    llvm::Constant *Val = getNullMemberDataPointer(MPT);<br>
+    return Builder.CreateICmpNE(MemPtr, Val, "memptr.tobool");<br>
+  }<br>
<br>
You forgot the virtual inheritance case here.<br></blockquote><div><br></div><div>OK, fixed, that will issue an error instead of asserting now.</div></div></div></div></blockquote><div><br></div></div><div class="im"><blockquote type="cite">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">I haven't figured out exactly how to do this with a virtual base yet, and Timur says that Clang currently has very little support for virtual inheritance.  I'd rather handle simple member data pointers that are just offsets first, and then come back when we tackle virtual inheritance.</div>
</div></div></blockquote><div><br></div></div>Okay.  I mean, to me it makes sense to get easy cases out of the way while</div><div>you're thinking about them, but it's ultimately up to you.</div><div><br></div><div>
I'm pretty sure that the way that this works with virtual bases work is that, if</div><div>the vbase offset field isn't null (and I'm not sure what that null value is), then</div><div>it's an offset within the primary vbtbl for the class.  So you ask the record</div>
<div>layout for the offset of the vbtbl, load the vbtbl, add the offset, load a size_t</div><div>out of that, and then just add that to the non-virtual offset.</div></div></blockquote><div><br></div><div style>Yes, this sounds right to me.</div>
<div style><br></div><div style>I'm just not confident in my ability to encode it correctly in LLVM IR without spending more time writing tests that confirm compatibility with MSVC.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div>What this implies is that the act of converting member pointers between</div><div>classes that don't use the same primary vbtbl potentially involves a</div><div>case-by-case conversion between vbase offsets ("for offset 0, use offset 4;</div>
<div>for offset 4, use offset 12;  for offset 8, use offset 0"), because there's no</div><div>fixed relationship between the order of vbases in different vbtbls.</div></div></blockquote><div style><br></div><div style>
That sounds exciting. </div></div></div></div>