]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/dmd/semantic2.c
ipa-param-manip: Be careful about a reallocating hash_map
[thirdparty/gcc.git] / gcc / d / dmd / semantic2.c
CommitLineData
a3b38b77
IB
1
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 */
9
10#include "dsymbol.h"
11#include "aggregate.h"
12#include "attrib.h"
13#include "declaration.h"
14#include "errors.h"
15#include "import.h"
16#include "init.h"
17#include "module.h"
18#include "nspace.h"
19#include "objc.h"
20#include "scope.h"
21#include "staticassert.h"
22#include "template.h"
23#include "visitor.h"
24
25bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors);
26void udaExpressionEval(Scope *sc, Expressions *exps);
27Objc *objc();
28
29class Semantic2Visitor : public Visitor
30{
31public:
32 Scope *sc;
33
34 Semantic2Visitor(Scope *sc)
35 {
36 this->sc = sc;
37 }
38
39 void visit(Dsymbol *)
40 {
41 // Most Dsymbols have no further semantic analysis needed
42 }
43
44 void visit(StaticAssert *sa)
45 {
46 //printf("StaticAssert::semantic2() %s\n", toChars());
47 ScopeDsymbol *sds = new ScopeDsymbol();
48 sc = sc->push(sds);
49 sc->tinst = NULL;
50 sc->minst = NULL;
51
52 bool errors = false;
53 bool result = evalStaticCondition(sc, sa->exp, sa->exp, errors);
54 sc = sc->pop();
55 if (errors)
56 {
57 errorSupplemental(sa->loc, "while evaluating: static assert(%s)", sa->exp->toChars());
58 }
59 else if (!result)
60 {
61 if (sa->msg)
62 {
63 sc = sc->startCTFE();
64 sa->msg = expressionSemantic(sa->msg, sc);
65 sa->msg = resolveProperties(sc, sa->msg);
66 sc = sc->endCTFE();
67 sa->msg = sa->msg->ctfeInterpret();
68 if (StringExp * se = sa->msg->toStringExp())
69 {
70 // same with pragma(msg)
71 se = se->toUTF8(sc);
72 sa->error("\"%.*s\"", (int)se->len, (char *)se->string);
73 }
74 else
75 sa->error("%s", sa->msg->toChars());
76 }
77 else
78 sa->error("(%s) is false", sa->exp->toChars());
79 if (sc->tinst)
80 sc->tinst->printInstantiationTrace();
81 if (!global.gag)
82 fatal();
83 }
84 }
85
86 void visit(TemplateInstance *tempinst)
87 {
88 if (tempinst->semanticRun >= PASSsemantic2)
89 return;
90 tempinst->semanticRun = PASSsemantic2;
91 if (!tempinst->errors && tempinst->members)
92 {
93 TemplateDeclaration *tempdecl = tempinst->tempdecl->isTemplateDeclaration();
94 assert(tempdecl);
95
96 sc = tempdecl->_scope;
97 assert(sc);
98 sc = sc->push(tempinst->argsym);
99 sc = sc->push(tempinst);
100 sc->tinst = tempinst;
101 sc->minst = tempinst->minst;
102
103 int needGagging = (tempinst->gagged && !global.gag);
104 unsigned int olderrors = global.errors;
105 int oldGaggedErrors = -1; // dead-store to prevent spurious warning
106 if (needGagging)
107 oldGaggedErrors = global.startGagging();
108
109 for (size_t i = 0; i < tempinst->members->length; i++)
110 {
111 Dsymbol *s = (*tempinst->members)[i];
112 semantic2(s, sc);
113 if (tempinst->gagged && global.errors != olderrors)
114 break;
115 }
116
117 if (global.errors != olderrors)
118 {
119 if (!tempinst->errors)
120 {
121 if (!tempdecl->literal)
122 tempinst->error(tempinst->loc, "error instantiating");
123 if (tempinst->tinst)
124 tempinst->tinst->printInstantiationTrace();
125 }
126 tempinst->errors = true;
127 }
128 if (needGagging)
129 global.endGagging(oldGaggedErrors);
130
131 sc = sc->pop();
132 sc->pop();
133 }
134 }
135
136 void visit(TemplateMixin *tmix)
137 {
138 if (tmix->semanticRun >= PASSsemantic2)
139 return;
140 tmix->semanticRun = PASSsemantic2;
141 if (tmix->members)
142 {
143 assert(sc);
144 sc = sc->push(tmix->argsym);
145 sc = sc->push(tmix);
146 for (size_t i = 0; i < tmix->members->length; i++)
147 {
148 Dsymbol *s = (*tmix->members)[i];
149 semantic2(s, sc);
150 }
151 sc = sc->pop();
152 sc->pop();
153 }
154 }
155
156 void visit(VarDeclaration *vd)
157 {
158 if (vd->semanticRun < PASSsemanticdone && vd->inuse)
159 return;
160
161 //printf("VarDeclaration::semantic2('%s')\n", toChars());
162
163 if (vd->_init && !vd->toParent()->isFuncDeclaration())
164 {
165 vd->inuse++;
5a0aa603
IB
166
167 /* https://issues.dlang.org/show_bug.cgi?id=20280
168 *
169 * Template instances may import modules that have not
170 * finished semantic1.
171 */
172 if (!vd->type)
173 dsymbolSemantic(vd, sc);
174
a3b38b77
IB
175 // Bugzilla 14166: Don't run CTFE for the temporary variables inside typeof
176 vd->_init = initializerSemantic(vd->_init, sc, vd->type, sc->intypeof == 1 ? INITnointerpret : INITinterpret);
177 vd->inuse--;
178 }
179 if (vd->_init && (vd->storage_class & STCmanifest))
180 {
181 /* Cannot initializer enums with CTFE classreferences and addresses of struct literals.
182 * Scan initializer looking for them. Issue error if found.
183 */
184 if (ExpInitializer *ei = vd->_init->isExpInitializer())
185 {
186 struct EnumInitializer
187 {
188 static bool arrayHasInvalidEnumInitializer(Expressions *elems)
189 {
190 for (size_t i = 0; i < elems->length; i++)
191 {
192 Expression *e = (*elems)[i];
193 if (e && hasInvalidEnumInitializer(e))
194 return true;
195 }
196 return false;
197 }
198
199 static bool hasInvalidEnumInitializer(Expression *e)
200 {
201 if (e->op == TOKclassreference)
202 return true;
203 if (e->op == TOKaddress && ((AddrExp *)e)->e1->op == TOKstructliteral)
204 return true;
205 if (e->op == TOKarrayliteral)
206 return arrayHasInvalidEnumInitializer(((ArrayLiteralExp *)e)->elements);
207 if (e->op == TOKstructliteral)
208 return arrayHasInvalidEnumInitializer(((StructLiteralExp *)e)->elements);
209 if (e->op == TOKassocarrayliteral)
210 {
211 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e;
212 return arrayHasInvalidEnumInitializer(ae->values) ||
213 arrayHasInvalidEnumInitializer(ae->keys);
214 }
215 return false;
216 }
217 };
218 if (EnumInitializer::hasInvalidEnumInitializer(ei->exp))
219 vd->error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead.");
220 }
221 }
222 else if (vd->_init && vd->isThreadlocal())
223 {
224 if ((vd->type->ty == Tclass) && vd->type->isMutable() && !vd->type->isShared())
225 {
226 ExpInitializer *ei = vd->_init->isExpInitializer();
227 if (ei && ei->exp->op == TOKclassreference)
228 vd->error("is mutable. Only const or immutable class thread local variable are allowed, not %s", vd->type->toChars());
229 }
230 else if (vd->type->ty == Tpointer && vd->type->nextOf()->ty == Tstruct && vd->type->nextOf()->isMutable() && !vd->type->nextOf()->isShared())
231 {
232 ExpInitializer *ei = vd->_init->isExpInitializer();
233 if (ei && ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral)
234 {
235 vd->error("is a pointer to mutable struct. Only pointers to const, immutable or shared struct thread local variable are allowed, not %s", vd->type->toChars());
236 }
237 }
238 }
239 vd->semanticRun = PASSsemantic2done;
240 }
241
242 void visit(Module *mod)
243 {
244 //printf("Module::semantic2('%s'): parent = %p\n", toChars(), mod->parent);
245 if (mod->semanticRun != PASSsemanticdone) // semantic() not completed yet - could be recursive call
246 return;
247 mod->semanticRun = PASSsemantic2;
248
249 // Note that modules get their own scope, from scratch.
250 // This is so regardless of where in the syntax a module
251 // gets imported, it is unaffected by context.
252 Scope *sc = Scope::createGlobal(mod); // create root scope
253 //printf("Module = %p\n", sc.scopesym);
254
255 // Pass 2 semantic routines: do initializers and function bodies
256 for (size_t i = 0; i < mod->members->length; i++)
257 {
258 Dsymbol *s = (*mod->members)[i];
259 semantic2(s, sc);
260 }
261
262 if (mod->userAttribDecl)
263 {
264 semantic2(mod->userAttribDecl, sc);
265 }
266
267 sc = sc->pop();
268 sc->pop();
269 mod->semanticRun = PASSsemantic2done;
270 //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), mod->parent);
271 }
272
273 void visit(FuncDeclaration *fd)
274 {
275 if (fd->semanticRun >= PASSsemantic2done)
276 return;
5a0aa603
IB
277
278 if (fd->semanticRun < PASSsemanticdone && !fd->errors)
279 {
280 /* https://issues.dlang.org/show_bug.cgi?id=21614
281 *
282 * Template instances may import modules that have not
283 * finished semantic1.
284 */
285 dsymbolSemantic(fd, sc);
286 }
287
a3b38b77
IB
288 assert(fd->semanticRun <= PASSsemantic2);
289 fd->semanticRun = PASSsemantic2;
290
291 objc()->setSelector(fd, sc);
292 objc()->validateSelector(fd);
293
294 if (fd->parent->isClassDeclaration())
295 {
296 objc()->checkLinkage(fd);
297 }
298 if (!fd->type || fd->type->ty != Tfunction)
299 return;
300 TypeFunction *f = fd->type->toTypeFunction();
301 const size_t nparams = f->parameterList.length();
302 // semantic for parameters' UDAs
303 for (size_t i = 0; i < nparams; i++)
304 {
305 Parameter *param = f->parameterList[i];
306 if (param && param->userAttribDecl)
307 semantic2(param->userAttribDecl, sc);
308 }
309 }
310
311 void visit(Import *i)
312 {
313 //printf("Import::semantic2('%s')\n", toChars());
314 if (i->mod)
315 {
316 semantic2(i->mod, NULL);
317 if (i->mod->needmoduleinfo)
318 {
319 //printf("module5 %s because of %s\n", sc->_module->toChars(), i->mod->toChars());
320 if (sc)
321 sc->_module->needmoduleinfo = 1;
322 }
323 }
324 }
325
326 void visit(Nspace *ns)
327 {
328 if (ns->semanticRun >= PASSsemantic2)
329 return;
330 ns->semanticRun = PASSsemantic2;
331 if (ns->members)
332 {
333 assert(sc);
334 sc = sc->push(ns);
335 sc->linkage = LINKcpp;
336 for (size_t i = 0; i < ns->members->length; i++)
337 {
338 Dsymbol *s = (*ns->members)[i];
339 semantic2(s, sc);
340 }
341 sc->pop();
342 }
343 }
344
345 void visit(AttribDeclaration *ad)
346 {
347 Dsymbols *d = ad->include(sc);
348
349 if (d)
350 {
351 Scope *sc2 = ad->newScope(sc);
352
353 for (size_t i = 0; i < d->length; i++)
354 {
355 Dsymbol *s = (*d)[i];
356 semantic2(s, sc2);
357 }
358
359 if (sc2 != sc)
360 sc2->pop();
361 }
362 }
363
364 /**
365 * Run the DeprecatedDeclaration's semantic2 phase then its members.
366 *
367 * The message set via a `DeprecatedDeclaration` can be either of:
368 * - a string literal
369 * - an enum
370 * - a static immutable
371 * So we need to call ctfe to resolve it.
372 * Afterward forwards to the members' semantic2.
373 */
374 void visit(DeprecatedDeclaration *dd)
375 {
376 dd->getMessage();
377 visit((AttribDeclaration *)dd);
378 }
379
380 void visit(AlignDeclaration *ad)
381 {
382 ad->getAlignment(sc);
383 visit((AttribDeclaration *)ad);
384 }
385
386 void visit(UserAttributeDeclaration *uad)
387 {
388 if (uad->decl && uad->atts && uad->atts->length && uad->_scope)
389 {
390 uad->_scope = NULL;
391 udaExpressionEval(sc, uad->atts);
392 }
393 visit((AttribDeclaration *)uad);
394 }
395
396 void visit(AggregateDeclaration *ad)
397 {
398 //printf("AggregateDeclaration::semantic2(%s) type = %s, errors = %d\n", toChars(), ad->type->toChars(), ad->errors);
399 if (!ad->members)
400 return;
401
402 if (ad->_scope)
403 {
404 ad->error("has forward references");
405 return;
406 }
407
408 Scope *sc2 = ad->newScope(sc);
409
410 ad->determineSize(ad->loc);
411
412 for (size_t i = 0; i < ad->members->length; i++)
413 {
414 Dsymbol *s = (*ad->members)[i];
415 //printf("\t[%d] %s\n", i, s->toChars());
416 semantic2(s, sc2);
417 }
418
419 sc2->pop();
420 }
421};
422
423/*************************************
424 * Does semantic analysis on initializers and members of aggregates.
425 */
426void semantic2(Dsymbol *dsym, Scope *sc)
427{
428 Semantic2Visitor v(sc);
429 dsym->accept(&v);
430}