@@ -999,10 +999,6 @@ class VTableBuilder {
999
999
dumpLayout (llvm::errs ());
1000
1000
}
1001
1001
1002
- bool isMicrosoftABI () const {
1003
- return VTables.isMicrosoftABI ();
1004
- }
1005
-
1006
1002
uint64_t getNumThunks () const {
1007
1003
return Thunks.size ();
1008
1004
}
@@ -1157,7 +1153,7 @@ void VTableBuilder::ComputeThisAdjustments() {
1157
1153
// Add it.
1158
1154
VTableThunks[VTableIndex].This = ThisAdjustment;
1159
1155
1160
- if (isa<CXXDestructorDecl>(MD) && ! isMicrosoftABI () ) {
1156
+ if (isa<CXXDestructorDecl>(MD)) {
1161
1157
// Add an adjustment for the deleting destructor as well.
1162
1158
VTableThunks[VTableIndex + 1 ].This = ThisAdjustment;
1163
1159
}
@@ -1188,8 +1184,6 @@ void VTableBuilder::ComputeThisAdjustments() {
1188
1184
break ;
1189
1185
case VTableComponent::CK_DeletingDtorPointer:
1190
1186
// We've already added the thunk when we saw the complete dtor pointer.
1191
- // FIXME: check how this works in the Microsoft ABI
1192
- // while working on the multiple inheritance patch.
1193
1187
continue ;
1194
1188
}
1195
1189
@@ -1326,15 +1320,9 @@ VTableBuilder::AddMethod(const CXXMethodDecl *MD,
1326
1320
assert (ReturnAdjustment.isEmpty () &&
1327
1321
" Destructor can't have return adjustment!" );
1328
1322
1329
- // FIXME: Should probably add a layer of abstraction for vtable generation.
1330
- if (!isMicrosoftABI ()) {
1331
- // Add both the complete destructor and the deleting destructor.
1332
- Components.push_back (VTableComponent::MakeCompleteDtor (DD));
1333
- Components.push_back (VTableComponent::MakeDeletingDtor (DD));
1334
- } else {
1335
- // Add the scalar deleting destructor.
1336
- Components.push_back (VTableComponent::MakeDeletingDtor (DD));
1337
- }
1323
+ // Add both the complete destructor and the deleting destructor.
1324
+ Components.push_back (VTableComponent::MakeCompleteDtor (DD));
1325
+ Components.push_back (VTableComponent::MakeDeletingDtor (DD));
1338
1326
} else {
1339
1327
// Add the return adjustment if necessary.
1340
1328
if (!ReturnAdjustment.isEmpty ())
@@ -1693,18 +1681,12 @@ VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
1693
1681
if (Base.getBase () == MostDerivedClass)
1694
1682
VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets ();
1695
1683
1696
- // FIXME: Should probably add a layer of abstraction for vtable generation.
1697
- if (!isMicrosoftABI ()) {
1698
- // Add the offset to top.
1699
- CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
1700
- Components.push_back (VTableComponent::MakeOffsetToTop (OffsetToTop));
1684
+ // Add the offset to top.
1685
+ CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
1686
+ Components.push_back (VTableComponent::MakeOffsetToTop (OffsetToTop));
1701
1687
1702
- // Next, add the RTTI.
1703
- Components.push_back (VTableComponent::MakeRTTI (MostDerivedClass));
1704
- } else {
1705
- // FIXME: unclear what to do with RTTI in MS ABI as emitting it anywhere
1706
- // breaks the vftable layout. Just skip RTTI for now, can't mangle anyway.
1707
- }
1688
+ // Next, add the RTTI.
1689
+ Components.push_back (VTableComponent::MakeRTTI (MostDerivedClass));
1708
1690
1709
1691
uint64_t AddressPoint = Components.size ();
1710
1692
@@ -1722,16 +1704,10 @@ VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
1722
1704
const CXXMethodDecl *MD = I->first ;
1723
1705
const MethodInfo &MI = I->second ;
1724
1706
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1725
- // FIXME: Should probably add a layer of abstraction for vtable generation.
1726
- if (!isMicrosoftABI ()) {
1727
- MethodVTableIndices[GlobalDecl (DD, Dtor_Complete)]
1728
- = MI.VTableIndex - AddressPoint;
1729
- MethodVTableIndices[GlobalDecl (DD, Dtor_Deleting)]
1730
- = MI.VTableIndex + 1 - AddressPoint;
1731
- } else {
1732
- MethodVTableIndices[GlobalDecl (DD, Dtor_Deleting)]
1733
- = MI.VTableIndex - AddressPoint;
1734
- }
1707
+ MethodVTableIndices[GlobalDecl (DD, Dtor_Complete)]
1708
+ = MI.VTableIndex - AddressPoint;
1709
+ MethodVTableIndices[GlobalDecl (DD, Dtor_Deleting)]
1710
+ = MI.VTableIndex + 1 - AddressPoint;
1735
1711
} else {
1736
1712
MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;
1737
1713
}
@@ -2044,8 +2020,6 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) {
2044
2020
Out << DD->getQualifiedNameAsString ();
2045
2021
if (IsComplete)
2046
2022
Out << " () [complete]" ;
2047
- else if (isMicrosoftABI ())
2048
- Out << " () [scalar deleting]" ;
2049
2023
else
2050
2024
Out << " () [deleting]" ;
2051
2025
@@ -2230,18 +2204,11 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) {
2230
2204
MD);
2231
2205
2232
2206
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2233
- // FIXME: Should add a layer of abstraction for vtable generation.
2234
- if (!isMicrosoftABI ()) {
2235
- GlobalDecl GD (DD, Dtor_Complete);
2236
- assert (MethodVTableIndices.count (GD));
2237
- uint64_t VTableIndex = MethodVTableIndices[GD];
2238
- IndicesMap[VTableIndex] = MethodName + " [complete]" ;
2239
- IndicesMap[VTableIndex + 1 ] = MethodName + " [deleting]" ;
2240
- } else {
2241
- GlobalDecl GD (DD, Dtor_Deleting);
2242
- assert (MethodVTableIndices.count (GD));
2243
- IndicesMap[MethodVTableIndices[GD]] = MethodName + " [scalar deleting]" ;
2244
- }
2207
+ GlobalDecl GD (DD, Dtor_Complete);
2208
+ assert (MethodVTableIndices.count (GD));
2209
+ uint64_t VTableIndex = MethodVTableIndices[GD];
2210
+ IndicesMap[VTableIndex] = MethodName + " [complete]" ;
2211
+ IndicesMap[VTableIndex + 1 ] = MethodName + " [deleting]" ;
2245
2212
} else {
2246
2213
assert (MethodVTableIndices.count (MD));
2247
2214
IndicesMap[MethodVTableIndices[MD]] = MethodName;
@@ -2352,10 +2319,12 @@ static VTableLayout *CreateVTableLayout(const VTableBuilder &Builder) {
2352
2319
VTableThunks.size (),
2353
2320
VTableThunks.data (),
2354
2321
Builder.getAddressPoints (),
2355
- Builder. isMicrosoftABI () );
2322
+ /* IsMicrosoftABI= */ false );
2356
2323
}
2357
2324
2358
2325
void VTableContext::computeVTableRelatedInformation (const CXXRecordDecl *RD) {
2326
+ assert (!IsMicrosoftABI && " Shouldn't be called in this ABI!" );
2327
+
2359
2328
const VTableLayout *&Entry = VTableLayouts[RD];
2360
2329
2361
2330
// Check if we've computed this information before.
@@ -3132,6 +3101,55 @@ static void EnumerateVFPtrs(
3132
3101
}
3133
3102
}
3134
3103
3104
+ // / CalculatePathToMangle - Calculate the subset of records that should be used
3105
+ // / to mangle the vftable for the given vfptr.
3106
+ // / Should only be called if a class has multiple vftables.
3107
+ static void
3108
+ CalculatePathToMangle (const CXXRecordDecl *RD, VFPtrInfo &VFPtr) {
3109
+ // FIXME: In some rare cases this code produces a slightly incorrect mangling.
3110
+ // It's very likely that the vbtable mangling code can be adjusted to mangle
3111
+ // both vftables and vbtables correctly.
3112
+
3113
+ VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr ;
3114
+ if (FullPath.empty ()) {
3115
+ // Mangle the class's own vftable.
3116
+ assert (RD->getNumVBases () &&
3117
+ " Something's wrong: if the most derived "
3118
+ " class has more than one vftable, it can only have its own "
3119
+ " vftable if it has vbases" );
3120
+ VFPtr.PathToMangle .push_back (RD);
3121
+ return ;
3122
+ }
3123
+
3124
+ unsigned Begin = 0 ;
3125
+
3126
+ // First, skip all the bases before the vbase.
3127
+ if (VFPtr.LastVBase ) {
3128
+ while (FullPath[Begin] != VFPtr.LastVBase ) {
3129
+ Begin++;
3130
+ assert (Begin < FullPath.size ());
3131
+ }
3132
+ }
3133
+
3134
+ // Then, put the rest of the base path in the reverse order.
3135
+ for (unsigned I = FullPath.size (); I != Begin; --I) {
3136
+ const CXXRecordDecl *CurBase = FullPath[I - 1 ],
3137
+ *ItsBase = (I == 1 ) ? RD : FullPath[I - 2 ];
3138
+ bool BaseIsVirtual = false ;
3139
+ for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin (),
3140
+ F = ItsBase->bases_end (); J != F; ++J) {
3141
+ if (J->getType ()->getAsCXXRecordDecl () == CurBase) {
3142
+ BaseIsVirtual = J->isVirtual ();
3143
+ break ;
3144
+ }
3145
+ }
3146
+
3147
+ // Should skip the current base if it is a non-virtual base with no siblings.
3148
+ if (BaseIsVirtual || ItsBase->getNumBases () != 1 )
3149
+ VFPtr.PathToMangle .push_back (CurBase);
3150
+ }
3151
+ }
3152
+
3135
3153
static void EnumerateVFPtrs (ASTContext &Context, const CXXRecordDecl *ForClass,
3136
3154
MicrosoftVFTableContext::VFPtrListTy &Result) {
3137
3155
Result.clear ();
@@ -3140,6 +3158,10 @@ static void EnumerateVFPtrs(ASTContext &Context, const CXXRecordDecl *ForClass,
3140
3158
EnumerateVFPtrs (Context, ForClass, ClassLayout,
3141
3159
BaseSubobject (ForClass, CharUnits::Zero ()), 0 ,
3142
3160
VFPtrInfo::BasePath (), VisitedVBases, Result);
3161
+ if (Result.size () > 1 ) {
3162
+ for (unsigned I = 0 , E = Result.size (); I != E; ++I)
3163
+ CalculatePathToMangle (ForClass, Result[I]);
3164
+ }
3143
3165
}
3144
3166
3145
3167
void MicrosoftVFTableContext::computeVTableRelatedInformation (
0 commit comments