summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGCXXABI.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-02-15 01:22:51 +0000
committerJohn McCall <rjmccall@apple.com>2012-02-15 01:22:51 +0000
commit4d4e5c1ae83f4510caa486b3ad19de13048f9f04 (patch)
tree26373f3fad4bc1dd6755ffdf202cba801aabc544 /lib/CodeGen/CGCXXABI.cpp
parent011d8b93b7cfa8492b8a9c909a850d6577e08dca (diff)
Split reinterpret_casts of member pointers out from CK_BitCast; this
is general goodness because representations of member pointers are not always equivalent across member pointer types on all ABIs (even though this isn't really standard-endorsed). Take advantage of the new information to teach IR-generation how to do these reinterprets in constant initializers. Make sure this works when intermingled with hierarchy conversions (although this is not part of our motivating use case). Doing this in the constant-evaluator would probably have been better, but that would require a *lot* of extra structure in the representation of constant member pointers: you'd really have to track an arbitrary chain of hierarchy conversions and reinterpretations in order to get this right. Ultimately, this seems less complex. I also wasn't quite sure how to extend the constant evaluator to handle foldings that we don't actually want to treat as extended constant expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150551 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXXABI.cpp')
-rw-r--r--lib/CodeGen/CGCXXABI.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index e5d3f2da6b..fc3f45d75b 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -71,6 +71,11 @@ llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
return GetBogusMemberPointer(CGM, E->getType());
}
+llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
+ llvm::Constant *Src) {
+ return GetBogusMemberPointer(CGM, E->getType());
+}
+
llvm::Value *
CGCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
llvm::Value *L,
@@ -172,3 +177,24 @@ void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
bool PerformInit) {
ErrorUnsupportedABI(CGF, "static local variable initialization");
}
+
+/// Returns the adjustment, in bytes, required for the given
+/// member-pointer operation. Returns null if no adjustment is
+/// required.
+llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
+ assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
+ E->getCastKind() == CK_BaseToDerivedMemberPointer);
+
+ QualType derivedType;
+ if (E->getCastKind() == CK_DerivedToBaseMemberPointer)
+ derivedType = E->getSubExpr()->getType();
+ else
+ derivedType = E->getType();
+
+ const CXXRecordDecl *derivedClass =
+ derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
+
+ return CGM.GetNonVirtualBaseClassOffset(derivedClass,
+ E->path_begin(),
+ E->path_end());
+}