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