2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/init.c
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
16 #include "expression.h"
17 #include "statement.h"
18 #include "identifier.h"
19 #include "declaration.h"
20 #include "aggregate.h"
28 Expression
*semantic(Expression
*e
, Scope
*sc
);
29 Initializer
*semantic(Initializer
*init
, Scope
*sc
, Type
*t
, NeedInterpret needInterpret
);
31 /********************************** Initializer *******************************/
33 Initializer::Initializer(Loc loc
)
38 Initializers
*Initializer::arraySyntaxCopy(Initializers
*ai
)
40 Initializers
*a
= NULL
;
43 a
= new Initializers();
45 for (size_t i
= 0; i
< a
->dim
; i
++)
46 (*a
)[i
] = (*ai
)[i
]->syntaxCopy();
51 const char *Initializer::toChars()
55 ::toCBuffer(this, &buf
, &hgs
);
56 return buf
.extractString();
59 /********************************** ErrorInitializer ***************************/
61 ErrorInitializer::ErrorInitializer()
66 Initializer
*ErrorInitializer::syntaxCopy()
71 /********************************** VoidInitializer ***************************/
73 VoidInitializer::VoidInitializer(Loc loc
)
79 Initializer
*VoidInitializer::syntaxCopy()
81 return new VoidInitializer(loc
);
84 /********************************** StructInitializer *************************/
86 StructInitializer::StructInitializer(Loc loc
)
91 Initializer
*StructInitializer::syntaxCopy()
93 StructInitializer
*ai
= new StructInitializer(loc
);
94 assert(field
.dim
== value
.dim
);
95 ai
->field
.setDim(field
.dim
);
96 ai
->value
.setDim(value
.dim
);
97 for (size_t i
= 0; i
< field
.dim
; i
++)
99 ai
->field
[i
] = field
[i
];
100 ai
->value
[i
] = value
[i
]->syntaxCopy();
105 void StructInitializer::addInit(Identifier
*field
, Initializer
*value
)
107 //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
108 this->field
.push(field
);
109 this->value
.push(value
);
112 /********************************** ArrayInitializer ************************************/
114 ArrayInitializer::ArrayInitializer(Loc loc
)
122 Initializer
*ArrayInitializer::syntaxCopy()
124 //printf("ArrayInitializer::syntaxCopy()\n");
125 ArrayInitializer
*ai
= new ArrayInitializer(loc
);
126 assert(index
.dim
== value
.dim
);
127 ai
->index
.setDim(index
.dim
);
128 ai
->value
.setDim(value
.dim
);
129 for (size_t i
= 0; i
< ai
->value
.dim
; i
++)
131 ai
->index
[i
] = index
[i
] ? index
[i
]->syntaxCopy() : NULL
;
132 ai
->value
[i
] = value
[i
]->syntaxCopy();
137 void ArrayInitializer::addInit(Expression
*index
, Initializer
*value
)
139 this->index
.push(index
);
140 this->value
.push(value
);
145 bool ArrayInitializer::isAssociativeArray()
147 for (size_t i
= 0; i
< value
.dim
; i
++)
155 /********************************
156 * If possible, convert array initializer to associative array initializer.
159 Expression
*ArrayInitializer::toAssocArrayLiteral()
163 //printf("ArrayInitializer::toAssocArrayInitializer()\n");
164 //static int i; if (++i == 2) halt();
165 Expressions
*keys
= new Expressions();
166 keys
->setDim(value
.dim
);
167 Expressions
*values
= new Expressions();
168 values
->setDim(value
.dim
);
170 for (size_t i
= 0; i
< value
.dim
; i
++)
177 Initializer
*iz
= value
[i
];
180 e
= initializerToExpression(iz
);
185 e
= new AssocArrayLiteralExp(loc
, keys
, values
);
191 error(loc
, "not an associative array initializer");
192 return new ErrorExp();
195 /********************************** ExpInitializer ************************************/
197 ExpInitializer::ExpInitializer(Loc loc
, Expression
*exp
)
201 this->expandTuples
= false;
204 Initializer
*ExpInitializer::syntaxCopy()
206 return new ExpInitializer(loc
, exp
->syntaxCopy());
209 #if 1 // should be removed and rely on ctfeInterpreter()
210 bool arrayHasNonConstPointers(Expressions
*elems
);
212 bool hasNonConstPointers(Expression
*e
)
214 if (e
->type
->ty
== Terror
)
217 if (e
->op
== TOKnull
)
219 if (e
->op
== TOKstructliteral
)
221 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
222 return arrayHasNonConstPointers(se
->elements
);
224 if (e
->op
== TOKarrayliteral
)
226 if (!e
->type
->nextOf()->hasPointers())
228 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)e
;
229 return arrayHasNonConstPointers(ae
->elements
);
231 if (e
->op
== TOKassocarrayliteral
)
233 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e
;
234 if (ae
->type
->nextOf()->hasPointers() &&
235 arrayHasNonConstPointers(ae
->values
))
237 if (((TypeAArray
*)ae
->type
)->index
->hasPointers())
238 return arrayHasNonConstPointers(ae
->keys
);
241 if(e
->op
== TOKaddress
)
243 AddrExp
*ae
= (AddrExp
*)e
;
244 if (ae
->e1
->op
== TOKstructliteral
)
246 StructLiteralExp
*se
= (StructLiteralExp
*)ae
->e1
;
247 if (!(se
->stageflags
& stageSearchPointers
))
249 int old
= se
->stageflags
;
250 se
->stageflags
|= stageSearchPointers
;
251 bool ret
= arrayHasNonConstPointers(se
->elements
);
252 se
->stageflags
= old
;
262 if (e
->type
->ty
== Tpointer
&& e
->type
->nextOf()->ty
!= Tfunction
)
264 if (e
->op
== TOKsymoff
) // address of a global is OK
266 if (e
->op
== TOKint64
) // cast(void *)int is OK
268 if (e
->op
== TOKstring
) // "abc".ptr is OK
275 bool arrayHasNonConstPointers(Expressions
*elems
)
277 for (size_t i
= 0; i
< elems
->dim
; i
++)
279 Expression
*e
= (*elems
)[i
];
280 if (e
&& hasNonConstPointers(e
))