]> granicus.if.org Git - clang/commitdiff
Improve handling of member pointers.
authorAnders Carlsson <andersca@mac.com>
Sun, 9 Aug 2009 18:26:27 +0000 (18:26 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 9 Aug 2009 18:26:27 +0000 (18:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78536 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.cpp
test/CodeGenCXX/member-pointers-zero-init.cpp [new file with mode: 0644]

index 047fecdc207885d8098be17e40aa93262750a176..d8fc31468945077ffd15c54c3736cb4e279cb14d 100644 (file)
@@ -773,7 +773,27 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
 }
 
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
-  // Always return an LLVM null constant for now; this will change when we
-  // get support for IRGen of member pointers.
+  if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) {
+    
+    QualType ElementTy = CAT->getElementType();
+
+    // FIXME: Handle arrays of structs that contain member pointers.
+    if (Context.getBaseElementType(ElementTy)->isMemberPointerType()) {
+      llvm::Constant *Element = EmitNullConstant(ElementTy);
+      uint64_t NumElements = CAT->getSize().getZExtValue();
+      std::vector<llvm::Constant *> Array(NumElements);
+      for (uint64_t i = 0; i != NumElements; ++i)
+        Array[i] = Element;
+      
+      const llvm::ArrayType *ATy = 
+        cast<llvm::ArrayType>(getTypes().ConvertTypeForMem(T));
+      return llvm::ConstantArray::get(ATy, Array);
+    }
+  }
+  
+  // FIXME: Handle structs that contain member pointers.
+  if (T->isMemberPointerType()) 
+    return llvm::Constant::getAllOnesValue(getTypes().ConvertTypeForMem(T));
+  
   return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
 }
index 44f4c27927b802c0ea0e2bb62e123cb2f2237d1e..e761e9f3c7d373f18f02f2fc969f9d647f35a978 100644 (file)
@@ -391,6 +391,14 @@ Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) {
     return Builder.CreateFCmpUNE(Src, Zero, "tobool");
   }
   
+  if (SrcType->isMemberPointerType()) {
+    // FIXME: This is ABI specific.
+    
+    // Compare against -1.
+    llvm::Value *NegativeOne = llvm::Constant::getAllOnesValue(Src->getType());
+    return Builder.CreateICmpNE(Src, NegativeOne, "tobool");
+  }
+  
   assert((SrcType->isIntegerType() || isa<llvm::PointerType>(Src->getType())) &&
          "Unknown scalar type to convert");
   
index 0b012592e4f37e3b6c538b34e1ce968243205792..6135f65513d2be3fd958590cdc9246fecf485a70 100644 (file)
@@ -68,9 +68,9 @@ const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
 bool CodeGenFunction::hasAggregateLLVMType(QualType T) {
   // FIXME: Use positive checks instead of negative ones to be more robust in
   // the face of extension.
-  return !T->hasPointerRepresentation() &&!T->isRealType() &&
+  return !T->hasPointerRepresentation() && !T->isRealType() &&
     !T->isVoidType() && !T->isVectorType() && !T->isFunctionType() && 
-    !T->isBlockPointerType();
+    !T->isBlockPointerType() && !T->isMemberPointerType();
 }
 
 void CodeGenFunction::EmitReturnBlock() {
diff --git a/test/CodeGenCXX/member-pointers-zero-init.cpp b/test/CodeGenCXX/member-pointers-zero-init.cpp
new file mode 100644 (file)
index 0000000..db7c71a
--- /dev/null
@@ -0,0 +1,24 @@
+// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 &&
+
+struct A {
+  int i;
+};
+
+// RUN: grep "@a = global i64 -1" %t &&
+int A::* a;
+
+// RUN: grep "@aa = global \[2 x i64\] \[i64 -1, i64 -1\], align 8" %t &&
+int A::* aa[2];
+
+// RUN: grep "@aaa = global \[2 x \[2 x i64\]\] \[\[2 x i64\] \[i64 -1, i64 -1\], \[2 x i64\] \[i64 -1, i64 -1\]\]" %t &&
+int A::* aaa[2][2];
+
+void f() {
+  // RUN: grep "%.obool = icmp ne i64 %.mp, -1" %t
+  if (a) { }
+  
+  // FIXME: This doesn't yet work
+//  if (a != 0) { }
+    
+}
+