<html><body><div style="color:#000; background-color:#fff; font-family:arial, helvetica, sans-serif;font-size:10pt"><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span><br></span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span>Sorry, my reply-all skills are lacking!</span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span><br></span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span>The problem with this is that the record builder doesn't know the value of Alignment until its done a complete pass on the layout - the double field might be right at the end of the struct.</span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span><br></span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span>Here are the modifications I've made that have allowed me to keep
 working - it passes all my tests, at least. I suppose we need to work on what's required to get this to patch-quality level :)</span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span><br></span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span>It will take me a while to get this up to quality as I'm self-employed currently and really need to spend time on my little business. Does this discussion need to be take to the commit list?</span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><span><br></span></div><div><span><div><font class="Apple-style-span" size="2">Index: RecordLayoutBuilder.cpp</font></div><div><font class="Apple-style-span" size="2">===================================================================</font></div><div><font class="Apple-style-span" size="2">--- RecordLayoutBuilder.cpp<span class="Apple-tab-span" style="white-space:pre">
        </span>(revision 134404)</font></div><div><font class="Apple-style-span" size="2">+++ RecordLayoutBuilder.cpp<span class="Apple-tab-span" style="white-space:pre">  </span>(working copy)</font></div><div><font class="Apple-style-span" size="2">@@ -722,6 +722,7 @@</font></div><div><font class="Apple-style-span" size="2">   void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); }</font></div><div><font class="Apple-style-span" size="2">   void setDataSize(uint64_t NewSize) { DataSize = NewSize; }</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span" size="2">+  CharUnits getAlignment() const { return Alignment; }</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span" size="2">   RecordLayoutBuilder(const RecordLayoutBuilder&);   // DO NOT IMPLEMENT</font></div><div><font
 class="Apple-style-span" size="2">   void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT</font></div><div><font class="Apple-style-span" size="2">@@ -1805,10 +1806,12 @@</font></div><div><font class="Apple-style-span" size="2"> namespace {</font></div><div><font class="Apple-style-span" size="2">   // This class implements layout specific to the Microsoft ABI.</font></div><div><font class="Apple-style-span" size="2">   class MSRecordLayoutBuilder : public RecordLayoutBuilder {</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">      </span>  CharUnits Alignment;</font></div><div><font class="Apple-style-span" size="2">   public:</font></div><div><font class="Apple-style-span" size="2">     MSRecordLayoutBuilder(const ASTContext& Ctx,</font></div><div><font class="Apple-style-span" size="2">-      
                    EmptySubobjectMap *EmptySubobjects) :</font></div><div><font class="Apple-style-span" size="2">-      RecordLayoutBuilder(Ctx, EmptySubobjects) {}</font></div><div><font class="Apple-style-span" size="2">+                          EmptySubobjectMap *EmptySubobjects,</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                                          </span>  CharUnits Alignment) :</font></div><div><font class="Apple-style-span" size="2">+      RecordLayoutBuilder(Ctx, EmptySubobjects), Alignment(Alignment) {}</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span" size="2">     virtual CharUnits GetVirtualPointersSize(const CXXRecordDecl *RD) const;</font></div><div><font
 class="Apple-style-span" size="2">   };</font></div><div><font class="Apple-style-span" size="2">@@ -1822,6 +1825,11 @@</font></div><div><font class="Apple-style-span" size="2">     Context.toCharUnitsFromBits(Context.Target.getPointerWidth(0));</font></div><div><font class="Apple-style-span" size="2">   if (RD->isPolymorphic() && RD->getNumVBases() > 0)</font></div><div><font class="Apple-style-span" size="2">     return 2 * PointerWidth;</font></div><div><font class="Apple-style-span" size="2">+</font></div><div><font class="Apple-style-span" size="2">+  // Align the vtable pointer to the struct alignment</font></div><div><font class="Apple-style-span" size="2">+  if (!Alignment.isZero())</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">      </span>  return
 PointerWidth.RoundUpToAlignment(Alignment);</font></div><div><font class="Apple-style-span" size="2">+</font></div><div><font class="Apple-style-span" size="2">   return PointerWidth;</font></div><div><font class="Apple-style-span" size="2"> }</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span" size="2">@@ -1851,7 +1859,8 @@</font></div><div><font class="Apple-style-span" size="2">       Builder.reset(new RecordLayoutBuilder(*this, &EmptySubobjects));</font></div><div><font class="Apple-style-span" size="2">       break;</font></div><div><font class="Apple-style-span" size="2">     case CXXABI_Microsoft:</font></div><div><font class="Apple-style-span" size="2">-      Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects));</font></div><div><font class="Apple-style-span" size="2">+  
    Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects,</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                </span>  CharUnits::Zero()));</font></div><div><font class="Apple-style-span" size="2">     }</font></div><div><font class="Apple-style-span" size="2">     // Recover resources if we crash before exiting this method.</font></div><div><font class="Apple-style-span" size="2">     llvm::CrashRecoveryContextCleanupRegistrar<RecordLayoutBuilder></font></div><div><font class="Apple-style-span" size="2">@@ -1859,10 +1868,27 @@</font></div><div><font class="Apple-style-span" size="2">     </font></div><div><font class="Apple-style-span" size="2">     Builder->Layout(RD);</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span"
 size="2">+<span class="Apple-tab-span" style="white-space:pre"> </span>if (Target.getCXXABI() == CXXABI_Microsoft &&</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                </span>Builder->getAlignment().getQuantity() > 4) {</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">           </span>// MSVC rounds the vtable pointer to the struct alignment in what must</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">               </span>// be a multi-pass operation. For now, let the builder figure out the</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                </span>// alignment and recalculate the layout once its known.</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">      
        </span>Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects,</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                 </span>Builder->getAlignment()));</font></div><div><font class="Apple-style-span" size="2">+</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">         </span>// Recover resources if we crash before exiting this method.</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">         </span>llvm::CrashRecoveryContextCleanupRegistrar<RecordLayoutBuilder></font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">                        </span>RecordBuilderCleanup(Builder.get());</font></div><div><font class="Apple-style-span" size="2">+</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span"
 style="white-space:pre">          </span>Builder->Layout(RD);</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">      </span>}</font></div><div><font class="Apple-style-span" size="2">+</font></div><div><font class="Apple-style-span" size="2">     // FIXME: This is not always correct. See the part about bitfields at</font></div><div><font class="Apple-style-span" size="2">     // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.</font></div><div><font class="Apple-style-span" size="2">     // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.</font></div><div><font class="Apple-style-span" size="2">-    bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">      </span>// This does
 not affect the calculations of MSVC layouts</font></div><div><font class="Apple-style-span" size="2">+    bool IsPODForThePurposeOfLayout = Target.getCXXABI() == CXXABI_Microsoft ||</font></div><div><font class="Apple-style-span" size="2">+<span class="Apple-tab-span" style="white-space:pre">              </span>cast<CXXRecordDecl>(D)->isPOD();</font></div><div><font class="Apple-style-span" size="2"> </font></div><div><font class="Apple-style-span" size="2">     // FIXME: This should be done in FinalizeLayout.</font></div><div><font class="Apple-style-span" size="2">     CharUnits DataSize =</font></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><br></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><br></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; ">Cheers,</div><div style="font-family: arial, helvetica, sans-serif;
 font-size: 10pt; ">- Don</div></span></div><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; "><br></div><div style="font-size: 10pt; font-family: arial, helvetica, sans-serif; "><div style="font-size: 12pt; font-family: 'times new roman', 'new york', times, serif; "><font size="2" face="Arial"><hr size="1"><b><span style="font-weight:bold;">From:</span></b> John McCall <rjmccall@apple.com><br><b><span style="font-weight: bold;">To:</span></b> Don Williamson <don.williamson@yahoo.com><br><b><span style="font-weight: bold;">Sent:</span></b> Tuesday, September 6, 2011 6:03 PM<br><b><span style="font-weight: bold;">Subject:</span></b> Re: [cfe-dev] Different class layouts between clang and MSVC<br></font><br><meta http-equiv="x-dns-prefetch-control" content="off"><div id="yiv296736323"><div><div>On Sep 6, 2011, at 9:36 AM, Don Williamson wrote:</div><blockquote type="cite"><div><div style="color: rgb(0, 0, 0);
 background-color: rgb(255, 255, 255); font-size: 10pt; font-family: arial, helvetica, sans-serif; "><div><span>Who would I talk to about implementation details? The only way I can think of fixing the virtual issue that doesn't duplicate code or bother existing behaviour to much is to check and see if Alignment is bigger than PointerWidth and rebuild the layout with a vtable ptr size of PointerWidth*2 (MS ABI only).</span></div></div></div></blockquote><div><br></div><div>My guess is that you should actually round up to Alignment after doing the vtable;  try adding something 16-byte aligned.  Basically, I'm guessing that MSVC is laying things out as if the class data were an independent struct following the vtable.</div><div><br></div><div>Feel free to just propose the simplest patch that achieves this;  maybe a simpler solution will present itself.</div><div><br></div><div>John.</div></div></div><meta http-equiv="x-dns-prefetch-control"
 content="on"><br><br></div></div></div></body></html>