[cfe-commits] r96587 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/vtable-layout-abi-examples.cpp
Anders Carlsson
andersca at mac.com
Thu Feb 18 09:26:41 PST 2010
Author: andersca
Date: Thu Feb 18 11:26:40 2010
New Revision: 96587
URL: http://llvm.org/viewvc/llvm-project?rev=96587&view=rev
Log:
More work on vcall offsets.
Modified:
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=96587&r1=96586&r2=96587&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Thu Feb 18 11:26:40 2010
@@ -803,6 +803,11 @@
// FIXME: This should be a real map and not a vector.
llvm::SmallVector<MethodAndOffsetPairTy, 16> Offsets;
+ /// MethodsCanShareVCallOffset - Returns whether two virtual member functions
+ /// can share the same vcall offset.
+ static bool MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
+ const CXXMethodDecl *RHS);
+
public:
/// AddVCallOffset - Adds a vcall offset to the map. Returns true if the
/// add was successful, or false if there was already a member function with
@@ -817,14 +822,50 @@
void clear() { Offsets.clear(); }
};
+bool VCallOffsetMap::MethodsCanShareVCallOffset(const CXXMethodDecl *LHS,
+ const CXXMethodDecl *RHS) {
+ assert(LHS->isVirtual() && "LHS must be virtual!");
+ assert(RHS->isVirtual() && "LHS must be virtual!");
+
+ // FIXME: We need to check more things here.
+
+ DeclarationName LHSName = LHS->getDeclName();
+ DeclarationName RHSName = RHS->getDeclName();
+ if (LHSName.getNameKind() != LHSName.getNameKind())
+ return false;
+
+ switch (LHSName.getNameKind()) {
+ default:
+ assert(false && "Unhandled name kind!");
+ case DeclarationName::Identifier:
+ if (LHSName.getAsIdentifierInfo() != RHSName.getAsIdentifierInfo())
+ return false;
+ }
+
+ return true;
+}
+
bool VCallOffsetMap::AddVCallOffset(const CXXMethodDecl *MD,
int64_t OffsetOffset) {
- /// FIXME: Implement this.
+ // Check if we can reuse an offset.
+ for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
+ if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
+ return false;
+ }
+
+ // Add the offset.
+ Offsets.push_back(MethodAndOffsetPairTy(MD, OffsetOffset));
return true;
}
int64_t VCallOffsetMap::getVCallOffsetOffset(const CXXMethodDecl *MD) {
- // FIXME: Implement this.
+ // Look for an offset.
+ for (unsigned I = 0, E = Offsets.size(); I != E; ++I) {
+ if (MethodsCanShareVCallOffset(Offsets[I].first, MD))
+ return Offsets[I].second;
+ }
+
+ assert(false && "Should always find a vcall offset offset!");
return 0;
}
@@ -1010,7 +1051,11 @@
ThisAdjustment Adjustment;
if (!Offset.isEmpty()) {
- assert(!Offset.VirtualBase && "FIXME: Handle virtual bases!");
+ if (Offset.VirtualBase) {
+ // Get the vcall offset offset.
+ Adjustment.VCallOffsetOffset = VCallOffsets.getVCallOffsetOffset(MD);
+ }
+
Adjustment.NonVirtual = Offset.NonVirtualOffset;
}
@@ -1069,8 +1114,20 @@
if (!MD->isVirtual())
continue;
- // FIXME: Check if we already have a vcall offset for this member function
+ // OffsetIndex is the index of this vcall offset, relative to the vtable
+ // address point. (We subtract 3 to account for the information just
+ // above the address point, the RTTI info, the offset to top, and the
+ // vcall offset itself).
+ int64_t OffsetIndex = -(3 + VCallAndVBaseOffsets.size());
+
+ // FIXME: We shouldn't use / 8 here.
+ int64_t OffsetOffset = OffsetIndex *
+ (int64_t)Context.Target.getPointerWidth(0) / 8;
+
+ // Don't add a vcall offset if we already have one for this member function
// signature.
+ if (!VCallOffsets.AddVCallOffset(MD, OffsetOffset))
+ continue;
// Get the 'this' pointer adjustment offset.
FinalOverriders::BaseOffset ThisAdjustmentOffset =
Modified: cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp?rev=96587&r1=96586&r2=96587&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout-abi-examples.cpp Thu Feb 18 11:26:40 2010
@@ -21,5 +21,30 @@
int ia;
};
void A::f() {}
+
+// CHECK: Vtable for 'Test1::B' (13 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test1::B RTTI
+// CHECK-NEXT: -- (Test1::B, 0) vtable address --
+// CHECK-NEXT: 3 | void Test1::B::f()
+// CHECK-NEXT: 4 | void Test1::B::h()
+// CHECK-NEXT: 5 | vcall_offset (-16)
+// CHECK-NEXT: 6 | vcall_offset (0)
+// CHECK-NEXT: 7 | vcall_offset (-16)
+// CHECK-NEXT: 8 | offset_to_top (-16)
+// CHECK-NEXT: 9 | Test1::B RTTI
+// CHECK-NEXT: -- (Test1::A, 16) vtable address --
+// CHECK-NEXT: 10 | void Test1::B::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 11 | void Test1::A::g()
+// CHECK-NEXT: 12 | void Test1::B::h()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct B: public virtual A {
+ void f ();
+ void h ();
+ int ib;
+};
+void B::f() {}
}
More information about the cfe-commits
mailing list