- formatting
Hi rjmccall,
http://llvm-reviews.chandlerc.com/D558
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D558?vs=1333&id=1338#toc
Files:
lib/CodeGen/CGCXXABI.cpp
lib/CodeGen/CGCXXABI.h
lib/CodeGen/ItaniumCXXABI.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/microsoft-abi-member-pointers.cpp
Index: lib/CodeGen/CGCXXABI.cpp
===================================================================
--- lib/CodeGen/CGCXXABI.cpp
+++ lib/CodeGen/CGCXXABI.cpp
@@ -19,18 +19,16 @@
CGCXXABI::~CGCXXABI() { }
-static void ErrorUnsupportedABI(CodeGenFunction &CGF,
- StringRef S) {
+void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot yet compile %0 in this ABI");
Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
DiagID)
<< S;
}
-static llvm::Constant *GetBogusMemberPointer(CodeGenModule &CGM,
- QualType T) {
+llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
}
@@ -67,12 +65,12 @@
const CastExpr *E,
llvm::Value *Src) {
ErrorUnsupportedABI(CGF, "member function pointer conversions");
- return GetBogusMemberPointer(CGM, E->getType());
+ return GetBogusMemberPointer(E->getType());
}
llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
llvm::Constant *Src) {
- return GetBogusMemberPointer(CGM, E->getType());
+ return GetBogusMemberPointer(E->getType());
}
llvm::Value *
@@ -95,22 +93,22 @@
llvm::Constant *
CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
- return GetBogusMemberPointer(CGM, QualType(MPT, 0));
+ return GetBogusMemberPointer(QualType(MPT, 0));
}
llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
- return GetBogusMemberPointer(CGM,
+ return GetBogusMemberPointer(
CGM.getContext().getMemberPointerType(MD->getType(),
MD->getParent()->getTypeForDecl()));
}
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
CharUnits offset) {
- return GetBogusMemberPointer(CGM, QualType(MPT, 0));
+ return GetBogusMemberPointer(QualType(MPT, 0));
}
llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
- return GetBogusMemberPointer(CGM, MPT);
+ return GetBogusMemberPointer(MPT);
}
bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
Index: lib/CodeGen/CGCXXABI.h
===================================================================
--- lib/CodeGen/CGCXXABI.h
+++ lib/CodeGen/CGCXXABI.h
@@ -42,9 +42,11 @@
protected:
CodeGenModule &CGM;
OwningPtr<MangleContext> MangleCtx;
+ llvm::IntegerType *PtrDiffTy;
CGCXXABI(CodeGenModule &CGM)
- : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
+ : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()),
+ PtrDiffTy(0) {}
protected:
ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) {
@@ -54,6 +56,22 @@
return CGF.CXXABIThisValue;
}
+ // It's a little silly for us to cache this.
+ llvm::IntegerType *getPtrDiffTy() {
+ if (!PtrDiffTy) {
+ QualType T = getContext().getPointerDiffType();
+ llvm::Type *Ty = CGM.getTypes().ConvertType(T);
+ PtrDiffTy = cast<llvm::IntegerType>(Ty);
+ }
+ return PtrDiffTy;
+ }
+
+ /// Issue a diagnostic about unsupported features in the ABI.
+ void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S);
+
+ /// Get a null value for unsupported member pointers.
+ llvm::Constant *GetBogusMemberPointer(QualType T);
+
// FIXME: Every place that calls getVTT{Decl,Value} is something
// that needs to be abstracted properly.
ImplicitParamDecl *&getVTTDecl(CodeGenFunction &CGF) {
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -34,24 +34,12 @@
namespace {
class ItaniumCXXABI : public CodeGen::CGCXXABI {
-private:
- llvm::IntegerType *PtrDiffTy;
protected:
bool IsARM;
- // It's a little silly for us to cache this.
- llvm::IntegerType *getPtrDiffTy() {
- if (!PtrDiffTy) {
- QualType T = getContext().getPointerDiffType();
- llvm::Type *Ty = CGM.getTypes().ConvertType(T);
- PtrDiffTy = cast<llvm::IntegerType>(Ty);
- }
- return PtrDiffTy;
- }
-
public:
ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) :
- CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { }
+ CGCXXABI(CGM), IsARM(IsARM) { }
bool isZeroInitializable(const MemberPointerType *MPT);
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -109,6 +109,26 @@
llvm::Value *allocPtr,
CharUnits cookieSize);
static bool needThisReturn(GlobalDecl GD);
+
+private:
+ llvm::Constant *
+ getNullMemberDataPointer(const MemberPointerType *MPT);
+
+public:
+ virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
+
+ virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
+ CharUnits offset);
+
+ virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+ llvm::Value *MemPtr,
+ const MemberPointerType *MPT);
+
+ virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
+ llvm::Value *Base,
+ llvm::Value *MemPtr,
+ const MemberPointerType *MPT);
+
};
}
@@ -352,6 +372,96 @@
CGF.EmitCXXGlobalVarDeclInit(D, DeclPtr, PerformInit);
}
+llvm::Constant *
+MicrosoftCXXABI::getNullMemberDataPointer(const MemberPointerType *MPT) {
+ assert(MPT->isMemberDataPointer());
+ llvm::Constant *Zero = llvm::ConstantInt::get(getPtrDiffTy(), 0);
+ llvm::Constant *AllOnes = llvm::Constant::getAllOnesValue(getPtrDiffTy());
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
+ if (RD->getNumVBases() == 0) {
+ // A null member data pointer is represented as -1 if the class is not
+ // polymorphic, and 0 otherwise.
+ if (RD->isPolymorphic())
+ return Zero;
+ return AllOnes;
+ }
+ // The null representation is {field: 0, vbtable: -1}.
+ // FIXME: In the Itanium ABI, member data pointers are always scalars.
+ // Returning this aggregate will assert until we change codegen.
+ assert(RD->getNumVBases() == 0 && "implement dynamic class member pointers");
+ llvm::Constant *Values[2] = { Zero, AllOnes };
+ return llvm::ConstantStruct::getAnon(Values);
+}
+
+llvm::Constant *
+MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
+ if (MPT->isMemberDataPointer())
+ return getNullMemberDataPointer(MPT);
+ // FIXME: Implement function member pointers.
+ return GetBogusMemberPointer(QualType(MPT, 0));
+}
+
+llvm::Constant *
+MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
+ CharUnits offset) {
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
+ // Member data pointers are plain offsets when no virtual bases are involved.
+ if (RD->getNumVBases() == 0)
+ return llvm::ConstantInt::get(getPtrDiffTy(), offset.getQuantity());
+ // FIXME: Emit a pair of {vbtable offset, field offset} when we know vbtable
+ // layout.
+ return GetBogusMemberPointer(QualType(MPT, 0));
+}
+
+llvm::Value *
+MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+ llvm::Value *MemPtr,
+ const MemberPointerType *MPT) {
+ CGBuilderTy &Builder = CGF.Builder;
+
+ // For member data pointers, this is just a check against -1 or 0.
+ if (MPT->isMemberDataPointer()) {
+ assert(MemPtr->getType() == getPtrDiffTy());
+ llvm::Constant *Val = getNullMemberDataPointer(MPT);
+ return Builder.CreateICmpNE(MemPtr, Val, "memptr.tobool");
+ }
+
+ // FIXME: Implement function member pointers.
+ ErrorUnsupportedABI(CGF, "function member pointer tests");
+ return GetBogusMemberPointer(QualType(MPT, 0));
+}
+
+llvm::Value *
+MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
+ llvm::Value *Base,
+ llvm::Value *MemPtr,
+ const MemberPointerType *MPT) {
+ unsigned AS = Base->getType()->getPointerAddressSpace();
+ llvm::Type *PType =
+ CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
+
+ if (MPT->isMemberFunctionPointer()) {
+ ErrorUnsupportedABI(CGF, "function member pointer address");
+ return llvm::Constant::getNullValue(PType);
+ }
+ if (MemPtr->getType() != getPtrDiffTy()) {
+ // If it's not a ptrdiff_t, then it's an aggregate.
+ ErrorUnsupportedABI(CGF, "non-scalar member pointers");
+ return llvm::Constant::getNullValue(PType);
+ }
+
+ // Simply add the offset with GEP and i8*.
+ CGBuilderTy &Builder = CGF.Builder;
+ Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
+ llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
+
+ // Cast the address to the appropriate pointer type, adopting the
+ // address space of the base pointer.
+ return Builder.CreateBitCast(Addr, PType);
+}
+
CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
return new MicrosoftCXXABI(CGM);
}
Index: test/CodeGenCXX/microsoft-abi-member-pointers.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+struct POD {
+ int a;
+ int b;
+};
+
+void podMemPtrs() {
+ int POD::*memptr;
+ memptr = &POD::a;
+ // CHECK: store i32 0,
+ memptr = &POD::b;
+ // CHECK: store i32 4,
+ if (memptr)
+ memptr = 0;
+ // Null is -1.
+ // CHECK: icmp ne i32 %{{.*}}, -1
+ // CHECK: store i32 -1,
+}
+
+struct Polymorphic {
+ virtual void myVirtual();
+ int a;
+ int b;
+};
+
+void polymorphicMemPtrs() {
+ int Polymorphic::*memptr;
+ memptr = &Polymorphic::a;
+ // CHECK: store i32 4,
+ memptr = &Polymorphic::b;
+ // CHECK: store i32 8,
+ if (memptr)
+ memptr = 0;
+ // Null is zero.
+ // CHECK: icmp ne i32 %{{.*}}, 0
+ // CHECK: store i32 0,
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits