]> granicus.if.org Git - clang/commitdiff
implement constant expr. sub ptr ptr
authorNuno Lopes <nunoplopes@sapo.pt>
Fri, 6 Jun 2008 16:41:08 +0000 (16:41 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Fri, 6 Jun 2008 16:41:08 +0000 (16:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52049 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprConstant.cpp
test/CodeGen/struct-init.c [new file with mode: 0644]

index be9eaad9acf9ef4a04c2df6ce5334b8f23aef35f..58b18848171bf42cfbfe4f85036a5522be8565f7 100644 (file)
@@ -447,9 +447,19 @@ public:
       // int - int
       return llvm::ConstantExpr::getSub(LHS, RHS);
     }
-    
-    assert(0 && "Unhandled bin sub case!");
-    return 0;
+
+    assert(isa<llvm::PointerType>(LHS->getType()));
+
+    const llvm::Type *ResultType = ConvertType(E->getType());
+    const QualType Type = E->getLHS()->getType();
+    const QualType ElementType = Type->getAsPointerType()->getPointeeType();
+
+    LHS = llvm::ConstantExpr::getPtrToInt(LHS, ResultType);
+    RHS = llvm::ConstantExpr::getPtrToInt(RHS, ResultType);
+
+    llvm::Constant *sub = llvm::ConstantExpr::getSub(LHS, RHS);
+    llvm::Constant *size = EmitSizeAlignOf(ElementType, E->getType(), true);
+    return llvm::ConstantExpr::getSDiv(sub, size);
   }
     
   llvm::Constant *VisitBinShl(const BinaryOperator *E) {
diff --git a/test/CodeGen/struct-init.c b/test/CodeGen/struct-init.c
new file mode 100644 (file)
index 0000000..5b815de
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: clang %s -emit-llvm
+
+typedef struct _zend_ini_entry zend_ini_entry;
+struct _zend_ini_entry {
+       void *mh_arg1;
+};
+
+char a;
+
+const zend_ini_entry ini_entries[] = {
+       {  ((char*)&((zend_ini_entry*)0)->mh_arg1 - (char*)(void*)0)},
+       {  ((long long*)&a - (long long*)(void*)2)},
+};