]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/init.c
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 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 /********************************** Initializer *******************************/
30 Initializer::Initializer(Loc loc
)
35 Initializers
*Initializer::arraySyntaxCopy(Initializers
*ai
)
37 Initializers
*a
= NULL
;
40 a
= new Initializers();
41 a
->setDim(ai
->length
);
42 for (size_t i
= 0; i
< a
->length
; i
++)
43 (*a
)[i
] = (*ai
)[i
]->syntaxCopy();
48 const char *Initializer::toChars()
52 ::toCBuffer(this, &buf
, &hgs
);
53 return buf
.extractChars();
56 /********************************** ErrorInitializer ***************************/
58 ErrorInitializer::ErrorInitializer()
63 Initializer
*ErrorInitializer::syntaxCopy()
68 /********************************** VoidInitializer ***************************/
70 VoidInitializer::VoidInitializer(Loc loc
)
76 Initializer
*VoidInitializer::syntaxCopy()
78 return new VoidInitializer(loc
);
81 /********************************** StructInitializer *************************/
83 StructInitializer::StructInitializer(Loc loc
)
88 Initializer
*StructInitializer::syntaxCopy()
90 StructInitializer
*ai
= new StructInitializer(loc
);
91 assert(field
.length
== value
.length
);
92 ai
->field
.setDim(field
.length
);
93 ai
->value
.setDim(value
.length
);
94 for (size_t i
= 0; i
< field
.length
; i
++)
96 ai
->field
[i
] = field
[i
];
97 ai
->value
[i
] = value
[i
]->syntaxCopy();
102 void StructInitializer::addInit(Identifier
*field
, Initializer
*value
)
104 //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
105 this->field
.push(field
);
106 this->value
.push(value
);
109 /********************************** ArrayInitializer ************************************/
111 ArrayInitializer::ArrayInitializer(Loc loc
)
119 Initializer
*ArrayInitializer::syntaxCopy()
121 //printf("ArrayInitializer::syntaxCopy()\n");
122 ArrayInitializer
*ai
= new ArrayInitializer(loc
);
123 assert(index
.length
== value
.length
);
124 ai
->index
.setDim(index
.length
);
125 ai
->value
.setDim(value
.length
);
126 for (size_t i
= 0; i
< ai
->value
.length
; i
++)
128 ai
->index
[i
] = index
[i
] ? index
[i
]->syntaxCopy() : NULL
;
129 ai
->value
[i
] = value
[i
]->syntaxCopy();
134 void ArrayInitializer::addInit(Expression
*index
, Initializer
*value
)
136 this->index
.push(index
);
137 this->value
.push(value
);
142 bool ArrayInitializer::isAssociativeArray()
144 for (size_t i
= 0; i
< value
.length
; i
++)
152 /********************************
153 * If possible, convert array initializer to associative array initializer.
156 Expression
*ArrayInitializer::toAssocArrayLiteral()
160 //printf("ArrayInitializer::toAssocArrayInitializer()\n");
161 //static int i; if (++i == 2) halt();
162 Expressions
*keys
= new Expressions();
163 keys
->setDim(value
.length
);
164 Expressions
*values
= new Expressions();
165 values
->setDim(value
.length
);
167 for (size_t i
= 0; i
< value
.length
; i
++)
174 Initializer
*iz
= value
[i
];
177 e
= initializerToExpression(iz
);
182 e
= new AssocArrayLiteralExp(loc
, keys
, values
);
188 error(loc
, "not an associative array initializer");
189 return new ErrorExp();
192 /********************************** ExpInitializer ************************************/
194 ExpInitializer::ExpInitializer(Loc loc
, Expression
*exp
)
198 this->expandTuples
= false;
201 Initializer
*ExpInitializer::syntaxCopy()
203 return new ExpInitializer(loc
, exp
->syntaxCopy());
206 #if 1 // should be removed and rely on ctfeInterpreter()
207 bool arrayHasNonConstPointers(Expressions
*elems
);
209 bool hasNonConstPointers(Expression
*e
)
211 if (e
->type
->ty
== Terror
)
214 if (e
->op
== TOKnull
)
216 if (e
->op
== TOKstructliteral
)
218 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
219 return arrayHasNonConstPointers(se
->elements
);
221 if (e
->op
== TOKarrayliteral
)
223 if (!e
->type
->nextOf()->hasPointers())
225 ArrayLiteralExp
*ae
= (ArrayLiteralExp
*)e
;
226 return arrayHasNonConstPointers(ae
->elements
);
228 if (e
->op
== TOKassocarrayliteral
)
230 AssocArrayLiteralExp
*ae
= (AssocArrayLiteralExp
*)e
;
231 if (ae
->type
->nextOf()->hasPointers() &&
232 arrayHasNonConstPointers(ae
->values
))
234 if (((TypeAArray
*)ae
->type
)->index
->hasPointers())
235 return arrayHasNonConstPointers(ae
->keys
);
238 if (e
->op
== TOKaddress
)
240 AddrExp
*ae
= (AddrExp
*)e
;
241 if (ae
->e1
->op
== TOKstructliteral
)
243 StructLiteralExp
*se
= (StructLiteralExp
*)ae
->e1
;
244 if (!(se
->stageflags
& stageSearchPointers
))
246 int old
= se
->stageflags
;
247 se
->stageflags
|= stageSearchPointers
;
248 bool ret
= arrayHasNonConstPointers(se
->elements
);
249 se
->stageflags
= old
;
259 if (e
->type
->ty
== Tpointer
&& e
->type
->nextOf()->ty
!= Tfunction
)
261 if (e
->op
== TOKsymoff
) // address of a global is OK
263 if (e
->op
== TOKint64
) // cast(void *)int is OK
265 if (e
->op
== TOKstring
) // "abc".ptr is OK
272 bool arrayHasNonConstPointers(Expressions
*elems
)
274 for (size_t i
= 0; i
< elems
->length
; i
++)
276 Expression
*e
= (*elems
)[i
];
277 if (e
&& hasNonConstPointers(e
))