Codegen array initializers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43385 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExprAgg.cpp b/CodeGen/CGExprAgg.cpp
index 743c248..5f353ed 100644
--- a/CodeGen/CGExprAgg.cpp
+++ b/CodeGen/CGExprAgg.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/AST.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace CodeGen;
@@ -73,6 +74,7 @@
void VisitConditionalOperator(const ConditionalOperator *CO);
+ void VisitInitListExpr(InitListExpr *E);
// case Expr::ChooseExprClass:
};
} // end anonymous namespace.
@@ -101,7 +103,8 @@
llvm::Value *MemCpyOps[4] = {
DestPtr, SrcPtr,
- llvm::ConstantInt::get(IntPtr, TypeInfo.first),
+ // TypeInfo.first describes size in bits.
+ llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
};
@@ -178,6 +181,79 @@
CGF.EmitBlock(ContBlock);
}
+void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
+
+ unsigned NumInitElements = E->getNumInits();
+
+ assert ( E->getType()->isArrayType()
+ && "Only Array initializers are supported");
+
+ std::vector<llvm::Constant*> ArrayElts;
+ const llvm::PointerType *APType = cast<llvm::PointerType>(DestPtr->getType());
+ const llvm::ArrayType *AType = cast<llvm::ArrayType>(APType->getElementType());
+
+ // Copy initializer elements.
+ bool AllConstElements = true;
+ unsigned i = 0;
+ for (i = 0; i < NumInitElements; ++i) {
+ if (llvm::Constant *C = dyn_cast<llvm::Constant>(CGF.EmitScalarExpr(E->getInit(i))))
+ ArrayElts.push_back(C);
+ else {
+ AllConstElements = false;
+ break;
+ }
+ }
+
+ 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)
+ 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;
+ }
+
+ // 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);
+ }
+
+ // 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
+ 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);
+ }
+}
+
//===----------------------------------------------------------------------===//
// Entry Points into this File
//===----------------------------------------------------------------------===//