summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-11 17:18:51 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-11 17:18:51 +0000
commit932c2f2a9afd35489d0b924260e48246786b667a (patch)
tree2ab8e8370ad8410f5b2d62050db8407634b44e59
parent9c13dfb5ddc4c215294f458c3fa2bad14097adca (diff)
downloadbcm5719-llvm-932c2f2a9afd35489d0b924260e48246786b667a.tar.gz
bcm5719-llvm-932c2f2a9afd35489d0b924260e48246786b667a.zip
Keep track of, and dump, vtable address points.
llvm-svn: 95874
-rw-r--r--clang/lib/CodeGen/CGVtable.cpp35
-rw-r--r--clang/test/CodeGenCXX/vtable-layout.cpp1
2 files changed, 34 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp
index 5d3944f6dd0..d2b6c08712e 100644
--- a/clang/lib/CodeGen/CGVtable.cpp
+++ b/clang/lib/CodeGen/CGVtable.cpp
@@ -132,6 +132,9 @@ class VtableBuilder {
/// Components - The components of the vtable being built.
llvm::SmallVector<VtableComponent, 64> Components;
+ /// AddressPoints - Address points for the vtable being built.
+ CGVtableInfo::AddressPointsMapTy AddressPoints;
+
/// layoutSimpleVtable - A test function that will layout very simple vtables
/// without any bases. Just used for testing for now.
void layoutSimpleVtable(const CXXRecordDecl *RD);
@@ -159,6 +162,9 @@ void VtableBuilder::layoutSimpleVtable(const CXXRecordDecl *RD) {
// Next, add the RTTI.
Components.push_back(VtableComponent::MakeRTTI(RD));
+ // Record the address point.
+ AddressPoints.insert(std::make_pair(BaseSubobject(RD, 0), Components.size()));
+
// Now go through all virtual member functions and add them.
for (CXXRecordDecl::method_iterator I = RD->method_begin(),
E = RD->method_end(); I != E; ++I) {
@@ -178,9 +184,34 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
Out << "Vtable for '" << MostDerivedClass->getQualifiedNameAsString();
Out << "' (" << Components.size() << " entries).\n";
+ // Iterate through the address points and insert them into a new map where
+ // they are keyed by the index and not the base object.
+ // Since an address point can be shared by multiple subobjects, we use an
+ // STL multimap.
+ std::multimap<uint64_t, BaseSubobject> AddressPointsByIndex;
+ for (CGVtableInfo::AddressPointsMapTy::const_iterator I =
+ AddressPoints.begin(), E = AddressPoints.end(); I != E; ++I) {
+ const BaseSubobject& Base = I->first;
+ uint64_t Index = I->second;
+
+ AddressPointsByIndex.insert(std::make_pair(Index, Base));
+ }
+
for (unsigned I = 0, E = Components.size(); I != E; ++I) {
+ if (AddressPointsByIndex.count(I)) {
+ assert(AddressPointsByIndex.count(I) == 1 &&
+ "FIXME: Handle dumping multiple base subobjects for a single "
+ "address point!");
+
+ const BaseSubobject &Base = AddressPointsByIndex.find(I)->second;
+ Out << " -- (" << Base.getBase()->getQualifiedNameAsString();
+
+ // FIXME: Instead of dividing by 8, we should be using CharUnits.
+ Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
+ }
+
Out << llvm::format("%4d | ", I);
-
+
const VtableComponent &Component = Components[I];
// Dump the component.
@@ -207,7 +238,7 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
}
}
-
+
Out << '\n';
}
diff --git a/clang/test/CodeGenCXX/vtable-layout.cpp b/clang/test/CodeGenCXX/vtable-layout.cpp
index 6bfa025beaa..beb82ef9054 100644
--- a/clang/test/CodeGenCXX/vtable-layout.cpp
+++ b/clang/test/CodeGenCXX/vtable-layout.cpp
@@ -4,6 +4,7 @@ namespace Test1 {
// CHECK: Vtable for 'Test1::A' (3 entries).
// CHECK-NEXT: 0 | offset_to_top (0)
// CHECK-NEXT: 1 | Test1::A RTTI
+// CHECK-NEXT: -- (Test1::A, 0) vtable address --
// CHECK-NEXT: 2 | Test1::A::f
struct A {
virtual void f();
OpenPOWER on IntegriCloud