diff options
author | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-18 22:44:02 +0000 |
---|---|---|
committer | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-18 22:44:02 +0000 |
commit | 305762c08975cd6e0bebd684ca910fa208792483 (patch) | |
tree | edeedf099d2394f24d2b1bb78d94eae22fe924f0 /CodeGen/CGExprAgg.cpp | |
parent | cb33093b4d342c01b8d01e3a2879da4644a5639e (diff) |
Implement multi-dimension array initalizer.
Fix McCat/08-main test.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47286 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CGExprAgg.cpp')
-rw-r--r-- | CodeGen/CGExprAgg.cpp | 145 |
1 files changed, 85 insertions, 60 deletions
diff --git a/CodeGen/CGExprAgg.cpp b/CodeGen/CGExprAgg.cpp index 0b12647efd..71f96aa675 100644 --- a/CodeGen/CGExprAgg.cpp +++ b/CodeGen/CGExprAgg.cpp @@ -82,6 +82,12 @@ public: 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 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) { 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); } //===----------------------------------------------------------------------===// |