- 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

Reply via email to