annotate gcc/d/dmd/initsem.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 /* Compiler implementation of the D programming language
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 * written by Walter Bright
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 * http://www.digitalmars.com
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 * Distributed under the Boost Software License, Version 1.0.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 * http://www.boost.org/LICENSE_1_0.txt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 #include "root/checkedint.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 #include "mars.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 #include "init.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 #include "expression.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 #include "statement.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 #include "declaration.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 #include "aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 #include "scope.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "mtype.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "template.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "id.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 Expression *semantic(Expression *e, Scope *sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 Initializer *inferType(Initializer *init, Scope *sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 bool hasNonConstPointers(Expression *e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 class InitializerSemanticVisitor : public Visitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 Initializer *result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 Scope *sc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 Type *t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 NeedInterpret needInterpret;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 InitializerSemanticVisitor(Scope *sc, Type *t, NeedInterpret needInterpret)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 this->result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 this->sc = sc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 this->t = t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 this->needInterpret = needInterpret;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 void visit(ErrorInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 //printf("ErrorInitializer::semantic(t = %p)\n", t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 void visit(VoidInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 //printf("VoidInitializer::semantic(t = %p)\n", t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 i->type = t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 void visit(StructInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 t = t->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 if (t->ty == Tsarray && t->nextOf()->toBasetype()->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 t = t->nextOf()->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 if (t->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 StructDeclaration *sd = ((TypeStruct *)t)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 if (sd->ctor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 error(i->loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 sd->kind(), sd->toChars(), sd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 sd->size(i->loc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 if (sd->sizeok != SIZEOKdone)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 size_t nfields = sd->fields.dim - sd->isNested();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 //expandTuples for non-identity arguments?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 Expressions *elements = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 elements->setDim(nfields);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 for (size_t j = 0; j < elements->dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 (*elements)[j] = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 // Run semantic for explicitly given initializers
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 // TODO: this part is slightly different from StructLiteralExp::semantic.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 bool errors = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 for (size_t fieldi = 0, j = 0; j < i->field.dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 if (Identifier *id = i->field[j])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 Dsymbol *s = sd->search(i->loc, id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 if (!s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 s = sd->search_correct(id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 if (s)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 error(i->loc, "'%s' is not a member of '%s', did you mean %s '%s'?",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 id->toChars(), sd->toChars(), s->kind(), s->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 error(i->loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 s = s->toAlias();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 // Find out which field index it is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 for (fieldi = 0; 1; fieldi++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 if (fieldi >= nfields)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 error(i->loc, "%s.%s is not a per-instance initializable field",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 sd->toChars(), s->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 if (s == sd->fields[fieldi])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 else if (fieldi >= nfields)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 error(i->loc, "too many initializers for %s", sd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 VarDeclaration *vd = sd->fields[fieldi];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 if ((*elements)[fieldi])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 error(i->loc, "duplicate initializer for field '%s'", vd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 for (size_t k = 0; k < nfields; k++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 VarDeclaration *v2 = sd->fields[k];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 if (vd->isOverlappedWith(v2) && (*elements)[k])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 error(i->loc, "overlapping initialization for field %s and %s",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 v2->toChars(), vd->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 assert(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 Initializer *iz = i->value[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 iz = ::semantic(iz, sc, vd->type->addMod(t->mod), needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 Expression *ex = initializerToExpression(iz);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 if (ex->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 i->value[j] = iz;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 (*elements)[fieldi] = doCopyOrMove(sc, ex);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 ++fieldi;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 if (errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 StructLiteralExp *sle = new StructLiteralExp(i->loc, sd, elements, t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 if (!sd->fill(i->loc, elements, false))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 sle->type = t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 ExpInitializer *ie = new ExpInitializer(i->loc, sle);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 result = ::semantic(ie, sc, t, needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 else if ((t->ty == Tdelegate || (t->ty == Tpointer && t->nextOf()->ty == Tfunction)) && i->value.dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 TOK tok = (t->ty == Tdelegate) ? TOKdelegate : TOKfunction;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 /* Rewrite as empty delegate literal { }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 Parameters *parameters = new Parameters;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 Type *tf = new TypeFunction(parameters, NULL, 0, LINKd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(i->loc, Loc(), tf, tok, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 fd->fbody = new CompoundStatement(i->loc, new Statements());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 fd->endloc = i->loc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 Expression *e = new FuncExp(i->loc, fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 ExpInitializer *ie = new ExpInitializer(i->loc, e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 result = ::semantic(ie, sc, t, needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 error(i->loc, "a struct is not a valid initializer for a %s", t->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 void visit(ArrayInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 unsigned length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 const unsigned amax = 0x80000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 bool errors = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 if (i->sem) // if semantic() already run
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 i->sem = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 t = t->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 switch (t->ty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 case Tsarray:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 case Tarray:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 case Tvector:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 t = ((TypeVector *)t)->basetype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 case Taarray:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 case Tstruct: // consider implicit constructor call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 Expression *e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 if (t->ty == Taarray || i->isAssociativeArray())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 e = i->toAssocArrayLiteral();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 e = initializerToExpression(i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 if (!e) // Bugzilla 13987
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 error(i->loc, "cannot use array to initialize %s", t->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 ExpInitializer *ei = new ExpInitializer(e->loc, e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 result = ::semantic(ei, sc, t, needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 case Tpointer:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 if (t->nextOf()->ty != Tfunction)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 error(i->loc, "cannot use array to initialize %s", t->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 i->type = t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 length = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 for (size_t j = 0; j < i->index.dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 Expression *idx = i->index[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 if (idx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 sc = sc->startCTFE();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 idx = ::semantic(idx, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 sc = sc->endCTFE();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 idx = idx->ctfeInterpret();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 i->index[j] = idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 const uinteger_t idxvalue = idx->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 if (idxvalue >= amax)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 error(i->loc, "array index %llu overflow", (ulonglong)idxvalue);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 length = (unsigned)idx->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 if (idx->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 Initializer *val = i->value[j];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 ExpInitializer *ei = val->isExpInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 if (ei && !idx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 ei->expandTuples = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 val = ::semantic(val, sc, t->nextOf(), needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 if (val->isErrorInitializer())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 errors = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 ei = val->isExpInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 // found a tuple, expand it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 if (ei && ei->exp->op == TOKtuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 TupleExp *te = (TupleExp *)ei->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 i->index.remove(j);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 i->value.remove(j);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 for (size_t k = 0; k < te->exps->dim; ++k)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 Expression *e = (*te->exps)[k];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 i->index.insert(j + k, (Expression *)NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 i->value.insert(j + k, new ExpInitializer(e->loc, e));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 j--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 i->value[j] = val;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 length++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 if (length == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 error(i->loc, "array dimension overflow");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 if (length > i->dim)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 i->dim = length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 if (t->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 uinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 if (i->dim > edim)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 error(i->loc, "array initializer has %u elements, but array length is %llu", i->dim, (ulonglong)edim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 if (errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 d_uns64 sz = t->nextOf()->size();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 bool overflow = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 const d_uns64 max = mulu((d_uns64)i->dim, sz, overflow);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 if (overflow || max > amax)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 error(i->loc, "array dimension %llu exceeds max of %llu", (ulonglong)i->dim, (ulonglong)(amax / sz));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 goto Lerr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 Lerr:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 void visit(ExpInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 //printf("ExpInitializer::semantic(%s), type = %s\n", i->exp->toChars(), t->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 if (needInterpret) sc = sc->startCTFE();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 i->exp = ::semantic(i->exp, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 i->exp = resolveProperties(sc, i->exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 if (needInterpret) sc = sc->endCTFE();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 if (i->exp->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 unsigned int olderrors = global.errors;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 if (needInterpret)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 // If the result will be implicitly cast, move the cast into CTFE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 // to avoid premature truncation of polysemous types.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 // eg real [] x = [1.1, 2.2]; should use real precision.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 if (i->exp->implicitConvTo(t))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 i->exp = i->exp->implicitCastTo(sc, t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 if (!global.gag && olderrors != global.errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 i->exp = i->exp->ctfeInterpret();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 i->exp = i->exp->optimize(WANTvalue);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 if (!global.gag && olderrors != global.errors)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 result = i; // Failed, suppress duplicate error messages
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 if (i->exp->type->ty == Ttuple && ((TypeTuple *)i->exp->type)->arguments->dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 Type *et = i->exp->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 i->exp = new TupleExp(i->exp->loc, new Expressions());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 i->exp->type = et;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 if (i->exp->op == TOKtype)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 i->exp->error("initializer must be an expression, not '%s'", i->exp->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 // Make sure all pointers are constants
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 if (needInterpret && hasNonConstPointers(i->exp))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 i->exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", i->exp->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 Type *tb = t->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 Type *ti = i->exp->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 if (i->exp->op == TOKtuple && i->expandTuples && !i->exp->implicitConvTo(t))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 result = new ExpInitializer(i->loc, i->exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 /* Look for case of initializing a static array with a too-short
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 * string literal, such as:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 * char[5] foo = "abc";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 * Allow this by doing an explicit cast, which will lengthen the string
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 * literal.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 if (i->exp->op == TOKstring && tb->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 StringExp *se = (StringExp *)i->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 Type *typeb = se->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 TY tynto = tb->nextOf()->ty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 if (!se->committed &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 (typeb->ty == Tarray || typeb->ty == Tsarray) &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 i->exp = se->castTo(sc, t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 goto L1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 // Look for implicit constructor call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 if (tb->ty == Tstruct &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 !(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 !i->exp->implicitConvTo(t))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 if (sd->ctor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 // Rewrite as S().ctor(exp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 Expression *e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 e = new StructLiteralExp(i->loc, sd, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 e = new DotIdExp(i->loc, e, Id::ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 e = new CallExp(i->loc, e, i->exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 e = ::semantic(e, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 if (needInterpret)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 i->exp = e->ctfeInterpret();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 i->exp = e->optimize(WANTvalue);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 // Look for the case of statically initializing an array
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 // with a single member.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 if (tb->ty == Tsarray &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 !tb->nextOf()->equals(ti->toBasetype()->nextOf()) &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 i->exp->implicitConvTo(tb->nextOf())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 /* If the variable is not actually used in compile time, array creation is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 * redundant. So delay it until invocation of toExpression() or toDt().
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 t = tb->nextOf();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 if (i->exp->implicitConvTo(t))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 i->exp = i->exp->implicitCastTo(sc, t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 // Look for mismatch of compile-time known length to emit
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 // better diagnostic message, as same as AssignExp::semantic.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 if (tb->ty == Tsarray &&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 i->exp->implicitConvTo(tb->nextOf()->arrayOf()) > MATCHnomatch)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 uinteger_t dim1 = ((TypeSArray *)tb)->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 uinteger_t dim2 = dim1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 if (i->exp->op == TOKarrayliteral)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 ArrayLiteralExp *ale = (ArrayLiteralExp *)i->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 dim2 = ale->elements ? ale->elements->dim : 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 else if (i->exp->op == TOKslice)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 Type *tx = toStaticArrayType((SliceExp *)i->exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 if (tx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 dim2 = ((TypeSArray *)tx)->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 if (dim1 != dim2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 i->exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 i->exp = new ErrorExp();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 i->exp = i->exp->implicitCastTo(sc, t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 L1:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 if (i->exp->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 if (needInterpret)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 i->exp = i->exp->ctfeInterpret();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 i->exp = i->exp->optimize(WANTvalue);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 //printf("-ExpInitializer::semantic(): "); i->exp->print();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 // Performs semantic analisys on Initializer AST nodes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 InitializerSemanticVisitor v = InitializerSemanticVisitor(sc, t, needInterpret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 init->accept(&v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 return v.result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 class InferTypeVisitor : public Visitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 Initializer *result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 Scope *sc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 InferTypeVisitor(Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 this->result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 this->sc = sc;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 void visit(ErrorInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 result = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 void visit(VoidInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 error(i->loc, "cannot infer type from void initializer");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 void visit(StructInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 error(i->loc, "cannot infer type from struct initializer");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 void visit(ArrayInitializer *init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 //printf("ArrayInitializer::inferType() %s\n", init->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 Expressions *keys = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 Expressions *values;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 if (init->isAssociativeArray())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 keys = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 keys->setDim(init->value.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 values = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 values->setDim(init->value.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 for (size_t i = 0; i < init->value.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 Expression *e = init->index[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 if (!e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 (*keys)[i] = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 Initializer *iz = init->value[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 if (!iz)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 iz = inferType(iz, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 if (iz->isErrorInitializer())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 result = iz;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 assert(iz->isExpInitializer());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 (*values)[i] = ((ExpInitializer *)iz)->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 assert((*values)[i]->op != TOKerror);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 Expression *e = new AssocArrayLiteralExp(init->loc, keys, values);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 ExpInitializer *ei = new ExpInitializer(init->loc, e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 result = inferType(ei, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 Expressions *elements = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 elements->setDim(init->value.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 elements->zero();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 for (size_t i = 0; i < init->value.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 assert(!init->index[i]); // already asserted by isAssociativeArray()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 Initializer *iz = init->value[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 if (!iz)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 iz = inferType(iz, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 if (iz->isErrorInitializer())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 result = iz;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 assert(iz->isExpInitializer());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 (*elements)[i] = ((ExpInitializer *)iz)->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 assert((*elements)[i]->op != TOKerror);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 Expression *e = new ArrayLiteralExp(init->loc, NULL, elements);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 ExpInitializer *ei = new ExpInitializer(init->loc, e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 result = inferType(ei, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 Lno:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 if (keys)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 delete keys;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 delete values;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 error(init->loc, "not an associative array initializer");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 error(init->loc, "cannot infer type from array initializer");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 void visit(ExpInitializer *init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 //printf("ExpInitializer::inferType() %s\n", init->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 init->exp = ::semantic(init->exp, sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 init->exp = resolveProperties(sc, init->exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 if (init->exp->op == TOKscope)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 ScopeExp *se = (ScopeExp *)init->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 TemplateInstance *ti = se->sds->isTemplateInstance();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 // Give error for overloaded function addresses
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 bool hasOverloads = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 if (FuncDeclaration *f = isFuncAddress(init->exp, &hasOverloads))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 if (f->checkForwardRef(init->loc))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 if (hasOverloads && !f->isUnique())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 if (init->exp->op == TOKaddress)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 AddrExp *ae = (AddrExp *)init->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 if (ae->e1->op == TOKoverloadset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 if (init->exp->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 if (!init->exp->type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 result = new ErrorInitializer();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 result = init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 /* Translates to an expression to infer type.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 * Returns ExpInitializer or ErrorInitializer.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 Initializer *inferType(Initializer *init, Scope *sc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 InferTypeVisitor v = InferTypeVisitor(sc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 init->accept(&v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 return v.result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 class InitToExpressionVisitor : public Visitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 Expression *result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 Type *itype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 InitToExpressionVisitor(Type *itype)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 this->result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 this->itype = itype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 void visit(ErrorInitializer *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 result = new ErrorExp();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 void visit(VoidInitializer *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 /***************************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 * This works by transforming a struct initializer into
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 * a struct literal. In the future, the two should be the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 * same thing.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 void visit(StructInitializer *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 // cannot convert to an expression without target 'ad'
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 /********************************
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 * If possible, convert array initializer to array literal.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 * Otherwise return NULL.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 void visit(ArrayInitializer *init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 //printf("ArrayInitializer::toExpression(), dim = %d\n", init->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 //static int i; if (++i == 2) halt();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 Expressions *elements;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 unsigned edim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 const unsigned amax = 0x80000000;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 Type *t = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 if (init->type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 if (init->type == Type::terror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 result = new ErrorExp();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 t = init->type->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 switch (t->ty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 case Tvector:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 t = ((TypeVector *)t)->basetype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 /* fall through */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 case Tsarray:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 uinteger_t adim = ((TypeSArray *)t)->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 if (adim >= amax)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 edim = (unsigned)adim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 case Tpointer:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 case Tarray:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 edim = init->dim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 assert(0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 edim = (unsigned)init->value.dim;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 for (size_t i = 0, j = 0; i < init->value.dim; i++, j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 if (init->index[i])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 if (init->index[i]->op == TOKint64)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 const uinteger_t idxval = init->index[i]->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 if (idxval >= amax)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 j = (size_t)idxval;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 if (j >= edim)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 edim = (unsigned)(j + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 elements = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 elements->setDim(edim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 elements->zero();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 for (size_t i = 0, j = 0; i < init->value.dim; i++, j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 if (init->index[i])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 j = (size_t)(init->index[i])->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 assert(j < edim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 Initializer *iz = init->value[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 if (!iz)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 Expression *ex = initializerToExpression(iz);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 if (!ex)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 (*elements)[j] = ex;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 /* Fill in any missing elements with the default initializer
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 Expression *_init = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 for (size_t i = 0; i < edim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 if (!(*elements)[i])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 if (!init->type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 goto Lno;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 if (!_init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 _init = ((TypeNext *)t)->next->defaultInit();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 (*elements)[i] = _init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 /* Expand any static array initializers that are a single expression
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 * into an array of them
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 if (t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 Type *tn = t->nextOf()->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 if (tn->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 size_t dim = ((TypeSArray *)tn)->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 Type *te = tn->nextOf()->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 for (size_t i = 0; i < elements->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 Expression *e = (*elements)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 if (te->equals(e->type))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 Expressions *elements2 = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 elements2->setDim(dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 for (size_t j = 0; j < dim; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 (*elements2)[j] = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 e = new ArrayLiteralExp(e->loc, tn, elements2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 (*elements)[i] = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 /* If any elements are errors, then the whole thing is an error
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 for (size_t i = 0; i < edim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 Expression *e = (*elements)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 if (e->op == TOKerror)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 result = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 Expression *e = new ArrayLiteralExp(init->loc, init->type, elements);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 result = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 Lno:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 result = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 void visit(ExpInitializer *i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 if (itype)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", itype->toChars(), i->exp->toChars());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 Type *tb = itype->toBasetype();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 Expression *e = (i->exp->op == TOKconstruct || i->exp->op == TOKblit) ? ((AssignExp *)i->exp)->e2 : i->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 if (tb->ty == Tsarray && e->implicitConvTo(tb->nextOf()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 TypeSArray *tsa = (TypeSArray *)tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 size_t d = (size_t)tsa->dim->toInteger();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 Expressions *elements = new Expressions();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 elements->setDim(d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 for (size_t i = 0; i < d; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 (*elements)[i] = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, itype, elements);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 result = ae;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 result = i->exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 Expression *initializerToExpression(Initializer *i, Type *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 InitToExpressionVisitor v = InitToExpressionVisitor(t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 i->accept(&v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 return v.result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 }