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:07:15 PDT 2013
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