Fix to dumpLayout; we want to be able to dump address points even if the vtable doesn't have any methods.

llvm-svn: 97350
This commit is contained in:
Anders Carlsson 2010-02-27 23:58:01 +00:00
parent 45e7ffc350
commit f98b47d3b9
1 changed files with 34 additions and 31 deletions

View File

@ -1866,37 +1866,6 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
unsigned NextThisAdjustmentIndex = 0;
for (unsigned I = 0, E = Components.size(); I != E; ++I) {
uint64_t Index = I;
if (AddressPointsByIndex.count(I)) {
if (AddressPointsByIndex.count(Index) == 1) {
const BaseSubobject &Base = AddressPointsByIndex.find(Index)->second;
// FIXME: Instead of dividing by 8, we should be using CharUnits.
Out << " -- (" << Base.getBase()->getQualifiedNameAsString();
Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
} else {
uint64_t BaseOffset =
AddressPointsByIndex.lower_bound(Index)->second.getBaseOffset();
// We store the class names in a set to get a stable order.
std::set<std::string> ClassNames;
for (std::multimap<uint64_t, BaseSubobject>::const_iterator I =
AddressPointsByIndex.lower_bound(Index), E =
AddressPointsByIndex.upper_bound(Index); I != E; ++I) {
assert(I->second.getBaseOffset() == BaseOffset &&
"Invalid base offset!");
const CXXRecordDecl *RD = I->second.getBase();
ClassNames.insert(RD->getQualifiedNameAsString());
}
for (std::set<std::string>::const_iterator I = ClassNames.begin(),
E = ClassNames.end(); I != E; ++I) {
// FIXME: Instead of dividing by 8, we should be using CharUnits.
Out << " -- (" << *I;
Out << ", " << BaseOffset / 8 << ") vtable address --\n";
}
}
}
Out << llvm::format("%4d | ", I);
@ -2019,6 +1988,40 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
}
Out << '\n';
// Dump the next address point.
uint64_t NextIndex = Index + 1;
if (AddressPointsByIndex.count(NextIndex)) {
if (AddressPointsByIndex.count(NextIndex) == 1) {
const BaseSubobject &Base =
AddressPointsByIndex.find(NextIndex)->second;
// FIXME: Instead of dividing by 8, we should be using CharUnits.
Out << " -- (" << Base.getBase()->getQualifiedNameAsString();
Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
} else {
uint64_t BaseOffset =
AddressPointsByIndex.lower_bound(NextIndex)->second.getBaseOffset();
// We store the class names in a set to get a stable order.
std::set<std::string> ClassNames;
for (std::multimap<uint64_t, BaseSubobject>::const_iterator I =
AddressPointsByIndex.lower_bound(NextIndex), E =
AddressPointsByIndex.upper_bound(NextIndex); I != E; ++I) {
assert(I->second.getBaseOffset() == BaseOffset &&
"Invalid base offset!");
const CXXRecordDecl *RD = I->second.getBase();
ClassNames.insert(RD->getQualifiedNameAsString());
}
for (std::set<std::string>::const_iterator I = ClassNames.begin(),
E = ClassNames.end(); I != E; ++I) {
// FIXME: Instead of dividing by 8, we should be using CharUnits.
Out << " -- (" << *I;
Out << ", " << BaseOffset / 8 << ") vtable address --\n";
}
}
}
}
Out << '\n';