forked from OSchip/llvm-project
[VTableBuilder] Use range-based for loops. No functional change intended
llvm-svn: 243222
This commit is contained in:
parent
0cfa68e01b
commit
a37e765497
|
@ -177,14 +177,12 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
|
||||||
CXXFinalOverriderMap FinalOverriders;
|
CXXFinalOverriderMap FinalOverriders;
|
||||||
MostDerivedClass->getFinalOverriders(FinalOverriders);
|
MostDerivedClass->getFinalOverriders(FinalOverriders);
|
||||||
|
|
||||||
for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(),
|
for (const auto &Overrider : FinalOverriders) {
|
||||||
E = FinalOverriders.end(); I != E; ++I) {
|
const CXXMethodDecl *MD = Overrider.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
const OverridingMethods &Methods = Overrider.second;
|
||||||
const OverridingMethods& Methods = I->second;
|
|
||||||
|
|
||||||
for (OverridingMethods::const_iterator I = Methods.begin(),
|
for (const auto &M : Methods) {
|
||||||
E = Methods.end(); I != E; ++I) {
|
unsigned SubobjectNumber = M.first;
|
||||||
unsigned SubobjectNumber = I->first;
|
|
||||||
assert(SubobjectOffsets.count(std::make_pair(MD->getParent(),
|
assert(SubobjectOffsets.count(std::make_pair(MD->getParent(),
|
||||||
SubobjectNumber)) &&
|
SubobjectNumber)) &&
|
||||||
"Did not find subobject offset!");
|
"Did not find subobject offset!");
|
||||||
|
@ -192,8 +190,8 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
|
||||||
CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(),
|
CharUnits BaseOffset = SubobjectOffsets[std::make_pair(MD->getParent(),
|
||||||
SubobjectNumber)];
|
SubobjectNumber)];
|
||||||
|
|
||||||
assert(I->second.size() == 1 && "Final overrider is not unique!");
|
assert(M.second.size() == 1 && "Final overrider is not unique!");
|
||||||
const UniqueVirtualMethod &Method = I->second.front();
|
const UniqueVirtualMethod &Method = M.second.front();
|
||||||
|
|
||||||
const CXXRecordDecl *OverriderRD = Method.Method->getParent();
|
const CXXRecordDecl *OverriderRD = Method.Method->getParent();
|
||||||
assert(SubobjectLayoutClassOffsets.count(
|
assert(SubobjectLayoutClassOffsets.count(
|
||||||
|
@ -482,13 +480,9 @@ static bool HasSameVirtualSignature(const CXXMethodDecl *LHS,
|
||||||
// Force the signatures to match. We can't rely on the overrides
|
// Force the signatures to match. We can't rely on the overrides
|
||||||
// list here because there isn't necessarily an inheritance
|
// list here because there isn't necessarily an inheritance
|
||||||
// relationship between the two methods.
|
// relationship between the two methods.
|
||||||
if (LT->getTypeQuals() != RT->getTypeQuals() ||
|
if (LT->getTypeQuals() != RT->getTypeQuals())
|
||||||
LT->getNumParams() != RT->getNumParams())
|
|
||||||
return false;
|
return false;
|
||||||
for (unsigned I = 0, E = LT->getNumParams(); I != E; ++I)
|
return LT->getParamTypes() == RT->getParamTypes();
|
||||||
if (LT->getParamType(I) != RT->getParamType(I))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
|
bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
|
||||||
|
@ -515,8 +509,8 @@ bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
|
||||||
bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD,
|
bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD,
|
||||||
CharUnits OffsetOffset) {
|
CharUnits OffsetOffset) {
|
||||||
// Check if we can reuse an offset.
|
// Check if we can reuse an offset.
|
||||||
for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
|
for (const auto &OffsetPair : Offsets) {
|
||||||
if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
|
if (MethodsCanShareVCallOffset(OffsetPair.first, MD))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,9 +521,9 @@ bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD,
|
||||||
|
|
||||||
CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) {
|
CharUnits VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) {
|
||||||
// Look for an offset.
|
// Look for an offset.
|
||||||
for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
|
for (const auto &OffsetPair : Offsets) {
|
||||||
if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
|
if (MethodsCanShareVCallOffset(OffsetPair.first, MD))
|
||||||
return Offsets[I].second;
|
return OffsetPair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_unreachable("Should always find a vcall offset offset!");
|
llvm_unreachable("Should always find a vcall offset offset!");
|
||||||
|
@ -1118,10 +1112,9 @@ ComputeAllOverriddenMethods(const CXXMethodDecl *MD,
|
||||||
void ItaniumVTableBuilder::ComputeThisAdjustments() {
|
void ItaniumVTableBuilder::ComputeThisAdjustments() {
|
||||||
// Now go through the method info map and see if any of the methods need
|
// Now go through the method info map and see if any of the methods need
|
||||||
// 'this' pointer adjustments.
|
// 'this' pointer adjustments.
|
||||||
for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
|
for (const auto &MI : MethodInfoMap) {
|
||||||
E = MethodInfoMap.end(); I != E; ++I) {
|
const CXXMethodDecl *MD = MI.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
const MethodInfo &MethodInfo = MI.second;
|
||||||
const MethodInfo &MethodInfo = I->second;
|
|
||||||
|
|
||||||
// Ignore adjustments for unused function pointers.
|
// Ignore adjustments for unused function pointers.
|
||||||
uint64_t VTableIndex = MethodInfo.VTableIndex;
|
uint64_t VTableIndex = MethodInfo.VTableIndex;
|
||||||
|
@ -1167,10 +1160,9 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (VTableThunksMapTy::const_iterator I = VTableThunks.begin(),
|
for (const auto &TI : VTableThunks) {
|
||||||
E = VTableThunks.end(); I != E; ++I) {
|
const VTableComponent &Component = Components[TI.first];
|
||||||
const VTableComponent &Component = Components[I->first];
|
const ThunkInfo &Thunk = TI.second;
|
||||||
const ThunkInfo &Thunk = I->second;
|
|
||||||
const CXXMethodDecl *MD;
|
const CXXMethodDecl *MD;
|
||||||
|
|
||||||
switch (Component.getKind()) {
|
switch (Component.getKind()) {
|
||||||
|
@ -1229,10 +1221,9 @@ BaseOffset ItaniumVTableBuilder::ComputeThisAdjustmentBaseOffset(
|
||||||
|
|
||||||
// We have to go through all the paths, and see which one leads us to the
|
// We have to go through all the paths, and see which one leads us to the
|
||||||
// right base subobject.
|
// right base subobject.
|
||||||
for (CXXBasePaths::const_paths_iterator I = Paths.begin(), E = Paths.end();
|
for (const CXXBasePath &Path : Paths) {
|
||||||
I != E; ++I) {
|
BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, Path);
|
||||||
BaseOffset Offset = ComputeBaseOffset(Context, DerivedRD, *I);
|
|
||||||
|
|
||||||
CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset;
|
CharUnits OffsetToBaseSubobject = Offset.NonVirtualOffset;
|
||||||
|
|
||||||
if (Offset.VirtualBase) {
|
if (Offset.VirtualBase) {
|
||||||
|
@ -1432,15 +1423,11 @@ FindNearestOverriddenMethod(const CXXMethodDecl *MD,
|
||||||
BasesSetVectorTy &Bases) {
|
BasesSetVectorTy &Bases) {
|
||||||
OverriddenMethodsSetTy OverriddenMethods;
|
OverriddenMethodsSetTy OverriddenMethods;
|
||||||
ComputeAllOverriddenMethods(MD, OverriddenMethods);
|
ComputeAllOverriddenMethods(MD, OverriddenMethods);
|
||||||
|
|
||||||
for (int I = Bases.size(), E = 0; I != E; --I) {
|
|
||||||
const CXXRecordDecl *PrimaryBase = Bases[I - 1];
|
|
||||||
|
|
||||||
|
for (const CXXRecordDecl *PrimaryBase :
|
||||||
|
llvm::make_range(Bases.rbegin(), Bases.rend())) {
|
||||||
// Now check the overridden methods.
|
// Now check the overridden methods.
|
||||||
for (OverriddenMethodsSetTy::const_iterator I = OverriddenMethods.begin(),
|
for (const CXXMethodDecl *OverriddenMD : OverriddenMethods) {
|
||||||
E = OverriddenMethods.end(); I != E; ++I) {
|
|
||||||
const CXXMethodDecl *OverriddenMD = *I;
|
|
||||||
|
|
||||||
// We found our overridden method.
|
// We found our overridden method.
|
||||||
if (OverriddenMD->getParent() == PrimaryBase)
|
if (OverriddenMD->getParent() == PrimaryBase)
|
||||||
return OverriddenMD;
|
return OverriddenMD;
|
||||||
|
@ -1588,10 +1575,7 @@ void ItaniumVTableBuilder::AddMethods(
|
||||||
if (ImplicitVirtualDtor)
|
if (ImplicitVirtualDtor)
|
||||||
NewVirtualFunctions.push_back(ImplicitVirtualDtor);
|
NewVirtualFunctions.push_back(ImplicitVirtualDtor);
|
||||||
|
|
||||||
for (NewVirtualFunctionsTy::const_iterator I = NewVirtualFunctions.begin(),
|
for (const CXXMethodDecl *MD : NewVirtualFunctions) {
|
||||||
E = NewVirtualFunctions.end(); I != E; ++I) {
|
|
||||||
const CXXMethodDecl *MD = *I;
|
|
||||||
|
|
||||||
// Get the final overrider.
|
// Get the final overrider.
|
||||||
FinalOverriders::OverriderInfo Overrider =
|
FinalOverriders::OverriderInfo Overrider =
|
||||||
Overriders.getOverrider(MD, Base.getBaseOffset());
|
Overriders.getOverrider(MD, Base.getBaseOffset());
|
||||||
|
@ -1692,10 +1676,9 @@ void ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
|
||||||
const CXXRecordDecl *RD = Base.getBase();
|
const CXXRecordDecl *RD = Base.getBase();
|
||||||
if (RD == MostDerivedClass) {
|
if (RD == MostDerivedClass) {
|
||||||
assert(MethodVTableIndices.empty());
|
assert(MethodVTableIndices.empty());
|
||||||
for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
|
for (const auto &I : MethodInfoMap) {
|
||||||
E = MethodInfoMap.end(); I != E; ++I) {
|
const CXXMethodDecl *MD = I.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
const MethodInfo &MI = I.second;
|
||||||
const MethodInfo &MI = I->second;
|
|
||||||
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
|
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
|
||||||
MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
|
MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
|
||||||
= MI.VTableIndex - AddressPoint;
|
= MI.VTableIndex - AddressPoint;
|
||||||
|
@ -1916,11 +1899,10 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
// Since an address point can be shared by multiple subobjects, we use an
|
// Since an address point can be shared by multiple subobjects, we use an
|
||||||
// STL multimap.
|
// STL multimap.
|
||||||
std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
|
std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
|
||||||
for (AddressPointsMapTy::const_iterator I = AddressPoints.begin(),
|
for (const auto &AP : AddressPoints) {
|
||||||
E = AddressPoints.end(); I != E; ++I) {
|
const BaseSubobject &Base = AP.first;
|
||||||
const BaseSubobject& Base = I->first;
|
uint64_t Index = AP.second;
|
||||||
uint64_t Index = I->second;
|
|
||||||
|
|
||||||
AddressPointsByIndex.insert(std::make_pair(Index, Base));
|
AddressPointsByIndex.insert(std::make_pair(Index, Base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2069,18 +2051,16 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
|
|
||||||
// We store the class names in a set to get a stable order.
|
// We store the class names in a set to get a stable order.
|
||||||
std::set<std::string> ClassNames;
|
std::set<std::string> ClassNames;
|
||||||
for (std::multimap<uint64_t, BaseSubobject>::const_iterator I =
|
for (const auto &I :
|
||||||
AddressPointsByIndex.lower_bound(NextIndex), E =
|
llvm::make_range(AddressPointsByIndex.equal_range(NextIndex))) {
|
||||||
AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) {
|
assert(I.second.getBaseOffset() == BaseOffset &&
|
||||||
assert(I->second.getBaseOffset() == BaseOffset &&
|
|
||||||
"Invalid base offset!");
|
"Invalid base offset!");
|
||||||
const CXXRecordDecl *RD = I->second.getBase();
|
const CXXRecordDecl *RD = I.second.getBase();
|
||||||
ClassNames.insert(RD->getQualifiedNameAsString());
|
ClassNames.insert(RD->getQualifiedNameAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::set<std::string>::const_iterator I = ClassNames.begin(),
|
for (const std::string &Name : ClassNames) {
|
||||||
E = ClassNames.end(); I != E; ++I) {
|
Out << " -- (" << Name;
|
||||||
Out << " -- (" << *I;
|
|
||||||
Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n";
|
Out << ", " << BaseOffset.getQuantity() << ") vtable address --\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2097,12 +2077,10 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
// a stable order.
|
// a stable order.
|
||||||
|
|
||||||
std::map<std::string, CharUnits> ClassNamesAndOffsets;
|
std::map<std::string, CharUnits> ClassNamesAndOffsets;
|
||||||
for (VBaseOffsetOffsetsMapTy::const_iterator I = VBaseOffsetOffsets.begin(),
|
for (const auto &I : VBaseOffsetOffsets) {
|
||||||
E = VBaseOffsetOffsets.end(); I != E; ++I) {
|
std::string ClassName = I.first->getQualifiedNameAsString();
|
||||||
std::string ClassName = I->first->getQualifiedNameAsString();
|
CharUnits OffsetOffset = I.second;
|
||||||
CharUnits OffsetOffset = I->second;
|
ClassNamesAndOffsets.insert(std::make_pair(ClassName, OffsetOffset));
|
||||||
ClassNamesAndOffsets.insert(
|
|
||||||
std::make_pair(ClassName, OffsetOffset));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Out << "Virtual base offset offsets for '";
|
Out << "Virtual base offset offsets for '";
|
||||||
|
@ -2111,10 +2089,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
Out << ClassNamesAndOffsets.size();
|
Out << ClassNamesAndOffsets.size();
|
||||||
Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
|
Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
|
||||||
|
|
||||||
for (std::map<std::string, CharUnits>::const_iterator I =
|
for (const auto &I : ClassNamesAndOffsets)
|
||||||
ClassNamesAndOffsets.begin(), E = ClassNamesAndOffsets.end();
|
Out << " " << I.first << " | " << I.second.getQuantity() << '\n';
|
||||||
I != E; ++I)
|
|
||||||
Out << " " << I->first << " | " << I->second.getQuantity() << '\n';
|
|
||||||
|
|
||||||
Out << "\n";
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
@ -2122,10 +2098,9 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
if (!Thunks.empty()) {
|
if (!Thunks.empty()) {
|
||||||
// We store the method names in a map to get a stable order.
|
// We store the method names in a map to get a stable order.
|
||||||
std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
|
std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
|
||||||
|
|
||||||
for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end();
|
for (const auto &I : Thunks) {
|
||||||
I != E; ++I) {
|
const CXXMethodDecl *MD = I.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
|
||||||
std::string MethodName =
|
std::string MethodName =
|
||||||
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
|
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
|
||||||
MD);
|
MD);
|
||||||
|
@ -2133,11 +2108,9 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
|
MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<std::string, const CXXMethodDecl *>::const_iterator I =
|
for (const auto &I : MethodNamesAndDecls) {
|
||||||
MethodNamesAndDecls.begin(), E = MethodNamesAndDecls.end();
|
const std::string &MethodName = I.first;
|
||||||
I != E; ++I) {
|
const CXXMethodDecl *MD = I.second;
|
||||||
const std::string &MethodName = I->first;
|
|
||||||
const CXXMethodDecl *MD = I->second;
|
|
||||||
|
|
||||||
ThunkInfoVectorTy ThunksVector = Thunks[MD];
|
ThunkInfoVectorTy ThunksVector = Thunks[MD];
|
||||||
std::sort(ThunksVector.begin(), ThunksVector.end(),
|
std::sort(ThunksVector.begin(), ThunksVector.end(),
|
||||||
|
@ -2217,10 +2190,9 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
MostDerivedClass->printQualifiedName(Out);
|
MostDerivedClass->printQualifiedName(Out);
|
||||||
Out << "' (" << IndicesMap.size() << " entries).\n";
|
Out << "' (" << IndicesMap.size() << " entries).\n";
|
||||||
|
|
||||||
for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(),
|
for (const auto &I : IndicesMap) {
|
||||||
E = IndicesMap.end(); I != E; ++I) {
|
uint64_t VTableIndex = I.first;
|
||||||
uint64_t VTableIndex = I->first;
|
const std::string &MethodName = I.second;
|
||||||
const std::string &MethodName = I->second;
|
|
||||||
|
|
||||||
Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName
|
Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
@ -2295,14 +2267,11 @@ ItaniumVTableContext::getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
|
||||||
/*BaseIsVirtual=*/false,
|
/*BaseIsVirtual=*/false,
|
||||||
/*OffsetInLayoutClass=*/CharUnits::Zero());
|
/*OffsetInLayoutClass=*/CharUnits::Zero());
|
||||||
|
|
||||||
for (VCallAndVBaseOffsetBuilder::VBaseOffsetOffsetsMapTy::const_iterator I =
|
for (const auto &I : Builder.getVBaseOffsetOffsets()) {
|
||||||
Builder.getVBaseOffsetOffsets().begin(),
|
|
||||||
E = Builder.getVBaseOffsetOffsets().end(); I != E; ++I) {
|
|
||||||
// Insert all types.
|
// Insert all types.
|
||||||
ClassPairTy ClassPair(RD, I->first);
|
ClassPairTy ClassPair(RD, I.first);
|
||||||
|
|
||||||
VirtualBaseClassOffsetOffsets.insert(
|
VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I.second));
|
||||||
std::make_pair(ClassPair, I->second));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
I = VirtualBaseClassOffsetOffsets.find(ClassPair);
|
I = VirtualBaseClassOffsetOffsets.find(ClassPair);
|
||||||
|
@ -2353,14 +2322,11 @@ ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) {
|
||||||
if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
|
if (VirtualBaseClassOffsetOffsets.count(std::make_pair(RD, VBase)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ItaniumVTableBuilder::VBaseOffsetOffsetsMapTy::const_iterator
|
for (const auto &I : Builder.getVBaseOffsetOffsets()) {
|
||||||
I = Builder.getVBaseOffsetOffsets().begin(),
|
|
||||||
E = Builder.getVBaseOffsetOffsets().end();
|
|
||||||
I != E; ++I) {
|
|
||||||
// Insert all types.
|
// Insert all types.
|
||||||
ClassPairTy ClassPair(RD, I->first);
|
ClassPairTy ClassPair(RD, I.first);
|
||||||
|
|
||||||
VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I->second));
|
VirtualBaseClassOffsetOffsets.insert(std::make_pair(ClassPair, I.second));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2553,10 +2519,9 @@ private:
|
||||||
"vftable can't be empty");
|
"vftable can't be empty");
|
||||||
|
|
||||||
assert(MethodVFTableLocations.empty());
|
assert(MethodVFTableLocations.empty());
|
||||||
for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
|
for (const auto &I : MethodInfoMap) {
|
||||||
E = MethodInfoMap.end(); I != E; ++I) {
|
const CXXMethodDecl *MD = I.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
const MethodInfo &MI = I.second;
|
||||||
const MethodInfo &MI = I->second;
|
|
||||||
// Skip the methods that the MostDerivedClass didn't override
|
// Skip the methods that the MostDerivedClass didn't override
|
||||||
// and the entries shadowed by return adjusting thunks.
|
// and the entries shadowed by return adjusting thunks.
|
||||||
if (MD->getParent() != MostDerivedClass || MI.Shadowed)
|
if (MD->getParent() != MostDerivedClass || MI.Shadowed)
|
||||||
|
@ -2720,17 +2685,14 @@ VFTableBuilder::ComputeThisOffset(FinalOverriders::OverriderInfo Overrider) {
|
||||||
|
|
||||||
const ASTRecordLayout &OverriderRDLayout =
|
const ASTRecordLayout &OverriderRDLayout =
|
||||||
Context.getASTRecordLayout(Overrider.Method->getParent());
|
Context.getASTRecordLayout(Overrider.Method->getParent());
|
||||||
for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
|
for (const CXXBasePath &Path : Paths) {
|
||||||
I != E; ++I) {
|
|
||||||
const CXXBasePath &Path = (*I);
|
|
||||||
CharUnits ThisOffset = Overrider.Offset;
|
CharUnits ThisOffset = Overrider.Offset;
|
||||||
CharUnits LastVBaseOffset;
|
CharUnits LastVBaseOffset;
|
||||||
|
|
||||||
// For each path from the overrider to the parents of the overridden
|
// For each path from the overrider to the parents of the overridden
|
||||||
// methods, traverse the path, calculating the this offset in the most
|
// methods, traverse the path, calculating the this offset in the most
|
||||||
// derived class.
|
// derived class.
|
||||||
for (int J = 0, F = Path.size(); J != F; ++J) {
|
for (const CXXBasePathElement &Element : Path) {
|
||||||
const CXXBasePathElement &Element = Path[J];
|
|
||||||
QualType CurTy = Element.Base->getType();
|
QualType CurTy = Element.Base->getType();
|
||||||
const CXXRecordDecl *PrevRD = Element.Class,
|
const CXXRecordDecl *PrevRD = Element.Class,
|
||||||
*CurRD = CurTy->getAsCXXRecordDecl();
|
*CurRD = CurTy->getAsCXXRecordDecl();
|
||||||
|
@ -2938,8 +2900,8 @@ static void GroupNewVirtualOverloads(
|
||||||
Groups[J->second].push_back(MD);
|
Groups[J->second].push_back(MD);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned I = 0, E = Groups.size(); I != E; ++I)
|
for (const MethodGroup &Group : Groups)
|
||||||
VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend());
|
VirtualMethods.append(Group.rbegin(), Group.rend());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
|
static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
|
||||||
|
@ -2999,9 +2961,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
|
||||||
// sub-bases;
|
// sub-bases;
|
||||||
// - adding new slots for methods that require Return adjustment.
|
// - adding new slots for methods that require Return adjustment.
|
||||||
// We keep track of the methods visited in the sub-bases in MethodInfoMap.
|
// We keep track of the methods visited in the sub-bases in MethodInfoMap.
|
||||||
for (unsigned I = 0, E = VirtualMethods.size(); I != E; ++I) {
|
for (const CXXMethodDecl *MD : VirtualMethods) {
|
||||||
const CXXMethodDecl *MD = VirtualMethods[I];
|
|
||||||
|
|
||||||
FinalOverriders::OverriderInfo FinalOverrider =
|
FinalOverriders::OverriderInfo FinalOverrider =
|
||||||
Overriders.getOverrider(MD, Base.getBaseOffset());
|
Overriders.getOverrider(MD, Base.getBaseOffset());
|
||||||
const CXXMethodDecl *FinalOverriderMD = FinalOverrider.Method;
|
const CXXMethodDecl *FinalOverriderMD = FinalOverrider.Method;
|
||||||
|
@ -3110,10 +3070,10 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) {
|
static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) {
|
||||||
for (VPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(),
|
for (const CXXRecordDecl *Elem :
|
||||||
E = Path.rend(); I != E; ++I) {
|
llvm::make_range(Path.rbegin(), Path.rend())) {
|
||||||
Out << "'";
|
Out << "'";
|
||||||
(*I)->printQualifiedName(Out);
|
Elem->printQualifiedName(Out);
|
||||||
Out << "' in ";
|
Out << "' in ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3235,21 +3195,17 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
// We store the method names in a map to get a stable order.
|
// We store the method names in a map to get a stable order.
|
||||||
std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
|
std::map<std::string, const CXXMethodDecl *> MethodNamesAndDecls;
|
||||||
|
|
||||||
for (ThunksMapTy::const_iterator I = Thunks.begin(), E = Thunks.end();
|
for (const auto &I : Thunks) {
|
||||||
I != E; ++I) {
|
const CXXMethodDecl *MD = I.first;
|
||||||
const CXXMethodDecl *MD = I->first;
|
|
||||||
std::string MethodName = PredefinedExpr::ComputeName(
|
std::string MethodName = PredefinedExpr::ComputeName(
|
||||||
PredefinedExpr::PrettyFunctionNoVirtual, MD);
|
PredefinedExpr::PrettyFunctionNoVirtual, MD);
|
||||||
|
|
||||||
MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
|
MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<std::string, const CXXMethodDecl *>::const_iterator
|
for (const auto &MethodNameAndDecl : MethodNamesAndDecls) {
|
||||||
I = MethodNamesAndDecls.begin(),
|
const std::string &MethodName = MethodNameAndDecl.first;
|
||||||
E = MethodNamesAndDecls.end();
|
const CXXMethodDecl *MD = MethodNameAndDecl.second;
|
||||||
I != E; ++I) {
|
|
||||||
const std::string &MethodName = I->first;
|
|
||||||
const CXXMethodDecl *MD = I->second;
|
|
||||||
|
|
||||||
ThunkInfoVectorTy ThunksVector = Thunks[MD];
|
ThunkInfoVectorTy ThunksVector = Thunks[MD];
|
||||||
std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
|
std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
|
||||||
|
@ -3279,9 +3235,8 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
|
||||||
|
|
||||||
static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
|
static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
|
||||||
ArrayRef<const CXXRecordDecl *> B) {
|
ArrayRef<const CXXRecordDecl *> B) {
|
||||||
for (ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), E = B.end();
|
for (const CXXRecordDecl *Decl : B) {
|
||||||
I != E; ++I) {
|
if (A.count(Decl))
|
||||||
if (A.count(*I))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -3624,11 +3579,10 @@ void MicrosoftVTableContext::computeVTableRelatedInformation(
|
||||||
VFPtrLocations[RD] = VFPtrs;
|
VFPtrLocations[RD] = VFPtrs;
|
||||||
|
|
||||||
MethodVFTableLocationsTy NewMethodLocations;
|
MethodVFTableLocationsTy NewMethodLocations;
|
||||||
for (VPtrInfoVector::iterator I = VFPtrs->begin(), E = VFPtrs->end();
|
for (const VPtrInfo *VFPtr : *VFPtrs) {
|
||||||
I != E; ++I) {
|
VFTableBuilder Builder(*this, RD, VFPtr);
|
||||||
VFTableBuilder Builder(*this, RD, *I);
|
|
||||||
|
|
||||||
VFTableIdTy id(RD, (*I)->FullOffsetInMDC);
|
VFTableIdTy id(RD, VFPtr->FullOffsetInMDC);
|
||||||
assert(VFTableLayouts.count(id) == 0);
|
assert(VFTableLayouts.count(id) == 0);
|
||||||
SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
|
SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
|
||||||
Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
|
Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
|
||||||
|
@ -3660,21 +3614,20 @@ void MicrosoftVTableContext::dumpMethodLocations(
|
||||||
std::map<MethodVFTableLocation, std::string> IndicesMap;
|
std::map<MethodVFTableLocation, std::string> IndicesMap;
|
||||||
bool HasNonzeroOffset = false;
|
bool HasNonzeroOffset = false;
|
||||||
|
|
||||||
for (MethodVFTableLocationsTy::const_iterator I = NewMethods.begin(),
|
for (const auto &I : NewMethods) {
|
||||||
E = NewMethods.end(); I != E; ++I) {
|
const CXXMethodDecl *MD = cast<const CXXMethodDecl>(I.first.getDecl());
|
||||||
const CXXMethodDecl *MD = cast<const CXXMethodDecl>(I->first.getDecl());
|
|
||||||
assert(MD->isVirtual());
|
assert(MD->isVirtual());
|
||||||
|
|
||||||
std::string MethodName = PredefinedExpr::ComputeName(
|
std::string MethodName = PredefinedExpr::ComputeName(
|
||||||
PredefinedExpr::PrettyFunctionNoVirtual, MD);
|
PredefinedExpr::PrettyFunctionNoVirtual, MD);
|
||||||
|
|
||||||
if (isa<CXXDestructorDecl>(MD)) {
|
if (isa<CXXDestructorDecl>(MD)) {
|
||||||
IndicesMap[I->second] = MethodName + " [scalar deleting]";
|
IndicesMap[I.second] = MethodName + " [scalar deleting]";
|
||||||
} else {
|
} else {
|
||||||
IndicesMap[I->second] = MethodName;
|
IndicesMap[I.second] = MethodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!I->second.VFPtrOffset.isZero() || I->second.VBTableIndex != 0)
|
if (!I.second.VFPtrOffset.isZero() || I.second.VBTableIndex != 0)
|
||||||
HasNonzeroOffset = true;
|
HasNonzeroOffset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3688,12 +3641,9 @@ void MicrosoftVTableContext::dumpMethodLocations(
|
||||||
|
|
||||||
CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1);
|
CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1);
|
||||||
uint64_t LastVBIndex = 0;
|
uint64_t LastVBIndex = 0;
|
||||||
for (std::map<MethodVFTableLocation, std::string>::const_iterator
|
for (const auto &I : IndicesMap) {
|
||||||
I = IndicesMap.begin(),
|
CharUnits VFPtrOffset = I.first.VFPtrOffset;
|
||||||
E = IndicesMap.end();
|
uint64_t VBIndex = I.first.VBTableIndex;
|
||||||
I != E; ++I) {
|
|
||||||
CharUnits VFPtrOffset = I->first.VFPtrOffset;
|
|
||||||
uint64_t VBIndex = I->first.VBTableIndex;
|
|
||||||
if (HasNonzeroOffset &&
|
if (HasNonzeroOffset &&
|
||||||
(VFPtrOffset != LastVFPtrOffset || VBIndex != LastVBIndex)) {
|
(VFPtrOffset != LastVFPtrOffset || VBIndex != LastVBIndex)) {
|
||||||
assert(VBIndex > LastVBIndex || VFPtrOffset > LastVFPtrOffset);
|
assert(VBIndex > LastVBIndex || VFPtrOffset > LastVFPtrOffset);
|
||||||
|
@ -3705,8 +3655,8 @@ void MicrosoftVTableContext::dumpMethodLocations(
|
||||||
LastVBIndex = VBIndex;
|
LastVBIndex = VBIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t VTableIndex = I->first.Index;
|
uint64_t VTableIndex = I.first.Index;
|
||||||
const std::string &MethodName = I->second;
|
const std::string &MethodName = I.second;
|
||||||
Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName << '\n';
|
Out << llvm::format("%4" PRIu64 " | ", VTableIndex) << MethodName << '\n';
|
||||||
}
|
}
|
||||||
Out << '\n';
|
Out << '\n';
|
||||||
|
|
Loading…
Reference in New Issue