@@ -2876,20 +2876,64 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
2876
2876
else
2877
2877
dstMem = DtoRawAlloca (llStoType, 0 , " arrayliteral" );
2878
2878
2879
- // store elements
2880
- for (size_t i=0 ; i<len; ++i)
2879
+ // Check for const'ness
2880
+ bool isAllConst = true ;
2881
+ for (size_t i = 0 ; i < len && isAllConst; ++i)
2881
2882
{
2882
- Expression* expr = static_cast <Expression*>(elements->data [i]);
2883
- LLValue* elemAddr;
2884
- if (dyn)
2885
- elemAddr = DtoGEPi1 (dstMem, i, " tmp" , p->scopebb ());
2883
+ Expression *expr = static_cast <Expression *>(elements->data [i]);
2884
+ isAllConst = expr->isConst () == 1 ;
2885
+ }
2886
+
2887
+ if (isAllConst)
2888
+ {
2889
+ // allocate room for initializers
2890
+ std::vector<LLConstant *> initvals (len, NULL );
2891
+
2892
+ // true if array elements differ in type
2893
+ bool mismatch = false ;
2894
+
2895
+ // store elements
2896
+ for (size_t i = 0 ; i < len; ++i)
2897
+ {
2898
+ Expression *expr = static_cast <Expression *>(elements->data [i]);
2899
+ llvm::Constant *c = expr->toConstElem (gIR );
2900
+ if (llElemType != c->getType ())
2901
+ mismatch = true ;
2902
+ initvals[i] = c;
2903
+ }
2904
+ LLConstant *constarr;
2905
+ if (mismatch)
2906
+ constarr = LLConstantStruct::getAnon (gIR ->context (), initvals); // FIXME should this pack?;
2907
+ else
2908
+ constarr = LLConstantArray::get (LLArrayType::get (llElemType, len), initvals);
2909
+
2910
+ // If the type pointed to by dstMem is different from the array type
2911
+ // then we must assign the value to a global variable.
2912
+ if (constarr->getType () != dstMem->getType ()->getPointerElementType ())
2913
+ {
2914
+ LLGlobalVariable *gvar = new LLGlobalVariable (*gIR ->module , constarr->getType (), true , LLGlobalValue::InternalLinkage, constarr, " .constarrayliteral_init" );
2915
+ DtoMemCpy (dstMem, gvar, DtoConstSize_t (getTypePaddedSize (constarr->getType ())));
2916
+ }
2886
2917
else
2887
- elemAddr = DtoGEPi (dstMem,0 ,i," tmp" ,p->scopebb ());
2918
+ DtoStore (constarr, dstMem);
2919
+ }
2920
+ else
2921
+ {
2922
+ // store elements
2923
+ for (size_t i = 0 ; i < len; ++i)
2924
+ {
2925
+ Expression *expr = static_cast <Expression *>(elements->data [i]);
2926
+ LLValue *elemAddr;
2927
+ if (dyn)
2928
+ elemAddr = DtoGEPi1 (dstMem, i, " tmp" , p->scopebb ());
2929
+ else
2930
+ elemAddr = DtoGEPi (dstMem, 0 , i, " tmp" , p->scopebb ());
2888
2931
2889
- // emulate assignment
2890
- DVarValue* vv = new DVarValue (expr->type , elemAddr);
2891
- DValue* e = expr->toElem (p);
2892
- DtoAssign (loc, vv, e);
2932
+ // emulate assignment
2933
+ DVarValue *vv = new DVarValue (expr->type , elemAddr);
2934
+ DValue *e = expr->toElem (p);
2935
+ DtoAssign (loc, vv, e);
2936
+ }
2893
2937
}
2894
2938
2895
2939
// return storage directly ?
0 commit comments