<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">This patch causes a test failure in a win64 buildbot.<div><br></div><div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">C:\public\win64\src\tools\clang\test\CodeGenCXX\microsoft-abi-multiple-nonvirtual-inheritance.cpp:165:12: error: expected string not found in input</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %this1 to [1 x i8*]**</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> ^</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> <stdin>:168:36: note: scanning from here</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> %2 = load %struct.ChildOverride** %1</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> ^</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> <stdin>:175:2: note: possible intended match here</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> %9 = bitcast %struct.ChildOverride* %2 to [1 x i8*]**</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> ^</div><div><br></div><div><br></div><div>- Fariborz</div><div><br></div><div><div>On Sep 27, 2013, at 7:48 AM, Timur Iskhodzhanov <<a href="mailto:timurrrr@google.com">timurrrr@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Author: timurrrr<br>Date: Fri Sep 27 09:48:01 2013<br>New Revision: 191523<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191523&view=rev">http://llvm.org/viewvc/llvm-project?rev=191523&view=rev</a><br>Log:<br>Abstract out the emission of vtables, add basic support for vtable emission when using -cxx-abi microsoft<br><br>Reviewed at <a href="http://llvm-reviews.chandlerc.com/D1532">http://llvm-reviews.chandlerc.com/D1532</a><br><br>Added:<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp<br>Modified:<br> cfe/trunk/include/clang/AST/Mangle.h<br> cfe/trunk/include/clang/AST/VTableBuilder.h<br> cfe/trunk/lib/AST/ItaniumMangle.cpp<br> cfe/trunk/lib/AST/MicrosoftMangle.cpp<br> cfe/trunk/lib/AST/VTableBuilder.cpp<br> cfe/trunk/lib/CodeGen/CGCXX.cpp<br> cfe/trunk/lib/CodeGen/CGCXXABI.h<br> cfe/trunk/lib/CodeGen/CGClass.cpp<br> cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br> cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br> cfe/trunk/lib/CodeGen/CGVTT.cpp<br> cfe/trunk/lib/CodeGen/CGVTables.cpp<br> cfe/trunk/lib/CodeGen/CGVTables.h<br> cfe/trunk/lib/CodeGen/CodeGenModule.h<br> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp<br> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp<br> cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp<br> cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp<br><br>Modified: cfe/trunk/include/clang/AST/Mangle.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Mangle.h?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Mangle.h?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/AST/Mangle.h (original)<br>+++ cfe/trunk/include/clang/AST/Mangle.h Fri Sep 27 09:48:01 2013<br>@@ -106,8 +106,16 @@ public:<br> raw_ostream &) = 0;<br> virtual void mangleReferenceTemporary(const VarDecl *D,<br> raw_ostream &) = 0;<br>+ // FIXME: Some of these objects only exist in select ABIs. We should probably<br>+ // only declare them in ABI-specific manglers?<br> virtual void mangleCXXVTable(const CXXRecordDecl *RD,<br> raw_ostream &) = 0;<br>+ /// \brief Mangle vftable symbols. Only a subset of the bases along the path<br>+ /// to the vftable are included in the name. It's up to the caller to pick<br>+ /// them correctly.<br>+ virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,<br>+ ArrayRef<const CXXRecordDecl *> BasePath,<br>+ raw_ostream &Out) = 0;<br> virtual void mangleCXXVTT(const CXXRecordDecl *RD,<br> raw_ostream &) = 0;<br> /// \brief Mangle vbtable symbols. Only a subset of the bases along the path<br><br>Modified: cfe/trunk/include/clang/AST/VTableBuilder.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/VTableBuilder.h?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/VTableBuilder.h?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/AST/VTableBuilder.h (original)<br>+++ cfe/trunk/include/clang/AST/VTableBuilder.h Fri Sep 27 09:48:01 2013<br>@@ -329,13 +329,6 @@ public:<br> VTableContext(ASTContext &Context);<br> ~VTableContext();<br><br>- bool isMicrosoftABI() const {<br>- // FIXME: Currently, this method is only used in the VTableContext and<br>- // VTableBuilder code which is ABI-specific. Probably we can remove it<br>- // when we add a layer of abstraction for vtable generation.<br>- return IsMicrosoftABI;<br>- }<br>-<br> const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) {<br> computeVTableRelatedInformation(RD);<br> assert(VTableLayouts.count(RD) && "No layout for this record decl!");<br>@@ -377,11 +370,13 @@ unsigned GetVBTableIndex(const CXXRecord<br> struct VFPtrInfo {<br> typedef SmallVector<const CXXRecordDecl *, 1> BasePath;<br><br>+ // Don't pass the PathToMangle as it should be calculated later.<br> VFPtrInfo(CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr)<br> : VBTableIndex(0), LastVBase(0), VFPtrOffset(VFPtrOffset),<br> PathToBaseWithVFPtr(PathToBaseWithVFPtr), VFPtrFullOffset(VFPtrOffset) {<br> }<br><br>+ // Don't pass the PathToMangle as it should be calculated later.<br> VFPtrInfo(uint64_t VBTableIndex, const CXXRecordDecl *LastVBase,<br> CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr,<br> CharUnits VFPtrFullOffset)<br>@@ -404,9 +399,13 @@ struct VFPtrInfo {<br> CharUnits VFPtrOffset;<br><br> /// This holds the base classes path from the complete type to the first base<br>- /// with the given vfptr offset.<br>+ /// with the given vfptr offset, in the base-to-derived order.<br> BasePath PathToBaseWithVFPtr;<br><br>+ /// This holds the subset of records that need to be mangled into the vftable<br>+ /// symbol name in order to get a unique name, in the derived-to-base order.<br>+ BasePath PathToMangle;<br>+<br> /// This is the full offset of the vfptr from the start of the complete type.<br> CharUnits VFPtrFullOffset;<br> };<br><br>Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Sep 27 09:48:01 2013<br>@@ -137,6 +137,9 @@ public:<br> raw_ostream &);<br> void mangleCXXVTable(const CXXRecordDecl *RD,<br> raw_ostream &);<br>+ void mangleCXXVFTable(const CXXRecordDecl *Derived,<br>+ ArrayRef<const CXXRecordDecl *> BasePath,<br>+ raw_ostream &Out);<br> void mangleCXXVTT(const CXXRecordDecl *RD,<br> raw_ostream &);<br> void mangleCXXVBTable(const CXXRecordDecl *Derived,<br>@@ -3772,6 +3775,14 @@ void ItaniumMangleContext::mangleCXXVTab<br> Mangler.mangleNameOrStandardSubstitution(RD);<br> }<br><br>+void<br>+ItaniumMangleContext::mangleCXXVFTable(const CXXRecordDecl *Derived,<br>+ ArrayRef<const CXXRecordDecl *> BasePath,<br>+ raw_ostream &Out) {<br>+ llvm_unreachable(<br>+ "The Itanium C++ ABI does not have vftables (use vtables instead)!");<br>+}<br>+<br> void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,<br> raw_ostream &Out) {<br> // <special-name> ::= TT <type> # VTT structure<br><br>Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)<br>+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Sep 27 09:48:01 2013<br>@@ -188,6 +188,9 @@ public:<br> raw_ostream &);<br> virtual void mangleCXXVTable(const CXXRecordDecl *RD,<br> raw_ostream &);<br>+ virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,<br>+ ArrayRef<const CXXRecordDecl *> BasePath,<br>+ raw_ostream &Out);<br> virtual void mangleCXXVTT(const CXXRecordDecl *RD,<br> raw_ostream &);<br> virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,<br>@@ -1900,16 +1903,26 @@ void MicrosoftMangleContext::mangleCXXDt<br><br> void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,<br> raw_ostream &Out) {<br>+ llvm_unreachable(<br>+ "The Microsoft C++ ABI does not have vtables (use vftables instead)!");<br>+}<br>+<br>+void MicrosoftMangleContext::mangleCXXVFTable(<br>+ const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,<br>+ raw_ostream &Out) {<br> // <mangled-name> ::= ?_7 <class-name> <storage-class><br> // <cvr-qualifiers> [<name>] @<br> // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class><br> // is always '6' for vftables.<br> MicrosoftCXXNameMangler Mangler(*this, Out);<br> Mangler.getStream() << "\01??_7";<br>- Mangler.mangleName(RD);<br>- Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.<br>- // TODO: If the class has more than one vtable, mangle in the class it came<br>- // from.<br>+ Mangler.mangleName(Derived);<br>+ Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.<br>+ for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(),<br>+ E = BasePath.end();<br>+ I != E; ++I) {<br>+ Mangler.mangleName(*I);<br>+ }<br> Mangler.getStream() << '@';<br> }<br><br><br>Modified: cfe/trunk/lib/AST/VTableBuilder.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/AST/VTableBuilder.cpp (original)<br>+++ cfe/trunk/lib/AST/VTableBuilder.cpp Fri Sep 27 09:48:01 2013<br>@@ -999,10 +999,6 @@ public:<br> dumpLayout(llvm::errs());<br> }<br><br>- bool isMicrosoftABI() const {<br>- return VTables.isMicrosoftABI();<br>- }<br>-<br> uint64_t getNumThunks() const {<br> return Thunks.size();<br> }<br>@@ -1157,7 +1153,7 @@ void VTableBuilder::ComputeThisAdjustmen<br> // Add it.<br> VTableThunks[VTableIndex].This = ThisAdjustment;<br><br>- if (isa<CXXDestructorDecl>(MD) && !isMicrosoftABI()) {<br>+ if (isa<CXXDestructorDecl>(MD)) {<br> // Add an adjustment for the deleting destructor as well.<br> VTableThunks[VTableIndex + 1].This = ThisAdjustment;<br> }<br>@@ -1188,8 +1184,6 @@ void VTableBuilder::ComputeThisAdjustmen<br> break;<br> case VTableComponent::CK_DeletingDtorPointer:<br> // We've already added the thunk when we saw the complete dtor pointer.<br>- // FIXME: check how this works in the Microsoft ABI<br>- // while working on the multiple inheritance patch.<br> continue;<br> }<br><br>@@ -1326,15 +1320,9 @@ VTableBuilder::AddMethod(const CXXMethod<br> assert(ReturnAdjustment.isEmpty() && <br> "Destructor can't have return adjustment!");<br><br>- // FIXME: Should probably add a layer of abstraction for vtable generation.<br>- if (!isMicrosoftABI()) {<br>- // Add both the complete destructor and the deleting destructor.<br>- Components.push_back(VTableComponent::MakeCompleteDtor(DD));<br>- Components.push_back(VTableComponent::MakeDeletingDtor(DD));<br>- } else {<br>- // Add the scalar deleting destructor.<br>- Components.push_back(VTableComponent::MakeDeletingDtor(DD));<br>- }<br>+ // Add both the complete destructor and the deleting destructor.<br>+ Components.push_back(VTableComponent::MakeCompleteDtor(DD));<br>+ Components.push_back(VTableComponent::MakeDeletingDtor(DD));<br> } else {<br> // Add the return adjustment if necessary.<br> if (!ReturnAdjustment.isEmpty())<br>@@ -1693,18 +1681,12 @@ VTableBuilder::LayoutPrimaryAndSecondary<br> if (Base.getBase() == MostDerivedClass)<br> VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();<br><br>- // FIXME: Should probably add a layer of abstraction for vtable generation.<br>- if (!isMicrosoftABI()) {<br>- // Add the offset to top.<br>- CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;<br>- Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));<br>+ // Add the offset to top.<br>+ CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;<br>+ Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));<br><br>- // Next, add the RTTI.<br>- Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));<br>- } else {<br>- // FIXME: unclear what to do with RTTI in MS ABI as emitting it anywhere<br>- // breaks the vftable layout. Just skip RTTI for now, can't mangle anyway.<br>- }<br>+ // Next, add the RTTI.<br>+ Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));<br><br> uint64_t AddressPoint = Components.size();<br><br>@@ -1722,16 +1704,10 @@ VTableBuilder::LayoutPrimaryAndSecondary<br> const CXXMethodDecl *MD = I->first;<br> const MethodInfo &MI = I->second;<br> if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {<br>- // FIXME: Should probably add a layer of abstraction for vtable generation.<br>- if (!isMicrosoftABI()) {<br>- MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]<br>- = MI.VTableIndex - AddressPoint;<br>- MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]<br>- = MI.VTableIndex + 1 - AddressPoint;<br>- } else {<br>- MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]<br>- = MI.VTableIndex - AddressPoint;<br>- }<br>+ MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]<br>+ = MI.VTableIndex - AddressPoint;<br>+ MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]<br>+ = MI.VTableIndex + 1 - AddressPoint;<br> } else {<br> MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;<br> }<br>@@ -2044,8 +2020,6 @@ void VTableBuilder::dumpLayout(raw_ostre<br> Out << DD->getQualifiedNameAsString();<br> if (IsComplete)<br> Out << "() [complete]";<br>- else if (isMicrosoftABI())<br>- Out << "() [scalar deleting]";<br> else<br> Out << "() [deleting]";<br><br>@@ -2230,18 +2204,11 @@ void VTableBuilder::dumpLayout(raw_ostre<br> MD);<br><br> if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {<br>- // FIXME: Should add a layer of abstraction for vtable generation.<br>- if (!isMicrosoftABI()) {<br>- GlobalDecl GD(DD, Dtor_Complete);<br>- assert(MethodVTableIndices.count(GD));<br>- uint64_t VTableIndex = MethodVTableIndices[GD];<br>- IndicesMap[VTableIndex] = MethodName + " [complete]";<br>- IndicesMap[VTableIndex + 1] = MethodName + " [deleting]";<br>- } else {<br>- GlobalDecl GD(DD, Dtor_Deleting);<br>- assert(MethodVTableIndices.count(GD));<br>- IndicesMap[MethodVTableIndices[GD]] = MethodName + " [scalar deleting]";<br>- }<br>+ GlobalDecl GD(DD, Dtor_Complete);<br>+ assert(MethodVTableIndices.count(GD));<br>+ uint64_t VTableIndex = MethodVTableIndices[GD];<br>+ IndicesMap[VTableIndex] = MethodName + " [complete]";<br>+ IndicesMap[VTableIndex + 1] = MethodName + " [deleting]";<br> } else {<br> assert(MethodVTableIndices.count(MD));<br> IndicesMap[MethodVTableIndices[MD]] = MethodName;<br>@@ -2352,10 +2319,12 @@ static VTableLayout *CreateVTableLayout(<br> VTableThunks.size(),<br> VTableThunks.data(),<br> Builder.getAddressPoints(),<br>- Builder.isMicrosoftABI());<br>+ /*IsMicrosoftABI=*/false);<br> }<br><br> void VTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) {<br>+ assert(!IsMicrosoftABI && "Shouldn't be called in this ABI!");<br>+<br> const VTableLayout *&Entry = VTableLayouts[RD];<br><br> // Check if we've computed this information before.<br>@@ -3132,6 +3101,55 @@ static void EnumerateVFPtrs(<br> }<br> }<br><br>+/// CalculatePathToMangle - Calculate the subset of records that should be used<br>+/// to mangle the vftable for the given vfptr.<br>+/// Should only be called if a class has multiple vftables.<br>+static void<br>+CalculatePathToMangle(const CXXRecordDecl *RD, VFPtrInfo &VFPtr) {<br>+ // FIXME: In some rare cases this code produces a slightly incorrect mangling.<br>+ // It's very likely that the vbtable mangling code can be adjusted to mangle<br>+ // both vftables and vbtables correctly.<br>+<br>+ VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr;<br>+ if (FullPath.empty()) {<br>+ // Mangle the class's own vftable.<br>+ assert(RD->getNumVBases() &&<br>+ "Something's wrong: if the most derived "<br>+ "class has more than one vftable, it can only have its own "<br>+ "vftable if it has vbases");<br>+ VFPtr.PathToMangle.push_back(RD);<br>+ return;<br>+ }<br>+<br>+ unsigned Begin = 0;<br>+<br>+ // First, skip all the bases before the vbase.<br>+ if (VFPtr.LastVBase) {<br>+ while (FullPath[Begin] != VFPtr.LastVBase) {<br>+ Begin++;<br>+ assert(Begin < FullPath.size());<br>+ }<br>+ }<br>+<br>+ // Then, put the rest of the base path in the reverse order.<br>+ for (unsigned I = FullPath.size(); I != Begin; --I) {<br>+ const CXXRecordDecl *CurBase = FullPath[I - 1],<br>+ *ItsBase = (I == 1) ? RD : FullPath[I - 2];<br>+ bool BaseIsVirtual = false;<br>+ for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin(),<br>+ F = ItsBase->bases_end(); J != F; ++J) {<br>+ if (J->getType()->getAsCXXRecordDecl() == CurBase) {<br>+ BaseIsVirtual = J->isVirtual();<br>+ break;<br>+ }<br>+ }<br>+<br>+ // Should skip the current base if it is a non-virtual base with no siblings.<br>+ if (BaseIsVirtual || ItsBase->getNumBases() != 1)<br>+ VFPtr.PathToMangle.push_back(CurBase);<br>+ }<br>+}<br>+<br> static void EnumerateVFPtrs(ASTContext &Context, const CXXRecordDecl *ForClass,<br> MicrosoftVFTableContext::VFPtrListTy &Result) {<br> Result.clear();<br>@@ -3140,6 +3158,10 @@ static void EnumerateVFPtrs(ASTContext &<br> EnumerateVFPtrs(Context, ForClass, ClassLayout,<br> BaseSubobject(ForClass, CharUnits::Zero()), 0,<br> VFPtrInfo::BasePath(), VisitedVBases, Result);<br>+ if (Result.size() > 1) {<br>+ for (unsigned I = 0, E = Result.size(); I != E; ++I)<br>+ CalculatePathToMangle(ForClass, Result[I]);<br>+ }<br> }<br><br> void MicrosoftVFTableContext::computeVTableRelatedInformation(<br><br>Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Sep 27 09:48:01 2013<br>@@ -280,7 +280,7 @@ static llvm::Value *BuildAppleKextVirtua<br> "No kext in Microsoft ABI");<br> GD = GD.getCanonicalDecl();<br> CodeGenModule &CGM = CGF.CGM;<br>- llvm::Value *VTable = CGM.getVTables().GetAddrOfVTable(RD);<br>+ llvm::Value *VTable = CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());<br> Ty = Ty->getPointerTo()->getPointerTo();<br> VTable = CGF.Builder.CreateBitCast(VTable, Ty);<br> assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");<br><br>Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)<br>+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Fri Sep 27 09:48:01 2013<br>@@ -303,6 +303,29 @@ public:<br> CallExpr::const_arg_iterator ArgBeg,<br> CallExpr::const_arg_iterator ArgEnd) = 0;<br><br>+ /// Emits the VTable definitions required for the given record type.<br>+ virtual void emitVTableDefinitions(CodeGenVTables &CGVT,<br>+ const CXXRecordDecl *RD) = 0;<br>+<br>+ /// Get the address point of the vtable for the given base subobject while<br>+ /// building a constructor or a destructor. On return, NeedsVirtualOffset<br>+ /// tells if a virtual base adjustment is needed in order to get the offset<br>+ /// of the base subobject.<br>+ virtual llvm::Value *getVTableAddressPointInStructor(<br>+ CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base,<br>+ const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) = 0;<br>+<br>+ /// Get the address point of the vtable for the given base subobject while<br>+ /// building a constexpr.<br>+ virtual llvm::Constant *<br>+ getVTableAddressPointForConstExpr(BaseSubobject Base,<br>+ const CXXRecordDecl *VTableClass) = 0;<br>+<br>+ /// Get the address of the vtable for the given record decl which should be<br>+ /// used for the vptr at the given offset in RD.<br>+ virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,<br>+ CharUnits VPtrOffset) = 0;<br>+<br> /// Build a virtual function pointer in the ABI-specific way.<br> virtual llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF,<br> GlobalDecl GD,<br>@@ -319,9 +342,7 @@ public:<br> /// Emit any tables needed to implement virtual inheritance. For Itanium,<br> /// this emits virtual table tables. For the MSVC++ ABI, this emits virtual<br> /// base tables.<br>- virtual void<br>- EmitVirtualInheritanceTables(llvm::GlobalVariable::LinkageTypes Linkage,<br>- const CXXRecordDecl *RD) = 0;<br>+ virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;<br><br> virtual void EmitReturnFromThunk(CodeGenFunction &CGF,<br> RValue RV, QualType ResultType);<br><br>Modified: cfe/trunk/lib/CodeGen/CGClass.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGClass.cpp Fri Sep 27 09:48:01 2013<br>@@ -1878,39 +1878,19 @@ CodeGenFunction::InitializeVTablePointer<br> const CXXRecordDecl *NearestVBase,<br> CharUnits OffsetFromNearestVBase,<br> const CXXRecordDecl *VTableClass) {<br>- const CXXRecordDecl *RD = Base.getBase();<br>-<br> // Compute the address point.<br>- llvm::Value *VTableAddressPoint;<br>-<br>- bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CurGD);<br>-<br>- // Check if we need to use a vtable from the VTT.<br>- if (NeedsVTTParam && (RD->getNumVBases() || NearestVBase)) {<br>- // Get the secondary vpointer index.<br>- uint64_t VirtualPointerIndex = <br>- CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);<br>- <br>- /// Load the VTT.<br>- llvm::Value *VTT = LoadCXXVTT();<br>- if (VirtualPointerIndex)<br>- VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);<br>-<br>- // And load the address point from the VTT.<br>- VTableAddressPoint = Builder.CreateLoad(VTT);<br>- } else {<br>- llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(VTableClass);<br>- uint64_t AddressPoint =<br>- CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);<br>- VTableAddressPoint =<br>- Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);<br>- }<br>+ bool NeedsVirtualOffset;<br>+ llvm::Value *VTableAddressPoint =<br>+ CGM.getCXXABI().getVTableAddressPointInStructor(<br>+ *this, VTableClass, Base, NearestVBase, NeedsVirtualOffset);<br>+ if (!VTableAddressPoint)<br>+ return;<br><br> // Compute where to store the address point.<br> llvm::Value *VirtualOffset = 0;<br> CharUnits NonVirtualOffset = CharUnits::Zero();<br><br>- if (NeedsVTTParam && NearestVBase) {<br>+ if (NeedsVirtualOffset) {<br> // We need to use the virtual base offset offset because the virtual base<br> // might have a different offset in the most derived class.<br> VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this,<br><br>Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Sep 27 09:48:01 2013<br>@@ -1053,7 +1053,11 @@ CGDebugInfo::CreateCXXMemberFunction(con<br><br> // It doesn't make sense to give a virtual destructor a vtable index,<br> // since a single destructor has two entries in the vtable.<br>- if (!isa<CXXDestructorDecl>(Method))<br>+ // FIXME: Add proper support for debug info for virtual calls in<br>+ // the Microsoft ABI, where we may use multiple vptrs to make a vftable<br>+ // lookup if we have multiple or virtual inheritance.<br>+ if (!isa<CXXDestructorDecl>(Method) &&<br>+ !CGM.getTarget().getCXXABI().isMicrosoft())<br> VIndex = CGM.getVTableContext().getMethodVTableIndex(Method);<br> ContainingType = RecordTy;<br> }<br><br>Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Fri Sep 27 09:48:01 2013<br>@@ -53,9 +53,6 @@ private:<br> NextFieldOffsetInChars(CharUnits::Zero()),<br> LLVMStructAlignment(CharUnits::One()) { }<br><br>- void AppendVTablePointer(BaseSubobject Base, llvm::Constant *VTable,<br>- const CXXRecordDecl *VTableClass);<br>-<br> void AppendField(const FieldDecl *Field, uint64_t FieldOffset,<br> llvm::Constant *InitExpr);<br><br>@@ -72,8 +69,7 @@ private:<br><br> bool Build(InitListExpr *ILE);<br> void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,<br>- llvm::Constant *VTable, const CXXRecordDecl *VTableClass,<br>- CharUnits BaseOffset);<br>+ const CXXRecordDecl *VTableClass, CharUnits BaseOffset);<br> llvm::Constant *Finalize(QualType Ty);<br><br> CharUnits getAlignment(const llvm::Constant *C) const {<br>@@ -88,23 +84,6 @@ private:<br> }<br> };<br><br>-void ConstStructBuilder::AppendVTablePointer(BaseSubobject Base,<br>- llvm::Constant *VTable,<br>- const CXXRecordDecl *VTableClass) {<br>- // Find the appropriate vtable within the vtable group.<br>- uint64_t AddressPoint =<br>- CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);<br>- llvm::Value *Indices[] = {<br>- llvm::ConstantInt::get(CGM.Int64Ty, 0),<br>- llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)<br>- };<br>- llvm::Constant *VTableAddressPoint =<br>- llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);<br>-<br>- // Add the vtable at the start of the object.<br>- AppendBytes(Base.getBaseOffset(), VTableAddressPoint);<br>-}<br>-<br> void ConstStructBuilder::<br> AppendField(const FieldDecl *Field, uint64_t FieldOffset,<br> llvm::Constant *InitCst) {<br>@@ -424,15 +403,19 @@ struct BaseInfo {<br> }<br><br> void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,<br>- bool IsPrimaryBase, llvm::Constant *VTable,<br>+ bool IsPrimaryBase,<br> const CXXRecordDecl *VTableClass,<br> CharUnits Offset) {<br> const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);<br><br> if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {<br> // Add a vtable pointer, if we need one and it hasn't already been added.<br>- if (CD->isDynamicClass() && !IsPrimaryBase)<br>- AppendVTablePointer(BaseSubobject(CD, Offset), VTable, VTableClass);<br>+ if (CD->isDynamicClass() && !IsPrimaryBase) {<br>+ llvm::Constant *VTableAddressPoint =<br>+ CGM.getCXXABI().getVTableAddressPointForConstExpr(<br>+ BaseSubobject(CD, Offset), VTableClass);<br>+ AppendBytes(Offset, VTableAddressPoint);<br>+ }<br><br> // Accumulate and sort bases, in order to visit them in address order, which<br> // may not be the same as declaration order.<br>@@ -453,7 +436,7 @@ void ConstStructBuilder::Build(const APV<br><br> bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;<br> Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,<br>- VTable, VTableClass, Offset + Base.Offset);<br>+ VTableClass, Offset + Base.Offset);<br> }<br> }<br><br>@@ -560,11 +543,7 @@ llvm::Constant *ConstStructBuilder::Buil<br><br> const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();<br> const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);<br>- llvm::Constant *VTable = 0;<br>- if (CD && CD->isDynamicClass())<br>- VTable = CGM.getVTables().GetAddrOfVTable(CD);<br>-<br>- Builder.Build(Val, RD, false, VTable, CD, CharUnits::Zero());<br>+ Builder.Build(Val, RD, false, CD, CharUnits::Zero());<br><br> return Builder.Finalize(ValTy);<br> }<br><br>Modified: cfe/trunk/lib/CodeGen/CGVTT.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTT.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTT.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGVTT.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGVTT.cpp Fri Sep 27 09:48:01 2013<br>@@ -19,7 +19,8 @@ using namespace clang;<br> using namespace CodeGen;<br><br> static llvm::Constant *<br>-GetAddrOfVTTVTable(CodeGenVTables &CGVT, const CXXRecordDecl *MostDerivedClass,<br>+GetAddrOfVTTVTable(CodeGenVTables &CGVT, CodeGenModule &CGM,<br>+ const CXXRecordDecl *MostDerivedClass,<br> const VTTVTable &VTable,<br> llvm::GlobalVariable::LinkageTypes Linkage,<br> llvm::DenseMap<BaseSubobject, uint64_t> &AddressPoints) {<br>@@ -27,7 +28,7 @@ GetAddrOfVTTVTable(CodeGenVTables &CGVT,<br> assert(VTable.getBaseOffset().isZero() &&<br> "Most derived class vtable must have a zero offset!");<br> // This is a regular vtable.<br>- return CGVT.GetAddrOfVTable(MostDerivedClass);<br>+ return CGM.getCXXABI().getAddrOfVTable(MostDerivedClass, CharUnits());<br> }<br><br> return CGVT.GenerateConstructionVTable(MostDerivedClass, <br>@@ -52,7 +53,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::<br> for (const VTTVTable *i = Builder.getVTTVTables().begin(),<br> *e = Builder.getVTTVTables().end(); i != e; ++i) {<br> VTableAddressPoints.push_back(VTableAddressPointsMapTy());<br>- VTables.push_back(GetAddrOfVTTVTable(*this, RD, *i, Linkage,<br>+ VTables.push_back(GetAddrOfVTTVTable(*this, CGM, RD, *i, Linkage,<br> VTableAddressPoints.back()));<br> }<br><br>@@ -106,7 +107,7 @@ llvm::GlobalVariable *CodeGenVTables::Ge<br> StringRef Name = OutName.str();<br><br> // This will also defer the definition of the VTT.<br>- (void) GetAddrOfVTable(RD);<br>+ (void) CGM.getCXXABI().getAddrOfVTable(RD, CharUnits());<br><br> VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false);<br><br><br>Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Fri Sep 27 09:48:01 2013<br>@@ -498,6 +498,7 @@ void CodeGenVTables::EmitThunks(GlobalDe<br> // FIXME: This is a temporary solution to force generation of vftables in<br> // Microsoft ABI. Remove when we thread VFTableContext through CodeGen.<br> VFTContext->getVFPtrOffsets(MD->getParent());<br>+ return;<br> }<br><br> const VTableContext::ThunkInfoVectorTy *ThunkInfoVector =<br>@@ -629,53 +630,6 @@ CodeGenVTables::CreateVTableInitializer(<br> return llvm::ConstantArray::get(ArrayType, Inits);<br> }<br><br>-llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {<br>- llvm::GlobalVariable *&VTable = VTables[RD];<br>- if (VTable)<br>- return VTable;<br>-<br>- // Queue up this v-table for possible deferred emission.<br>- CGM.addDeferredVTable(RD);<br>-<br>- SmallString<256> OutName;<br>- llvm::raw_svector_ostream Out(OutName);<br>- CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out);<br>- Out.flush();<br>- StringRef Name = OutName.str();<br>-<br>- llvm::ArrayType *ArrayType = <br>- llvm::ArrayType::get(CGM.Int8PtrTy,<br>- VTContext.getVTableLayout(RD).getNumVTableComponents());<br>-<br>- VTable =<br>- CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, <br>- llvm::GlobalValue::ExternalLinkage);<br>- VTable->setUnnamedAddr(true);<br>- return VTable;<br>-}<br>-<br>-void<br>-CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,<br>- llvm::GlobalVariable::LinkageTypes Linkage,<br>- const CXXRecordDecl *RD) {<br>- const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);<br>-<br>- // Create and set the initializer.<br>- llvm::Constant *Init = <br>- CreateVTableInitializer(RD,<br>- VTLayout.vtable_component_begin(),<br>- VTLayout.getNumVTableComponents(),<br>- VTLayout.vtable_thunk_begin(),<br>- VTLayout.getNumVTableThunks());<br>- VTable->setInitializer(Init);<br>- <br>- // Set the correct linkage.<br>- VTable->setLinkage(Linkage);<br>- <br>- // Set the right visibility.<br>- CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable);<br>-}<br>-<br> llvm::GlobalVariable *<br> CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, <br> const BaseSubobject &Base, <br>@@ -818,35 +772,10 @@ CodeGenVTables::GenerateClassData(const<br> if (CGDebugInfo *DI = CGM.getModuleDebugInfo())<br> DI->completeClassData(RD);<br><br>- if (VFTContext.isValid()) {<br>- // FIXME: This is a temporary solution to force generation of vftables in<br>- // Microsoft ABI. Remove when we thread VFTableContext through CodeGen.<br>- VFTContext->getVFPtrOffsets(RD);<br>- }<br>-<br>- // First off, check whether we've already emitted the v-table and<br>- // associated stuff.<br>- llvm::GlobalVariable *VTable = GetAddrOfVTable(RD);<br>- if (VTable->hasInitializer())<br>- return;<br>-<br>- llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);<br>- EmitVTableDefinition(VTable, Linkage, RD);<br>-<br> if (RD->getNumVBases())<br>- CGM.getCXXABI().EmitVirtualInheritanceTables(Linkage, RD);<br>+ CGM.getCXXABI().emitVirtualInheritanceTables(RD);<br><br>- // If this is the magic class __cxxabiv1::__fundamental_type_info,<br>- // we will emit the typeinfo for the fundamental types. This is the<br>- // same behaviour as GCC.<br>- const DeclContext *DC = RD->getDeclContext();<br>- if (RD->getIdentifier() &&<br>- RD->getIdentifier()->isStr("__fundamental_type_info") &&<br>- isa<NamespaceDecl>(DC) &&<br>- cast<NamespaceDecl>(DC)->getIdentifier() &&<br>- cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&<br>- DC->getParent()->isTranslationUnit())<br>- CGM.EmitFundamentalRTTIDescriptors();<br>+ CGM.getCXXABI().emitVTableDefinitions(*this, RD);<br> }<br><br> /// At this point in the translation unit, does it appear that can we<br><br>Modified: cfe/trunk/lib/CodeGen/CGVTables.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGVTables.h (original)<br>+++ cfe/trunk/lib/CodeGen/CGVTables.h Fri Sep 27 09:48:01 2013<br>@@ -35,9 +35,6 @@ class CodeGenVTables {<br> // classes?<br> VTableContext VTContext;<br> OwningPtr<MicrosoftVFTableContext> VFTContext;<br>-<br>- /// VTables - All the vtables which have been defined.<br>- llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;<br><br> /// VTableAddressPointsMapTy - Address points for a single vtable.<br> typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;<br>@@ -65,6 +62,7 @@ class CodeGenVTables {<br> /// doesn't contain any incomplete types.<br> void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk);<br><br>+public:<br> /// CreateVTableInitializer - Create a vtable initializer for the given record<br> /// decl.<br> /// \param Components - The vtable components; this is really an array of<br>@@ -75,7 +73,6 @@ class CodeGenVTables {<br> const VTableLayout::VTableThunkTy *VTableThunks,<br> unsigned NumVTableThunks);<br><br>-public:<br> CodeGenVTables(CodeGenModule &CGM);<br><br> VTableContext &getVTableContext() { return VTContext; }<br>@@ -95,14 +92,6 @@ public:<br> /// class decl.<br> uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD);<br><br>- /// GetAddrOfVTable - Get the address of the vtable for the given record decl.<br>- llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD);<br>-<br>- /// EmitVTableDefinition - Emit the definition of the given vtable.<br>- void EmitVTableDefinition(llvm::GlobalVariable *VTable,<br>- llvm::GlobalVariable::LinkageTypes Linkage,<br>- const CXXRecordDecl *RD);<br>- <br> /// GenerateConstructionVTable - Generate a construction vtable for the given <br> /// base subobject.<br> llvm::GlobalVariable *<br><br>Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Sep 27 09:48:01 2013<br>@@ -250,7 +250,6 @@ class CodeGenModule : public CodeGenType<br><br> /// VTables - Holds information about C++ vtables.<br> CodeGenVTables VTables;<br>- friend class CodeGenVTables;<br><br> CGObjCRuntime* ObjCRuntime;<br> CGOpenCLRuntime* OpenCLRuntime;<br>@@ -915,6 +914,10 @@ public:<br><br> void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired);<br><br>+ /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the<br>+ /// builtin types.<br>+ void EmitFundamentalRTTIDescriptors();<br>+<br> /// \brief Appends Opts to the "Linker Options" metadata value.<br> void AppendLinkerOptions(StringRef Opts);<br><br>@@ -1068,10 +1071,6 @@ private:<br> /// given type.<br> void EmitFundamentalRTTIDescriptor(QualType Type);<br><br>- /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the<br>- /// builtin types.<br>- void EmitFundamentalRTTIDescriptors();<br>-<br> /// EmitDeferred - Emit any needed decls for which code generation<br> /// was deferred.<br> void EmitDeferred();<br><br>Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Sep 27 09:48:01 2013<br>@@ -34,6 +34,9 @@ using namespace CodeGen;<br><br> namespace {<br> class ItaniumCXXABI : public CodeGen::CGCXXABI {<br>+ /// VTables - All the vtables which have been defined.<br>+ llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;<br>+<br> protected:<br> bool UseARMMethodPtrABI;<br> bool UseARMGuardVarABI;<br>@@ -142,6 +145,20 @@ public:<br> CallExpr::const_arg_iterator ArgBeg,<br> CallExpr::const_arg_iterator ArgEnd);<br><br>+ void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD);<br>+<br>+ llvm::Value *getVTableAddressPointInStructor(<br>+ CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,<br>+ BaseSubobject Base, const CXXRecordDecl *NearestVBase,<br>+ bool &NeedsVirtualOffset);<br>+<br>+ llvm::Constant *<br>+ getVTableAddressPointForConstExpr(BaseSubobject Base,<br>+ const CXXRecordDecl *VTableClass);<br>+<br>+ llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,<br>+ CharUnits VPtrOffset);<br>+<br> llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,<br> llvm::Value *This, llvm::Type *Ty);<br><br>@@ -150,8 +167,7 @@ public:<br> CXXDtorType DtorType, SourceLocation CallLoc,<br> llvm::Value *This);<br><br>- void EmitVirtualInheritanceTables(llvm::GlobalVariable::LinkageTypes Linkage,<br>- const CXXRecordDecl *RD);<br>+ void emitVirtualInheritanceTables(const CXXRecordDecl *RD);<br><br> StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }<br> StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }<br>@@ -888,6 +904,113 @@ void ItaniumCXXABI::EmitConstructorCall(<br> This, VTT, VTTTy, ArgBeg, ArgEnd);<br> }<br><br>+void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,<br>+ const CXXRecordDecl *RD) {<br>+ llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());<br>+ if (VTable->hasInitializer())<br>+ return;<br>+<br>+ VTableContext &VTContext = CGM.getVTableContext();<br>+ const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);<br>+ llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);<br>+<br>+ // Create and set the initializer.<br>+ llvm::Constant *Init = CGVT.CreateVTableInitializer(<br>+ RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),<br>+ VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks());<br>+ VTable->setInitializer(Init);<br>+<br>+ // Set the correct linkage.<br>+ VTable->setLinkage(Linkage);<br>+<br>+ // Set the right visibility.<br>+ CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable);<br>+<br>+ // If this is the magic class __cxxabiv1::__fundamental_type_info,<br>+ // we will emit the typeinfo for the fundamental types. This is the<br>+ // same behaviour as GCC.<br>+ const DeclContext *DC = RD->getDeclContext();<br>+ if (RD->getIdentifier() &&<br>+ RD->getIdentifier()->isStr("__fundamental_type_info") &&<br>+ isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&<br>+ cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&<br>+ DC->getParent()->isTranslationUnit())<br>+ CGM.EmitFundamentalRTTIDescriptors();<br>+}<br>+<br>+llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(<br>+ CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,<br>+ const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {<br>+ bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.CurGD);<br>+ NeedsVirtualOffset = (NeedsVTTParam && NearestVBase);<br>+<br>+ llvm::Value *VTableAddressPoint;<br>+ if (NeedsVTTParam && (Base.getBase()->getNumVBases() || NearestVBase)) {<br>+ // Get the secondary vpointer index.<br>+ uint64_t VirtualPointerIndex =<br>+ CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);<br>+<br>+ /// Load the VTT.<br>+ llvm::Value *VTT = CGF.LoadCXXVTT();<br>+ if (VirtualPointerIndex)<br>+ VTT = CGF.Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);<br>+<br>+ // And load the address point from the VTT.<br>+ VTableAddressPoint = CGF.Builder.CreateLoad(VTT);<br>+ } else {<br>+ llvm::Constant *VTable =<br>+ CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());<br>+ uint64_t AddressPoint = CGM.getVTableContext().getVTableLayout(VTableClass)<br>+ .getAddressPoint(Base);<br>+ VTableAddressPoint =<br>+ CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);<br>+ }<br>+<br>+ return VTableAddressPoint;<br>+}<br>+<br>+llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(<br>+ BaseSubobject Base, const CXXRecordDecl *VTableClass) {<br>+ llvm::Constant *VTable = getAddrOfVTable(VTableClass, CharUnits());<br>+<br>+ // Find the appropriate vtable within the vtable group.<br>+ uint64_t AddressPoint =<br>+ CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);<br>+ llvm::Value *Indices[] = {<br>+ llvm::ConstantInt::get(CGM.Int64Ty, 0),<br>+ llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)<br>+ };<br>+<br>+ return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);<br>+}<br>+<br>+llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,<br>+ CharUnits VPtrOffset) {<br>+ assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets");<br>+<br>+ llvm::GlobalVariable *&VTable = VTables[RD];<br>+ if (VTable)<br>+ return VTable;<br>+<br>+ // Queue up this v-table for possible deferred emission.<br>+ CGM.addDeferredVTable(RD);<br>+<br>+ SmallString<256> OutName;<br>+ llvm::raw_svector_ostream Out(OutName);<br>+ CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out);<br>+ Out.flush();<br>+ StringRef Name = OutName.str();<br>+<br>+ VTableContext &VTContext = CGM.getVTableContext();<br>+ llvm::ArrayType *ArrayType = llvm::ArrayType::get(<br>+ CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents());<br>+<br>+ VTable = CGM.CreateOrReplaceCXXRuntimeVariable(<br>+ Name, ArrayType, llvm::GlobalValue::ExternalLinkage);<br>+ VTable->setUnnamedAddr(true);<br>+ return VTable;<br>+}<br>+<br> llvm::Value *ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,<br> GlobalDecl GD,<br> llvm::Value *This,<br>@@ -919,11 +1042,10 @@ void ItaniumCXXABI::EmitVirtualDestructo<br> /*ImplicitParam=*/0, QualType(), 0, 0);<br> }<br><br>-void ItaniumCXXABI::EmitVirtualInheritanceTables(<br>- llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD) {<br>+void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {<br> CodeGenVTables &VTables = CGM.getVTables();<br> llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD);<br>- VTables.EmitVTTDefinition(VTT, Linkage, RD);<br>+ VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD);<br> }<br><br> void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,<br><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=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Fri Sep 27 09:48:01 2013<br>@@ -21,6 +21,7 @@<br> #include "clang/AST/Decl.h"<br> #include "clang/AST/DeclCXX.h"<br> #include "clang/AST/VTableBuilder.h"<br>+#include "llvm/ADT/StringSet.h"<br><br> using namespace clang;<br> using namespace CodeGen;<br>@@ -150,6 +151,20 @@ public:<br> CallExpr::const_arg_iterator ArgBeg,<br> CallExpr::const_arg_iterator ArgEnd);<br><br>+ void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD);<br>+<br>+ llvm::Value *getVTableAddressPointInStructor(<br>+ CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,<br>+ BaseSubobject Base, const CXXRecordDecl *NearestVBase,<br>+ bool &NeedsVirtualOffset);<br>+<br>+ llvm::Constant *<br>+ getVTableAddressPointForConstExpr(BaseSubobject Base,<br>+ const CXXRecordDecl *VTableClass);<br>+<br>+ llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,<br>+ CharUnits VPtrOffset);<br>+<br> llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,<br> llvm::Value *This, llvm::Type *Ty);<br><br>@@ -158,8 +173,7 @@ public:<br> CXXDtorType DtorType, SourceLocation CallLoc,<br> llvm::Value *This);<br><br>- void EmitVirtualInheritanceTables(llvm::GlobalVariable::LinkageTypes Linkage,<br>- const CXXRecordDecl *RD);<br>+ void emitVirtualInheritanceTables(const CXXRecordDecl *RD);<br><br> void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,<br> llvm::GlobalVariable *DeclPtr,<br>@@ -303,7 +317,16 @@ public:<br> const MemberPointerType *MPT);<br><br> private:<br>- /// VBTables - All the vbtables which have been referenced.<br>+ typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;<br>+ typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VFTablesMapTy;<br>+ /// \brief All the vftables that have been referenced.<br>+ VFTablesMapTy VFTablesMap;<br>+<br>+ /// \brief This set holds the record decls we've deferred vtable emission for.<br>+ llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;<br>+<br>+<br>+ /// \brief All the vbtables which have been referenced.<br> llvm::DenseMap<const CXXRecordDecl *, VBTableVector> VBTablesMap;<br><br> /// Info on the global variable used to guard initialization of static locals.<br>@@ -616,6 +639,116 @@ void MicrosoftCXXABI::EmitConstructorCal<br> ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd);<br> }<br><br>+void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,<br>+ const CXXRecordDecl *RD) {<br>+ MicrosoftVFTableContext &VFTContext = CGM.getVFTableContext();<br>+ MicrosoftVFTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD);<br>+ llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);<br>+<br>+ for (MicrosoftVFTableContext::VFPtrListTy::iterator I = VFPtrs.begin(),<br>+ E = VFPtrs.end(); I != E; ++I) {<br>+ llvm::GlobalVariable *VTable = getAddrOfVTable(RD, I->VFPtrFullOffset);<br>+ if (VTable->hasInitializer())<br>+ continue;<br>+<br>+ const VTableLayout &VTLayout =<br>+ VFTContext.getVFTableLayout(RD, I->VFPtrFullOffset);<br>+ llvm::Constant *Init = CGVT.CreateVTableInitializer(<br>+ RD, VTLayout.vtable_component_begin(),<br>+ VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),<br>+ VTLayout.getNumVTableThunks());<br>+ VTable->setInitializer(Init);<br>+<br>+ VTable->setLinkage(Linkage);<br>+ CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable);<br>+ }<br>+}<br>+<br>+llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(<br>+ CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,<br>+ const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {<br>+ NeedsVirtualOffset = (NearestVBase != 0);<br>+<br>+ llvm::Value *VTableAddressPoint =<br>+ getAddrOfVTable(VTableClass, Base.getBaseOffset());<br>+ if (!VTableAddressPoint) {<br>+ assert(Base.getBase()->getNumVBases() &&<br>+ !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());<br>+ }<br>+ return VTableAddressPoint;<br>+}<br>+<br>+static void mangleVFTableName(CodeGenModule &CGM, const CXXRecordDecl *RD,<br>+ const VFPtrInfo &VFPtr, SmallString<256> &Name) {<br>+ llvm::raw_svector_ostream Out(Name);<br>+ CGM.getCXXABI().getMangleContext().mangleCXXVFTable(<br>+ RD, VFPtr.PathToMangle, Out);<br>+}<br>+<br>+llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(<br>+ BaseSubobject Base, const CXXRecordDecl *VTableClass) {<br>+ llvm::Constant *VTable = getAddrOfVTable(VTableClass, Base.getBaseOffset());<br>+ assert(VTable && "Couldn't find a vftable for the given base?");<br>+ return VTable;<br>+}<br>+<br>+llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,<br>+ CharUnits VPtrOffset) {<br>+ // getAddrOfVTable may return 0 if asked to get an address of a vtable which<br>+ // shouldn't be used in the given record type. We want to cache this result in<br>+ // VFTablesMap, thus a simple zero check is not sufficient.<br>+ VFTableIdTy ID(RD, VPtrOffset);<br>+ VFTablesMapTy::iterator I;<br>+ bool Inserted;<br>+ llvm::tie(I, Inserted) = VFTablesMap.insert(<br>+ std::make_pair(ID, static_cast<llvm::GlobalVariable *>(0)));<br>+ if (!Inserted)<br>+ return I->second;<br>+<br>+ llvm::GlobalVariable *&VTable = I->second;<br>+<br>+ MicrosoftVFTableContext &VFTContext = CGM.getVFTableContext();<br>+ const MicrosoftVFTableContext::VFPtrListTy &VFPtrs =<br>+ VFTContext.getVFPtrOffsets(RD);<br>+<br>+ if (DeferredVFTables.insert(RD)) {<br>+ // We haven't processed this record type before.<br>+ // Queue up this v-table for possible deferred emission.<br>+ CGM.addDeferredVTable(RD);<br>+<br>+#ifndef NDEBUG<br>+ // Create all the vftables at once in order to make sure each vftable has<br>+ // a unique mangled name.<br>+ llvm::StringSet<> ObservedMangledNames;<br>+ for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {<br>+ SmallString<256> Name;<br>+ mangleVFTableName(CGM, RD, VFPtrs[J], Name);<br>+ if (!ObservedMangledNames.insert(Name.str()))<br>+ llvm_unreachable("Already saw this mangling before?");<br>+ }<br>+#endif<br>+ }<br>+<br>+ for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {<br>+ if (VFPtrs[J].VFPtrFullOffset != VPtrOffset)<br>+ continue;<br>+<br>+ llvm::ArrayType *ArrayType = llvm::ArrayType::get(<br>+ CGM.Int8PtrTy,<br>+ VFTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset)<br>+ .getNumVTableComponents());<br>+<br>+ SmallString<256> Name;<br>+ mangleVFTableName(CGM, RD, VFPtrs[J], Name);<br>+ VTable = CGM.CreateOrReplaceCXXRuntimeVariable(<br>+ Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage);<br>+ VTable->setUnnamedAddr(true);<br>+ break;<br>+ }<br>+<br>+ return VTable;<br>+}<br>+<br> llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,<br> GlobalDecl GD,<br> llvm::Value *This,<br>@@ -674,9 +807,10 @@ MicrosoftCXXABI::EnumerateVBTables(const<br> return VBTables;<br> }<br><br>-void MicrosoftCXXABI::EmitVirtualInheritanceTables(<br>- llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD) {<br>+void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {<br> const VBTableVector &VBTables = EnumerateVBTables(RD);<br>+ llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);<br>+<br> for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end();<br> I != E; ++I) {<br> I->EmitVBTableDefinition(CGM, RD, Linkage);<br><br>Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp?rev=191523&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp?rev=191523&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp (added)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -0,0 +1,23 @@<br>+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s<br>+<br>+struct A {<br>+ constexpr A(int x) : x(x) {}<br>+ virtual void f();<br>+ int x;<br>+};<br>+<br>+A a(42);<br>+// CHECK: @"\01?a@@3UA@@A" = global { [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7A@@6B@", i32 42 }, align 4<br>+<br>+struct B {<br>+ constexpr B(int y) : y(y) {}<br>+ virtual void g();<br>+ int y;<br>+};<br>+<br>+struct C : A, B {<br>+ constexpr C() : A(777), B(13) {}<br>+};<br>+<br>+C c;<br>+// CHECK: @"\01?c@@3UC@@A" = global { [1 x i8*]*, i32, [1 x i8*]*, i32 } { [1 x i8*]* @"\01??_7C@@6BA@@@", i32 777, [1 x i8*]* @"\01??_7C@@6BB@@@", i32 13 }<br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -145,3 +145,39 @@ void call_grandchild_right(GrandchildOve<br> // Just make sure we don't crash.<br> obj->right();<br> }<br>+<br>+void emit_ctors() {<br>+ Left l;<br>+ // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"<br>+ // CHECK-NOT: getelementptr<br>+ // CHECK: store [1 x i8*]* @"\01??_7Left@@6B@"<br>+ // CHECK: ret<br>+<br>+ Right r;<br>+ // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"<br>+ // CHECK-NOT: getelementptr<br>+ // CHECK: store [1 x i8*]* @"\01??_7Right@@6B@"<br>+ // CHECK: ret<br>+<br>+ ChildOverride co;<br>+ // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"<br>+ // CHECK: %[[THIS:.*]] = load %struct.ChildOverride**<br>+ // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %this1 to [1 x i8*]**<br>+ // CHECK: store [1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@", [1 x i8*]** %[[VFPTR]]<br>+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*<br>+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4<br>+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [1 x i8*]**<br>+ // CHECK: store [1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@", [1 x i8*]** %[[VFPTR]]<br>+ // CHECK: ret<br>+<br>+ GrandchildOverride gc;<br>+ // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"<br>+ // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride**<br>+ // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %this1 to [1 x i8*]**<br>+ // CHECK: store [1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@", [1 x i8*]** %[[VFPTR]]<br>+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*<br>+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4<br>+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [1 x i8*]**<br>+ // CHECK: store [1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@", [1 x i8*]** %[[VFPTR]]<br>+ // CHECK: ret<br>+}<br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Fri Sep 27 09:48:01 2013<br>@@ -71,8 +71,8 @@ void C::foo() {}<br> void check_vftable_offset() {<br> C c;<br> // The vftable pointer should point at the beginning of the vftable.<br>-// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to i8***<br>-// CHECK: store i8** getelementptr inbounds ([2 x i8*]* @"\01??_7C@basic@@6B@", i64 0, i64 0), i8*** [[THIS_PTR]]<br>+// CHECK: [[THIS_PTR:%[0-9]+]] = bitcast %"struct.basic::C"* {{.*}} to [2 x i8*]**<br>+// CHECK: store [2 x i8*]* @"\01??_7C@basic@@6B@", [2 x i8*]** [[THIS_PTR]]<br> }<br><br> void call_complete_dtor(C *obj_ptr) {<br>@@ -161,7 +161,8 @@ C::C() {<br> // CHECK-NEXT: br label %[[SKIP_VBASES]]<br> //<br> // CHECK: [[SKIP_VBASES]]<br>- // CHECK: @"\01??_7C@constructors@@6B@"<br>+ // Class C does not define or override methods, so shouldn't change the vfptr.<br>+ // CHECK-NOT: @"\01??_7C@constructors@@6B@"<br> // CHECK: ret<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -7,10 +7,26 @@ struct VBase {<br> };<br><br> struct B : virtual VBase {<br>+ B();<br> virtual void foo();<br> virtual void bar();<br> };<br><br>+B::B() {<br>+ // CHECK: @"\01??0B@@QAE@XZ"<br>+ // CHECK: %[[THIS:.*]] = load %struct.B**<br>+ // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]]<br>+ // CHECK: %[[SKIP_VBASES]]<br>+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*<br>+ // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0<br>+ // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8*<br>+ // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}}<br>+ // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to [2 x i8*]**<br>+ // CHECK: store [2 x i8*]* @"\01??_7B@@6B@", [2 x i8*]** %[[VFPTR]]<br>+ // FIXME: Should initialize the vtorDisp here.<br>+ // CHECK: ret<br>+}<br>+<br> void B::foo() {<br> // CHECK: define x86_thiscallcc void @"\01?foo@B@@UAEXXZ"(i8*<br> //<br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -19,6 +19,8 @@<br> // RUN: FileCheck --check-prefix=RET-THUNKS-Test4 %s < %t<br> // RUN: FileCheck --check-prefix=RET-THUNKS-Test5 %s < %t<br><br>+// RUN: FileCheck --check-prefix=MANGLING %s < %t<br>+<br> struct Empty {<br> // Doesn't have a vftable!<br> };<br>@@ -51,6 +53,9 @@ struct Test1: A, B {<br> // NO-THUNKS-Test1: VFTable indices for 'no_thunks::Test1' (1 entries)<br> // NO-THUNKS-Test1-NEXT: 0 | void no_thunks::Test1::f()<br><br>+ // MANGLING-DAG: @"\01??_7Test1@no_thunks@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7Test1@no_thunks@@6BB@@@"<br>+<br> // Overrides only the left child's method (A::f), needs no thunks.<br> virtual void f();<br> };<br>@@ -102,6 +107,8 @@ struct Test4 : Empty, A {<br> // NO-THUNKS-Test4: VFTable indices for 'no_thunks::Test4' (1 entries).<br> // NO-THUNKS-Test4-NEXT: 0 | void no_thunks::Test4::f()<br><br>+ // MANGLING-DAG: @"\01??_7Test4@no_thunks@@6B@"<br>+<br> virtual void f();<br> };<br><br>@@ -127,6 +134,11 @@ struct Test5: Test1, Test2 {<br> // NO-THUNKS-Test5: VFTable indices for 'no_thunks::Test5' (1 entries).<br> // NO-THUNKS-Test5-NEXT: 1 | void no_thunks::Test5::z()<br><br>+ // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BA@@Test1@1@@"<br>+ // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BA@@Test2@1@@"<br>+ // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BB@@Test1@1@@"<br>+ // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BB@@Test2@1@@"<br>+<br> virtual void z();<br> };<br><br>@@ -143,6 +155,9 @@ struct Test6: Test1 {<br> // NO-THUNKS-Test6: VFTable indices for 'no_thunks::Test6' (1 entries).<br> // NO-THUNKS-Test6-NEXT: 0 | void no_thunks::Test6::f()<br><br>+ // MANGLING-DAG: @"\01??_7Test6@no_thunks@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7Test6@no_thunks@@6BB@@@"<br>+<br> // Overrides both no_thunks::Test1::f and A::f.<br> virtual void f();<br> };<br>@@ -203,6 +218,9 @@ struct Test9: A, D {<br> // NO-THUNKS-Test9: VFTable indices for 'no_thunks::Test9' (1 entries).<br> // NO-THUNKS-Test9-NEXT: 1 | void no_thunks::Test9::h()<br><br>+ // MANGLING-DAG: @"\01??_7Test9@no_thunks@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7Test9@no_thunks@@6BD@1@@"<br>+<br> virtual void h();<br> };<br><br>@@ -228,6 +246,9 @@ struct Test1: A, D {<br> // PURE-VIRTUAL-Test1-NEXT: via vfptr at offset 4<br> // PURE-VIRTUAL-Test1-NEXT: 0 | void pure_virtual::Test1::g()<br><br>+ // MANGLING-DAG: @"\01??_7Test1@pure_virtual@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7Test1@pure_virtual@@6BD@1@@"<br>+<br> // Overrides only the right child's method (pure_virtual::D::g), needs this adjustment but<br> // not thunks.<br> virtual void g();<br>@@ -254,6 +275,9 @@ struct Test1 : B, C {<br> // THIS-THUNKS-Test1: VFTable indices for 'this_adjustment::Test1' (1 entries).<br> // THIS-THUNKS-Test1-NEXT: 0 | void this_adjustment::Test1::g()<br><br>+ // MANGLING-DAG: @"\01??_7Test1@this_adjustment@@6BB@@@"<br>+ // MANGLING-DAG: @"\01??_7Test1@this_adjustment@@6BC@@@"<br>+<br> virtual void g();<br> };<br><br>@@ -278,6 +302,10 @@ struct Test2 : A, B, C {<br> // THIS-THUNKS-Test2-NEXT: via vfptr at offset 4<br> // THIS-THUNKS-Test2-NEXT: 0 | void this_adjustment::Test2::g()<br><br>+ // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BB@@@"<br>+ // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BC@@@"<br>+<br> virtual void g();<br> };<br><br>@@ -337,6 +365,8 @@ struct Test1 : Ret1 {<br> // RET-THUNKS-Test1: VFTable indices for 'return_adjustment::Test1' (1 entries).<br> // RET-THUNKS-Test1-NEXT: 2 | this_adjustment::Test1 *return_adjustment::Test1::foo()<br><br>+ // MANGLING-DAG: @"\01??_7Test1@return_adjustment@@6B@"<br>+<br> virtual this_adjustment::Test1* foo();<br> };<br><br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -1,6 +1,6 @@<br> // RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o - > %t 2>&1<br>-// RUN: FileCheck --check-prefix=EMITS-VTABLE %s < %t<br>-// RUN: FileCheck --check-prefix=NO-VTABLE %s < %t<br>+// RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t<br>+// RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t<br> // RUN: FileCheck --check-prefix=CHECK-A %s < %t<br> // RUN: FileCheck --check-prefix=CHECK-B %s < %t<br> // RUN: FileCheck --check-prefix=CHECK-C %s < %t<br>@@ -10,19 +10,12 @@<br> // RUN: FileCheck --check-prefix=CHECK-G %s < %t<br> // RUN: FileCheck --check-prefix=CHECK-I %s < %t<br><br>-// FIXME: Currently, we only test VFTableContext in the AST, but still use<br>-// VTableContext for CodeGen. We should remove the "Vtable" checks below when we<br>-// completely switch from VTableContext to VFTableContext.<br>-// Currently, the order of Vtable vs VFTable output depends on whether the<br>-// v*table info was required by a constructor or a method definition.<br>-<br> struct A {<br> // CHECK-A: VFTable for 'A' (3 entries)<br> // CHECK-A-NEXT: 0 | void A::f()<br> // CHECK-A-NEXT: 1 | void A::g()<br> // CHECK-A-NEXT: 2 | void A::h()<br>-<br>- // CHECK-A: Vtable for 'A' (3 entries)<br>+ // CHECK-A: VFTable indices for 'A' (3 entries)<br> // CHECK-A-NEXT: 0 | void A::f()<br> // CHECK-A-NEXT: 1 | void A::g()<br> // CHECK-A-NEXT: 2 | void A::h()<br>@@ -33,20 +26,17 @@ struct A {<br> int ia;<br> };<br> A a;<br>-// EMITS-VTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]<br>+// EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]<br><br> struct B : A {<br>- // CHECK-B: Vtable for 'B' (5 entries)<br>+ // CHECK-B: VFTable for 'A' in 'B' (5 entries)<br> // CHECK-B-NEXT: 0 | void B::f()<br> // CHECK-B-NEXT: 1 | void A::g()<br> // CHECK-B-NEXT: 2 | void A::h()<br> // CHECK-B-NEXT: 3 | void B::i()<br> // CHECK-B-NEXT: 4 | void B::j()<br>-<br>- // CHECK-B: VFTable for 'A' in 'B' (5 entries)<br>+ // CHECK-B: VFTable indices for 'B' (3 entries)<br> // CHECK-B-NEXT: 0 | void B::f()<br>- // CHECK-B-NEXT: 1 | void A::g()<br>- // CHECK-B-NEXT: 2 | void A::h()<br> // CHECK-B-NEXT: 3 | void B::i()<br> // CHECK-B-NEXT: 4 | void B::j()<br><br>@@ -55,7 +45,7 @@ struct B : A {<br> virtual void j();<br> };<br> B b;<br>-// EMITS-VTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]<br>+// EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]<br><br> struct C {<br> // CHECK-C: VFTable for 'C' (2 entries)<br>@@ -65,25 +55,17 @@ struct C {<br> // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]<br> // CHECK-C-NEXT: 1 | void C::f()<br><br>- // CHECK-C: Vtable for 'C' (2 entries)<br>- // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]<br>- // CHECK-C-NEXT: 1 | void C::f()<br>- // CHECK-C: VTable indices for 'C' (2 entries).<br>- // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]<br>- // CHECK-C-NEXT: 1 | void C::f()<br>-<br> virtual ~C();<br> virtual void f();<br> };<br> void C::f() {}<br>-// NO-VTABLE-NOT: @"\01??_7C@@6B@"<br>+// NO-VFTABLE-NOT: @"\01??_7C@@6B@"<br><br> struct D {<br>- // CHECK-D: Vtable for 'D' (2 entries)<br>+ // CHECK-D: VFTable for 'D' (2 entries)<br> // CHECK-D-NEXT: 0 | void D::f()<br> // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]<br>-<br>- // CHECK-D: VFTable for 'D' (2 entries)<br>+ // CHECK-D: VFTable indices for 'D' (2 entries)<br> // CHECK-D-NEXT: 0 | void D::f()<br> // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]<br><br>@@ -91,7 +73,7 @@ struct D {<br> virtual ~D();<br> };<br> D d;<br>-// EMITS-VTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]<br>+// EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]<br><br> struct E : A {<br> // CHECK-E: VFTable for 'A' in 'E' (5 entries)<br>@@ -104,35 +86,15 @@ struct E : A {<br> // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]<br> // CHECK-E-NEXT: 4 | void E::i()<br><br>- // CHECK-E: Vtable for 'E' (5 entries)<br>- // CHECK-E-NEXT: 0 | void A::f()<br>- // CHECK-E-NEXT: 1 | void A::g()<br>- // CHECK-E-NEXT: 2 | void A::h()<br>- // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]<br>- // CHECK-E-NEXT: 4 | void E::i()<br>- // CHECK-E: VTable indices for 'E' (2 entries).<br>- // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]<br>- // CHECK-E-NEXT: 4 | void E::i()<br>-<br> // ~E would be the key method, but it isn't used, and MS ABI has no key<br> // methods.<br> virtual ~E();<br> virtual void i();<br> };<br> void E::i() {}<br>-// NO-VTABLE-NOT: @"\01??_7E@@6B@"<br>+// NO-VFTABLE-NOT: @"\01??_7E@@6B@"<br><br> struct F : A {<br>- // CHECK-F: Vtable for 'F' (5 entries)<br>- // CHECK-F-NEXT: 0 | void A::f()<br>- // CHECK-F-NEXT: 1 | void A::g()<br>- // CHECK-F-NEXT: 2 | void A::h()<br>- // CHECK-F-NEXT: 3 | void F::i()<br>- // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]<br>- // CHECK-F: VTable indices for 'F' (2 entries).<br>- // CHECK-F-NEXT: 3 | void F::i()<br>- // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]<br>-<br> // CHECK-F: VFTable for 'A' in 'F' (5 entries)<br> // CHECK-F-NEXT: 0 | void A::f()<br> // CHECK-F-NEXT: 1 | void A::g()<br>@@ -147,7 +109,7 @@ struct F : A {<br> virtual ~F();<br> };<br> F f;<br>-// EMITS-VTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]<br>+// EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]<br><br> struct G : E {<br> // CHECK-G: VFTable for 'A' in 'E' in 'G' (6 entries)<br>@@ -162,31 +124,19 @@ struct G : E {<br> // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]<br> // CHECK-G-NEXT: 5 | void G::j()<br><br>- // CHECK-G: Vtable for 'G' (6 entries)<br>- // CHECK-G-NEXT: 0 | void G::f()<br>- // CHECK-G-NEXT: 1 | void A::g()<br>- // CHECK-G-NEXT: 2 | void A::h()<br>- // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]<br>- // CHECK-G-NEXT: 4 | void E::i()<br>- // CHECK-G-NEXT: 5 | void G::j()<br>- // CHECK-G: VTable indices for 'G' (3 entries).<br>- // CHECK-G-NEXT: 0 | void G::f()<br>- // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]<br>- // CHECK-G-NEXT: 5 | void G::j()<br>-<br> virtual void f(); // overrides A::f()<br> virtual ~G();<br> virtual void j();<br> };<br> void G::j() {}<br>-// NO-VTABLE-NOT: @"\01??_7G@@6B@"<br>+// NO-VFTABLE-NOT: @"\01??_7G@@6B@"<br><br> // Test that the usual Itanium-style key method does not emit a vtable.<br> struct H {<br> virtual void f();<br> };<br> void H::f() {}<br>-// NO-VTABLE-NOT: @"\01??_7H@@6B@"<br>+// NO-VFTABLE-NOT: @"\01??_7H@@6B@"<br><br> struct Empty { };<br><br><br>Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp Fri Sep 27 09:48:01 2013<br>@@ -18,6 +18,8 @@<br> // RUN: FileCheck --check-prefix=RET-W %s < %t<br> // RUN: FileCheck --check-prefix=RET-T %s < %t<br><br>+// RUN: FileCheck --check-prefix=MANGLING %s < %t<br>+<br> struct Empty { };<br><br> struct A {<br>@@ -38,6 +40,8 @@ struct C: virtual A {<br> // VTABLE-C-NEXT: vbtable index 1, vfptr at offset 0<br> // VTABLE-C-NEXT: 0 | void C::f()<br><br>+ // MANGLING-DAG: @"\01??_7C@@6B@"<br>+<br> ~C(); // Currently required to have correct record layout, see PR16406<br> virtual void f();<br> };<br>@@ -58,6 +62,9 @@ struct D: virtual A {<br> // VTABLE-D-NEXT: via vbtable index 1, vfptr at offset 0<br> // VTABLE-D-NEXT: 0 | void D::f()<br><br>+ // MANGLING-DAG: @"\01??_7D@@6B0@@"<br>+ // MANGLING-DAG: @"\01??_7D@@6BA@@@"<br>+<br> virtual void f();<br> virtual void h();<br> };<br>@@ -71,6 +78,7 @@ struct X { int x; };<br><br> // X and A get reordered in the layout since X doesn't have a vfptr while A has.<br> struct Y : X, A { };<br>+// MANGLING-DAG: @"\01??_7Y@Test1@@6B@"<br><br> struct Z : virtual Y {<br> // TEST1: VFTable for 'A' in 'Test1::Y' in 'Test1::Z' (2 entries).<br>@@ -78,6 +86,8 @@ struct Z : virtual Y {<br> // TEST1-NEXT: 1 | void A::z()<br><br> // TEST1-NOT: VFTable indices for 'Test1::Z'<br>+<br>+ // MANGLING-DAG: @"\01??_7Z@Test1@@6B@"<br> };<br><br> Z z;<br>@@ -99,6 +109,10 @@ struct X: virtual A, virtual B {<br> // TEST2: VFTable indices for 'Test2::X' (1 entries).<br> // TEST2-NEXT: 0 | void Test2::X::h()<br><br>+ // MANGLING-DAG: @"\01??_7X@Test2@@6B01@@"<br>+ // MANGLING-DAG: @"\01??_7X@Test2@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7X@Test2@@6BB@@@"<br>+<br> virtual void h();<br> };<br><br>@@ -107,7 +121,9 @@ X x;<br><br> namespace Test3 {<br><br>-struct X : virtual A { };<br>+struct X : virtual A {<br>+ // MANGLING-DAG: @"\01??_7X@Test3@@6B@"<br>+};<br><br> struct Y: virtual X {<br> // TEST3: VFTable for 'A' in 'Test3::X' in 'Test3::Y' (2 entries).<br>@@ -115,6 +131,8 @@ struct Y: virtual X {<br> // TEST3-NEXT: 1 | void A::z()<br><br> // TEST3-NOT: VFTable indices for 'Test3::Y'<br>+<br>+ // MANGLING-DAG: @"\01??_7Y@Test3@@6B@"<br> };<br><br> Y y;<br>@@ -134,6 +152,8 @@ struct X: virtual C {<br> // TEST4-NEXT: 1 | void A::z()<br><br> // TEST4-NOT: VFTable indices for 'Test4::X'<br>+<br>+ // MANGLING-DAG: @"\01??_7X@Test4@@6B@"<br> };<br><br> X x;<br>@@ -143,6 +163,7 @@ namespace Test5 {<br><br> // New methods are added to the base's vftable.<br> struct X : A {<br>+ // MANGLING-DAG: @"\01??_7X@Test5@@6B@"<br> virtual void g();<br> };<br><br>@@ -158,6 +179,9 @@ struct Y : virtual X {<br> // TEST5: VFTable indices for 'Test5::Y' (1 entries).<br> // TEST5-NEXT: 0 | void Test5::Y::h()<br><br>+ // MANGLING-DAG: @"\01??_7Y@Test5@@6B01@@"<br>+ // MANGLING-DAG: @"\01??_7Y@Test5@@6BX@1@@"<br>+<br> virtual void h();<br> };<br><br>@@ -172,6 +196,8 @@ struct X : A, virtual Empty {<br> // TEST6-NEXT: 1 | void A::z()<br><br> // TEST6-NOT: VFTable indices for 'Test6::X'<br>+<br>+ // MANGLING-DAG: @"\01??_7X@Test6@@6B@"<br> };<br><br> X x;<br>@@ -179,7 +205,9 @@ X x;<br><br> namespace Test7 {<br><br>-struct X : C { };<br>+struct X : C {<br>+ // MANGLING-DAG: @"\01??_7X@Test7@@6B@"<br>+};<br><br> struct Y : virtual X {<br> // TEST7: VFTable for 'A' in 'C' in 'Test7::X' in 'Test7::Y' (2 entries).<br>@@ -191,6 +219,8 @@ struct Y : virtual X {<br> // TEST7-NEXT: 0 | this adjustment: 12 non-virtual<br><br> // TEST7-NOT: VFTable indices for 'Test7::Y'<br>+<br>+ // MANGLING-DAG: @"\01??_7Y@Test7@@6B@"<br> };<br><br> Y y;<br>@@ -210,6 +240,9 @@ struct X : D, C {<br> // TEST8: VFTable indices for 'Test8::X' (1 entries).<br> // TEST8-NEXT: via vbtable index 1, vfptr at offset 0<br><br>+ // MANGLING-DAG: @"\01??_7X@Test8@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7X@Test8@@6BD@@@"<br>+<br> virtual void f();<br> };<br><br>@@ -231,6 +264,9 @@ struct Y : virtual X {<br> // TEST9-Y: VFTable indices for 'Test9::Y' (1 entries).<br> // TEST9-Y-NEXT: 0 | void Test9::Y::h()<br><br>+ // MANGLING-DAG: @"\01??_7Y@Test9@@6B01@@"<br>+ // MANGLING-DAG: @"\01??_7Y@Test9@@6BX@1@@"<br>+<br> virtual void h();<br> };<br><br>@@ -248,6 +284,13 @@ struct Z : Y, virtual B {<br> // TEST9-Z-NEXT: 0 | void B::g()<br><br> // TEST9-Z-NOT: VFTable indices for 'Test9::Z'<br>+<br>+ // MANGLING-DAG: @"\01??_7Z@Test9@@6BX@1@@"<br>+ // MANGLING-DAG: @"\01??_7Z@Test9@@6BY@1@@"<br>+<br>+ // FIXME this one is wrong:<br>+ // INCORRECT MANGLING-DAG: @"\01??_7Z@Test9@@6BB@@@"<br>+ // MANGLING-DAG-SHOULD-BE: @"\01??_7Z@Test9@@6B@"<br> };<br><br> Z z;<br>@@ -275,6 +318,16 @@ struct W : Z, D, virtual A, virtual B {<br> // TEST9-W-NEXT: 0 | this adjustment: -8 non-virtual<br><br> // TEST9-W-NOT: VFTable indices for 'Test9::W'<br>+<br>+ // MANGLING-DAG: @"\01??_7W@Test9@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7W@Test9@@6BD@@@"<br>+ // MANGLING-DAG: @"\01??_7W@Test9@@6BX@1@@"<br>+<br>+ // FIXME: these two are wrong:<br>+ // INCORRECT MANGLING-DAG: @"\01??_7W@Test9@@6BB@@@"<br>+ // MANGLING-DAG-SHOULD-BE: @"\01??_7W@Test9@@6B@"<br>+ // INCORRECT MANGLING-DAG: @"\01??_7W@Test9@@6BY@1@Z@1@@"<br>+ // MANGLING-DAG-SHOULD-BE: @"\01??_7W@Test9@@6BY@1@@"<br> };<br><br> W w;<br>@@ -320,6 +373,16 @@ struct T : Z, D, virtual A, virtual B {<br> // TEST9-T-NEXT: via vbtable index 2, vfptr at offset 0<br> // TEST9-T-NEXT: 0 | void Test9::T::g()<br><br>+ // MANGLING-DAG: @"\01??_7T@Test9@@6BA@@@"<br>+ // MANGLING-DAG: @"\01??_7T@Test9@@6BD@@@"<br>+ // MANGLING-DAG: @"\01??_7T@Test9@@6BX@1@@"<br>+<br>+ // FIXME: these two are wrong:<br>+ // INCORRECT MANGLING-DAG: @"\01??_7T@Test9@@6BB@@@"<br>+ // MANGLING-DAG-SHOULD-BE: @"\01??_7T@Test9@@6B@"<br>+ // INCORRECT MANGLING-DAG: @"\01??_7T@Test9@@6BY@1@Z@1@@"<br>+ // MANGLING-DAG-SHOULD-BE: @"\01??_7T@Test9@@6BY@1@@"<br>+<br> virtual void f();<br> virtual void g();<br> virtual void h();<br><br>Modified: cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp?rev=191523&r1=191522&r2=191523&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp?rev=191523&r1=191522&r2=191523&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp Fri Sep 27 09:48:01 2013<br>@@ -27,12 +27,6 @@ int main() {<br> // CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev<br> // CHECK: }<br><br>-// basic_iostream's deleting dtor calls its complete dtor, then<br>-// operator delete().<br>-// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr<br>-// CHECK: call {{.*}} @_ZN14basic_iostreamIcED1Ev<br>-// CHECK: call {{.*}} @_ZdlPv<br>-<br> // basic_istream's complete dtor calls the base dtor,<br> // then its virtual base's base dtor.<br> // CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr<br>@@ -45,6 +39,12 @@ int main() {<br> // CHECK: call {{.*}} @_ZN13basic_istreamIcED1Ev<br> // CHECK: call {{.*}} @_ZdlPv<br><br>+// basic_iostream's deleting dtor calls its complete dtor, then<br>+// operator delete().<br>+// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* {{.*}}%this) unnamed_addr<br>+// CHECK: call {{.*}} @_ZN14basic_iostreamIcED1Ev<br>+// CHECK: call {{.*}} @_ZdlPv<br>+<br> // basic_istream's base dtor is a no-op.<br> // CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* {{.*}}%this, i8** %vtt) unnamed_addr<br> // CHECK-NOT: call<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></div></body></html>