PR libstdc++/87308 adjust regex used in std::any pretty printer
[official-gcc.git] / gcc / d / dmd / init.c
blob6603f66bfe618156dbf63ae1c11821492051a862
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
9 */
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
14 #include "mars.h"
15 #include "init.h"
16 #include "expression.h"
17 #include "statement.h"
18 #include "identifier.h"
19 #include "declaration.h"
20 #include "aggregate.h"
21 #include "scope.h"
22 #include "mtype.h"
23 #include "hdrgen.h"
24 #include "template.h"
25 #include "id.h"
26 #include "tokens.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)
35 this->loc = loc;
38 Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
40 Initializers *a = NULL;
41 if (ai)
43 a = new Initializers();
44 a->setDim(ai->dim);
45 for (size_t i = 0; i < a->dim; i++)
46 (*a)[i] = (*ai)[i]->syntaxCopy();
48 return a;
51 const char *Initializer::toChars()
53 OutBuffer buf;
54 HdrGenState hgs;
55 ::toCBuffer(this, &buf, &hgs);
56 return buf.extractString();
59 /********************************** ErrorInitializer ***************************/
61 ErrorInitializer::ErrorInitializer()
62 : Initializer(Loc())
66 Initializer *ErrorInitializer::syntaxCopy()
68 return this;
71 /********************************** VoidInitializer ***************************/
73 VoidInitializer::VoidInitializer(Loc loc)
74 : Initializer(loc)
76 type = NULL;
79 Initializer *VoidInitializer::syntaxCopy()
81 return new VoidInitializer(loc);
84 /********************************** StructInitializer *************************/
86 StructInitializer::StructInitializer(Loc loc)
87 : Initializer(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();
102 return ai;
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)
115 : Initializer(loc)
117 dim = 0;
118 type = NULL;
119 sem = false;
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();
134 return ai;
137 void ArrayInitializer::addInit(Expression *index, Initializer *value)
139 this->index.push(index);
140 this->value.push(value);
141 dim = 0;
142 type = NULL;
145 bool ArrayInitializer::isAssociativeArray()
147 for (size_t i = 0; i < value.dim; i++)
149 if (index[i])
150 return true;
152 return false;
155 /********************************
156 * If possible, convert array initializer to associative array initializer.
159 Expression *ArrayInitializer::toAssocArrayLiteral()
161 Expression *e;
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++)
172 e = index[i];
173 if (!e)
174 goto Lno;
175 (*keys)[i] = e;
177 Initializer *iz = value[i];
178 if (!iz)
179 goto Lno;
180 e = initializerToExpression(iz);
181 if (!e)
182 goto Lno;
183 (*values)[i] = e;
185 e = new AssocArrayLiteralExp(loc, keys, values);
186 return e;
188 Lno:
189 delete keys;
190 delete values;
191 error(loc, "not an associative array initializer");
192 return new ErrorExp();
195 /********************************** ExpInitializer ************************************/
197 ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
198 : Initializer(loc)
200 this->exp = 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)
215 return false;
217 if (e->op == TOKnull)
218 return false;
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())
227 return false;
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))
236 return true;
237 if (((TypeAArray *)ae->type)->index->hasPointers())
238 return arrayHasNonConstPointers(ae->keys);
239 return false;
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;
253 return ret;
255 else
257 return false;
260 return true;
262 if (e->type->ty== Tpointer && e->type->nextOf()->ty != Tfunction)
264 if (e->op == TOKsymoff) // address of a global is OK
265 return false;
266 if (e->op == TOKint64) // cast(void *)int is OK
267 return false;
268 if (e->op == TOKstring) // "abc".ptr is OK
269 return false;
270 return true;
272 return false;
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))
281 return true;
283 return false;
285 #endif