[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