[cfe-commits] r47286 - in /cfe/trunk: CodeGen/CGExprAgg.cpp test/CodeGen/init.c

Lauro Ramos Venancio lauro.venancio at gmail.com
Mon Feb 18 14:44:03 PST 2008


Author: laurov
Date: Mon Feb 18 16:44:02 2008
New Revision: 47286

URL: http://llvm.org/viewvc/llvm-project?rev=47286&view=rev
Log:
Implement multi-dimension array initalizer.
Fix McCat/08-main test.


Modified:
    cfe/trunk/CodeGen/CGExprAgg.cpp
    cfe/trunk/test/CodeGen/init.c

Modified: cfe/trunk/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprAgg.cpp?rev=47286&r1=47285&r2=47286&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/CodeGen/CGExprAgg.cpp Mon Feb 18 16:44:02 2008
@@ -82,6 +82,12 @@
   void VisitConditionalOperator(const ConditionalOperator *CO);
   void VisitInitListExpr(InitListExpr *E);
   //  case Expr::ChooseExprClass:
+
+private:
+
+  llvm::Constant *GetConstantInit(InitListExpr *E,
+                                  const llvm::ArrayType *AType);
+  void EmitNonConstInit(Expr *E, llvm::Value *Dest, const llvm::Type *DestType);
 };
 }  // end anonymous namespace.
 
@@ -230,81 +236,100 @@
   CGF.EmitBlock(ContBlock);
 }
 
-void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
-
-  unsigned NumInitElements = E->getNumInits();
-
-  if (!E->getType()->isArrayType()) {
-    CGF.WarnUnsupported(E, "aggregate init-list expression");
-    return;
-  }
-
+llvm::Constant *AggExprEmitter::GetConstantInit(InitListExpr *E,
+                                                const llvm::ArrayType *AType) {
   std::vector<llvm::Constant*> ArrayElts;
-  const llvm::PointerType *APType = cast<llvm::PointerType>(DestPtr->getType());
-  const llvm::ArrayType *AType = 
-    cast<llvm::ArrayType>(APType->getElementType());
+  unsigned NumInitElements = E->getNumInits();
+  const llvm::Type *ElementType = AType->getElementType();
+  unsigned i;
 
-  // Copy initializer elements.
-  bool AllConstElements = true;
-  unsigned i = 0;
   for (i = 0; i != NumInitElements; ++i) {
-    if (llvm::Constant *C = 
+    if (InitListExpr *InitList = dyn_cast<InitListExpr>(E->getInit(i))) {
+      assert(isa<llvm::ArrayType>(ElementType) && "Invalid initilizer");
+      llvm::Constant *C =
+        GetConstantInit(InitList, cast<llvm::ArrayType>(ElementType));
+      if (!C) return NULL;
+      ArrayElts.push_back(C);
+    } else if (llvm::Constant *C =
         dyn_cast<llvm::Constant>(CGF.EmitScalarExpr(E->getInit(i))))
       ArrayElts.push_back(C);
-    else {
-      AllConstElements = false;
-      break;
-    }
+    else
+      return NULL;
   }
 
+  // Remaining default initializers
   unsigned NumArrayElements = AType->getNumElements();
-  const llvm::Type *ElementType = CGF.ConvertType(E->getInit(0)->getType());
-
-  if (AllConstElements) {
-    // Initialize remaining array elements.
-    for (/*Do not initialize i*/; i < NumArrayElements; ++i)
+  for (/*Do not initialize i*/; i < NumArrayElements; ++i)
       ArrayElts.push_back(llvm::Constant::getNullValue(ElementType));
 
-    // Create global value to hold this array.
-    llvm::Constant *V = llvm::ConstantArray::get(AType, ArrayElts);
-    V = new llvm::GlobalVariable(V->getType(), true, 
-                                 llvm::GlobalValue::InternalLinkage,
-                                 V, ".array", 
-                                 &CGF.CGM.getModule());
-    
-    EmitAggregateCopy(DestPtr, V , E->getType());
-    return;
-  }
+  return llvm::ConstantArray::get(AType, ArrayElts);
+}
 
-  // Emit indiviudal array element stores.
-  unsigned index = 0;
-  llvm::Value *NextVal = NULL;
-  llvm::Value *Idxs[] = {
-    llvm::Constant::getNullValue(llvm::Type::Int32Ty),
-    NULL
-  };
-  
-  // Emit already seen constants initializers.
-  for (i = 0; i < ArrayElts.size(); i++) {
-    Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++);
-    NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array");
-    Builder.CreateStore(ArrayElts[i], NextVal);
-  }
+void AggExprEmitter::EmitNonConstInit(Expr *E, llvm::Value *DestPtr,
+                                      const llvm::Type *DestType) {
+
+  if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(DestType)) {
+    unsigned NumInitElements = 0;
+    InitListExpr *InitList = NULL;
+
+    if (E) {
+      InitList = cast<InitListExpr>(E);
+      NumInitElements = InitList->getNumInits();
+    }
+
+    llvm::Value *Idxs[] = {
+      llvm::Constant::getNullValue(llvm::Type::Int32Ty),
+      NULL
+    };
+    llvm::Value *NextVal = NULL;
+    unsigned i;
+    for (i = 0; i != NumInitElements; ++i) {
+      Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
+      NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
+      EmitNonConstInit(InitList->getInit(i), NextVal, AType->getElementType());
+    }
 
-  // Emit remaining initializers
-  for (/*Do not initizalize i*/; i < NumInitElements; ++i) {
-    Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++);
-    NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array");
-    llvm::Value *V = CGF.EmitScalarExpr(E->getInit(i));
-    Builder.CreateStore(V, NextVal);
+    // Emit remaining default initializers
+    unsigned NumArrayElements = AType->getNumElements();
+    for (/*Do not initialize i*/; i < NumArrayElements; ++i) {
+      Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
+      NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
+      EmitNonConstInit(NULL, NextVal, AType->getElementType());
+    }
+
+  } else {
+    llvm::Value *V;
+    if (E)
+      V = CGF.EmitScalarExpr(E);
+    else
+      V = llvm::Constant::getNullValue(DestType);
+    Builder.CreateStore(V, DestPtr);
   }
+}
 
-  // Emit remaining default initializers
-  for (/*Do not initialize i*/; i < NumArrayElements; ++i) {
-    Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++);
-    NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array");
-    Builder.CreateStore(llvm::Constant::getNullValue(ElementType), NextVal);
+void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
+
+  if (!E->getType()->isArrayType()) {
+    CGF.WarnUnsupported(E, "aggregate init-list expression");
+    return;
   }
+
+  const llvm::PointerType *APType = cast<llvm::PointerType>(DestPtr->getType());
+  const llvm::ArrayType *AType =
+    cast<llvm::ArrayType>(APType->getElementType());
+
+  llvm::Constant *V = GetConstantInit(E, AType);
+  if (V) {
+    // Create global value to hold this array.
+    V = new llvm::GlobalVariable(V->getType(), true,
+                                 llvm::GlobalValue::InternalLinkage,
+                                 V, ".array",
+                                 &CGF.CGM.getModule());
+
+    EmitAggregateCopy(DestPtr, V , E->getType());
+    return;
+  } else
+    EmitNonConstInit(E, DestPtr, AType);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/CodeGen/init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/init.c?rev=47286&r1=47285&r2=47286&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/init.c (original)
+++ cfe/trunk/test/CodeGen/init.c Mon Feb 18 16:44:02 2008
@@ -1,7 +1,14 @@
 // RUN: clang -emit-llvm %s
-void f1()
-{
-	// Scalars in braces.
-	int a = { 1 };
-	int b = { 1, 2 };
+void f1() {
+  // Scalars in braces.
+  int a = { 1 };
+  int b = { 1, 2 };
+}
+
+void f2() {
+  int a[2][2] = { { 1, 2 }, { 3, 4 } };
+  int b[3][3] = { { 1, 2 }, { 3, 4 } };
+  int *c[2] = { &a[1][1], &b[2][2] };
+  int *d[2][2] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
+  int *e[3][3] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
 }





More information about the cfe-commits mailing list