@@ -492,7 +492,7 @@ DValue* AssignExp::toElem(IRState* p)
492
492
{
493
493
Logger::println (" performing ref variable initialization" );
494
494
// Note that the variable value is accessed directly (instead
495
- // of via getLValue (), which would perform a load from the
495
+ // of via getLVal (), which would perform a load from the
496
496
// uninitialized location), and that rhs is stored as an l-value!
497
497
DVarValue* lhs = e1 ->toElem (p)->isVar ();
498
498
assert (lhs);
@@ -508,6 +508,26 @@ DValue* AssignExp::toElem(IRState* p)
508
508
}
509
509
}
510
510
511
+ if (e1 ->op == TOKslice)
512
+ {
513
+ // Check if this is an initialization of a static array with an array
514
+ // literal that the frontend has foolishly rewritten into an
515
+ // assignment of a dynamic array literal to a slice.
516
+ Logger::println (" performing static array literal assignment" );
517
+ SliceExp * const se = static_cast <SliceExp *>(e1 );
518
+ Type * const t2 = e2 ->type ->toBasetype ();
519
+ Type * const ta = se->e1 ->type ->toBasetype ();
520
+
521
+ if (se->lwr == NULL && ta->ty == Tsarray &&
522
+ e2 ->op == TOKarrayliteral &&
523
+ t2->nextOf ()->mutableOf ()->implicitConvTo (ta->nextOf ()))
524
+ {
525
+ ArrayLiteralExp * const ale = static_cast <ArrayLiteralExp *>(e2 );
526
+ initializeArrayLiteral (p, ale, se->e1 ->toElem (p)->getLVal ());
527
+ return e1 ->toElem (p);
528
+ }
529
+ }
530
+
511
531
DValue* l = e1 ->toElem (p);
512
532
DValue* r = e2 ->toElem (p);
513
533
@@ -2850,9 +2870,9 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
2850
2870
Type* elemType = arrayType->nextOf ()->toBasetype ();
2851
2871
2852
2872
// is dynamic ?
2853
- bool dyn = (arrayType->ty == Tarray);
2873
+ bool const dyn = (arrayType->ty == Tarray);
2854
2874
// length
2855
- size_t len = elements->dim ;
2875
+ size_t const len = elements->dim ;
2856
2876
2857
2877
// llvm target type
2858
2878
LLType* llType = DtoType (arrayType);
@@ -2872,95 +2892,34 @@ DValue* ArrayLiteralExp::toElem(IRState* p)
2872
2892
return new DSliceValue (type, DtoConstSize_t (0 ), getNullPtr (getPtrToType (llElemType)));
2873
2893
}
2874
2894
2875
- // dst pointer
2876
- LLValue* dstMem;
2877
- DSliceValue* dynSlice = NULL ;
2878
- if (dyn)
2879
- {
2880
- dynSlice = DtoNewDynArray (loc, arrayType, new DConstValue (Type::tsize_t , DtoConstSize_t (len)), false );
2881
- dstMem = dynSlice->ptr ;
2882
- }
2883
- else
2884
- dstMem = DtoRawAlloca (llStoType, 0 , " arrayliteral" );
2885
-
2886
- // Check for const'ness
2887
- bool isAllConst = true ;
2888
- for (size_t i = 0 ; i < len && isAllConst; ++i)
2895
+ if (dyn)
2889
2896
{
2890
- Expression *expr = static_cast <Expression *>(elements->data [i]);
2891
- isAllConst = expr->isConst () == 1 ;
2892
- }
2893
-
2894
- if (isAllConst)
2895
- {
2896
- // allocate room for initializers
2897
- std::vector<LLConstant *> initvals (len, NULL );
2898
-
2899
- // true if array elements differ in type
2900
- bool mismatch = false ;
2901
-
2902
- // store elements
2903
- for (size_t i = 0 ; i < len; ++i)
2897
+ if (arrayType->isImmutable () && isConstLiteral (this ))
2904
2898
{
2905
- Expression *expr = static_cast <Expression *>(elements->data [i]);
2906
- llvm::Constant *c = expr->toConstElem (gIR );
2907
- if (llElemType != c->getType ())
2908
- mismatch = true ;
2909
- initvals[i] = c;
2910
- }
2911
- LLConstant *constarr;
2912
- if (mismatch)
2913
- constarr = LLConstantStruct::getAnon (gIR ->context (), initvals); // FIXME should this pack?;
2914
- else
2915
- constarr = LLConstantArray::get (LLArrayType::get (llElemType, len), initvals);
2916
-
2917
- #if LDC_LLVM_VER == 301
2918
- // Simply storing the constant array triggers a problem in LLVM 3.1.
2919
- // With -O3 the statement
2920
- // void[0] sa0 = (void[0]).init;
2921
- // is compiled to
2922
- // tail call void @llvm.trap()
2923
- // which is not what we want!
2924
- // Therefore a global variable is always used.
2925
- LLGlobalVariable *gvar = new LLGlobalVariable (*gIR ->module , constarr->getType (), true , LLGlobalValue::InternalLinkage, constarr, " .constarrayliteral_init" );
2926
- DtoMemCpy (dstMem, gvar, DtoConstSize_t (getTypePaddedSize (constarr->getType ())));
2927
- #else
2928
- // If the type pointed to by dstMem is different from the array type
2929
- // then we must assign the value to a global variable.
2930
- if (constarr->getType () != dstMem->getType ()->getPointerElementType ())
2931
- {
2932
- LLGlobalVariable *gvar = new LLGlobalVariable (*gIR ->module , constarr->getType (), true , LLGlobalValue::InternalLinkage, constarr, " .constarrayliteral_init" );
2933
- DtoMemCpy (dstMem, gvar, DtoConstSize_t (getTypePaddedSize (constarr->getType ())));
2934
- }
2935
- else
2936
- DtoStore (constarr, dstMem);
2937
- #endif
2899
+ llvm::Constant* init = arrayLiteralToConst (p, this );
2900
+ llvm::GlobalVariable* global = new llvm::GlobalVariable (
2901
+ *gIR ->module ,
2902
+ init->getType (),
2903
+ true ,
2904
+ llvm::GlobalValue::InternalLinkage,
2905
+ init,
2906
+ " .immutablearray"
2907
+ );
2908
+ return new DSliceValue (arrayType, DtoConstSize_t (elements->dim ),
2909
+ DtoBitCast (global, getPtrToType (llElemType)));
2910
+ }
2911
+
2912
+ DSliceValue* dynSlice = DtoNewDynArray (loc, arrayType,
2913
+ new DConstValue (Type::tsize_t , DtoConstSize_t (len)), false );
2914
+ initializeArrayLiteral (p, this , DtoBitCast (dynSlice->ptr , getPtrToType (llStoType)));
2915
+ return dynSlice;
2938
2916
}
2939
2917
else
2940
2918
{
2941
- // store elements
2942
- for (size_t i = 0 ; i < len; ++i)
2943
- {
2944
- Expression *expr = static_cast <Expression *>(elements->data [i]);
2945
- LLValue *elemAddr;
2946
- if (dyn)
2947
- elemAddr = DtoGEPi1 (dstMem, i, " tmp" , p->scopebb ());
2948
- else
2949
- elemAddr = DtoGEPi (dstMem, 0 , i, " tmp" , p->scopebb ());
2950
-
2951
- // emulate assignment
2952
- DVarValue *vv = new DVarValue (expr->type , elemAddr);
2953
- DValue *e = expr->toElem (p);
2954
- DtoAssign (loc, vv, e);
2955
- }
2919
+ llvm::Value* storage = DtoRawAlloca (llStoType, 0 , " arrayliteral" );
2920
+ initializeArrayLiteral (p, this , storage);
2921
+ return new DImValue (type, storage);
2956
2922
}
2957
-
2958
- // return storage directly ?
2959
- if (!dyn)
2960
- return new DImValue (type, dstMem);
2961
-
2962
- // return slice
2963
- return dynSlice;
2964
2923
}
2965
2924
2966
2925
// ////////////////////////////////////////////////////////////////////////////////////////
@@ -2980,45 +2939,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
2980
2939
// dynamic arrays can occur here as well ...
2981
2940
bool dyn = (bt->ty != Tsarray);
2982
2941
2983
- // Build the initializer. We have to take care as due to unions in the
2984
- // element types (with different fields being initialized), we can end up
2985
- // with different types for the initializer values. In this case, we
2986
- // generate a packed struct constant instead of an array constant.
2987
- LLType *elementType = NULL ;
2988
- bool differentTypes = false ;
2989
-
2990
- std::vector<LLConstant*> vals;
2991
- vals.reserve (elements->dim );
2992
- for (unsigned i = 0 ; i < elements->dim ; ++i)
2993
- {
2994
- LLConstant *val = (*elements)[i]->toConstElem (p);
2995
- if (!elementType)
2996
- elementType = val->getType ();
2997
- else
2998
- differentTypes |= (elementType != val->getType ());
2999
- vals.push_back (val);
3000
- }
3001
-
3002
- LLConstant *initval;
3003
- if (differentTypes)
3004
- {
3005
- std::vector<llvm::Type*> types;
3006
- types.reserve (elements->dim );
3007
- for (unsigned i = 0 ; i < elements->dim ; ++i)
3008
- types.push_back (vals[i]->getType ());
3009
- LLStructType *t = llvm::StructType::get (gIR ->context (), types, true );
3010
- initval = LLConstantStruct::get (t, vals);
3011
- }
3012
- else if (!elementType)
3013
- {
3014
- assert (elements->dim == 0 );
3015
- initval = LLConstantArray::get (arrtype, vals);
3016
- }
3017
- else
3018
- {
3019
- LLArrayType *t = LLArrayType::get (elementType, elements->dim );
3020
- initval = LLConstantArray::get (t, vals);
3021
- }
2942
+ llvm::Constant* initval = arrayLiteralToConst (p, this );
3022
2943
3023
2944
// if static array, we're done
3024
2945
if (!dyn)
0 commit comments