aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-02-12 07:43:48 +0000
committerAnders Carlsson <andersca@mac.com>2010-02-12 07:43:48 +0000
commit28cbc8b512db420748601dba276144d729a0d7a2 (patch)
treef9dd1a52803bebf70b16bb28998b7bed16c5b82b /lib/CodeGen/CGVtable.cpp
parente13ad837709cd7730e18d8af1cf6b7d35a56d6b7 (diff)
Keep track of the address points for all primary bases, and add the ability to dump multiple address points for a single offset.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95970 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index e2ea4736d3..226be1972e 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
#include <cstdio>
@@ -608,14 +609,26 @@ void VtableBuilder::layoutSimpleVtable(BaseSubobject Base) {
// Next, add the RTTI.
Components.push_back(VtableComponent::MakeRTTI(RD));
- // Record the address point.
- // FIXME: Record the address point for all primary bases.
- AddressPoints.insert(std::make_pair(Base, Components.size()));
+ uint64_t AddressPoint = Components.size();
// Now go through all virtual member functions and add them.
PrimaryBasesSetTy PrimaryBases;
layoutVirtualMemberFunctions(Base, PrimaryBases);
+ // Record the address point.
+ AddressPoints.insert(std::make_pair(Base, AddressPoint));
+
+ // Record the address points for all primary bases.
+ for (PrimaryBasesSetTy::const_iterator I = PrimaryBases.begin(),
+ E = PrimaryBases.end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl = *I;
+
+ // We know that all the primary bases have the same offset as the base
+ // subobject.
+ BaseSubobject PrimaryBase(BaseDecl, Base.getBaseOffset());
+ AddressPoints.insert(std::make_pair(PrimaryBase, AddressPoint));
+ }
+
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
@@ -655,16 +668,40 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) {
}
for (unsigned I = 0, E = Components.size(); I != E; ++I) {
+ uint64_t Index = 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();
+ std::string Str;
+
- // FIXME: Instead of dividing by 8, we should be using CharUnits.
- Out << ", " << Base.getBaseOffset() / 8 << ") vtable address --\n";
+ 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);