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
14 #include "checkedint.h"
17 #include "expression.h"
18 #include "statement.h"
19 #include "identifier.h"
20 #include "declaration.h"
21 #include "aggregate.h"
29 Expression
*semantic(Expression
*e
, Scope
*sc
);
30 Initializer
*semantic(Initializer
*init
, Scope
*sc
, Type
*t
, NeedInterpret needInterpret
);
32 /********************************** Initializer *******************************/
34 Initializer::Initializer(Loc loc
)
39 Initializers
*Initializer::arraySyntaxCopy(Initializers
*ai
)
41 Initializers
*a
= NULL
;
44 a
= new Initializers();
46 for (size_t i
= 0; i
< a
->dim
; i
++)
47 (*a
)[i
] = (*ai
)[i
]->syntaxCopy();
52 const char *Initializer::toChars()
56 ::toCBuffer(this, &buf
, &hgs
);
57 return buf
.extractString();
60 /********************************** ErrorInitializer ***************************/
62 ErrorInitializer::ErrorInitializer()
67 Initializer
*ErrorInitializer::syntaxCopy()
72 /********************************** VoidInitializer ***************************/
74 VoidInitializer::VoidInitializer(Loc loc
)
80 Initializer
*VoidInitializer::syntaxCopy()
82 return new VoidInitializer(loc
);
85 /********************************** StructInitializer *************************/
87 StructInitializer::StructInitializer(Loc loc
)
92 Initializer
*StructInitializer::syntaxCopy()
94 StructInitializer
*ai
= new StructInitializer(loc
);
95 assert(field
.dim
== value
.dim
);
96 ai
->field
.setDim(field
.dim
);
97 ai
->value
.setDim(value
.dim
);
98 for (size_t i
= 0; i
< field
.dim
; i
++)
100 ai
->field
[i
] = field
[i
];
101 ai
->value
[i
] = value
[i
]->syntaxCopy();
106 void StructInitializer::addInit(Identifier
*field
, Initializer
*value
)
108 //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
109 this->field
.push(field
);
110 this->value
.push(value
);
113 /********************************** ArrayInitializer ************************************/
115 ArrayInitializer::ArrayInitializer(Loc loc
)
123 Initializer
*ArrayInitializer::syntaxCopy()
125 //printf("ArrayInitializer::syntaxCopy()\n");
126 ArrayInitializer
*ai
= new ArrayInitializer(loc
);
127 assert(index
.dim
== value
.dim
);
128 ai
->index
.setDim(index
.dim
);
129 ai
->value
.setDim(value
.dim
);
130 for (size_t i
= 0; i
< ai
->value
.dim
; i
++)
132 ai
->index
[i
] = index
[i
] ? index
[i
]->syntaxCopy() : NULL
;
133 ai
->value
[i
] = value
[i
]->syntaxCopy();
138 void ArrayInitializer::addInit(Expression
*index
, Initializer
*value
)
140 this->index
.push(index
);
141 this->value
.push(value
);
146 bool ArrayInitializer::isAssociativeArray()
148 for (size_t i
= 0; i
< value
.dim
; i
++)
156 /********************************
157 * If possible, convert array initializer to associative array initializer.
160 Expression
*ArrayInitializer::toAssocArrayLiteral()
164 //printf("ArrayInitializer::toAssocArrayInitializer()\n");
165 //static int i; if (++i == 2) halt();
166 Expressions
*keys
= new Expressions();
167 keys
->setDim(value
.dim
);
168 Expressions
*values
= new Expressions();
169 values
->setDim(value
.dim
);
171 for (size_t i
= 0; i
< value
.dim
; i
++)
178 Initializer
*iz
= value
[i
];
181 e
= initializerToExpression(iz
);
186 e
= new AssocArrayLiteralExp(loc
, keys
, values
);
192 error(loc
, "not an associative array initializer");
193 return new ErrorExp();
196 /********************************** ExpInitializer ************************************/
198 ExpInitializer::ExpInitializer(Loc loc
, Expression
*exp
)
202 this->expandTuples
= false;
205 Initializer
*ExpInitializer::syntaxCopy()
207 return new ExpInitializer(loc
, exp
->syntaxCopy());
210 #if 1 // should be removed and rely on ctfeInterpreter()
211 bool arrayHasNonConstPointers(Expressions
*elems
);
213 bool hasNonConstPointers(Expression
*e
)
215 if (e
->type
->ty
== Terror
)
218 if (e
->op
== TOKnull
)
220 if (e
->op
== TOKstructliteral
)
222 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
223 return arrayHasNonConstPointers(se
->elements
);
225 if (e
->op
== TOKarrayliteral
)
227 if (!e
->type
->nextOf()->hasPointers())
229 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)e
;
230 return arrayHasNonConstPointers(ae
->elements
);
232 if (e
->op
== TOKassocarrayliteral
)
234 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e
;
235 if (ae
->type
->nextOf()->hasPointers() &&
236 arrayHasNonConstPointers(ae
->values
))
238 if (((TypeAArray
*)ae
->type
)->index
->hasPointers())
239 return arrayHasNonConstPointers(ae
->keys
);
242 if(e
->op
== TOKaddress
)
244 AddrExp
*ae
= (AddrExp
*)e
;
245 if (ae
->e1
->op
== TOKstructliteral
)
247 StructLiteralExp
*se
= (StructLiteralExp
*)ae
->e1
;
248 if (!(se
->stageflags
& stageSearchPointers
))
250 int old
= se
->stageflags
;
251 se
->stageflags
|= stageSearchPointers
;
252 bool ret
= arrayHasNonConstPointers(se
->elements
);
253 se
->stageflags
= old
;
263 if (e
->type
->ty
== Tpointer
&& e
->type
->nextOf()->ty
!= Tfunction
)
265 if (e
->op
== TOKsymoff
) // address of a global is OK
267 if (e
->op
== TOKint64
) // cast(void *)int is OK
269 if (e
->op
== TOKstring
) // "abc".ptr is OK
276 bool arrayHasNonConstPointers(Expressions
*elems
)
278 for (size_t i
= 0; i
< elems
->dim
; i
++)
280 Expression
*e
= (*elems
)[i
];
281 if (e
&& hasNonConstPointers(e
))