1 /**
2 * Does the semantic 1 pass on the AST, which looks at symbol declarations but not initializers
3 * or function bodies.
4 *
5 * Copyright: Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
6 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dsymbolsem.d, _dsymbolsem.d)
9 * Documentation: https://dlang.org/phobos/dmd_dsymbolsem.html
10 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dsymbolsem.d
11 */
12
13 module dmd.dsymbolsem;
14
15 import core.stdc.stdio;
16 import core.stdc.string;
17
18 import dmd.aggregate;
19 import dmd.aliasthis;
20 import dmd.apply;
21 import dmd.arraytypes;
22 import dmd.astcodegen;
23 import dmd.astenums;
24 import dmd.attrib;
25 import dmd.blockexit;
26 import dmd.clone;
27 import dmd.compiler;
28 import dmd.dcast;
29 import dmd.dclass;
30 import dmd.declaration;
31 import dmd.denum;
32 import dmd.dimport;
33 import dmd.dinterpret;
34 import dmd.dmangle;
35 import dmd.dmodule;
36 import dmd.dscope;
37 import dmd.dstruct;
38 import dmd.dsymbol;
39 import dmd.dtemplate;
40 import dmd.dversion;
41 import dmd.errors;
42 import dmd.escape;
43 import dmd.expression;
44 import dmd.expressionsem;
45 import dmd.func;
46 import dmd.globals;
47 import dmd.id;
48 import dmd.identifier;
49 import dmd.init;
50 import dmd.initsem;
51 import dmd.hdrgen;
52 import dmd.mtype;
53 import dmd.nogc;
54 import dmd.nspace;
55 import dmd.objc;
56 import dmd.opover;
57 import dmd.parse;
58 import dmd.root.filename;
59 import dmd.root.outbuffer;
60 import dmd.root.rmem;
61 import dmd.root.rootobject;
62 import dmd.semantic2;
63 import dmd.semantic3;
64 import dmd.sideeffect;
65 import dmd.statementsem;
66 import dmd.staticassert;
67 import dmd.tokens;
68 import dmd.utf;
69 import dmd.utils;
70 import dmd.statement;
71 import dmd.target;
72 import dmd.templateparamsem;
73 import dmd.typesem;
74 import dmd.visitor;
75
76 enum LOG = false;
77
setMangleOverride(Dsymbol s,const (char)[]sym)78 private uint setMangleOverride(Dsymbol s, const(char)[] sym)
79 {
80 if (s.isFuncDeclaration() || s.isVarDeclaration())
81 {
82 s.isDeclaration().mangleOverride = sym;
83 return 1;
84 }
85
86 if (auto ad = s.isAttribDeclaration())
87 {
88 uint nestedCount = 0;
89
90 ad.include(null).foreachDsymbol( (s) { nestedCount += setMangleOverride(s, sym); } );
91
92 return nestedCount;
93 }
94 return 0;
95 }
96
97 /*************************************
98 * Does semantic analysis on the public face of declarations.
99 */
dsymbolSemantic(Dsymbol dsym,Scope * sc)100 extern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc)
101 {
102 scope v = new DsymbolSemanticVisitor(sc);
103 dsym.accept(v);
104 }
105
106 /***************************************************
107 * Determine the numerical value of the AlignmentDeclaration
108 * Params:
109 * ad = AlignmentDeclaration
110 * sc = context
111 * Returns:
112 * alignment as numerical value that is never 0.
113 * STRUCTALIGN_DEFAULT is used instead.
114 * STRUCTALIGN_DEFAULT is returned for errors
115 */
getAlignment(AlignDeclaration ad,Scope * sc)116 structalign_t getAlignment(AlignDeclaration ad, Scope* sc)
117 {
118 if (ad.salign != ad.UNKNOWN) // UNKNOWN is 0
119 return ad.salign;
120
121 if (!ad.exps)
122 return ad.salign = STRUCTALIGN_DEFAULT;
123
124 dinteger_t strictest = 0; // strictest alignment
125 bool errors;
126 foreach (ref exp; (*ad.exps)[])
127 {
128 sc = sc.startCTFE();
129 auto e = exp.expressionSemantic(sc);
130 e = resolveProperties(sc, e);
131 sc = sc.endCTFE();
132 e = e.ctfeInterpret();
133 exp = e; // could be re-evaluated if exps are assigned to more than one AlignDeclaration by CParser.applySpecifier(),
134 // e.g. `_Alignas(8) int a, b;`
135 if (e.op == TOK.error)
136 errors = true;
137 else
138 {
139 auto n = e.toInteger();
140 if (sc.flags & SCOPE.Cfile && n == 0) // C11 6.7.5-6 allows 0 for alignment
141 continue;
142
143 if (n < 1 || n & (n - 1) || structalign_t.max < n || !e.type.isintegral())
144 {
145 error(ad.loc, "alignment must be an integer positive power of 2, not 0x%llx", cast(ulong)n);
146 errors = true;
147 }
148 if (n > strictest) // C11 6.7.5-6
149 strictest = n;
150 }
151 }
152
153 ad.salign = (errors || strictest == 0) // C11 6.7.5-6 says alignment of 0 means no effect
154 ? STRUCTALIGN_DEFAULT
155 : cast(structalign_t) strictest;
156 return ad.salign;
157 }
158
getMessage(DeprecatedDeclaration dd)159 const(char)* getMessage(DeprecatedDeclaration dd)
160 {
161 if (auto sc = dd._scope)
162 {
163 dd._scope = null;
164
165 sc = sc.startCTFE();
166 dd.msg = dd.msg.expressionSemantic(sc);
167 dd.msg = resolveProperties(sc, dd.msg);
168 sc = sc.endCTFE();
169 dd.msg = dd.msg.ctfeInterpret();
170
171 if (auto se = dd.msg.toStringExp())
172 dd.msgstr = se.toStringz().ptr;
173 else
174 dd.msg.error("compile time constant expected, not `%s`", dd.msg.toChars());
175 }
176 return dd.msgstr;
177 }
178
179
180 // Returns true if a contract can appear without a function body.
allowsContractWithoutBody(FuncDeclaration funcdecl)181 package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
182 {
183 assert(!funcdecl.fbody);
184
185 /* Contracts can only appear without a body when they are virtual
186 * interface functions or abstract.
187 */
188 Dsymbol parent = funcdecl.toParent();
189 InterfaceDeclaration id = parent.isInterfaceDeclaration();
190
191 if (!funcdecl.isAbstract() &&
192 (funcdecl.fensures || funcdecl.frequires) &&
193 !(id && funcdecl.isVirtual()))
194 {
195 auto cd = parent.isClassDeclaration();
196 if (!(cd && cd.isAbstract()))
197 return false;
198 }
199 return true;
200 }
201
202 private extern(C++) final class DsymbolSemanticVisitor : Visitor
203 {
204 alias visit = Visitor.visit;
205
206 Scope* sc;
this(Scope * sc)207 this(Scope* sc)
208 {
209 this.sc = sc;
210 }
211
212 // Save the scope and defer semantic analysis on the Dsymbol.
deferDsymbolSemantic(Dsymbol s,Scope * scx)213 private void deferDsymbolSemantic(Dsymbol s, Scope *scx)
214 {
215 s._scope = scx ? scx : sc.copy();
216 s._scope.setNoFree();
217 Module.addDeferredSemantic(s);
218 }
219
visit(Dsymbol dsym)220 override void visit(Dsymbol dsym)
221 {
222 dsym.error("%p has no semantic routine", dsym);
223 }
224
visit(ScopeDsymbol)225 override void visit(ScopeDsymbol) { }
visit(Declaration)226 override void visit(Declaration) { }
227
visit(AliasThis dsym)228 override void visit(AliasThis dsym)
229 {
230 if (dsym.semanticRun != PASS.init)
231 return;
232
233 if (dsym._scope)
234 {
235 sc = dsym._scope;
236 dsym._scope = null;
237 }
238
239 if (!sc)
240 return;
241
242 dsym.semanticRun = PASS.semantic;
243 dsym.isDeprecated_ = !!(sc.stc & STC.deprecated_);
244
245 Dsymbol p = sc.parent.pastMixin();
246 AggregateDeclaration ad = p.isAggregateDeclaration();
247 if (!ad)
248 {
249 error(dsym.loc, "alias this can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
250 return;
251 }
252
253 assert(ad.members);
254 Dsymbol s = ad.search(dsym.loc, dsym.ident);
255 if (!s)
256 {
257 s = sc.search(dsym.loc, dsym.ident, null);
258 if (s)
259 error(dsym.loc, "`%s` is not a member of `%s`", s.toChars(), ad.toChars());
260 else
261 error(dsym.loc, "undefined identifier `%s`", dsym.ident.toChars());
262 return;
263 }
264 if (ad.aliasthis && s != ad.aliasthis)
265 {
266 error(dsym.loc, "there can be only one alias this");
267 return;
268 }
269
270 /* disable the alias this conversion so the implicit conversion check
271 * doesn't use it.
272 */
273 ad.aliasthis = null;
274
275 Dsymbol sx = s;
276 if (sx.isAliasDeclaration())
277 sx = sx.toAlias();
278 Declaration d = sx.isDeclaration();
279 if (d && !d.isTupleDeclaration())
280 {
281 /* https://issues.dlang.org/show_bug.cgi?id=18429
282 *
283 * If the identifier in the AliasThis declaration
284 * is defined later and is a voldemort type, we must
285 * perform semantic on the declaration to deduce the type.
286 */
287 if (!d.type)
288 d.dsymbolSemantic(sc);
289
290 Type t = d.type;
291 assert(t);
292 if (ad.type.implicitConvTo(t) > MATCH.nomatch)
293 {
294 error(dsym.loc, "alias this is not reachable as `%s` already converts to `%s`", ad.toChars(), t.toChars());
295 }
296 }
297
298 dsym.sym = s;
299 // Restore alias this
300 ad.aliasthis = dsym;
301 dsym.semanticRun = PASS.semanticdone;
302 }
303
visit(AliasDeclaration dsym)304 override void visit(AliasDeclaration dsym)
305 {
306 if (dsym.semanticRun >= PASS.semanticdone)
307 return;
308 assert(dsym.semanticRun <= PASS.semantic);
309
310 dsym.storage_class |= sc.stc & STC.deprecated_;
311 dsym.visibility = sc.visibility;
312 dsym.userAttribDecl = sc.userAttribDecl;
313
314 if (!sc.func && dsym.inNonRoot())
315 return;
316
317 aliasSemantic(dsym, sc);
318 }
319
visit(AliasAssign dsym)320 override void visit(AliasAssign dsym)
321 {
322 //printf("visit(AliasAssign)\n");
323 if (dsym.semanticRun >= PASS.semanticdone)
324 return;
325 assert(dsym.semanticRun <= PASS.semantic);
326
327 if (!sc.func && dsym.inNonRoot())
328 return;
329
330 aliasAssignSemantic(dsym, sc);
331 }
332
visit(VarDeclaration dsym)333 override void visit(VarDeclaration dsym)
334 {
335 version (none)
336 {
337 printf("VarDeclaration::semantic('%s', parent = '%s') sem = %d\n",
338 dsym.toChars(), sc.parent ? sc.parent.toChars() : null, dsym.semanticRun);
339 printf(" type = %s\n", dsym.type ? dsym.type.toChars() : "null");
340 printf(" stc = x%llx\n", dsym.storage_class);
341 printf(" storage_class = x%llx\n", dsym.storage_class);
342 printf("linkage = %d\n", dsym.linkage);
343 //if (strcmp(toChars(), "mul") == 0) assert(0);
344 }
345 //if (semanticRun > PASS.init)
346 // return;
347 //semanticRun = PSSsemantic;
348
349 if (dsym.semanticRun >= PASS.semanticdone)
350 return;
351
352 if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
353 dsym.overlapped = true;
354
355 Scope* scx = null;
356 if (dsym._scope)
357 {
358 sc = dsym._scope;
359 scx = sc;
360 dsym._scope = null;
361 }
362
363 if (!sc)
364 return;
365
366 dsym.semanticRun = PASS.semantic;
367
368 /* Pick up storage classes from context, but except synchronized,
369 * override, abstract, and final.
370 */
371 dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));
372 if (dsym.storage_class & STC.extern_ && dsym._init)
373 dsym.error("extern symbols cannot have initializers");
374
375 dsym.userAttribDecl = sc.userAttribDecl;
376 dsym.cppnamespace = sc.namespace;
377
378 AggregateDeclaration ad = dsym.isThis();
379 if (ad)
380 dsym.storage_class |= ad.storage_class & STC.TYPECTOR;
381
382 /* If auto type inference, do the inference
383 */
384 int inferred = 0;
385 if (!dsym.type)
386 {
387 dsym.inuse++;
388
389 // Infering the type requires running semantic,
390 // so mark the scope as ctfe if required
391 bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
392 if (needctfe)
393 {
394 sc.flags |= SCOPE.condition;
395 sc = sc.startCTFE();
396 }
397 //printf("inferring type for %s with init %s\n", dsym.toChars(), dsym._init.toChars());
398 dsym._init = dsym._init.inferType(sc);
399 dsym.type = dsym._init.initializerToExpression().type;
400 if (needctfe)
401 sc = sc.endCTFE();
402
403 dsym.inuse--;
404 inferred = 1;
405
406 /* This is a kludge to support the existing syntax for RAII
407 * declarations.
408 */
409 dsym.storage_class &= ~STC.auto_;
410 dsym.originalType = dsym.type.syntaxCopy();
411 }
412 else
413 {
414 if (!dsym.originalType)
415 dsym.originalType = dsym.type.syntaxCopy();
416
417 /* Prefix function attributes of variable declaration can affect
418 * its type:
419 * pure nothrow void function() fp;
420 * static assert(is(typeof(fp) == void function() pure nothrow));
421 */
422 Scope* sc2 = sc.push();
423 sc2.stc |= (dsym.storage_class & STC.FUNCATTR);
424 dsym.inuse++;
425 dsym.type = dsym.type.typeSemantic(dsym.loc, sc2);
426 dsym.inuse--;
427 sc2.pop();
428 }
429 //printf(" semantic type = %s\n", dsym.type ? dsym.type.toChars() : "null");
430 if (dsym.type.ty == Terror)
431 dsym.errors = true;
432
433 dsym.type.checkDeprecated(dsym.loc, sc);
434 dsym.linkage = sc.linkage;
435 dsym.parent = sc.parent;
436 //printf("this = %p, parent = %p, '%s'\n", dsym, dsym.parent, dsym.parent.toChars());
437 dsym.visibility = sc.visibility;
438
439 /* If scope's alignment is the default, use the type's alignment,
440 * otherwise the scope overrrides.
441 */
442 dsym.alignment = sc.alignment();
443 if (dsym.alignment == STRUCTALIGN_DEFAULT)
444 dsym.alignment = dsym.type.alignment(); // use type's alignment
445
446 //printf("sc.stc = %x\n", sc.stc);
447 //printf("storage_class = x%x\n", storage_class);
448
449 if (global.params.vcomplex)
450 dsym.type.checkComplexTransition(dsym.loc, sc);
451
452 // Calculate type size + safety checks
453 if (sc.func && !sc.intypeof)
454 {
455 if (dsym.storage_class & STC.gshared && !dsym.isMember())
456 {
457 if (sc.func.setUnsafe())
458 dsym.error("__gshared not allowed in safe functions; use shared");
459 }
460 }
461
462 Dsymbol parent = dsym.toParent();
463
464 Type tb = dsym.type.toBasetype();
465 Type tbn = tb.baseElemOf();
466 if (tb.ty == Tvoid && !(dsym.storage_class & STC.lazy_))
467 {
468 if (inferred)
469 {
470 dsym.error("type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", dsym.type.toChars(), dsym._init.toChars());
471 }
472 else
473 dsym.error("variables cannot be of type `void`");
474 dsym.type = Type.terror;
475 tb = dsym.type;
476 }
477 if (tb.ty == Tfunction)
478 {
479 dsym.error("cannot be declared to be a function");
480 dsym.type = Type.terror;
481 tb = dsym.type;
482 }
483 if (auto ts = tb.isTypeStruct())
484 {
485 // Require declarations, except when it's just a reference (as done for pointers)
486 // or when the variable is defined externally
487 if (!ts.sym.members && !(dsym.storage_class & (STC.ref_ | STC.extern_)))
488 {
489 dsym.error("no definition of struct `%s`", ts.toChars());
490
491 // Explain why the definition is required when it's part of another type
492 if (!dsym.type.isTypeStruct())
493 {
494 // Prefer Loc of the dependant type
495 const s = dsym.type.toDsymbol(sc);
496 const loc = (s ? s : dsym).loc;
497 loc.errorSupplemental("required by type `%s`", dsym.type.toChars());
498 }
499
500 // Flag variable as error to avoid invalid error messages due to unknown size
501 dsym.type = Type.terror;
502 }
503 }
504 if ((dsym.storage_class & STC.auto_) && !inferred)
505 dsym.error("storage class `auto` has no effect if type is not inferred, did you mean `scope`?");
506
507 if (auto tt = tb.isTypeTuple())
508 {
509 /* Instead, declare variables for each of the tuple elements
510 * and add those.
511 */
512 size_t nelems = Parameter.dim(tt.arguments);
513 Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression() : null;
514 if (ie)
515 ie = ie.expressionSemantic(sc);
516 if (nelems > 0 && ie)
517 {
518 auto iexps = new Expressions();
519 iexps.push(ie);
520 auto exps = new Expressions();
521 for (size_t pos = 0; pos < iexps.dim; pos++)
522 {
523 Lexpand1:
524 Expression e = (*iexps)[pos];
525 Parameter arg = Parameter.getNth(tt.arguments, pos);
526 arg.type = arg.type.typeSemantic(dsym.loc, sc);
527 //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
528 //printf("e = (%s %s, %s), ", Token::tochars[e.op], e.toChars(), e.type.toChars());
529 //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
530
531 if (e != ie)
532 {
533 if (iexps.dim > nelems)
534 goto Lnomatch;
535 if (e.type.implicitConvTo(arg.type))
536 continue;
537 }
538
539 if (auto te = e.isTupleExp())
540 {
541 if (iexps.dim - 1 + te.exps.dim > nelems)
542 goto Lnomatch;
543
544 iexps.remove(pos);
545 iexps.insert(pos, te.exps);
546 (*iexps)[pos] = Expression.combine(te.e0, (*iexps)[pos]);
547 goto Lexpand1;
548 }
549 else if (isAliasThisTuple(e))
550 {
551 auto v = copyToTemp(0, "__tup", e);
552 v.dsymbolSemantic(sc);
553 auto ve = new VarExp(dsym.loc, v);
554 ve.type = e.type;
555
556 exps.setDim(1);
557 (*exps)[0] = ve;
558 expandAliasThisTuples(exps, 0);
559
560 for (size_t u = 0; u < exps.dim; u++)
561 {
562 Lexpand2:
563 Expression ee = (*exps)[u];
564 arg = Parameter.getNth(tt.arguments, pos + u);
565 arg.type = arg.type.typeSemantic(dsym.loc, sc);
566 //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
567 //printf("ee = (%s %s, %s), ", Token::tochars[ee.op], ee.toChars(), ee.type.toChars());
568 //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
569
570 size_t iexps_dim = iexps.dim - 1 + exps.dim;
571 if (iexps_dim > nelems)
572 goto Lnomatch;
573 if (ee.type.implicitConvTo(arg.type))
574 continue;
575
576 if (expandAliasThisTuples(exps, u) != -1)
577 goto Lexpand2;
578 }
579
580 if ((*exps)[0] != ve)
581 {
582 Expression e0 = (*exps)[0];
583 (*exps)[0] = new CommaExp(dsym.loc, new DeclarationExp(dsym.loc, v), e0);
584 (*exps)[0].type = e0.type;
585
586 iexps.remove(pos);
587 iexps.insert(pos, exps);
588 goto Lexpand1;
589 }
590 }
591 }
592 if (iexps.dim < nelems)
593 goto Lnomatch;
594
595 ie = new TupleExp(dsym._init.loc, iexps);
596 }
597 Lnomatch:
598
599 if (ie && ie.op == TOK.tuple)
600 {
601 auto te = ie.isTupleExp();
602 size_t tedim = te.exps.dim;
603 if (tedim != nelems)
604 {
605 error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
606 for (size_t u = tedim; u < nelems; u++) // fill dummy expression
607 te.exps.push(ErrorExp.get());
608 }
609 }
610
611 auto exps = new Objects(nelems);
612 for (size_t i = 0; i < nelems; i++)
613 {
614 Parameter arg = Parameter.getNth(tt.arguments, i);
615
616 OutBuffer buf;
617 buf.printf("__%s_field_%llu", dsym.ident.toChars(), cast(ulong)i);
618 auto id = Identifier.idPool(buf[]);
619
620 Initializer ti;
621 if (ie)
622 {
623 Expression einit = ie;
624 if (auto te = ie.isTupleExp())
625 {
626 einit = (*te.exps)[i];
627 if (i == 0)
628 einit = Expression.combine(te.e0, einit);
629 }
630 ti = new ExpInitializer(einit.loc, einit);
631 }
632 else
633 ti = dsym._init ? dsym._init.syntaxCopy() : null;
634
635 StorageClass storage_class = STC.temp | STC.local | dsym.storage_class;
636 if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter))
637 storage_class |= arg.storageClass;
638 auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);
639 //printf("declaring field %s of type %s\n", v.toChars(), v.type.toChars());
640 v.dsymbolSemantic(sc);
641
642 if (sc.scopesym)
643 {
644 //printf("adding %s to %s\n", v.toChars(), sc.scopesym.toChars());
645 if (sc.scopesym.members)
646 // Note this prevents using foreach() over members, because the limits can change
647 sc.scopesym.members.push(v);
648 }
649
650 Expression e = new DsymbolExp(dsym.loc, v);
651 (*exps)[i] = e;
652 }
653 auto v2 = new TupleDeclaration(dsym.loc, dsym.ident, exps);
654 v2.parent = dsym.parent;
655 v2.isexp = true;
656 dsym.aliassym = v2;
657 dsym.semanticRun = PASS.semanticdone;
658 return;
659 }
660
661 /* Storage class can modify the type
662 */
663 dsym.type = dsym.type.addStorageClass(dsym.storage_class);
664
665 /* Adjust storage class to reflect type
666 */
667 if (dsym.type.isConst())
668 {
669 dsym.storage_class |= STC.const_;
670 if (dsym.type.isShared())
671 dsym.storage_class |= STC.shared_;
672 }
673 else if (dsym.type.isImmutable())
674 dsym.storage_class |= STC.immutable_;
675 else if (dsym.type.isShared())
676 dsym.storage_class |= STC.shared_;
677 else if (dsym.type.isWild())
678 dsym.storage_class |= STC.wild;
679
680 if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_))
681 {
682 if (stc == STC.final_)
683 dsym.error("cannot be `final`, perhaps you meant `const`?");
684 else
685 {
686 OutBuffer buf;
687 stcToBuffer(&buf, stc);
688 dsym.error("cannot be `%s`", buf.peekChars());
689 }
690 dsym.storage_class &= ~stc; // strip off
691 }
692
693 // At this point we can add `scope` to the STC instead of `in`,
694 // because we are never going to use this variable's STC for user messages
695 if (dsym.storage_class & STC.in_ && global.params.previewIn)
696 dsym.storage_class |= STC.scope_;
697
698 if (dsym.storage_class & STC.scope_)
699 {
700 StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.tls | STC.gshared);
701 if (stc)
702 {
703 OutBuffer buf;
704 stcToBuffer(&buf, stc);
705 dsym.error("cannot be `scope` and `%s`", buf.peekChars());
706 }
707 else if (dsym.isMember())
708 {
709 dsym.error("field cannot be `scope`");
710 }
711 else if (!dsym.type.hasPointers())
712 {
713 dsym.storage_class &= ~STC.scope_; // silently ignore; may occur in generic code
714 }
715 }
716
717 if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.tls | STC.gshared | STC.ctfe))
718 {
719 }
720 else
721 {
722 AggregateDeclaration aad = parent.isAggregateDeclaration();
723 if (aad)
724 {
725 if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer())
726 {
727 const(char)* s = (dsym.storage_class & STC.immutable_) ? "immutable" : "const";
728 message(dsym.loc, "`%s.%s` is `%s` field", ad.toPrettyChars(), dsym.toChars(), s);
729 }
730 dsym.storage_class |= STC.field;
731 if (auto ts = tbn.isTypeStruct())
732 if (ts.sym.noDefaultCtor)
733 {
734 if (!dsym.isThisDeclaration() && !dsym._init)
735 aad.noDefaultCtor = true;
736 }
737 }
738
739 InterfaceDeclaration id = parent.isInterfaceDeclaration();
740 if (id)
741 {
742 dsym.error("field not allowed in interface");
743 }
744 else if (aad && aad.sizeok == Sizeok.done)
745 {
746 dsym.error("cannot be further field because it will change the determined %s size", aad.toChars());
747 }
748
749 /* Templates cannot add fields to aggregates
750 */
751 TemplateInstance ti = parent.isTemplateInstance();
752 if (ti)
753 {
754 // Take care of nested templates
755 while (1)
756 {
757 TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
758 if (!ti2)
759 break;
760 ti = ti2;
761 }
762 // If it's a member template
763 AggregateDeclaration ad2 = ti.tempdecl.isMember();
764 if (ad2 && dsym.storage_class != STC.undefined_)
765 {
766 dsym.error("cannot use template to add field to aggregate `%s`", ad2.toChars());
767 }
768 }
769 }
770
771 if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)
772 {
773 dsym.error("only parameters or `foreach` declarations can be `ref`");
774 }
775
776 if (dsym.type.hasWild())
777 {
778 if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg())
779 {
780 dsym.error("only parameters or stack based variables can be `inout`");
781 }
782 FuncDeclaration func = sc.func;
783 if (func)
784 {
785 if (func.fes)
786 func = func.fes.func;
787 bool isWild = false;
788 for (FuncDeclaration fd = func; fd; fd = fd.toParentDecl().isFuncDeclaration())
789 {
790 if (fd.type.isTypeFunction().iswild)
791 {
792 isWild = true;
793 break;
794 }
795 }
796 if (!isWild)
797 {
798 dsym.error("`inout` variables can only be declared inside `inout` functions");
799 }
800 }
801 }
802
803 if (!(dsym.storage_class & (STC.ctfe | STC.extern_ | STC.ref_ | STC.result)) &&
804 tbn.ty == Tstruct && tbn.isTypeStruct().sym.noDefaultCtor)
805 {
806 if (!dsym._init)
807 {
808 if (dsym.isField())
809 {
810 /* For fields, we'll check the constructor later to make sure it is initialized
811 */
812 dsym.storage_class |= STC.nodefaultctor;
813 }
814 else if (dsym.storage_class & STC.parameter)
815 {
816 }
817 else
818 dsym.error("default construction is disabled for type `%s`", dsym.type.toChars());
819 }
820 }
821
822 FuncDeclaration fd = parent.isFuncDeclaration();
823 if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor))
824 {
825 if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.tls | STC.gshared) || !fd)
826 {
827 dsym.error("globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`");
828 }
829
830 // @@@DEPRECATED@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
831 // Deprecated in 2.087
832 // Remove this when the feature is removed from the language
833 if (0 && // deprecation disabled for now to accommodate existing extensive use
834 !(dsym.storage_class & STC.scope_))
835 {
836 if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym)
837 dsym.error("reference to `scope class` must be `scope`");
838 }
839 }
840
841 // Calculate type size + safety checks
842 if (sc.func && !sc.intypeof)
843 {
844 if (dsym._init && dsym._init.isVoidInitializer() &&
845 (dsym.type.hasPointers() || dsym.type.hasInvariant())) // also computes type size
846 {
847 if (sc.func.setUnsafe())
848 {
849 if (dsym.type.hasPointers())
850 dsym.error("`void` initializers for pointers not allowed in safe functions");
851 else
852 dsym.error("`void` initializers for structs with invariants are not allowed in safe functions");
853 }
854 }
855 else if (!dsym._init &&
856 !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&
857 dsym.type.hasVoidInitPointers())
858 {
859 if (sc.func.setUnsafe())
860 dsym.error("`void` initializers for pointers not allowed in safe functions");
861 }
862 }
863
864 if ((!dsym._init || dsym._init.isVoidInitializer) && !fd)
865 {
866 // If not mutable, initializable by constructor only
867 dsym.storage_class |= STC.ctorinit;
868 }
869
870 if (dsym._init)
871 dsym.storage_class |= STC.init; // remember we had an explicit initializer
872 else if (dsym.storage_class & STC.manifest)
873 dsym.error("manifest constants must have initializers");
874
875 bool isBlit = false;
876 d_uns64 sz;
877 if (!dsym._init &&
878 !(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&
879 fd &&
880 (!(dsym.storage_class & (STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result)) ||
881 (dsym.storage_class & STC.out_)) &&
882 (sz = dsym.type.size()) != 0)
883 {
884 // Provide a default initializer
885
886 //printf("Providing default initializer for '%s'\n", toChars());
887 if (sz == SIZE_INVALID && dsym.type.ty != Terror)
888 dsym.error("size of type `%s` is invalid", dsym.type.toChars());
889
890 Type tv = dsym.type;
891 while (tv.ty == Tsarray) // Don't skip Tenum
892 tv = tv.nextOf();
893 if (tv.needsNested())
894 {
895 /* Nested struct requires valid enclosing frame pointer.
896 * In StructLiteralExp::toElem(), it's calculated.
897 */
898 assert(tbn.ty == Tstruct);
899 checkFrameAccess(dsym.loc, sc, tbn.isTypeStruct().sym);
900
901 Expression e = tv.defaultInitLiteral(dsym.loc);
902 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
903 e = e.expressionSemantic(sc);
904 dsym._init = new ExpInitializer(dsym.loc, e);
905 goto Ldtor;
906 }
907 if (tv.ty == Tstruct && tv.isTypeStruct().sym.zeroInit)
908 {
909 /* If a struct is all zeros, as a special case
910 * set its initializer to the integer 0.
911 * In AssignExp::toElem(), we check for this and issue
912 * a memset() to initialize the struct.
913 * Must do same check in interpreter.
914 */
915 Expression e = IntegerExp.literal!0;
916 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
917 e.type = dsym.type; // don't type check this, it would fail
918 dsym._init = new ExpInitializer(dsym.loc, e);
919 goto Ldtor;
920 }
921 if (dsym.type.baseElemOf().ty == Tvoid)
922 {
923 dsym.error("`%s` does not have a default initializer", dsym.type.toChars());
924 }
925 else if (auto e = dsym.type.defaultInit(dsym.loc))
926 {
927 dsym._init = new ExpInitializer(dsym.loc, e);
928 }
929
930 // Default initializer is always a blit
931 isBlit = true;
932 }
933 if (dsym._init)
934 {
935 sc = sc.push();
936 sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);
937
938 ExpInitializer ei = dsym._init.isExpInitializer();
939
940 if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424
941 // Preset the required type to fail in FuncLiteralDeclaration::semantic3
942 ei.exp = inferType(ei.exp, dsym.type);
943
944 // If inside function, there is no semantic3() call
945 if (sc.func || sc.intypeof == 1)
946 {
947 // If local variable, use AssignExp to handle all the various
948 // possibilities.
949 if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.tls | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())
950 {
951 //printf("fd = '%s', var = '%s'\n", fd.toChars(), toChars());
952 if (!ei)
953 {
954 ArrayInitializer ai = dsym._init.isArrayInitializer();
955 Expression e;
956 if (ai && tb.ty == Taarray)
957 e = ai.toAssocArrayLiteral();
958 else
959 e = dsym._init.initializerToExpression();
960 if (!e)
961 {
962 // Run semantic, but don't need to interpret
963 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret);
964 e = dsym._init.initializerToExpression();
965 if (!e)
966 {
967 dsym.error("is not a static and cannot have static initializer");
968 e = ErrorExp.get();
969 }
970 }
971 ei = new ExpInitializer(dsym._init.loc, e);
972 dsym._init = ei;
973 }
974
975 Expression exp = ei.exp;
976 Expression e1 = new VarExp(dsym.loc, dsym);
977 if (isBlit)
978 exp = new BlitExp(dsym.loc, e1, exp);
979 else
980 exp = new ConstructExp(dsym.loc, e1, exp);
981 dsym.canassign++;
982 exp = exp.expressionSemantic(sc);
983 dsym.canassign--;
984 exp = exp.optimize(WANTvalue);
985 if (exp.op == TOK.error)
986 {
987 dsym._init = new ErrorInitializer();
988 ei = null;
989 }
990 else
991 ei.exp = exp;
992
993 if (ei && dsym.isScope())
994 {
995 Expression ex = ei.exp.lastComma();
996 if (ex.op == TOK.blit || ex.op == TOK.construct)
997 ex = (cast(AssignExp)ex).e2;
998 if (auto ne = ex.isNewExp())
999 {
1000 // See if initializer is a NewExp that can be allocated on the stack
1001 if (dsym.type.toBasetype().ty == Tclass)
1002 {
1003 if (ne.newargs && ne.newargs.dim > 1)
1004 {
1005 dsym.mynew = true;
1006 }
1007 else
1008 {
1009 ne.onstack = 1;
1010 dsym.onstack = true;
1011 }
1012 }
1013 }
1014 else if (auto fe = ex.isFuncExp())
1015 {
1016 // or a delegate that doesn't escape a reference to the function
1017 FuncDeclaration f = fe.fd;
1018 if (f.tookAddressOf)
1019 f.tookAddressOf--;
1020 }
1021 }
1022 }
1023 else
1024 {
1025 // https://issues.dlang.org/show_bug.cgi?id=14166
1026 // Don't run CTFE for the temporary variables inside typeof
1027 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);
1028 const init_err = dsym._init.isExpInitializer();
1029 if (init_err && init_err.exp.op == TOK.showCtfeContext)
1030 {
1031 errorSupplemental(dsym.loc, "compile time context created here");
1032 }
1033 }
1034 }
1035 else if (parent.isAggregateDeclaration())
1036 {
1037 dsym._scope = scx ? scx : sc.copy();
1038 dsym._scope.setNoFree();
1039 }
1040 else if (dsym.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) ||
1041 dsym.type.isConst() || dsym.type.isImmutable() ||
1042 sc.flags & SCOPE.Cfile)
1043 {
1044 /* Because we may need the results of a const declaration in a
1045 * subsequent type, such as an array dimension, before semantic2()
1046 * gets ordinarily run, try to run semantic2() now.
1047 * If a C array is of unknown size, the initializer can provide the size. Do this
1048 * eagerly because C does it eagerly.
1049 * Ignore failure.
1050 */
1051 if (!inferred)
1052 {
1053 uint errors = global.errors;
1054 dsym.inuse++;
1055 // Bug 20549. Don't try this on modules or packages, syntaxCopy
1056 // could crash (inf. recursion) on a mod/pkg referencing itself
1057 if (ei && (ei.exp.op != TOK.scope_ ? true : !ei.exp.isScopeExp().sds.isPackage()))
1058 {
1059 Expression exp = ei.exp.syntaxCopy();
1060
1061 bool needctfe = dsym.isDataseg() || (dsym.storage_class & STC.manifest);
1062 if (needctfe)
1063 sc = sc.startCTFE();
1064 exp = exp.expressionSemantic(sc);
1065 exp = resolveProperties(sc, exp);
1066 if (needctfe)
1067 sc = sc.endCTFE();
1068
1069 Type tb2 = dsym.type.toBasetype();
1070 Type ti = exp.type.toBasetype();
1071
1072 /* The problem is the following code:
1073 * struct CopyTest {
1074 * double x;
1075 * this(double a) { x = a * 10.0;}
1076 * this(this) { x += 2.0; }
1077 * }
1078 * const CopyTest z = CopyTest(5.3); // ok
1079 * const CopyTest w = z; // not ok, postblit not run
1080 * static assert(w.x == 55.0);
1081 * because the postblit doesn't get run on the initialization of w.
1082 */
1083 if (auto ts = ti.isTypeStruct())
1084 {
1085 StructDeclaration sd = ts.sym;
1086 /* Look to see if initializer involves a copy constructor
1087 * (which implies a postblit)
1088 */
1089 // there is a copy constructor
1090 // and exp is the same struct
1091 if (sd.postblit && tb2.toDsymbol(null) == sd)
1092 {
1093 // The only allowable initializer is a (non-copy) constructor
1094 if (exp.isLvalue())
1095 dsym.error("of type struct `%s` uses `this(this)`, which is not allowed in static initialization", tb2.toChars());
1096 }
1097 }
1098 ei.exp = exp;
1099 }
1100
1101 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
1102 dsym.inuse--;
1103 if (global.errors > errors)
1104 {
1105 dsym._init = new ErrorInitializer();
1106 dsym.type = Type.terror;
1107 }
1108 }
1109 else
1110 {
1111 dsym._scope = scx ? scx : sc.copy();
1112 dsym._scope.setNoFree();
1113 }
1114 }
1115 sc = sc.pop();
1116 }
1117
1118 Ldtor:
1119 /* Build code to execute destruction, if necessary
1120 */
1121 dsym.edtor = dsym.callScopeDtor(sc);
1122 if (dsym.edtor)
1123 {
1124 /* If dsym is a local variable, who's type is a struct with a scope destructor,
1125 * then make dsym scope, too.
1126 */
1127 if (global.params.useDIP1000 == FeatureState.enabled &&
1128 !(dsym.storage_class & (STC.parameter | STC.temp | STC.field | STC.in_ | STC.foreach_ | STC.result | STC.manifest)) &&
1129 !dsym.isDataseg() &&
1130 !dsym.doNotInferScope &&
1131 dsym.type.hasPointers())
1132 {
1133 auto tv = dsym.type.baseElemOf();
1134 if (tv.ty == Tstruct &&
1135 tv.isTypeStruct().sym.dtor.storage_class & STC.scope_)
1136 {
1137 dsym.storage_class |= STC.scope_;
1138 }
1139 }
1140
1141 if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared))
1142 dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope);
1143 else
1144 dsym.edtor = dsym.edtor.expressionSemantic(sc);
1145
1146 version (none)
1147 {
1148 // currently disabled because of std.stdio.stdin, stdout and stderr
1149 if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_))
1150 dsym.error("static storage variables cannot have destructors");
1151 }
1152 }
1153
1154 dsym.semanticRun = PASS.semanticdone;
1155
1156 if (dsym.type.toBasetype().ty == Terror)
1157 dsym.errors = true;
1158
1159 if(sc.scopesym && !sc.scopesym.isAggregateDeclaration())
1160 {
1161 for (ScopeDsymbol sym = sc.scopesym; sym && dsym.endlinnum == 0;
1162 sym = sym.parent ? sym.parent.isScopeDsymbol() : null)
1163 dsym.endlinnum = sym.endlinnum;
1164 }
1165 }
1166
visit(TypeInfoDeclaration dsym)1167 override void visit(TypeInfoDeclaration dsym)
1168 {
1169 assert(dsym.linkage == LINK.c);
1170 }
1171
visit(BitFieldDeclaration dsym)1172 override void visit(BitFieldDeclaration dsym)
1173 {
1174 //printf("BitField::semantic('%s') %s\n", toPrettyChars(), id.toChars());
1175 if (dsym.semanticRun >= PASS.semanticdone)
1176 return;
1177
1178 visit(cast(VarDeclaration)dsym);
1179 if (dsym.errors)
1180 return;
1181
1182 sc = sc.startCTFE();
1183 auto width = dsym.width.expressionSemantic(sc);
1184 sc = sc.endCTFE();
1185 width = width.ctfeInterpret();
1186 if (!dsym.type.isintegral())
1187 {
1188 // C11 6.7.2.1-5
1189 width.error("bit-field type `%s` is not an integer type", dsym.type.toChars());
1190 dsym.errors = true;
1191 }
1192 if (!width.isIntegerExp())
1193 {
1194 width.error("bit-field width `%s` is not an integer constant", dsym.width.toChars());
1195 dsym.errors = true;
1196 }
1197 const uwidth = width.toInteger(); // uwidth is unsigned
1198 if (uwidth == 0 && !dsym.isAnonymous())
1199 {
1200 width.error("bit-field `%s` has zero width", dsym.toChars());
1201 dsym.errors = true;
1202 }
1203 const max_width = dsym.type.size() * 8;
1204 if (uwidth > max_width)
1205 {
1206 width.error("width `%lld` of bit-field `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());
1207 dsym.errors = true;
1208 }
1209 dsym.fieldWidth = cast(uint)uwidth;
1210 }
1211
visit(Import imp)1212 override void visit(Import imp)
1213 {
1214 //printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
1215 if (imp.semanticRun > PASS.init)
1216 return;
1217
1218 if (imp._scope)
1219 {
1220 sc = imp._scope;
1221 imp._scope = null;
1222 }
1223 if (!sc)
1224 return;
1225
1226 imp.parent = sc.parent;
1227
1228 imp.semanticRun = PASS.semantic;
1229
1230 // Load if not already done so
1231 bool loadErrored = false;
1232 if (!imp.mod)
1233 {
1234 loadErrored = imp.load(sc);
1235 if (imp.mod)
1236 {
1237 imp.mod.importAll(null);
1238 imp.mod.checkImportDeprecation(imp.loc, sc);
1239 }
1240 }
1241 if (imp.mod)
1242 {
1243 // Modules need a list of each imported module
1244
1245 // if inside a template instantiation, the instantianting
1246 // module gets the import.
1247 // https://issues.dlang.org/show_bug.cgi?id=17181
1248 Module importer = sc._module;
1249 if (sc.minst && sc.tinst)
1250 {
1251 importer = sc.minst;
1252 if (!sc.tinst.importedModules.contains(imp.mod))
1253 sc.tinst.importedModules.push(imp.mod);
1254 }
1255 //printf("%s imports %s\n", importer.toChars(), imp.mod.toChars());
1256 if (!importer.aimports.contains(imp.mod))
1257 importer.aimports.push(imp.mod);
1258
1259 if (sc.explicitVisibility)
1260 imp.visibility = sc.visibility;
1261
1262 if (!imp.aliasId && !imp.names.dim) // neither a selective nor a renamed import
1263 {
1264 ScopeDsymbol scopesym = sc.getScopesym();
1265
1266 if (!imp.isstatic)
1267 {
1268 scopesym.importScope(imp.mod, imp.visibility);
1269 }
1270
1271
1272 imp.addPackageAccess(scopesym);
1273 }
1274
1275 if (!loadErrored)
1276 {
1277 imp.mod.dsymbolSemantic(null);
1278 }
1279
1280 if (imp.mod.needmoduleinfo)
1281 {
1282 //printf("module4 %s because of %s\n", importer.toChars(), imp.mod.toChars());
1283 importer.needmoduleinfo = 1;
1284 }
1285
1286 sc = sc.push(imp.mod);
1287 sc.visibility = imp.visibility;
1288 for (size_t i = 0; i < imp.aliasdecls.dim; i++)
1289 {
1290 AliasDeclaration ad = imp.aliasdecls[i];
1291 //printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
1292 Dsymbol sym = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);
1293 if (sym)
1294 {
1295 import dmd.access : symbolIsVisible;
1296 if (!symbolIsVisible(sc, sym))
1297 imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`",
1298 imp.names[i].toChars(), sc._module.toChars());
1299 ad.dsymbolSemantic(sc);
1300 // If the import declaration is in non-root module,
1301 // analysis of the aliased symbol is deferred.
1302 // Therefore, don't see the ad.aliassym or ad.type here.
1303 }
1304 else
1305 {
1306 Dsymbol s = imp.mod.search_correct(imp.names[i]);
1307 if (s)
1308 imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
1309 else
1310 imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
1311 ad.type = Type.terror;
1312 }
1313 }
1314 sc = sc.pop();
1315 }
1316
1317 imp.semanticRun = PASS.semanticdone;
1318
1319 // object self-imports itself, so skip that
1320 // https://issues.dlang.org/show_bug.cgi?id=7547
1321 // don't list pseudo modules __entrypoint.d, __main.d
1322 // https://issues.dlang.org/show_bug.cgi?id=11117
1323 // https://issues.dlang.org/show_bug.cgi?id=11164
1324 if (global.params.moduleDeps !is null && !(imp.id == Id.object && sc._module.ident == Id.object) &&
1325 strcmp(sc._module.ident.toChars(), "__main") != 0)
1326 {
1327 /* The grammar of the file is:
1328 * ImportDeclaration
1329 * ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
1330 * ModuleAliasIdentifier ] "\n"
1331 *
1332 * BasicImportDeclaration
1333 * ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
1334 * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
1335 *
1336 * FilePath
1337 * - any string with '(', ')' and '\' escaped with the '\' character
1338 */
1339 OutBuffer* ob = global.params.moduleDeps;
1340 Module imod = sc._module;
1341 if (!global.params.moduleDepsFile)
1342 ob.writestring("depsImport ");
1343 ob.writestring(imod.toPrettyChars());
1344 ob.writestring(" (");
1345 escapePath(ob, imod.srcfile.toChars());
1346 ob.writestring(") : ");
1347 // use visibility instead of sc.visibility because it couldn't be
1348 // resolved yet, see the comment above
1349 visibilityToBuffer(ob, imp.visibility);
1350 ob.writeByte(' ');
1351 if (imp.isstatic)
1352 {
1353 stcToBuffer(ob, STC.static_);
1354 ob.writeByte(' ');
1355 }
1356 ob.writestring(": ");
1357 foreach (pid; imp.packages)
1358 {
1359 ob.printf("%s.", pid.toChars());
1360 }
1361 ob.writestring(imp.id.toString());
1362 ob.writestring(" (");
1363 if (imp.mod)
1364 escapePath(ob, imp.mod.srcfile.toChars());
1365 else
1366 ob.writestring("???");
1367 ob.writeByte(')');
1368 foreach (i, name; imp.names)
1369 {
1370 if (i == 0)
1371 ob.writeByte(':');
1372 else
1373 ob.writeByte(',');
1374 Identifier _alias = imp.aliases[i];
1375 if (!_alias)
1376 {
1377 ob.printf("%s", name.toChars());
1378 _alias = name;
1379 }
1380 else
1381 ob.printf("%s=%s", _alias.toChars(), name.toChars());
1382 }
1383 if (imp.aliasId)
1384 ob.printf(" -> %s", imp.aliasId.toChars());
1385 ob.writenl();
1386 }
1387 //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
1388 }
1389
attribSemantic(AttribDeclaration ad)1390 void attribSemantic(AttribDeclaration ad)
1391 {
1392 if (ad.semanticRun != PASS.init)
1393 return;
1394 ad.semanticRun = PASS.semantic;
1395 Dsymbols* d = ad.include(sc);
1396 //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
1397 if (d)
1398 {
1399 Scope* sc2 = ad.newScope(sc);
1400 bool errors;
1401 for (size_t i = 0; i < d.dim; i++)
1402 {
1403 Dsymbol s = (*d)[i];
1404 s.dsymbolSemantic(sc2);
1405 errors |= s.errors;
1406 }
1407 ad.errors |= errors;
1408 if (sc2 != sc)
1409 sc2.pop();
1410 }
1411 ad.semanticRun = PASS.semanticdone;
1412 }
1413
visit(AttribDeclaration atd)1414 override void visit(AttribDeclaration atd)
1415 {
1416 attribSemantic(atd);
1417 }
1418
visit(AnonDeclaration scd)1419 override void visit(AnonDeclaration scd)
1420 {
1421 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
1422 assert(sc.parent);
1423 auto p = sc.parent.pastMixin();
1424 auto ad = p.isAggregateDeclaration();
1425 if (!ad)
1426 {
1427 error(scd.loc, "%s can only be a part of an aggregate, not %s `%s`", scd.kind(), p.kind(), p.toChars());
1428 scd.errors = true;
1429 return;
1430 }
1431
1432 if (scd.decl)
1433 {
1434 sc = sc.push();
1435 sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.tls | STC.gshared);
1436 sc.inunion = scd.isunion ? scd : null;
1437 sc.flags = 0;
1438 for (size_t i = 0; i < scd.decl.dim; i++)
1439 {
1440 Dsymbol s = (*scd.decl)[i];
1441 s.dsymbolSemantic(sc);
1442 }
1443 sc = sc.pop();
1444 }
1445 }
1446
visit(PragmaDeclaration pd)1447 override void visit(PragmaDeclaration pd)
1448 {
1449 StringExp verifyMangleString(ref Expression e)
1450 {
1451 auto se = semanticString(sc, e, "mangled name");
1452 if (!se)
1453 return null;
1454 e = se;
1455 if (!se.len)
1456 {
1457 pd.error("zero-length string not allowed for mangled name");
1458 return null;
1459 }
1460 if (se.sz != 1)
1461 {
1462 pd.error("mangled name characters can only be of type `char`");
1463 return null;
1464 }
1465 version (all)
1466 {
1467 /* Note: D language specification should not have any assumption about backend
1468 * implementation. Ideally pragma(mangle) can accept a string of any content.
1469 *
1470 * Therefore, this validation is compiler implementation specific.
1471 */
1472 auto slice = se.peekString();
1473 for (size_t i = 0; i < se.len;)
1474 {
1475 dchar c = slice[i];
1476 if (c < 0x80)
1477 {
1478 if (c.isValidMangling)
1479 {
1480 ++i;
1481 continue;
1482 }
1483 else
1484 {
1485 pd.error("char 0x%02x not allowed in mangled name", c);
1486 break;
1487 }
1488 }
1489 if (const msg = utf_decodeChar(slice, i, c))
1490 {
1491 pd.error("%.*s", cast(int)msg.length, msg.ptr);
1492 break;
1493 }
1494 if (!isUniAlpha(c))
1495 {
1496 pd.error("char `0x%04x` not allowed in mangled name", c);
1497 break;
1498 }
1499 }
1500 }
1501 return se;
1502 }
1503 void declarations()
1504 {
1505 if (!pd.decl)
1506 return;
1507
1508 Scope* sc2 = pd.newScope(sc);
1509 scope(exit)
1510 if (sc2 != sc)
1511 sc2.pop();
1512
1513 foreach (s; (*pd.decl)[])
1514 {
1515 s.dsymbolSemantic(sc2);
1516 if (pd.ident != Id.mangle)
1517 continue;
1518 assert(pd.args);
1519 if (auto ad = s.isAggregateDeclaration())
1520 {
1521 Expression e = (*pd.args)[0];
1522 sc2 = sc2.startCTFE();
1523 e = e.expressionSemantic(sc);
1524 e = resolveProperties(sc2, e);
1525 sc2 = sc2.endCTFE();
1526 AggregateDeclaration agg;
1527 if (auto tc = e.type.isTypeClass())
1528 agg = tc.sym;
1529 else if (auto ts = e.type.isTypeStruct())
1530 agg = ts.sym;
1531 ad.mangleOverride = new MangleOverride;
1532 void setString(ref Expression e)
1533 {
1534 if (auto se = verifyMangleString(e))
1535 {
1536 const name = (cast(const(char)[])se.peekData()).xarraydup;
1537 ad.mangleOverride.id = Identifier.idPool(name);
1538 e = se;
1539 }
1540 else
1541 e.error("must be a string");
1542 }
1543 if (agg)
1544 {
1545 ad.mangleOverride.agg = agg;
1546 if (pd.args.dim == 2)
1547 {
1548 setString((*pd.args)[1]);
1549 }
1550 else
1551 ad.mangleOverride.id = agg.ident;
1552 }
1553 else
1554 setString((*pd.args)[0]);
1555 }
1556 else if (auto td = s.isTemplateDeclaration())
1557 {
1558 pd.error("cannot apply to a template declaration");
1559 errorSupplemental(pd.loc, "use `template Class(Args...){ pragma(mangle, \"other_name\") class Class {} }`");
1560 }
1561 else if (auto se = verifyMangleString((*pd.args)[0]))
1562 {
1563 const name = (cast(const(char)[])se.peekData()).xarraydup;
1564 uint cnt = setMangleOverride(s, name);
1565 if (cnt > 1)
1566 pd.error("can only apply to a single declaration");
1567 }
1568 }
1569 }
1570
1571 void noDeclarations()
1572 {
1573 if (pd.decl)
1574 {
1575 pd.error("is missing a terminating `;`");
1576 declarations();
1577 // do them anyway, to avoid segfaults.
1578 }
1579 }
1580
1581 // Should be merged with PragmaStatement
1582 //printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
1583 if (target.mscoff)
1584 {
1585 if (pd.ident == Id.linkerDirective)
1586 {
1587 if (!pd.args || pd.args.dim != 1)
1588 pd.error("one string argument expected for pragma(linkerDirective)");
1589 else
1590 {
1591 auto se = semanticString(sc, (*pd.args)[0], "linker directive");
1592 if (!se)
1593 return noDeclarations();
1594 (*pd.args)[0] = se;
1595 if (global.params.verbose)
1596 message("linkopt %.*s", cast(int)se.len, se.peekString().ptr);
1597 }
1598 return noDeclarations();
1599 }
1600 }
1601 if (pd.ident == Id.msg)
1602 {
1603 if (pd.args)
1604 {
1605 for (size_t i = 0; i < pd.args.dim; i++)
1606 {
1607 Expression e = (*pd.args)[i];
1608 sc = sc.startCTFE();
1609 e = e.expressionSemantic(sc);
1610 e = resolveProperties(sc, e);
1611 sc = sc.endCTFE();
1612 e = ctfeInterpretForPragmaMsg(e);
1613 if (e.op == TOK.error)
1614 {
1615 errorSupplemental(pd.loc, "while evaluating `pragma(msg, %s)`", (*pd.args)[i].toChars());
1616 return;
1617 }
1618 StringExp se = e.toStringExp();
1619 if (se)
1620 {
1621 se = se.toUTF8(sc);
1622 fprintf(stderr, "%.*s", cast(int)se.len, se.peekString().ptr);
1623 }
1624 else
1625 fprintf(stderr, "%s", e.toChars());
1626 }
1627 fprintf(stderr, "\n");
1628 }
1629 return noDeclarations();
1630 }
1631 else if (pd.ident == Id.lib)
1632 {
1633 if (!pd.args || pd.args.dim != 1)
1634 pd.error("string expected for library name");
1635 else
1636 {
1637 auto se = semanticString(sc, (*pd.args)[0], "library name");
1638 if (!se)
1639 return noDeclarations();
1640 (*pd.args)[0] = se;
1641
1642 auto name = se.peekString().xarraydup;
1643 if (global.params.verbose)
1644 message("library %s", name.ptr);
1645 if (global.params.moduleDeps && !global.params.moduleDepsFile)
1646 {
1647 OutBuffer* ob = global.params.moduleDeps;
1648 Module imod = sc._module;
1649 ob.writestring("depsLib ");
1650 ob.writestring(imod.toPrettyChars());
1651 ob.writestring(" (");
1652 escapePath(ob, imod.srcfile.toChars());
1653 ob.writestring(") : ");
1654 ob.writestring(name);
1655 ob.writenl();
1656 }
1657 mem.xfree(name.ptr);
1658 }
1659 return noDeclarations();
1660 }
1661 else if (pd.ident == Id.startaddress)
1662 {
1663 if (!pd.args || pd.args.dim != 1)
1664 pd.error("function name expected for start address");
1665 else
1666 {
1667 /* https://issues.dlang.org/show_bug.cgi?id=11980
1668 * resolveProperties and ctfeInterpret call are not necessary.
1669 */
1670 Expression e = (*pd.args)[0];
1671 sc = sc.startCTFE();
1672 e = e.expressionSemantic(sc);
1673 sc = sc.endCTFE();
1674 (*pd.args)[0] = e;
1675 Dsymbol sa = getDsymbol(e);
1676 if (!sa || !sa.isFuncDeclaration())
1677 pd.error("function name expected for start address, not `%s`", e.toChars());
1678 }
1679 return noDeclarations();
1680 }
1681 else if (pd.ident == Id.Pinline)
1682 {
1683 if (pd.args && pd.args.dim > 1)
1684 {
1685 pd.error("one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) pd.args.dim);
1686 pd.args.setDim(1);
1687 (*pd.args)[0] = ErrorExp.get();
1688 }
1689
1690 // this pragma now gets evaluated on demand in function semantic
1691
1692 return declarations();
1693 }
1694 else if (pd.ident == Id.mangle)
1695 {
1696 if (!pd.args)
1697 pd.args = new Expressions();
1698 if (pd.args.dim == 0 || pd.args.dim > 2)
1699 {
1700 pd.error(pd.args.dim == 0 ? "string expected for mangled name"
1701 : "expected 1 or 2 arguments");
1702 pd.args.setDim(1);
1703 (*pd.args)[0] = ErrorExp.get(); // error recovery
1704 }
1705 return declarations();
1706 }
1707 else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
1708 {
1709 if (pd.args && pd.args.dim != 0)
1710 pd.error("takes no argument");
1711 return declarations();
1712 }
1713 else if (pd.ident == Id.printf || pd.ident == Id.scanf)
1714 {
1715 if (pd.args && pd.args.dim != 0)
1716 pd.error("takes no argument");
1717 return declarations();
1718 }
1719 else if (!global.params.ignoreUnsupportedPragmas)
1720 {
1721 error(pd.loc, "unrecognized `pragma(%s)`", pd.ident.toChars());
1722 return declarations();
1723 }
1724
1725 if (!global.params.verbose)
1726 return declarations();
1727
1728 /* Print unrecognized pragmas
1729 */
1730 OutBuffer buf;
1731 buf.writestring(pd.ident.toString());
1732 if (pd.args)
1733 {
1734 const errors_save = global.startGagging();
1735 for (size_t i = 0; i < pd.args.dim; i++)
1736 {
1737 Expression e = (*pd.args)[i];
1738 sc = sc.startCTFE();
1739 e = e.expressionSemantic(sc);
1740 e = resolveProperties(sc, e);
1741 sc = sc.endCTFE();
1742 e = e.ctfeInterpret();
1743 if (i == 0)
1744 buf.writestring(" (");
1745 else
1746 buf.writeByte(',');
1747 buf.writestring(e.toChars());
1748 }
1749 if (pd.args.dim)
1750 buf.writeByte(')');
1751 global.endGagging(errors_save);
1752 }
1753 message("pragma %s", buf.peekChars());
1754 return declarations();
1755 }
1756
visit(StaticIfDeclaration sid)1757 override void visit(StaticIfDeclaration sid)
1758 {
1759 attribSemantic(sid);
1760 }
1761
visit(StaticForeachDeclaration sfd)1762 override void visit(StaticForeachDeclaration sfd)
1763 {
1764 attribSemantic(sfd);
1765 }
1766
compileIt(CompileDeclaration cd)1767 private Dsymbols* compileIt(CompileDeclaration cd)
1768 {
1769 //printf("CompileDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars());
1770 OutBuffer buf;
1771 if (expressionsToString(buf, sc, cd.exps))
1772 return null;
1773
1774 const errors = global.errors;
1775 const len = buf.length;
1776 buf.writeByte(0);
1777 const str = buf.extractSlice()[0 .. len];
1778 scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false);
1779 p.nextToken();
1780
1781 auto d = p.parseDeclDefs(0);
1782 if (global.errors != errors)
1783 return null;
1784
1785 if (p.token.value != TOK.endOfFile)
1786 {
1787 cd.error("incomplete mixin declaration `%s`", str.ptr);
1788 return null;
1789 }
1790 return d;
1791 }
1792
1793 /***********************************************************
1794 * https://dlang.org/spec/module.html#mixin-declaration
1795 */
visit(CompileDeclaration cd)1796 override void visit(CompileDeclaration cd)
1797 {
1798 //printf("CompileDeclaration::semantic()\n");
1799 if (!cd.compiled)
1800 {
1801 cd.decl = compileIt(cd);
1802 cd.AttribDeclaration.addMember(sc, cd.scopesym);
1803 cd.compiled = true;
1804
1805 if (cd._scope && cd.decl)
1806 {
1807 for (size_t i = 0; i < cd.decl.dim; i++)
1808 {
1809 Dsymbol s = (*cd.decl)[i];
1810 s.setScope(cd._scope);
1811 }
1812 }
1813 }
1814 attribSemantic(cd);
1815 }
1816
visit(CPPNamespaceDeclaration ns)1817 override void visit(CPPNamespaceDeclaration ns)
1818 {
1819 Identifier identFromSE (StringExp se)
1820 {
1821 const sident = se.toStringz();
1822 if (!sident.length || !Identifier.isValidIdentifier(sident))
1823 {
1824 ns.exp.error("expected valid identifier for C++ namespace but got `%.*s`",
1825 cast(int)sident.length, sident.ptr);
1826 return null;
1827 }
1828 else
1829 return Identifier.idPool(sident);
1830 }
1831
1832 if (ns.ident is null)
1833 {
1834 ns.cppnamespace = sc.namespace;
1835 sc = sc.startCTFE();
1836 ns.exp = ns.exp.expressionSemantic(sc);
1837 ns.exp = resolveProperties(sc, ns.exp);
1838 sc = sc.endCTFE();
1839 ns.exp = ns.exp.ctfeInterpret();
1840 // Can be either a tuple of strings or a string itself
1841 if (auto te = ns.exp.isTupleExp())
1842 {
1843 expandTuples(te.exps);
1844 CPPNamespaceDeclaration current = ns.cppnamespace;
1845 for (size_t d = 0; d < te.exps.dim; ++d)
1846 {
1847 auto exp = (*te.exps)[d];
1848 auto prev = d ? current : ns.cppnamespace;
1849 current = (d + 1) != te.exps.dim
1850 ? new CPPNamespaceDeclaration(ns.loc, exp, null)
1851 : ns;
1852 current.exp = exp;
1853 current.cppnamespace = prev;
1854 if (auto se = exp.toStringExp())
1855 {
1856 current.ident = identFromSE(se);
1857 if (current.ident is null)
1858 return; // An error happened in `identFromSE`
1859 }
1860 else
1861 ns.exp.error("`%s`: index %llu is not a string constant, it is a `%s`",
1862 ns.exp.toChars(), cast(ulong) d, ns.exp.type.toChars());
1863 }
1864 }
1865 else if (auto se = ns.exp.toStringExp())
1866 ns.ident = identFromSE(se);
1867 // Empty Tuple
1868 else if (ns.exp.isTypeExp() && ns.exp.isTypeExp().type.toBasetype().isTypeTuple())
1869 {
1870 }
1871 else
1872 ns.exp.error("compile time string constant (or tuple) expected, not `%s`",
1873 ns.exp.toChars());
1874 }
1875 attribSemantic(ns);
1876 }
1877
visit(UserAttributeDeclaration uad)1878 override void visit(UserAttributeDeclaration uad)
1879 {
1880 //printf("UserAttributeDeclaration::semantic() %p\n", this);
1881 if (uad.decl && !uad._scope)
1882 uad.Dsymbol.setScope(sc); // for function local symbols
1883 arrayExpressionSemantic(uad.atts, sc, true);
1884 return attribSemantic(uad);
1885 }
1886
visit(StaticAssert sa)1887 override void visit(StaticAssert sa)
1888 {
1889 if (sa.semanticRun < PASS.semanticdone)
1890 sa.semanticRun = PASS.semanticdone;
1891 }
1892
visit(DebugSymbol ds)1893 override void visit(DebugSymbol ds)
1894 {
1895 //printf("DebugSymbol::semantic() %s\n", toChars());
1896 if (ds.semanticRun < PASS.semanticdone)
1897 ds.semanticRun = PASS.semanticdone;
1898 }
1899
visit(VersionSymbol vs)1900 override void visit(VersionSymbol vs)
1901 {
1902 if (vs.semanticRun < PASS.semanticdone)
1903 vs.semanticRun = PASS.semanticdone;
1904 }
1905
visit(Package pkg)1906 override void visit(Package pkg)
1907 {
1908 if (pkg.semanticRun < PASS.semanticdone)
1909 pkg.semanticRun = PASS.semanticdone;
1910 }
1911
visit(Module m)1912 override void visit(Module m)
1913 {
1914 if (m.semanticRun != PASS.init)
1915 return;
1916 //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
1917 m.semanticRun = PASS.semantic;
1918 // Note that modules get their own scope, from scratch.
1919 // This is so regardless of where in the syntax a module
1920 // gets imported, it is unaffected by context.
1921 Scope* sc = m._scope; // see if already got one from importAll()
1922 if (!sc)
1923 {
1924 sc = Scope.createGlobal(m); // create root scope
1925 }
1926
1927 //printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
1928 // Pass 1 semantic routines: do public side of the definition
1929 m.members.foreachDsymbol( (s)
1930 {
1931 //printf("\tModule('%s'): '%s'.dsymbolSemantic()\n", toChars(), s.toChars());
1932 s.dsymbolSemantic(sc);
1933 m.runDeferredSemantic();
1934 });
1935
1936 if (m.userAttribDecl)
1937 {
1938 m.userAttribDecl.dsymbolSemantic(sc);
1939 }
1940 if (!m._scope)
1941 {
1942 sc = sc.pop();
1943 sc.pop(); // 2 pops because Scope.createGlobal() created 2
1944 }
1945 m.semanticRun = PASS.semanticdone;
1946 //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
1947 }
1948
visit(EnumDeclaration ed)1949 override void visit(EnumDeclaration ed)
1950 {
1951 //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), ed.toChars());
1952 //printf("EnumDeclaration::semantic() %p %s\n", this, ed.toChars());
1953 if (ed.semanticRun >= PASS.semanticdone)
1954 return; // semantic() already completed
1955 if (ed.semanticRun == PASS.semantic)
1956 {
1957 assert(ed.memtype);
1958 error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
1959 ed.errors = true;
1960 ed.semanticRun = PASS.semanticdone;
1961 return;
1962 }
1963 uint dprogress_save = Module.dprogress;
1964
1965 Scope* scx = null;
1966 if (ed._scope)
1967 {
1968 sc = ed._scope;
1969 scx = ed._scope; // save so we don't make redundant copies
1970 ed._scope = null;
1971 }
1972
1973 if (!sc)
1974 return;
1975
1976 ed.parent = sc.parent;
1977 ed.type = ed.type.typeSemantic(ed.loc, sc);
1978
1979 ed.visibility = sc.visibility;
1980 if (sc.stc & STC.deprecated_)
1981 ed.isdeprecated = true;
1982 ed.userAttribDecl = sc.userAttribDecl;
1983 ed.cppnamespace = sc.namespace;
1984
1985 ed.semanticRun = PASS.semantic;
1986 UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
1987
1988 if (!ed.members && !ed.memtype) // enum ident;
1989 {
1990 ed.semanticRun = PASS.semanticdone;
1991 return;
1992 }
1993
1994 if (!ed.symtab)
1995 ed.symtab = new DsymbolTable();
1996
1997 /* The separate, and distinct, cases are:
1998 * 1. enum { ... }
1999 * 2. enum : memtype { ... }
2000 * 3. enum ident { ... }
2001 * 4. enum ident : memtype { ... }
2002 * 5. enum ident : memtype;
2003 * 6. enum ident;
2004 */
2005
2006 if (ed.memtype)
2007 {
2008 ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
2009
2010 /* Check to see if memtype is forward referenced
2011 */
2012 if (auto te = ed.memtype.isTypeEnum())
2013 {
2014 auto sym = te.toDsymbol(sc).isEnumDeclaration();
2015 // Special enums like __c_[u]long[long] are fine to forward reference
2016 // see https://issues.dlang.org/show_bug.cgi?id=20599
2017 if (!sym.isSpecial() && (!sym.memtype || !sym.members || !sym.symtab || sym._scope))
2018 {
2019 // memtype is forward referenced, so try again later
2020 deferDsymbolSemantic(ed, scx);
2021 Module.dprogress = dprogress_save;
2022 //printf("\tdeferring %s\n", toChars());
2023 ed.semanticRun = PASS.init;
2024 return;
2025 }
2026 else
2027 // Ensure that semantic is run to detect. e.g. invalid forward references
2028 sym.dsymbolSemantic(sc);
2029 }
2030 if (ed.memtype.ty == Tvoid)
2031 {
2032 ed.error("base type must not be `void`");
2033 ed.memtype = Type.terror;
2034 }
2035 if (ed.memtype.ty == Terror)
2036 {
2037 ed.errors = true;
2038 // poison all the members
2039 ed.members.foreachDsymbol( (s) { s.errors = true; } );
2040 ed.semanticRun = PASS.semanticdone;
2041 return;
2042 }
2043 }
2044
2045 if (!ed.members) // enum ident : memtype;
2046 {
2047 ed.semanticRun = PASS.semanticdone;
2048 return;
2049 }
2050
2051 if (ed.members.dim == 0)
2052 {
2053 ed.error("enum `%s` must have at least one member", ed.toChars());
2054 ed.errors = true;
2055 ed.semanticRun = PASS.semanticdone;
2056 return;
2057 }
2058
2059 if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done
2060 ed.semanticRun = PASS.semanticdone;
2061
2062 Module.dprogress++;
2063
2064 Scope* sce;
2065 if (ed.isAnonymous())
2066 sce = sc;
2067 else
2068 {
2069 sce = sc.push(ed);
2070 sce.parent = ed;
2071 }
2072 sce = sce.startCTFE();
2073 sce.setNoFree(); // needed for getMaxMinValue()
2074
2075 /* Each enum member gets the sce scope
2076 */
2077 ed.members.foreachDsymbol( (s)
2078 {
2079 EnumMember em = s.isEnumMember();
2080 if (em)
2081 em._scope = sce;
2082 });
2083
2084 /* addMember() is not called when the EnumDeclaration appears as a function statement,
2085 * so we have to do what addMember() does and install the enum members in the right symbol
2086 * table
2087 */
2088 addEnumMembers(ed, sc, sc.getScopesym());
2089
2090 if (sc.flags & SCOPE.Cfile)
2091 {
2092 /* C11 6.7.2.2
2093 */
2094 ed.memtype = Type.tint32; // C11 6.7.2.2-4 implementation defined
2095 int nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0
2096
2097 void emSemantic(EnumMember em, ref int nextValue)
2098 {
2099 static void errorReturn(EnumMember em)
2100 {
2101 em.errors = true;
2102 em.semanticRun = PASS.semanticdone;
2103 }
2104
2105 em.semanticRun = PASS.semantic;
2106 em.type = Type.tint32;
2107 em.linkage = LINK.c;
2108 em.storage_class |= STC.manifest;
2109 if (em.value)
2110 {
2111 Expression e = em.value;
2112 assert(e.dyncast() == DYNCAST.expression);
2113 e = e.expressionSemantic(sc);
2114 e = resolveProperties(sc, e);
2115 e = e.integralPromotions(sc);
2116 e = e.ctfeInterpret();
2117 if (e.op == TOK.error)
2118 return errorReturn(em);
2119 auto ie = e.isIntegerExp();
2120 if (!ie)
2121 {
2122 // C11 6.7.2.2-2
2123 em.error("enum member must be an integral constant expression, not `%s` of type `%s`", e.toChars(), e.type.toChars());
2124 return errorReturn(em);
2125 }
2126 const sinteger_t v = ie.toInteger();
2127 if (v < int.min || v > uint.max)
2128 {
2129 // C11 6.7.2.2-2
2130 em.error("enum member value `%s` does not fit in an `int`", e.toChars());
2131 return errorReturn(em);
2132 }
2133 em.value = new IntegerExp(em.loc, cast(int)v, Type.tint32);
2134 nextValue = cast(int)v;
2135 }
2136 else
2137 {
2138 em.value = new IntegerExp(em.loc, nextValue, Type.tint32);
2139 }
2140 ++nextValue; // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
2141 em.semanticRun = PASS.semanticdone;
2142 }
2143
2144 ed.members.foreachDsymbol( (s)
2145 {
2146 if (EnumMember em = s.isEnumMember())
2147 emSemantic(em, nextValue);
2148 });
2149 ed.semanticRun = PASS.semanticdone;
2150 return;
2151 }
2152
2153 ed.members.foreachDsymbol( (s)
2154 {
2155 if (EnumMember em = s.isEnumMember())
2156 em.dsymbolSemantic(em._scope);
2157 });
2158 //printf("defaultval = %lld\n", defaultval);
2159
2160 //if (defaultval) printf("defaultval: %s %s\n", defaultval.toChars(), defaultval.type.toChars());
2161 //printf("members = %s\n", members.toChars());
2162 }
2163
visit(EnumMember em)2164 override void visit(EnumMember em)
2165 {
2166 //printf("EnumMember::semantic() %s\n", em.toChars());
2167
2168 void errorReturn()
2169 {
2170 em.errors = true;
2171 em.semanticRun = PASS.semanticdone;
2172 }
2173
2174 if (em.errors || em.semanticRun >= PASS.semanticdone)
2175 return;
2176 if (em.semanticRun == PASS.semantic)
2177 {
2178 em.error("circular reference to `enum` member");
2179 return errorReturn();
2180 }
2181 assert(em.ed);
2182
2183 em.ed.dsymbolSemantic(sc);
2184 if (em.ed.errors)
2185 return errorReturn();
2186 if (em.errors || em.semanticRun >= PASS.semanticdone)
2187 return;
2188
2189 if (em._scope)
2190 sc = em._scope;
2191 if (!sc)
2192 return;
2193
2194 em.semanticRun = PASS.semantic;
2195
2196 em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_);
2197 em.linkage = LINK.d;
2198 em.storage_class |= STC.manifest;
2199
2200 // https://issues.dlang.org/show_bug.cgi?id=9701
2201 if (em.ed.isAnonymous())
2202 {
2203 if (em.userAttribDecl)
2204 em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
2205 else
2206 em.userAttribDecl = em.ed.userAttribDecl;
2207 }
2208
2209 // Eval UDA in this same scope. Issues 19344, 20835, 21122
2210 if (em.userAttribDecl)
2211 {
2212 // Set scope but avoid extra sc.uda attachment inside setScope()
2213 auto inneruda = em.userAttribDecl.userAttribDecl;
2214 em.userAttribDecl.setScope(sc);
2215 em.userAttribDecl.userAttribDecl = inneruda;
2216 }
2217
2218 // The first enum member is special
2219 bool first = (em == (*em.ed.members)[0]);
2220
2221 if (em.origType)
2222 {
2223 em.origType = em.origType.typeSemantic(em.loc, sc);
2224 em.type = em.origType;
2225 assert(em.value); // "type id;" is not a valid enum member declaration
2226 }
2227
2228 if (em.value)
2229 {
2230 Expression e = em.value;
2231 assert(e.dyncast() == DYNCAST.expression);
2232 e = e.expressionSemantic(sc);
2233 e = resolveProperties(sc, e);
2234 e = e.ctfeInterpret();
2235 if (e.op == TOK.error)
2236 return errorReturn();
2237 if (first && !em.ed.memtype && !em.ed.isAnonymous())
2238 {
2239 em.ed.memtype = e.type;
2240 if (em.ed.memtype.ty == Terror)
2241 {
2242 em.ed.errors = true;
2243 return errorReturn();
2244 }
2245 if (em.ed.memtype.ty != Terror)
2246 {
2247 /* https://issues.dlang.org/show_bug.cgi?id=11746
2248 * All of named enum members should have same type
2249 * with the first member. If the following members were referenced
2250 * during the first member semantic, their types should be unified.
2251 */
2252 em.ed.members.foreachDsymbol( (s)
2253 {
2254 EnumMember enm = s.isEnumMember();
2255 if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
2256 return;
2257
2258 //printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
2259 Expression ev = enm.value;
2260 ev = ev.implicitCastTo(sc, em.ed.memtype);
2261 ev = ev.ctfeInterpret();
2262 ev = ev.castTo(sc, em.ed.type);
2263 if (ev.op == TOK.error)
2264 em.ed.errors = true;
2265 enm.value = ev;
2266 });
2267
2268 if (em.ed.errors)
2269 {
2270 em.ed.memtype = Type.terror;
2271 return errorReturn();
2272 }
2273 }
2274 }
2275
2276 if (em.ed.memtype && !em.origType)
2277 {
2278 e = e.implicitCastTo(sc, em.ed.memtype);
2279 e = e.ctfeInterpret();
2280
2281 // save origValue for better json output
2282 em.origValue = e;
2283
2284 if (!em.ed.isAnonymous())
2285 {
2286 e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
2287 e = e.ctfeInterpret();
2288 }
2289 }
2290 else if (em.origType)
2291 {
2292 e = e.implicitCastTo(sc, em.origType);
2293 e = e.ctfeInterpret();
2294 assert(em.ed.isAnonymous());
2295
2296 // save origValue for better json output
2297 em.origValue = e;
2298 }
2299 em.value = e;
2300 }
2301 else if (first)
2302 {
2303 Type t;
2304 if (em.ed.memtype)
2305 t = em.ed.memtype;
2306 else
2307 {
2308 t = Type.tint32;
2309 if (!em.ed.isAnonymous())
2310 em.ed.memtype = t;
2311 }
2312 Expression e = new IntegerExp(em.loc, 0, t);
2313 e = e.ctfeInterpret();
2314
2315 // save origValue for better json output
2316 em.origValue = e;
2317
2318 if (!em.ed.isAnonymous())
2319 {
2320 e = e.castTo(sc, em.ed.type);
2321 e = e.ctfeInterpret();
2322 }
2323 em.value = e;
2324 }
2325 else
2326 {
2327 /* Find the previous enum member,
2328 * and set this to be the previous value + 1
2329 */
2330 EnumMember emprev = null;
2331 em.ed.members.foreachDsymbol( (s)
2332 {
2333 if (auto enm = s.isEnumMember())
2334 {
2335 if (enm == em)
2336 return 1; // found
2337 emprev = enm;
2338 }
2339 return 0; // continue
2340 });
2341
2342 assert(emprev);
2343 if (emprev.semanticRun < PASS.semanticdone) // if forward reference
2344 emprev.dsymbolSemantic(emprev._scope); // resolve it
2345 if (emprev.errors)
2346 return errorReturn();
2347
2348 Expression eprev = emprev.value;
2349 // .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
2350 Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
2351 ? em.ed.memtype
2352 : eprev.type;
2353
2354 Expression emax = tprev.getProperty(sc, em.ed.loc, Id.max, 0);
2355 emax = emax.expressionSemantic(sc);
2356 emax = emax.ctfeInterpret();
2357
2358 // Set value to (eprev + 1).
2359 // But first check that (eprev != emax)
2360 assert(eprev);
2361 Expression e = new EqualExp(TOK.equal, em.loc, eprev, emax);
2362 e = e.expressionSemantic(sc);
2363 e = e.ctfeInterpret();
2364 if (e.toInteger())
2365 {
2366 em.error("initialization with `%s.%s+1` causes overflow for type `%s`",
2367 emprev.ed.toChars(), emprev.toChars(), em.ed.memtype.toChars());
2368 return errorReturn();
2369 }
2370
2371 // Now set e to (eprev + 1)
2372 e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
2373 e = e.expressionSemantic(sc);
2374 e = e.castTo(sc, eprev.type);
2375 e = e.ctfeInterpret();
2376
2377 // save origValue (without cast) for better json output
2378 if (e.op != TOK.error) // avoid duplicate diagnostics
2379 {
2380 assert(emprev.origValue);
2381 em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
2382 em.origValue = em.origValue.expressionSemantic(sc);
2383 em.origValue = em.origValue.ctfeInterpret();
2384 }
2385
2386 if (e.op == TOK.error)
2387 return errorReturn();
2388 if (e.type.isfloating())
2389 {
2390 // Check that e != eprev (not always true for floats)
2391 Expression etest = new EqualExp(TOK.equal, em.loc, e, eprev);
2392 etest = etest.expressionSemantic(sc);
2393 etest = etest.ctfeInterpret();
2394 if (etest.toInteger())
2395 {
2396 em.error("has inexact value due to loss of precision");
2397 return errorReturn();
2398 }
2399 }
2400 em.value = e;
2401 }
2402 if (!em.origType)
2403 em.type = em.value.type;
2404
2405 assert(em.origValue);
2406 em.semanticRun = PASS.semanticdone;
2407 }
2408
visit(TemplateDeclaration tempdecl)2409 override void visit(TemplateDeclaration tempdecl)
2410 {
2411 static if (LOG)
2412 {
2413 printf("TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\n", this, tempdecl.ident.toChars());
2414 printf("sc.stc = %llx\n", sc.stc);
2415 printf("sc.module = %s\n", sc._module.toChars());
2416 }
2417 if (tempdecl.semanticRun != PASS.init)
2418 return; // semantic() already run
2419
2420 if (tempdecl._scope)
2421 {
2422 sc = tempdecl._scope;
2423 tempdecl._scope = null;
2424 }
2425 if (!sc)
2426 return;
2427
2428 // Remember templates defined in module object that we need to know about
2429 if (sc._module && sc._module.ident == Id.object)
2430 {
2431 if (tempdecl.ident == Id.RTInfo)
2432 Type.rtinfo = tempdecl;
2433 }
2434
2435 /* Remember Scope for later instantiations, but make
2436 * a copy since attributes can change.
2437 */
2438 if (!tempdecl._scope)
2439 {
2440 tempdecl._scope = sc.copy();
2441 tempdecl._scope.setNoFree();
2442 }
2443
2444 tempdecl.semanticRun = PASS.semantic;
2445
2446 tempdecl.parent = sc.parent;
2447 tempdecl.visibility = sc.visibility;
2448 tempdecl.cppnamespace = sc.namespace;
2449 tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);
2450 tempdecl.deprecated_ = !!(sc.stc & STC.deprecated_);
2451
2452 UserAttributeDeclaration.checkGNUABITag(tempdecl, sc.linkage);
2453
2454 if (!tempdecl.isstatic)
2455 {
2456 if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())
2457 ad.makeNested();
2458 }
2459
2460 // Set up scope for parameters
2461 auto paramsym = new ScopeDsymbol();
2462 paramsym.parent = tempdecl.parent;
2463 Scope* paramscope = sc.push(paramsym);
2464 paramscope.stc = 0;
2465
2466 if (global.params.doDocComments)
2467 {
2468 tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.dim);
2469 for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2470 {
2471 TemplateParameter tp = (*tempdecl.parameters)[i];
2472 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
2473 }
2474 }
2475
2476 for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2477 {
2478 TemplateParameter tp = (*tempdecl.parameters)[i];
2479 if (!tp.declareParameter(paramscope))
2480 {
2481 error(tp.loc, "parameter `%s` multiply defined", tp.ident.toChars());
2482 tempdecl.errors = true;
2483 }
2484 if (!tp.tpsemantic(paramscope, tempdecl.parameters))
2485 {
2486 tempdecl.errors = true;
2487 }
2488 if (i + 1 != tempdecl.parameters.dim && tp.isTemplateTupleParameter())
2489 {
2490 tempdecl.error("template tuple parameter must be last one");
2491 tempdecl.errors = true;
2492 }
2493 }
2494
2495 /* Calculate TemplateParameter.dependent
2496 */
2497 TemplateParameters tparams = TemplateParameters(1);
2498 for (size_t i = 0; i < tempdecl.parameters.dim; i++)
2499 {
2500 TemplateParameter tp = (*tempdecl.parameters)[i];
2501 tparams[0] = tp;
2502
2503 for (size_t j = 0; j < tempdecl.parameters.dim; j++)
2504 {
2505 // Skip cases like: X(T : T)
2506 if (i == j)
2507 continue;
2508
2509 if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())
2510 {
2511 if (reliesOnTident(ttp.specType, &tparams))
2512 tp.dependent = true;
2513 }
2514 else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())
2515 {
2516 if (reliesOnTident(tap.specType, &tparams) ||
2517 reliesOnTident(isType(tap.specAlias), &tparams))
2518 {
2519 tp.dependent = true;
2520 }
2521 }
2522 }
2523 }
2524
2525 paramscope.pop();
2526
2527 // Compute again
2528 tempdecl.onemember = null;
2529 if (tempdecl.members)
2530 {
2531 Dsymbol s;
2532 if (Dsymbol.oneMembers(tempdecl.members, &s, tempdecl.ident) && s)
2533 {
2534 tempdecl.onemember = s;
2535 s.parent = tempdecl;
2536 }
2537 }
2538
2539 /* BUG: should check:
2540 * 1. template functions must not introduce virtual functions, as they
2541 * cannot be accomodated in the vtbl[]
2542 * 2. templates cannot introduce non-static data members (i.e. fields)
2543 * as they would change the instance size of the aggregate.
2544 */
2545
2546 tempdecl.semanticRun = PASS.semanticdone;
2547 }
2548
visit(TemplateInstance ti)2549 override void visit(TemplateInstance ti)
2550 {
2551 templateInstanceSemantic(ti, sc, null);
2552 }
2553
visit(TemplateMixin tm)2554 override void visit(TemplateMixin tm)
2555 {
2556 static if (LOG)
2557 {
2558 printf("+TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
2559 fflush(stdout);
2560 }
2561 if (tm.semanticRun != PASS.init)
2562 {
2563 // When a class/struct contains mixin members, and is done over
2564 // because of forward references, never reach here so semanticRun
2565 // has been reset to PASS.init.
2566 static if (LOG)
2567 {
2568 printf("\tsemantic done\n");
2569 }
2570 return;
2571 }
2572 tm.semanticRun = PASS.semantic;
2573 static if (LOG)
2574 {
2575 printf("\tdo semantic\n");
2576 }
2577
2578 Scope* scx = null;
2579 if (tm._scope)
2580 {
2581 sc = tm._scope;
2582 scx = tm._scope; // save so we don't make redundant copies
2583 tm._scope = null;
2584 }
2585
2586 /* Run semantic on each argument, place results in tiargs[],
2587 * then find best match template with tiargs
2588 */
2589 if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, null))
2590 {
2591 if (tm.semanticRun == PASS.init) // forward reference had occurred
2592 {
2593 //printf("forward reference - deferring\n");
2594 return deferDsymbolSemantic(tm, scx);
2595 }
2596
2597 tm.inst = tm;
2598 tm.errors = true;
2599 return; // error recovery
2600 }
2601
2602 auto tempdecl = tm.tempdecl.isTemplateDeclaration();
2603 assert(tempdecl);
2604
2605 if (!tm.ident)
2606 {
2607 /* Assign scope local unique identifier, as same as lambdas.
2608 */
2609 const(char)[] s = "__mixin";
2610
2611 if (FuncDeclaration func = sc.parent.isFuncDeclaration())
2612 {
2613 tm.symtab = func.localsymtab;
2614 if (tm.symtab)
2615 {
2616 // Inside template constraint, symtab is not set yet.
2617 goto L1;
2618 }
2619 }
2620 else
2621 {
2622 tm.symtab = sc.parent.isScopeDsymbol().symtab;
2623 L1:
2624 assert(tm.symtab);
2625 tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
2626 tm.symtab.insert(tm);
2627 }
2628 }
2629
2630 tm.inst = tm;
2631 tm.parent = sc.parent;
2632
2633 /* Detect recursive mixin instantiations.
2634 */
2635 for (Dsymbol s = tm.parent; s; s = s.parent)
2636 {
2637 //printf("\ts = '%s'\n", s.toChars());
2638 TemplateMixin tmix = s.isTemplateMixin();
2639 if (!tmix || tempdecl != tmix.tempdecl)
2640 continue;
2641
2642 /* Different argument list lengths happen with variadic args
2643 */
2644 if (tm.tiargs.dim != tmix.tiargs.dim)
2645 continue;
2646
2647 for (size_t i = 0; i < tm.tiargs.dim; i++)
2648 {
2649 RootObject o = (*tm.tiargs)[i];
2650 Type ta = isType(o);
2651 Expression ea = isExpression(o);
2652 Dsymbol sa = isDsymbol(o);
2653 RootObject tmo = (*tmix.tiargs)[i];
2654 if (ta)
2655 {
2656 Type tmta = isType(tmo);
2657 if (!tmta)
2658 goto Lcontinue;
2659 if (!ta.equals(tmta))
2660 goto Lcontinue;
2661 }
2662 else if (ea)
2663 {
2664 Expression tme = isExpression(tmo);
2665 if (!tme || !ea.equals(tme))
2666 goto Lcontinue;
2667 }
2668 else if (sa)
2669 {
2670 Dsymbol tmsa = isDsymbol(tmo);
2671 if (sa != tmsa)
2672 goto Lcontinue;
2673 }
2674 else
2675 assert(0);
2676 }
2677 tm.error("recursive mixin instantiation");
2678 return;
2679
2680 Lcontinue:
2681 continue;
2682 }
2683
2684 // Copy the syntax trees from the TemplateDeclaration
2685 tm.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
2686 if (!tm.members)
2687 return;
2688
2689 tm.symtab = new DsymbolTable();
2690
2691 sc.getScopesym().importScope(tm, Visibility(Visibility.Kind.public_));
2692
2693 static if (LOG)
2694 {
2695 printf("\tcreate scope for template parameters '%s'\n", tm.toChars());
2696 }
2697 Scope* scy = sc.push(tm);
2698 scy.parent = tm;
2699
2700 /* https://issues.dlang.org/show_bug.cgi?id=930
2701 *
2702 * If the template that is to be mixed in is in the scope of a template
2703 * instance, we have to also declare the type aliases in the new mixin scope.
2704 */
2705 auto parentInstance = tempdecl.parent ? tempdecl.parent.isTemplateInstance() : null;
2706 if (parentInstance)
2707 parentInstance.declareParameters(scy);
2708
2709 tm.argsym = new ScopeDsymbol();
2710 tm.argsym.parent = scy.parent;
2711 Scope* argscope = scy.push(tm.argsym);
2712
2713 uint errorsave = global.errors;
2714
2715 // Declare each template parameter as an alias for the argument type
2716 tm.declareParameters(argscope);
2717
2718 // Add members to enclosing scope, as well as this scope
2719 tm.members.foreachDsymbol(s => s.addMember(argscope, tm));
2720
2721 // Do semantic() analysis on template instance members
2722 static if (LOG)
2723 {
2724 printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
2725 }
2726 Scope* sc2 = argscope.push(tm);
2727 //size_t deferred_dim = Module.deferred.dim;
2728
2729 __gshared int nest;
2730 //printf("%d\n", nest);
2731 if (++nest > global.recursionLimit)
2732 {
2733 global.gag = 0; // ensure error message gets printed
2734 tm.error("recursive expansion");
2735 fatal();
2736 }
2737
2738 tm.members.foreachDsymbol( s => s.setScope(sc2) );
2739
2740 tm.members.foreachDsymbol( s => s.importAll(sc2) );
2741
2742 tm.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
2743
2744 nest--;
2745
2746 /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
2747 * Because the members would already call Module.addDeferredSemantic() for themselves.
2748 * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
2749 */
2750 //if (!sc.func && Module.deferred.dim > deferred_dim) {}
2751
2752 AggregateDeclaration ad = tm.toParent().isAggregateDeclaration();
2753 if (sc.func && !ad)
2754 {
2755 tm.semantic2(sc2);
2756 tm.semantic3(sc2);
2757 }
2758
2759 // Give additional context info if error occurred during instantiation
2760 if (global.errors != errorsave)
2761 {
2762 tm.error("error instantiating");
2763 tm.errors = true;
2764 }
2765
2766 sc2.pop();
2767 argscope.pop();
2768 scy.pop();
2769
2770 static if (LOG)
2771 {
2772 printf("-TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
2773 }
2774 }
2775
visit(Nspace ns)2776 override void visit(Nspace ns)
2777 {
2778 if (ns.semanticRun != PASS.init)
2779 return;
2780 static if (LOG)
2781 {
2782 printf("+Nspace::semantic('%s')\n", ns.toChars());
2783 }
2784 if (ns._scope)
2785 {
2786 sc = ns._scope;
2787 ns._scope = null;
2788 }
2789 if (!sc)
2790 return;
2791
2792 bool repopulateMembers = false;
2793 if (ns.identExp)
2794 {
2795 // resolve the namespace identifier
2796 sc = sc.startCTFE();
2797 Expression resolved = ns.identExp.expressionSemantic(sc);
2798 resolved = resolveProperties(sc, resolved);
2799 sc = sc.endCTFE();
2800 resolved = resolved.ctfeInterpret();
2801 StringExp name = resolved.toStringExp();
2802 TupleExp tup = name ? null : resolved.toTupleExp();
2803 if (!tup && !name)
2804 {
2805 error(ns.loc, "expected string expression for namespace name, got `%s`", ns.identExp.toChars());
2806 return;
2807 }
2808 ns.identExp = resolved; // we don't need to keep the old AST around
2809 if (name)
2810 {
2811 const(char)[] ident = name.toStringz();
2812 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
2813 {
2814 error(ns.loc, "expected valid identifier for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
2815 return;
2816 }
2817 ns.ident = Identifier.idPool(ident);
2818 }
2819 else
2820 {
2821 // create namespace stack from the tuple
2822 Nspace parentns = ns;
2823 foreach (i, exp; *tup.exps)
2824 {
2825 name = exp.toStringExp();
2826 if (!name)
2827 {
2828 error(ns.loc, "expected string expression for namespace name, got `%s`", exp.toChars());
2829 return;
2830 }
2831 const(char)[] ident = name.toStringz();
2832 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
2833 {
2834 error(ns.loc, "expected valid identifier for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
2835 return;
2836 }
2837 if (i == 0)
2838 {
2839 ns.ident = Identifier.idPool(ident);
2840 }
2841 else
2842 {
2843 // insert the new namespace
2844 Nspace childns = new Nspace(ns.loc, Identifier.idPool(ident), null, parentns.members);
2845 parentns.members = new Dsymbols;
2846 parentns.members.push(childns);
2847 parentns = childns;
2848 repopulateMembers = true;
2849 }
2850 }
2851 }
2852 }
2853
2854 ns.semanticRun = PASS.semantic;
2855 ns.parent = sc.parent;
2856 // Link does not matter here, if the UDA is present it will error
2857 UserAttributeDeclaration.checkGNUABITag(ns, LINK.cpp);
2858
2859 if (ns.members)
2860 {
2861 assert(sc);
2862 sc = sc.push(ns);
2863 sc.linkage = LINK.cpp; // note that namespaces imply C++ linkage
2864 sc.parent = ns;
2865 foreach (s; *ns.members)
2866 {
2867 if (repopulateMembers)
2868 {
2869 s.addMember(sc, sc.scopesym);
2870 s.setScope(sc);
2871 }
2872 s.importAll(sc);
2873 }
2874 foreach (s; *ns.members)
2875 {
2876 static if (LOG)
2877 {
2878 printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
2879 }
2880 s.dsymbolSemantic(sc);
2881 }
2882 sc.pop();
2883 }
2884 ns.semanticRun = PASS.semanticdone;
2885 static if (LOG)
2886 {
2887 printf("-Nspace::semantic('%s')\n", ns.toChars());
2888 }
2889 }
2890
funcDeclarationSemantic(FuncDeclaration funcdecl)2891 void funcDeclarationSemantic(FuncDeclaration funcdecl)
2892 {
2893 TypeFunction f;
2894 AggregateDeclaration ad;
2895 InterfaceDeclaration id;
2896
2897 version (none)
2898 {
2899 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, funcdecl, funcdecl.toPrettyChars(), sc.linkage);
2900 if (funcdecl.isFuncLiteralDeclaration())
2901 printf("\tFuncLiteralDeclaration()\n");
2902 printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), funcdecl.parent ? funcdecl.parent.toChars() : "");
2903 printf("type: %p, %s\n", funcdecl.type, funcdecl.type.toChars());
2904 }
2905
2906 if (funcdecl.semanticRun != PASS.init && funcdecl.isFuncLiteralDeclaration())
2907 {
2908 /* Member functions that have return types that are
2909 * forward references can have semantic() run more than
2910 * once on them.
2911 * See test\interface2.d, test20
2912 */
2913 return;
2914 }
2915
2916 if (funcdecl.semanticRun >= PASS.semanticdone)
2917 return;
2918 assert(funcdecl.semanticRun <= PASS.semantic);
2919 funcdecl.semanticRun = PASS.semantic;
2920
2921 if (funcdecl._scope)
2922 {
2923 sc = funcdecl._scope;
2924 funcdecl._scope = null;
2925 }
2926
2927 if (!sc || funcdecl.errors)
2928 return;
2929
2930 funcdecl.cppnamespace = sc.namespace;
2931 funcdecl.parent = sc.parent;
2932 Dsymbol parent = funcdecl.toParent();
2933
2934 funcdecl.foverrides.setDim(0); // reset in case semantic() is being retried for this function
2935
2936 funcdecl.storage_class |= sc.stc & ~STC.ref_;
2937 ad = funcdecl.isThis();
2938 // Don't nest structs b/c of generated methods which should not access the outer scopes.
2939 // https://issues.dlang.org/show_bug.cgi?id=16627
2940 if (ad && !funcdecl.generated)
2941 {
2942 funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_);
2943 ad.makeNested();
2944 }
2945 if (sc.func)
2946 funcdecl.storage_class |= sc.func.storage_class & STC.disable;
2947 // Remove prefix storage classes silently.
2948 if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
2949 funcdecl.storage_class &= ~STC.TYPECTOR;
2950
2951 //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration::isFinal());
2952
2953 if (sc.flags & SCOPE.compile)
2954 funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
2955
2956 FuncLiteralDeclaration fld = funcdecl.isFuncLiteralDeclaration();
2957 if (fld && fld.treq)
2958 {
2959 Type treq = fld.treq;
2960 assert(treq.nextOf().ty == Tfunction);
2961 if (treq.ty == Tdelegate)
2962 fld.tok = TOK.delegate_;
2963 else if (treq.isPtrToFunction())
2964 fld.tok = TOK.function_;
2965 else
2966 assert(0);
2967 funcdecl.linkage = treq.nextOf().toTypeFunction().linkage;
2968 }
2969 else
2970 funcdecl.linkage = sc.linkage;
2971
2972 // evaluate pragma(inline)
2973 if (auto pragmadecl = sc.inlining)
2974 funcdecl.inlining = pragmadecl.evalPragmaInline(sc);
2975
2976 funcdecl.visibility = sc.visibility;
2977 funcdecl.userAttribDecl = sc.userAttribDecl;
2978 UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage);
2979
2980 if (!funcdecl.originalType)
2981 funcdecl.originalType = funcdecl.type.syntaxCopy();
2982 if (funcdecl.type.ty != Tfunction)
2983 {
2984 if (funcdecl.type.ty != Terror)
2985 {
2986 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
2987 funcdecl.type = Type.terror;
2988 }
2989 funcdecl.errors = true;
2990 return;
2991 }
2992 if (!funcdecl.type.deco)
2993 {
2994 sc = sc.push();
2995 sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
2996
2997 TypeFunction tf = funcdecl.type.toTypeFunction();
2998 if (sc.func)
2999 {
3000 /* If the nesting parent is pure without inference,
3001 * then this function defaults to pure too.
3002 *
3003 * auto foo() pure {
3004 * auto bar() {} // become a weak purity function
3005 * class C { // nested class
3006 * auto baz() {} // become a weak purity function
3007 * }
3008 *
3009 * static auto boo() {} // typed as impure
3010 * // Even though, boo cannot call any impure functions.
3011 * // See also Expression::checkPurity().
3012 * }
3013 */
3014 if (tf.purity == PURE.impure && (funcdecl.isNested() || funcdecl.isThis()))
3015 {
3016 FuncDeclaration fd = null;
3017 for (Dsymbol p = funcdecl.toParent2(); p; p = p.toParent2())
3018 {
3019 if (AggregateDeclaration adx = p.isAggregateDeclaration())
3020 {
3021 if (adx.isNested())
3022 continue;
3023 break;
3024 }
3025 if ((fd = p.isFuncDeclaration()) !is null)
3026 break;
3027 }
3028
3029 /* If the parent's purity is inferred, then this function's purity needs
3030 * to be inferred first.
3031 */
3032 if (fd && fd.isPureBypassingInference() >= PURE.weak && !funcdecl.isInstantiated())
3033 {
3034 tf.purity = PURE.fwdref; // default to pure
3035 }
3036 }
3037 }
3038
3039 if (tf.isref)
3040 sc.stc |= STC.ref_;
3041 if (tf.isScopeQual)
3042 sc.stc |= STC.scope_;
3043 if (tf.isnothrow)
3044 sc.stc |= STC.nothrow_;
3045 if (tf.isnogc)
3046 sc.stc |= STC.nogc;
3047 if (tf.isproperty)
3048 sc.stc |= STC.property;
3049 if (tf.purity == PURE.fwdref)
3050 sc.stc |= STC.pure_;
3051 if (tf.trust != TRUST.default_)
3052 sc.stc &= ~STC.safeGroup;
3053 if (tf.trust == TRUST.safe)
3054 sc.stc |= STC.safe;
3055 if (tf.trust == TRUST.system)
3056 sc.stc |= STC.system;
3057 if (tf.trust == TRUST.trusted)
3058 sc.stc |= STC.trusted;
3059
3060 if (funcdecl.isCtorDeclaration())
3061 {
3062 tf.isctor = true;
3063 Type tret = ad.handleType();
3064 assert(tret);
3065 tret = tret.addStorageClass(funcdecl.storage_class | sc.stc);
3066 tret = tret.addMod(funcdecl.type.mod);
3067 tf.next = tret;
3068 if (ad.isStructDeclaration())
3069 sc.stc |= STC.ref_;
3070 }
3071
3072 // 'return' on a non-static class member function implies 'scope' as well
3073 if (ad && ad.isClassDeclaration() && (tf.isreturn || sc.stc & STC.return_) && !(sc.stc & STC.static_))
3074 sc.stc |= STC.scope_;
3075
3076 // If 'this' has no pointers, remove 'scope' as it has no meaning
3077 if (sc.stc & STC.scope_ && ad && ad.isStructDeclaration() && !ad.type.hasPointers())
3078 {
3079 sc.stc &= ~STC.scope_;
3080 tf.isScopeQual = false;
3081 }
3082
3083 sc.linkage = funcdecl.linkage;
3084
3085 if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
3086 {
3087 OutBuffer buf;
3088 MODtoBuffer(&buf, tf.mod);
3089 funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
3090 tf.mod = 0; // remove qualifiers
3091 }
3092
3093 /* Apply const, immutable, wild and shared storage class
3094 * to the function type. Do this before type semantic.
3095 */
3096 auto stc = funcdecl.storage_class;
3097 if (funcdecl.type.isImmutable())
3098 stc |= STC.immutable_;
3099 if (funcdecl.type.isConst())
3100 stc |= STC.const_;
3101 if (funcdecl.type.isShared() || funcdecl.storage_class & STC.synchronized_)
3102 stc |= STC.shared_;
3103 if (funcdecl.type.isWild())
3104 stc |= STC.wild;
3105 funcdecl.type = funcdecl.type.addSTC(stc);
3106
3107 funcdecl.type = funcdecl.type.typeSemantic(funcdecl.loc, sc);
3108 sc = sc.pop();
3109 }
3110 if (funcdecl.type.ty != Tfunction)
3111 {
3112 if (funcdecl.type.ty != Terror)
3113 {
3114 funcdecl.error("`%s` must be a function instead of `%s`", funcdecl.toChars(), funcdecl.type.toChars());
3115 funcdecl.type = Type.terror;
3116 }
3117 funcdecl.errors = true;
3118 return;
3119 }
3120 else
3121 {
3122 // Merge back function attributes into 'originalType'.
3123 // It's used for mangling, ddoc, and json output.
3124 TypeFunction tfo = funcdecl.originalType.toTypeFunction();
3125 TypeFunction tfx = funcdecl.type.toTypeFunction();
3126 tfo.mod = tfx.mod;
3127 tfo.isScopeQual = tfx.isScopeQual;
3128 tfo.isreturninferred = tfx.isreturninferred;
3129 tfo.isscopeinferred = tfx.isscopeinferred;
3130 tfo.isref = tfx.isref;
3131 tfo.isnothrow = tfx.isnothrow;
3132 tfo.isnogc = tfx.isnogc;
3133 tfo.isproperty = tfx.isproperty;
3134 tfo.purity = tfx.purity;
3135 tfo.trust = tfx.trust;
3136
3137 funcdecl.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);
3138 }
3139
3140 f = cast(TypeFunction)funcdecl.type;
3141
3142 if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)
3143 funcdecl.error("storage class `auto` has no effect if return type is not inferred");
3144
3145 /* Functions can only be 'scope' if they have a 'this'
3146 */
3147 if (f.isScopeQual && !funcdecl.isNested() && !ad)
3148 {
3149 funcdecl.error("functions cannot be `scope`");
3150 }
3151
3152 if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())
3153 {
3154 /* Non-static nested functions have a hidden 'this' pointer to which
3155 * the 'return' applies
3156 */
3157 if (sc.scopesym && sc.scopesym.isAggregateDeclaration())
3158 funcdecl.error("`static` member has no `this` to which `return` can apply");
3159 else
3160 error(funcdecl.loc, "Top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars());
3161 }
3162
3163 if (funcdecl.isAbstract() && !funcdecl.isVirtual())
3164 {
3165 const(char)* sfunc;
3166 if (funcdecl.isStatic())
3167 sfunc = "static";
3168 else if (funcdecl.visibility.kind == Visibility.Kind.private_ || funcdecl.visibility.kind == Visibility.Kind.package_)
3169 sfunc = visibilityToChars(funcdecl.visibility.kind);
3170 else
3171 sfunc = "final";
3172 funcdecl.error("`%s` functions cannot be `abstract`", sfunc);
3173 }
3174
3175 if (funcdecl.isOverride() && !funcdecl.isVirtual() && !funcdecl.isFuncLiteralDeclaration())
3176 {
3177 Visibility.Kind kind = funcdecl.visible().kind;
3178 if ((kind == Visibility.Kind.private_ || kind == Visibility.Kind.package_) && funcdecl.isMember())
3179 funcdecl.error("`%s` method is not virtual and cannot override", visibilityToChars(kind));
3180 else
3181 funcdecl.error("cannot override a non-virtual function");
3182 }
3183
3184 if (funcdecl.isAbstract() && funcdecl.isFinalFunc())
3185 funcdecl.error("cannot be both `final` and `abstract`");
3186 version (none)
3187 {
3188 if (funcdecl.isAbstract() && funcdecl.fbody)
3189 funcdecl.error("`abstract` functions cannot have bodies");
3190 }
3191
3192 version (none)
3193 {
3194 if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())
3195 {
3196 if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
3197 funcdecl.error("static constructors / destructors must be `static void`");
3198 if (f.arguments && f.arguments.dim)
3199 funcdecl.error("static constructors / destructors must have empty parameter list");
3200 // BUG: check for invalid storage classes
3201 }
3202 }
3203
3204 if (const pors = sc.flags & (SCOPE.printf | SCOPE.scanf))
3205 {
3206 /* printf/scanf-like functions must be of the form:
3207 * extern (C/C++) T printf([parameters...], const(char)* format, ...);
3208 * or:
3209 * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
3210 */
3211
3212 static bool isPointerToChar(Parameter p)
3213 {
3214 if (auto tptr = p.type.isTypePointer())
3215 {
3216 return tptr.next.ty == Tchar;
3217 }
3218 return false;
3219 }
3220
3221 bool isVa_list(Parameter p)
3222 {
3223 return p.type.equals(target.va_listType(funcdecl.loc, sc));
3224 }
3225
3226 const nparams = f.parameterList.length;
3227 if ((f.linkage == LINK.c || f.linkage == LINK.cpp) &&
3228
3229 (f.parameterList.varargs == VarArg.variadic &&
3230 nparams >= 1 &&
3231 isPointerToChar(f.parameterList[nparams - 1]) ||
3232
3233 f.parameterList.varargs == VarArg.none &&
3234 nparams >= 2 &&
3235 isPointerToChar(f.parameterList[nparams - 2]) &&
3236 isVa_list(f.parameterList[nparams - 1])
3237 )
3238 )
3239 {
3240 funcdecl.flags |= (pors == SCOPE.printf) ? FUNCFLAG.printf : FUNCFLAG.scanf;
3241 }
3242 else
3243 {
3244 const p = (pors == SCOPE.printf ? Id.printf : Id.scanf).toChars();
3245 if (f.parameterList.varargs == VarArg.variadic)
3246 {
3247 funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`"
3248 ~ " not `%s`",
3249 p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
3250 }
3251 else
3252 {
3253 funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`",
3254 p, f.next.toChars(), funcdecl.toChars());
3255 }
3256 }
3257 }
3258
3259 id = parent.isInterfaceDeclaration();
3260 if (id)
3261 {
3262 funcdecl.storage_class |= STC.abstract_;
3263 if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete())
3264 funcdecl.error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", id.toChars());
3265 if (funcdecl.fbody && funcdecl.isVirtual())
3266 funcdecl.error("function body only allowed in `final` functions in interface `%s`", id.toChars());
3267 }
3268 if (UnionDeclaration ud = parent.isUnionDeclaration())
3269 {
3270 if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration())
3271 funcdecl.error("destructors, postblits and invariants are not allowed in union `%s`", ud.toChars());
3272 }
3273
3274 if (StructDeclaration sd = parent.isStructDeclaration())
3275 {
3276 if (funcdecl.isCtorDeclaration())
3277 {
3278 goto Ldone;
3279 }
3280 }
3281
3282 if (ClassDeclaration cd = parent.isClassDeclaration())
3283 {
3284 parent = cd = objc.getParent(funcdecl, cd);
3285
3286 if (funcdecl.isCtorDeclaration())
3287 {
3288 goto Ldone;
3289 }
3290
3291 if (funcdecl.storage_class & STC.abstract_)
3292 cd.isabstract = ThreeState.yes;
3293
3294 // if static function, do not put in vtbl[]
3295 if (!funcdecl.isVirtual())
3296 {
3297 //printf("\tnot virtual\n");
3298 goto Ldone;
3299 }
3300 // Suppress further errors if the return type is an error
3301 if (funcdecl.type.nextOf() == Type.terror)
3302 goto Ldone;
3303
3304 bool may_override = false;
3305 for (size_t i = 0; i < cd.baseclasses.dim; i++)
3306 {
3307 BaseClass* b = (*cd.baseclasses)[i];
3308 ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
3309 if (!cbd)
3310 continue;
3311 for (size_t j = 0; j < cbd.vtbl.dim; j++)
3312 {
3313 FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
3314 if (!f2 || f2.ident != funcdecl.ident)
3315 continue;
3316 if (cbd.parent && cbd.parent.isTemplateInstance())
3317 {
3318 if (!f2.functionSemantic())
3319 goto Ldone;
3320 }
3321 may_override = true;
3322 }
3323 }
3324 if (may_override && funcdecl.type.nextOf() is null)
3325 {
3326 /* If same name function exists in base class but 'this' is auto return,
3327 * cannot find index of base class's vtbl[] to override.
3328 */
3329 funcdecl.error("return type inference is not supported if may override base class function");
3330 }
3331
3332 /* Find index of existing function in base class's vtbl[] to override
3333 * (the index will be the same as in cd's current vtbl[])
3334 */
3335 int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.dim) : -1;
3336
3337 bool doesoverride = false;
3338 switch (vi)
3339 {
3340 case -1:
3341 Lintro:
3342 /* Didn't find one, so
3343 * This is an 'introducing' function which gets a new
3344 * slot in the vtbl[].
3345 */
3346
3347 // Verify this doesn't override previous final function
3348 if (cd.baseClass)
3349 {
3350 Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
3351 if (s)
3352 {
3353 FuncDeclaration f2 = s.isFuncDeclaration();
3354 if (f2)
3355 {
3356 f2 = f2.overloadExactMatch(funcdecl.type);
3357 if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
3358 funcdecl.error("cannot override `final` function `%s`", f2.toPrettyChars());
3359 }
3360 }
3361 }
3362
3363 /* These quirky conditions mimic what VC++ appears to do
3364 */
3365 if (target.mscoff && cd.classKind == ClassKind.cpp &&
3366 cd.baseClass && cd.baseClass.vtbl.dim)
3367 {
3368 /* if overriding an interface function, then this is not
3369 * introducing and don't put it in the class vtbl[]
3370 */
3371 funcdecl.interfaceVirtual = funcdecl.overrideInterface();
3372 if (funcdecl.interfaceVirtual)
3373 {
3374 //printf("\tinterface function %s\n", toChars());
3375 cd.vtblFinal.push(funcdecl);
3376 goto Linterfaces;
3377 }
3378 }
3379
3380 if (funcdecl.isFinalFunc())
3381 {
3382 // Don't check here, as it may override an interface function
3383 //if (isOverride())
3384 // error("is marked as override, but does not override any function");
3385 cd.vtblFinal.push(funcdecl);
3386 }
3387 else
3388 {
3389 //printf("\tintroducing function %s\n", funcdecl.toChars());
3390 funcdecl.introducing = 1;
3391 if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
3392 {
3393 /* Overloaded functions with same name are grouped and in reverse order.
3394 * Search for first function of overload group, and insert
3395 * funcdecl into vtbl[] immediately before it.
3396 */
3397 funcdecl.vtblIndex = cast(int)cd.vtbl.dim;
3398 bool found;
3399 foreach (const i, s; cd.vtbl)
3400 {
3401 if (found)
3402 // the rest get shifted forward
3403 ++s.isFuncDeclaration().vtblIndex;
3404 else if (s.ident == funcdecl.ident && s.parent == parent)
3405 {
3406 // found first function of overload group
3407 funcdecl.vtblIndex = cast(int)i;
3408 found = true;
3409 ++s.isFuncDeclaration().vtblIndex;
3410 }
3411 }
3412 cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
3413
3414 debug foreach (const i, s; cd.vtbl)
3415 {
3416 // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
3417 // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
3418 if (auto fd = s.isFuncDeclaration())
3419 assert(fd.vtblIndex == i ||
3420 (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
3421 funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
3422 }
3423 }
3424 else
3425 {
3426 // Append to end of vtbl[]
3427 vi = cast(int)cd.vtbl.dim;
3428 cd.vtbl.push(funcdecl);
3429 funcdecl.vtblIndex = vi;
3430 }
3431 }
3432 break;
3433
3434 case -2:
3435 // can't determine because of forward references
3436 funcdecl.errors = true;
3437 return;
3438
3439 default:
3440 {
3441 FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
3442 FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
3443 // This function is covariant with fdv
3444
3445 if (fdc == funcdecl)
3446 {
3447 doesoverride = true;
3448 break;
3449 }
3450
3451 if (fdc.toParent() == parent)
3452 {
3453 //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc = %p %s %s @ [%s]\n\tfdv = %p %s %s @ [%s]\n",
3454 // vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
3455 // fdc, fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
3456 // fdv, fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
3457
3458 // fdc overrides fdv exactly, then this introduces new function.
3459 if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
3460 goto Lintro;
3461 }
3462
3463 if (fdv.isDeprecated)
3464 deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
3465 funcdecl.toPrettyChars, fdv.toPrettyChars);
3466
3467 // This function overrides fdv
3468 if (fdv.isFinalFunc())
3469 funcdecl.error("cannot override `final` function `%s`", fdv.toPrettyChars());
3470
3471 if (!funcdecl.isOverride())
3472 {
3473 if (fdv.isFuture())
3474 {
3475 deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars());
3476 // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
3477 goto Lintro;
3478 }
3479 else
3480 {
3481 // https://issues.dlang.org/show_bug.cgi?id=17349
3482 error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
3483 fdv.toPrettyChars(), funcdecl.toPrettyChars());
3484 }
3485 }
3486 doesoverride = true;
3487 if (fdc.toParent() == parent)
3488 {
3489 // If both are mixins, or both are not, then error.
3490 // If either is not, the one that is not overrides the other.
3491 bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
3492 bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
3493 if (thismixin == fdcmixin)
3494 {
3495 funcdecl.error("multiple overrides of same function");
3496 }
3497 /*
3498 * https://issues.dlang.org/show_bug.cgi?id=711
3499 *
3500 * If an overriding method is introduced through a mixin,
3501 * we need to update the vtbl so that both methods are
3502 * present.
3503 */
3504 else if (thismixin)
3505 {
3506 /* if the mixin introduced the overriding method, then reintroduce it
3507 * in the vtbl. The initial entry for the mixined method
3508 * will be updated at the end of the enclosing `if` block
3509 * to point to the current (non-mixined) function.
3510 */
3511 auto vitmp = cast(int)cd.vtbl.dim;
3512 cd.vtbl.push(fdc);
3513 fdc.vtblIndex = vitmp;
3514 }
3515 else if (fdcmixin)
3516 {
3517 /* if the current overriding function is coming from a
3518 * mixined block, then push the current function in the
3519 * vtbl, but keep the previous (non-mixined) function as
3520 * the overriding one.
3521 */
3522 auto vitmp = cast(int)cd.vtbl.dim;
3523 cd.vtbl.push(funcdecl);
3524 funcdecl.vtblIndex = vitmp;
3525 break;
3526 }
3527 else // fdc overrides fdv
3528 {
3529 // this doesn't override any function
3530 break;
3531 }
3532 }
3533 cd.vtbl[vi] = funcdecl;
3534 funcdecl.vtblIndex = vi;
3535
3536 /* Remember which functions this overrides
3537 */
3538 funcdecl.foverrides.push(fdv);
3539
3540 /* This works by whenever this function is called,
3541 * it actually returns tintro, which gets dynamically
3542 * cast to type. But we know that tintro is a base
3543 * of type, so we could optimize it by not doing a
3544 * dynamic cast, but just subtracting the isBaseOf()
3545 * offset if the value is != null.
3546 */
3547
3548 if (fdv.tintro)
3549 funcdecl.tintro = fdv.tintro;
3550 else if (!funcdecl.type.equals(fdv.type))
3551 {
3552 /* Only need to have a tintro if the vptr
3553 * offsets differ
3554 */
3555 int offset;
3556 if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
3557 {
3558 funcdecl.tintro = fdv.type;
3559 }
3560 }
3561 break;
3562 }
3563 }
3564
3565 /* Go through all the interface bases.
3566 * If this function is covariant with any members of those interface
3567 * functions, set the tintro.
3568 */
3569 Linterfaces:
3570 bool foundVtblMatch = false;
3571
3572 for (ClassDeclaration bcd = cd; !foundVtblMatch && bcd; bcd = bcd.baseClass)
3573 {
3574 foreach (b; bcd.interfaces)
3575 {
3576 vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.dim);
3577 switch (vi)
3578 {
3579 case -1:
3580 break;
3581
3582 case -2:
3583 // can't determine because of forward references
3584 funcdecl.errors = true;
3585 return;
3586
3587 default:
3588 {
3589 auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
3590 Type ti = null;
3591
3592 foundVtblMatch = true;
3593
3594 /* Remember which functions this overrides
3595 */
3596 funcdecl.foverrides.push(fdv);
3597
3598 /* Should we really require 'override' when implementing
3599 * an interface function?
3600 */
3601 //if (!isOverride())
3602 // warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
3603
3604 if (fdv.tintro)
3605 ti = fdv.tintro;
3606 else if (!funcdecl.type.equals(fdv.type))
3607 {
3608 /* Only need to have a tintro if the vptr
3609 * offsets differ
3610 */
3611 int offset;
3612 if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
3613 {
3614 ti = fdv.type;
3615 }
3616 }
3617 if (ti)
3618 {
3619 if (funcdecl.tintro)
3620 {
3621 if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
3622 {
3623 funcdecl.error("incompatible covariant types `%s` and `%s`", funcdecl.tintro.toChars(), ti.toChars());
3624 }
3625 }
3626 else
3627 {
3628 funcdecl.tintro = ti;
3629 }
3630 }
3631 }
3632 }
3633 }
3634 }
3635 if (foundVtblMatch)
3636 {
3637 goto L2;
3638 }
3639
3640 if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
3641 {
3642 BaseClass* bc = null;
3643 Dsymbol s = null;
3644 for (size_t i = 0; i < cd.baseclasses.dim; i++)
3645 {
3646 bc = (*cd.baseclasses)[i];
3647 s = bc.sym.search_correct(funcdecl.ident);
3648 if (s)
3649 break;
3650 }
3651
3652 if (s)
3653 {
3654 HdrGenState hgs;
3655 OutBuffer buf;
3656
3657 auto fd = s.isFuncDeclaration();
3658 functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
3659 new Identifier(funcdecl.toPrettyChars()), &hgs, null);
3660 const(char)* funcdeclToChars = buf.peekChars();
3661
3662 if (fd)
3663 {
3664 OutBuffer buf1;
3665
3666 if (fd.ident == funcdecl.ident)
3667 hgs.fullQual = true;
3668 functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
3669 new Identifier(fd.toPrettyChars()), &hgs, null);
3670
3671 error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
3672 funcdeclToChars, buf1.peekChars());
3673 }
3674 else
3675 {
3676 error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
3677 funcdeclToChars, s.kind, s.toPrettyChars());
3678 errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overriden");
3679 }
3680 }
3681 else
3682 funcdecl.error("does not override any function");
3683 }
3684
3685 L2:
3686 objc.setSelector(funcdecl, sc);
3687 objc.checkLinkage(funcdecl);
3688 objc.addToClassMethodList(funcdecl, cd);
3689 objc.setAsOptional(funcdecl, sc);
3690
3691 /* Go through all the interface bases.
3692 * Disallow overriding any final functions in the interface(s).
3693 */
3694 foreach (b; cd.interfaces)
3695 {
3696 if (b.sym)
3697 {
3698 Dsymbol s = search_function(b.sym, funcdecl.ident);
3699 if (s)
3700 {
3701 FuncDeclaration f2 = s.isFuncDeclaration();
3702 if (f2)
3703 {
3704 f2 = f2.overloadExactMatch(funcdecl.type);
3705 if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
3706 funcdecl.error("cannot override `final` function `%s.%s`", b.sym.toChars(), f2.toPrettyChars());
3707 }
3708 }
3709 }
3710 }
3711
3712 if (funcdecl.isOverride)
3713 {
3714 if (funcdecl.storage_class & STC.disable)
3715 deprecation(funcdecl.loc,
3716 "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
3717 funcdecl.toPrettyChars);
3718 if (funcdecl.isDeprecated)
3719 deprecation(funcdecl.loc,
3720 "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
3721 funcdecl.toPrettyChars);
3722 }
3723
3724 }
3725 else if (funcdecl.isOverride() && !parent.isTemplateInstance())
3726 funcdecl.error("`override` only applies to class member functions");
3727
3728 if (auto ti = parent.isTemplateInstance)
3729 {
3730 objc.setSelector(funcdecl, sc);
3731 objc.setAsOptional(funcdecl, sc);
3732 }
3733
3734 objc.validateSelector(funcdecl);
3735 objc.validateOptional(funcdecl);
3736 // Reflect this.type to f because it could be changed by findVtblIndex
3737 f = funcdecl.type.toTypeFunction();
3738
3739 Ldone:
3740 if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
3741 funcdecl.error("`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract");
3742
3743 /* Do not allow template instances to add virtual functions
3744 * to a class.
3745 */
3746 if (funcdecl.isVirtual())
3747 {
3748 TemplateInstance ti = parent.isTemplateInstance();
3749 if (ti)
3750 {
3751 // Take care of nested templates
3752 while (1)
3753 {
3754 TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
3755 if (!ti2)
3756 break;
3757 ti = ti2;
3758 }
3759
3760 // If it's a member template
3761 ClassDeclaration cd = ti.tempdecl.isClassMember();
3762 if (cd)
3763 {
3764 funcdecl.error("cannot use template to add virtual function to class `%s`", cd.toChars());
3765 }
3766 }
3767 }
3768
3769 if (funcdecl.isMain())
3770 funcdecl.checkDmain(); // Check main() parameters and return type
3771
3772 /* Purity and safety can be inferred for some functions by examining
3773 * the function body.
3774 */
3775 if (funcdecl.canInferAttributes(sc))
3776 funcdecl.initInferAttributes();
3777
3778 Module.dprogress++;
3779 funcdecl.semanticRun = PASS.semanticdone;
3780
3781 /* Save scope for possible later use (if we need the
3782 * function internals)
3783 */
3784 funcdecl._scope = sc.copy();
3785 funcdecl._scope.setNoFree();
3786
3787 __gshared bool printedMain = false; // semantic might run more than once
3788 if (global.params.verbose && !printedMain)
3789 {
3790 const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
3791 Module mod = sc._module;
3792
3793 if (type && mod)
3794 {
3795 printedMain = true;
3796 auto name = mod.srcfile.toChars();
3797 auto path = FileName.searchPath(global.path, name, true);
3798 message("entry %-10s\t%s", type, path ? path : name);
3799 }
3800 }
3801
3802 if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
3803 {
3804 // check if `_d_cmain` is defined
3805 bool cmainTemplateExists()
3806 {
3807 auto rootSymbol = sc.search(funcdecl.loc, Id.empty, null);
3808 if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
3809 if (moduleSymbol.search(funcdecl.loc, Id.CMain))
3810 return true;
3811
3812 return false;
3813 }
3814
3815 // Only mixin `_d_cmain` if it is defined
3816 if (cmainTemplateExists())
3817 {
3818 // add `mixin _d_cmain!();` to the declaring module
3819 auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
3820 auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
3821 sc._module.members.push(tm);
3822 }
3823 }
3824
3825 assert(funcdecl.type.ty != Terror || funcdecl.errors);
3826
3827 // semantic for parameters' UDAs
3828 foreach (i, param; f.parameterList)
3829 {
3830 if (param && param.userAttribDecl)
3831 param.userAttribDecl.dsymbolSemantic(sc);
3832 }
3833 }
3834
3835 /// Do the semantic analysis on the external interface to the function.
visit(FuncDeclaration funcdecl)3836 override void visit(FuncDeclaration funcdecl)
3837 {
3838 funcDeclarationSemantic(funcdecl);
3839 }
3840
visit(CtorDeclaration ctd)3841 override void visit(CtorDeclaration ctd)
3842 {
3843 //printf("CtorDeclaration::semantic() %s\n", toChars());
3844 if (ctd.semanticRun >= PASS.semanticdone)
3845 return;
3846 if (ctd._scope)
3847 {
3848 sc = ctd._scope;
3849 ctd._scope = null;
3850 }
3851
3852 ctd.parent = sc.parent;
3853 Dsymbol p = ctd.toParentDecl();
3854 AggregateDeclaration ad = p.isAggregateDeclaration();
3855 if (!ad)
3856 {
3857 error(ctd.loc, "constructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
3858 ctd.type = Type.terror;
3859 ctd.errors = true;
3860 return;
3861 }
3862
3863 sc = sc.push();
3864
3865 if (sc.stc & STC.static_)
3866 {
3867 if (sc.stc & STC.shared_)
3868 error(ctd.loc, "`shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`");
3869 else
3870 error(ctd.loc, "`static` has no effect on a constructor inside a `static` block. Use `static this()`");
3871 }
3872
3873 sc.stc &= ~STC.static_; // not a static constructor
3874
3875 funcDeclarationSemantic(ctd);
3876
3877 sc.pop();
3878
3879 if (ctd.errors)
3880 return;
3881
3882 TypeFunction tf = ctd.type.toTypeFunction();
3883
3884 /* See if it's the default constructor
3885 * But, template constructor should not become a default constructor.
3886 */
3887 if (ad && (!ctd.parent.isTemplateInstance() || ctd.parent.isTemplateMixin()))
3888 {
3889 immutable dim = tf.parameterList.length;
3890
3891 if (auto sd = ad.isStructDeclaration())
3892 {
3893 if (dim == 0 && tf.parameterList.varargs == VarArg.none) // empty default ctor w/o any varargs
3894 {
3895 if (ctd.fbody || !(ctd.storage_class & STC.disable))
3896 {
3897 ctd.error("default constructor for structs only allowed " ~
3898 "with `@disable`, no body, and no parameters");
3899 ctd.storage_class |= STC.disable;
3900 ctd.fbody = null;
3901 }
3902 sd.noDefaultCtor = true;
3903 }
3904 else if (dim == 0 && tf.parameterList.varargs != VarArg.none) // allow varargs only ctor
3905 {
3906 }
3907 else if (dim && tf.parameterList[0].defaultArg)
3908 {
3909 // if the first parameter has a default argument, then the rest does as well
3910 if (ctd.storage_class & STC.disable)
3911 {
3912 ctd.error("is marked `@disable`, so it cannot have default "~
3913 "arguments for all parameters.");
3914 errorSupplemental(ctd.loc, "Use `@disable this();` if you want to disable default initialization.");
3915 }
3916 else
3917 ctd.error("all parameters have default arguments, "~
3918 "but structs cannot have default constructors.");
3919 }
3920 else if ((dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
3921 {
3922 //printf("tf: %s\n", tf.toChars());
3923 auto param = tf.parameterList[0];
3924 if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
3925 {
3926 //printf("copy constructor\n");
3927 ctd.isCpCtor = true;
3928 }
3929 }
3930 }
3931 else if (dim == 0 && tf.parameterList.varargs == VarArg.none)
3932 {
3933 ad.defaultCtor = ctd;
3934 }
3935 }
3936 }
3937
visit(PostBlitDeclaration pbd)3938 override void visit(PostBlitDeclaration pbd)
3939 {
3940 //printf("PostBlitDeclaration::semantic() %s\n", toChars());
3941 //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
3942 //printf("stc = x%llx\n", sc.stc);
3943 if (pbd.semanticRun >= PASS.semanticdone)
3944 return;
3945 if (pbd._scope)
3946 {
3947 sc = pbd._scope;
3948 pbd._scope = null;
3949 }
3950
3951 pbd.parent = sc.parent;
3952 Dsymbol p = pbd.toParent2();
3953 StructDeclaration ad = p.isStructDeclaration();
3954 if (!ad)
3955 {
3956 error(pbd.loc, "postblit can only be a member of struct, not %s `%s`", p.kind(), p.toChars());
3957 pbd.type = Type.terror;
3958 pbd.errors = true;
3959 return;
3960 }
3961 if (pbd.ident == Id.postblit && pbd.semanticRun < PASS.semantic)
3962 ad.postblits.push(pbd);
3963 if (!pbd.type)
3964 pbd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, pbd.storage_class);
3965
3966 sc = sc.push();
3967 sc.stc &= ~STC.static_; // not static
3968 sc.linkage = LINK.d;
3969
3970 funcDeclarationSemantic(pbd);
3971
3972 sc.pop();
3973 }
3974
visit(DtorDeclaration dd)3975 override void visit(DtorDeclaration dd)
3976 {
3977 //printf("DtorDeclaration::semantic() %s\n", toChars());
3978 //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
3979 if (dd.semanticRun >= PASS.semanticdone)
3980 return;
3981 if (dd._scope)
3982 {
3983 sc = dd._scope;
3984 dd._scope = null;
3985 }
3986
3987 dd.parent = sc.parent;
3988 Dsymbol p = dd.toParent2();
3989 AggregateDeclaration ad = p.isAggregateDeclaration();
3990 if (!ad)
3991 {
3992 error(dd.loc, "destructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
3993 dd.type = Type.terror;
3994 dd.errors = true;
3995 return;
3996 }
3997 if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)
3998 ad.dtors.push(dd);
3999 if (!dd.type)
4000 {
4001 dd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, dd.storage_class);
4002 if (ad.classKind == ClassKind.cpp && dd.ident == Id.dtor)
4003 {
4004 if (auto cldec = ad.isClassDeclaration())
4005 {
4006 assert (cldec.cppDtorVtblIndex == -1); // double-call check already by dd.type
4007 if (cldec.baseClass && cldec.baseClass.cppDtorVtblIndex != -1)
4008 {
4009 // override the base virtual
4010 cldec.cppDtorVtblIndex = cldec.baseClass.cppDtorVtblIndex;
4011 }
4012 else if (!dd.isFinal())
4013 {
4014 // reserve the dtor slot for the destructor (which we'll create later)
4015 cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.dim;
4016 cldec.vtbl.push(dd);
4017 if (target.cpp.twoDtorInVtable)
4018 cldec.vtbl.push(dd); // deleting destructor uses a second slot
4019 }
4020 }
4021 }
4022 }
4023
4024 sc = sc.push();
4025 sc.stc &= ~STC.static_; // not a static destructor
4026 if (sc.linkage != LINK.cpp)
4027 sc.linkage = LINK.d;
4028
4029 funcDeclarationSemantic(dd);
4030
4031 sc.pop();
4032 }
4033
visit(StaticCtorDeclaration scd)4034 override void visit(StaticCtorDeclaration scd)
4035 {
4036 //printf("StaticCtorDeclaration::semantic()\n");
4037 if (scd.semanticRun >= PASS.semanticdone)
4038 return;
4039 if (scd._scope)
4040 {
4041 sc = scd._scope;
4042 scd._scope = null;
4043 }
4044
4045 scd.parent = sc.parent;
4046 Dsymbol p = scd.parent.pastMixin();
4047 if (!p.isScopeDsymbol())
4048 {
4049 const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4050 error(scd.loc, "`%sstatic` constructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4051 scd.type = Type.terror;
4052 scd.errors = true;
4053 return;
4054 }
4055 if (!scd.type)
4056 scd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, scd.storage_class);
4057
4058 /* If the static ctor appears within a template instantiation,
4059 * it could get called multiple times by the module constructors
4060 * for different modules. Thus, protect it with a gate.
4061 */
4062 if (scd.isInstantiated() && scd.semanticRun < PASS.semantic)
4063 {
4064 /* Add this prefix to the function:
4065 * static int gate;
4066 * if (++gate != 1) return;
4067 * Note that this is not thread safe; should not have threads
4068 * during static construction.
4069 */
4070 auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4071 v.storage_class = STC.temp | (scd.isSharedStaticCtorDeclaration() ? STC.static_ : STC.tls);
4072
4073 auto sa = new Statements();
4074 Statement s = new ExpStatement(Loc.initial, v);
4075 sa.push(s);
4076
4077 Expression e = new IdentifierExp(Loc.initial, v.ident);
4078 e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!1);
4079 e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!1);
4080 s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4081
4082 sa.push(s);
4083 if (scd.fbody)
4084 sa.push(scd.fbody);
4085
4086 scd.fbody = new CompoundStatement(Loc.initial, sa);
4087 }
4088
4089 const LINK save = sc.linkage;
4090 if (save != LINK.d)
4091 {
4092 const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4093 deprecation(scd.loc, "`%sstatic` constructor can only be of D linkage", s);
4094 // Just correct it
4095 sc.linkage = LINK.d;
4096 }
4097 funcDeclarationSemantic(scd);
4098 sc.linkage = save;
4099
4100 // We're going to need ModuleInfo
4101 Module m = scd.getModule();
4102 if (!m)
4103 m = sc._module;
4104 if (m)
4105 {
4106 m.needmoduleinfo = 1;
4107 //printf("module1 %s needs moduleinfo\n", m.toChars());
4108 }
4109 }
4110
visit(StaticDtorDeclaration sdd)4111 override void visit(StaticDtorDeclaration sdd)
4112 {
4113 if (sdd.semanticRun >= PASS.semanticdone)
4114 return;
4115 if (sdd._scope)
4116 {
4117 sc = sdd._scope;
4118 sdd._scope = null;
4119 }
4120
4121 sdd.parent = sc.parent;
4122 Dsymbol p = sdd.parent.pastMixin();
4123 if (!p.isScopeDsymbol())
4124 {
4125 const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4126 error(sdd.loc, "`%sstatic` destructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4127 sdd.type = Type.terror;
4128 sdd.errors = true;
4129 return;
4130 }
4131 if (!sdd.type)
4132 sdd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, sdd.storage_class);
4133
4134 /* If the static ctor appears within a template instantiation,
4135 * it could get called multiple times by the module constructors
4136 * for different modules. Thus, protect it with a gate.
4137 */
4138 if (sdd.isInstantiated() && sdd.semanticRun < PASS.semantic)
4139 {
4140 /* Add this prefix to the function:
4141 * static int gate;
4142 * if (--gate != 0) return;
4143 * Increment gate during constructor execution.
4144 * Note that this is not thread safe; should not have threads
4145 * during static destruction.
4146 */
4147 auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4148 v.storage_class = STC.temp | (sdd.isSharedStaticDtorDeclaration() ? STC.static_ : STC.tls);
4149
4150 auto sa = new Statements();
4151 Statement s = new ExpStatement(Loc.initial, v);
4152 sa.push(s);
4153
4154 Expression e = new IdentifierExp(Loc.initial, v.ident);
4155 e = new AddAssignExp(Loc.initial, e, IntegerExp.literal!(-1));
4156 e = new EqualExp(TOK.notEqual, Loc.initial, e, IntegerExp.literal!0);
4157 s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4158
4159 sa.push(s);
4160 if (sdd.fbody)
4161 sa.push(sdd.fbody);
4162
4163 sdd.fbody = new CompoundStatement(Loc.initial, sa);
4164
4165 sdd.vgate = v;
4166 }
4167
4168 const LINK save = sc.linkage;
4169 if (save != LINK.d)
4170 {
4171 const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4172 deprecation(sdd.loc, "`%sstatic` destructor can only be of D linkage", s);
4173 // Just correct it
4174 sc.linkage = LINK.d;
4175 }
4176 funcDeclarationSemantic(sdd);
4177 sc.linkage = save;
4178
4179 // We're going to need ModuleInfo
4180 Module m = sdd.getModule();
4181 if (!m)
4182 m = sc._module;
4183 if (m)
4184 {
4185 m.needmoduleinfo = 1;
4186 //printf("module2 %s needs moduleinfo\n", m.toChars());
4187 }
4188 }
4189
visit(InvariantDeclaration invd)4190 override void visit(InvariantDeclaration invd)
4191 {
4192 if (invd.semanticRun >= PASS.semanticdone)
4193 return;
4194 if (invd._scope)
4195 {
4196 sc = invd._scope;
4197 invd._scope = null;
4198 }
4199
4200 invd.parent = sc.parent;
4201 Dsymbol p = invd.parent.pastMixin();
4202 AggregateDeclaration ad = p.isAggregateDeclaration();
4203 if (!ad)
4204 {
4205 error(invd.loc, "`invariant` can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4206 invd.type = Type.terror;
4207 invd.errors = true;
4208 return;
4209 }
4210 if (invd.ident != Id.classInvariant &&
4211 invd.semanticRun < PASS.semantic &&
4212 !ad.isUnionDeclaration() // users are on their own with union fields
4213 )
4214 ad.invs.push(invd);
4215 if (!invd.type)
4216 invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class);
4217
4218 sc = sc.push();
4219 sc.stc &= ~STC.static_; // not a static invariant
4220 sc.stc |= STC.const_; // invariant() is always const
4221 sc.flags = (sc.flags & ~SCOPE.contract) | SCOPE.invariant_;
4222 sc.linkage = LINK.d;
4223
4224 funcDeclarationSemantic(invd);
4225
4226 sc.pop();
4227 }
4228
visit(UnitTestDeclaration utd)4229 override void visit(UnitTestDeclaration utd)
4230 {
4231 if (utd.semanticRun >= PASS.semanticdone)
4232 return;
4233 if (utd._scope)
4234 {
4235 sc = utd._scope;
4236 utd._scope = null;
4237 }
4238
4239 utd.visibility = sc.visibility;
4240
4241 utd.parent = sc.parent;
4242 Dsymbol p = utd.parent.pastMixin();
4243 if (!p.isScopeDsymbol())
4244 {
4245 error(utd.loc, "`unittest` can only be a member of module/aggregate/template, not %s `%s`", p.kind(), p.toChars());
4246 utd.type = Type.terror;
4247 utd.errors = true;
4248 return;
4249 }
4250
4251 if (global.params.useUnitTests)
4252 {
4253 if (!utd.type)
4254 utd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, utd.storage_class);
4255 Scope* sc2 = sc.push();
4256 sc2.linkage = LINK.d;
4257 funcDeclarationSemantic(utd);
4258 sc2.pop();
4259 }
4260
4261 version (none)
4262 {
4263 // We're going to need ModuleInfo even if the unit tests are not
4264 // compiled in, because other modules may import this module and refer
4265 // to this ModuleInfo.
4266 // (This doesn't make sense to me?)
4267 Module m = utd.getModule();
4268 if (!m)
4269 m = sc._module;
4270 if (m)
4271 {
4272 //printf("module3 %s needs moduleinfo\n", m.toChars());
4273 m.needmoduleinfo = 1;
4274 }
4275 }
4276 }
4277
visit(NewDeclaration nd)4278 override void visit(NewDeclaration nd)
4279 {
4280 //printf("NewDeclaration::semantic()\n");
4281 if (nd.semanticRun >= PASS.semanticdone)
4282 return;
4283 if (!nd.type)
4284 nd.type = new TypeFunction(ParameterList(), Type.tvoid.pointerTo(), LINK.d, nd.storage_class);
4285
4286 funcDeclarationSemantic(nd);
4287 }
4288
visit(StructDeclaration sd)4289 override void visit(StructDeclaration sd)
4290 {
4291 //printf("StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4292
4293 //static int count; if (++count == 20) assert(0);
4294
4295 if (sd.semanticRun >= PASS.semanticdone)
4296 return;
4297 int errors = global.errors;
4298
4299 //printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", this, sd.toPrettyChars(), sd.sizeok);
4300 Scope* scx = null;
4301 if (sd._scope)
4302 {
4303 sc = sd._scope;
4304 scx = sd._scope; // save so we don't make redundant copies
4305 sd._scope = null;
4306 }
4307
4308 if (!sd.parent)
4309 {
4310 assert(sc.parent && sc.func);
4311 sd.parent = sc.parent;
4312 }
4313 assert(sd.parent && !sd.isAnonymous());
4314
4315 if (sd.errors)
4316 sd.type = Type.terror;
4317 if (sd.semanticRun == PASS.init)
4318 sd.type = sd.type.addSTC(sc.stc | sd.storage_class);
4319 sd.type = sd.type.typeSemantic(sd.loc, sc);
4320 if (auto ts = sd.type.isTypeStruct())
4321 if (ts.sym != sd)
4322 {
4323 auto ti = ts.sym.isInstantiated();
4324 if (ti && isError(ti))
4325 ts.sym = sd;
4326 }
4327
4328 // Ungag errors when not speculative
4329 Ungag ungag = sd.ungagSpeculative();
4330
4331 if (sd.semanticRun == PASS.init)
4332 {
4333 sd.visibility = sc.visibility;
4334
4335 sd.alignment = sc.alignment();
4336
4337 sd.storage_class |= sc.stc;
4338 if (sd.storage_class & STC.abstract_)
4339 sd.error("structs, unions cannot be `abstract`");
4340
4341 sd.userAttribDecl = sc.userAttribDecl;
4342
4343 if (sc.linkage == LINK.cpp)
4344 sd.classKind = ClassKind.cpp;
4345 else if (sc.linkage == LINK.c)
4346 sd.classKind = ClassKind.c;
4347 sd.cppnamespace = sc.namespace;
4348 sd.cppmangle = sc.cppmangle;
4349 }
4350 else if (sd.symtab && !scx)
4351 return;
4352
4353 sd.semanticRun = PASS.semantic;
4354 UserAttributeDeclaration.checkGNUABITag(sd, sc.linkage);
4355
4356 if (!sd.members) // if opaque declaration
4357 {
4358 sd.semanticRun = PASS.semanticdone;
4359 return;
4360 }
4361 if (!sd.symtab)
4362 {
4363 sd.symtab = new DsymbolTable();
4364
4365 sd.members.foreachDsymbol( s => s.addMember(sc, sd) );
4366 }
4367
4368 auto sc2 = sd.newScope(sc);
4369
4370 /* Set scope so if there are forward references, we still might be able to
4371 * resolve individual members like enums.
4372 */
4373 sd.members.foreachDsymbol( s => s.setScope(sc2) );
4374 sd.members.foreachDsymbol( s => s.importAll(sc2) );
4375 sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); sd.errors |= s.errors; } );
4376
4377 if (sd.errors)
4378 sd.type = Type.terror;
4379
4380 if (!sd.determineFields())
4381 {
4382 if (sd.type.ty != Terror)
4383 {
4384 sd.error(sd.loc, "circular or forward reference");
4385 sd.errors = true;
4386 sd.type = Type.terror;
4387 }
4388
4389 sc2.pop();
4390 sd.semanticRun = PASS.semanticdone;
4391 return;
4392 }
4393 /* Following special member functions creation needs semantic analysis
4394 * completion of sub-structs in each field types. For example, buildDtor
4395 * needs to check existence of elaborate dtor in type of each fields.
4396 * See the case in compilable/test14838.d
4397 */
4398 foreach (v; sd.fields)
4399 {
4400 Type tb = v.type.baseElemOf();
4401 if (tb.ty != Tstruct)
4402 continue;
4403 auto sdec = (cast(TypeStruct)tb).sym;
4404 if (sdec.semanticRun >= PASS.semanticdone)
4405 continue;
4406
4407 sc2.pop();
4408
4409 //printf("\tdeferring %s\n", toChars());
4410 return deferDsymbolSemantic(sd, scx);
4411 }
4412
4413 /* Look for special member functions.
4414 */
4415 sd.disableNew = sd.search(Loc.initial, Id.classNew) !is null;
4416
4417 // Look for the constructor
4418 sd.ctor = sd.searchCtor();
4419
4420 sd.dtor = buildDtor(sd, sc2);
4421 sd.tidtor = buildExternDDtor(sd, sc2);
4422 sd.hasCopyCtor = buildCopyCtor(sd, sc2);
4423 sd.postblit = buildPostBlit(sd, sc2);
4424
4425 buildOpAssign(sd, sc2);
4426 buildOpEquals(sd, sc2);
4427
4428 if (global.params.useTypeInfo && Type.dtypeinfo) // these functions are used for TypeInfo
4429 {
4430 sd.xeq = buildXopEquals(sd, sc2);
4431 sd.xcmp = buildXopCmp(sd, sc2);
4432 sd.xhash = buildXtoHash(sd, sc2);
4433 }
4434
4435 sd.inv = buildInv(sd, sc2);
4436
4437 Module.dprogress++;
4438 sd.semanticRun = PASS.semanticdone;
4439 //printf("-StructDeclaration::semantic(this=%p, '%s')\n", sd, sd.toChars());
4440
4441 sc2.pop();
4442
4443 if (sd.ctor)
4444 {
4445 Dsymbol scall = sd.search(Loc.initial, Id.call);
4446 if (scall)
4447 {
4448 uint xerrors = global.startGagging();
4449 sc = sc.push();
4450 sc.tinst = null;
4451 sc.minst = null;
4452 auto fcall = resolveFuncCall(sd.loc, sc, scall, null, null, null, FuncResolveFlag.quiet);
4453 sc = sc.pop();
4454 global.endGagging(xerrors);
4455
4456 if (fcall && fcall.isStatic())
4457 {
4458 sd.error(fcall.loc, "`static opCall` is hidden by constructors and can never be called");
4459 errorSupplemental(fcall.loc, "Please use a factory method instead, or replace all constructors with `static opCall`.");
4460 }
4461 }
4462 }
4463
4464 if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd)
4465 {
4466 // https://issues.dlang.org/show_bug.cgi?id=19024
4467 StructDeclaration sym = (cast(TypeStruct)sd.type).sym;
4468 version (none)
4469 {
4470 printf("this = %p %s\n", sd, sd.toChars());
4471 printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars());
4472 }
4473 sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars());
4474 }
4475
4476 if (global.errors != errors)
4477 {
4478 // The type is no good.
4479 sd.type = Type.terror;
4480 sd.errors = true;
4481 if (sd.deferred)
4482 sd.deferred.errors = true;
4483 }
4484
4485 if (sd.deferred && !global.gag)
4486 {
4487 sd.deferred.semantic2(sc);
4488 sd.deferred.semantic3(sc);
4489 }
4490 }
4491
interfaceSemantic(ClassDeclaration cd)4492 void interfaceSemantic(ClassDeclaration cd)
4493 {
4494 cd.vtblInterfaces = new BaseClasses();
4495 cd.vtblInterfaces.reserve(cd.interfaces.length);
4496 foreach (b; cd.interfaces)
4497 {
4498 cd.vtblInterfaces.push(b);
4499 b.copyBaseInterfaces(cd.vtblInterfaces);
4500 }
4501 }
4502
visit(ClassDeclaration cldec)4503 override void visit(ClassDeclaration cldec)
4504 {
4505 //printf("ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", cldec.toChars(), cldec.type, cldec.sizeok, this);
4506 //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : "");
4507 //printf("sc.stc = %x\n", sc.stc);
4508
4509 //{ static int n; if (++n == 20) *(char*)0=0; }
4510
4511 if (cldec.semanticRun >= PASS.semanticdone)
4512 return;
4513 int errors = global.errors;
4514
4515 //printf("+ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
4516
4517 Scope* scx = null;
4518 if (cldec._scope)
4519 {
4520 sc = cldec._scope;
4521 scx = cldec._scope; // save so we don't make redundant copies
4522 cldec._scope = null;
4523 }
4524
4525 if (!cldec.parent)
4526 {
4527 assert(sc.parent);
4528 cldec.parent = sc.parent;
4529 }
4530
4531 if (cldec.errors)
4532 cldec.type = Type.terror;
4533 cldec.type = cldec.type.typeSemantic(cldec.loc, sc);
4534 if (auto tc = cldec.type.isTypeClass())
4535 if (tc.sym != cldec)
4536 {
4537 auto ti = tc.sym.isInstantiated();
4538 if (ti && isError(ti))
4539 tc.sym = cldec;
4540 }
4541
4542 // Ungag errors when not speculative
4543 Ungag ungag = cldec.ungagSpeculative();
4544
4545 if (cldec.semanticRun == PASS.init)
4546 {
4547 cldec.visibility = sc.visibility;
4548
4549 cldec.storage_class |= sc.stc;
4550 if (cldec.storage_class & STC.auto_)
4551 cldec.error("storage class `auto` is invalid when declaring a class, did you mean to use `scope`?");
4552 if (cldec.storage_class & STC.scope_)
4553 cldec.stack = true;
4554 if (cldec.storage_class & STC.abstract_)
4555 cldec.isabstract = ThreeState.yes;
4556
4557 cldec.userAttribDecl = sc.userAttribDecl;
4558
4559 if (sc.linkage == LINK.cpp)
4560 cldec.classKind = ClassKind.cpp;
4561 cldec.cppnamespace = sc.namespace;
4562 cldec.cppmangle = sc.cppmangle;
4563 if (sc.linkage == LINK.objc)
4564 objc.setObjc(cldec);
4565 }
4566 else if (cldec.symtab && !scx)
4567 {
4568 return;
4569 }
4570 cldec.semanticRun = PASS.semantic;
4571 UserAttributeDeclaration.checkGNUABITag(cldec, sc.linkage);
4572
4573 if (cldec.baseok < Baseok.done)
4574 {
4575 /* https://issues.dlang.org/show_bug.cgi?id=12078
4576 * https://issues.dlang.org/show_bug.cgi?id=12143
4577 * https://issues.dlang.org/show_bug.cgi?id=15733
4578 * While resolving base classes and interfaces, a base may refer
4579 * the member of this derived class. In that time, if all bases of
4580 * this class can be determined, we can go forward the semantc process
4581 * beyond the Lancestorsdone. To do the recursive semantic analysis,
4582 * temporarily set and unset `_scope` around exp().
4583 */
4584 T resolveBase(T)(lazy T exp)
4585 {
4586 if (!scx)
4587 {
4588 scx = sc.copy();
4589 scx.setNoFree();
4590 }
4591 static if (!is(T == void))
4592 {
4593 cldec._scope = scx;
4594 auto r = exp();
4595 cldec._scope = null;
4596 return r;
4597 }
4598 else
4599 {
4600 cldec._scope = scx;
4601 exp();
4602 cldec._scope = null;
4603 }
4604 }
4605
4606 cldec.baseok = Baseok.start;
4607
4608 // Expand any tuples in baseclasses[]
4609 for (size_t i = 0; i < cldec.baseclasses.dim;)
4610 {
4611 auto b = (*cldec.baseclasses)[i];
4612 b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));
4613
4614 Type tb = b.type.toBasetype();
4615 if (auto tup = tb.isTypeTuple())
4616 {
4617 cldec.baseclasses.remove(i);
4618 size_t dim = Parameter.dim(tup.arguments);
4619 for (size_t j = 0; j < dim; j++)
4620 {
4621 Parameter arg = Parameter.getNth(tup.arguments, j);
4622 b = new BaseClass(arg.type);
4623 cldec.baseclasses.insert(i + j, b);
4624 }
4625 }
4626 else
4627 i++;
4628 }
4629
4630 if (cldec.baseok >= Baseok.done)
4631 {
4632 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
4633 if (cldec.semanticRun >= PASS.semanticdone)
4634 return;
4635 goto Lancestorsdone;
4636 }
4637
4638 // See if there's a base class as first in baseclasses[]
4639 if (cldec.baseclasses.dim)
4640 {
4641 BaseClass* b = (*cldec.baseclasses)[0];
4642 Type tb = b.type.toBasetype();
4643 TypeClass tc = tb.isTypeClass();
4644 if (!tc)
4645 {
4646 if (b.type != Type.terror)
4647 cldec.error("base type must be `class` or `interface`, not `%s`", b.type.toChars());
4648 cldec.baseclasses.remove(0);
4649 goto L7;
4650 }
4651 if (tc.sym.isDeprecated())
4652 {
4653 if (!cldec.isDeprecated())
4654 {
4655 // Deriving from deprecated class makes this one deprecated too
4656 cldec.setDeprecated();
4657 tc.checkDeprecated(cldec.loc, sc);
4658 }
4659 }
4660 if (tc.sym.isInterfaceDeclaration())
4661 goto L7;
4662
4663 for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass)
4664 {
4665 if (cdb == cldec)
4666 {
4667 cldec.error("circular inheritance");
4668 cldec.baseclasses.remove(0);
4669 goto L7;
4670 }
4671 }
4672
4673 /* https://issues.dlang.org/show_bug.cgi?id=11034
4674 * Class inheritance hierarchy
4675 * and instance size of each classes are orthogonal information.
4676 * Therefore, even if tc.sym.sizeof == Sizeok.none,
4677 * we need to set baseClass field for class covariance check.
4678 */
4679 cldec.baseClass = tc.sym;
4680 b.sym = cldec.baseClass;
4681
4682 if (tc.sym.baseok < Baseok.done)
4683 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
4684 if (tc.sym.baseok < Baseok.done)
4685 {
4686 //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars());
4687 if (tc.sym._scope)
4688 Module.addDeferredSemantic(tc.sym);
4689 cldec.baseok = Baseok.none;
4690 }
4691 L7:
4692 }
4693
4694 // Treat the remaining entries in baseclasses as interfaces
4695 // Check for errors, handle forward references
4696 int multiClassError = cldec.baseClass is null ? 0 : 1;
4697
4698 BCLoop:
4699 for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.dim;)
4700 {
4701 BaseClass* b = (*cldec.baseclasses)[i];
4702 Type tb = b.type.toBasetype();
4703 TypeClass tc = tb.isTypeClass();
4704 if (!tc || !tc.sym.isInterfaceDeclaration())
4705 {
4706 // It's a class
4707 if (tc)
4708 {
4709 if (multiClassError == 0)
4710 {
4711 error(cldec.loc,"`%s`: base class must be specified first, " ~
4712 "before any interfaces.", cldec.toPrettyChars());
4713 multiClassError += 1;
4714 }
4715 else if (multiClassError >= 1)
4716 {
4717 if(multiClassError == 1)
4718 error(cldec.loc,"`%s`: multiple class inheritance is not supported." ~
4719 " Use multiple interface inheritance and/or composition.", cldec.toPrettyChars());
4720 multiClassError += 1;
4721
4722 if (tc.sym.fields.dim)
4723 errorSupplemental(cldec.loc,"`%s` has fields, consider making it a member of `%s`",
4724 b.type.toChars(), cldec.type.toChars());
4725 else
4726 errorSupplemental(cldec.loc,"`%s` has no fields, consider making it an `interface`",
4727 b.type.toChars());
4728 }
4729 }
4730 // It's something else: e.g. `int` in `class Foo : Bar, int { ... }`
4731 else if (b.type != Type.terror)
4732 {
4733 error(cldec.loc,"`%s`: base type must be `interface`, not `%s`",
4734 cldec.toPrettyChars(), b.type.toChars());
4735 }
4736 cldec.baseclasses.remove(i);
4737 continue;
4738 }
4739
4740 // Check for duplicate interfaces
4741 for (size_t j = (cldec.baseClass ? 1 : 0); j < i; j++)
4742 {
4743 BaseClass* b2 = (*cldec.baseclasses)[j];
4744 if (b2.sym == tc.sym)
4745 {
4746 cldec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
4747 cldec.baseclasses.remove(i);
4748 continue BCLoop;
4749 }
4750 }
4751 if (tc.sym.isDeprecated())
4752 {
4753 if (!cldec.isDeprecated())
4754 {
4755 // Deriving from deprecated class makes this one deprecated too
4756 cldec.setDeprecated();
4757 tc.checkDeprecated(cldec.loc, sc);
4758 }
4759 }
4760
4761 b.sym = tc.sym;
4762
4763 if (tc.sym.baseok < Baseok.done)
4764 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
4765 if (tc.sym.baseok < Baseok.done)
4766 {
4767 //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
4768 if (tc.sym._scope)
4769 Module.addDeferredSemantic(tc.sym);
4770 cldec.baseok = Baseok.none;
4771 }
4772 i++;
4773 }
4774 if (cldec.baseok == Baseok.none)
4775 {
4776 // Forward referencee of one or more bases, try again later
4777 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
4778 return deferDsymbolSemantic(cldec, scx);
4779 }
4780 cldec.baseok = Baseok.done;
4781
4782 if (cldec.classKind == ClassKind.objc || (cldec.baseClass && cldec.baseClass.classKind == ClassKind.objc))
4783 cldec.classKind = ClassKind.objc; // Objective-C classes do not inherit from Object
4784
4785 // If no base class, and this is not an Object, use Object as base class
4786 if (!cldec.baseClass && cldec.ident != Id.Object && cldec.object && cldec.classKind == ClassKind.d)
4787 {
4788 void badObjectDotD()
4789 {
4790 cldec.error("missing or corrupt object.d");
4791 fatal();
4792 }
4793
4794 if (!cldec.object || cldec.object.errors)
4795 badObjectDotD();
4796
4797 Type t = cldec.object.type;
4798 t = t.typeSemantic(cldec.loc, sc).toBasetype();
4799 if (t.ty == Terror)
4800 badObjectDotD();
4801 TypeClass tc = t.isTypeClass();
4802 assert(tc);
4803
4804 auto b = new BaseClass(tc);
4805 cldec.baseclasses.shift(b);
4806
4807 cldec.baseClass = tc.sym;
4808 assert(!cldec.baseClass.isInterfaceDeclaration());
4809 b.sym = cldec.baseClass;
4810 }
4811 if (cldec.baseClass)
4812 {
4813 if (cldec.baseClass.storage_class & STC.final_)
4814 cldec.error("cannot inherit from class `%s` because it is `final`", cldec.baseClass.toChars());
4815
4816 // Inherit properties from base class
4817 if (cldec.baseClass.isCOMclass())
4818 cldec.com = true;
4819 if (cldec.baseClass.isCPPclass())
4820 cldec.classKind = ClassKind.cpp;
4821 if (cldec.baseClass.stack)
4822 cldec.stack = true;
4823 cldec.enclosing = cldec.baseClass.enclosing;
4824 cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;
4825 }
4826
4827 cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.dim];
4828 foreach (b; cldec.interfaces)
4829 {
4830 // If this is an interface, and it derives from a COM interface,
4831 // then this is a COM interface too.
4832 if (b.sym.isCOMinterface())
4833 cldec.com = true;
4834 if (cldec.classKind == ClassKind.cpp && !b.sym.isCPPinterface())
4835 {
4836 error(cldec.loc, "C++ class `%s` cannot implement D interface `%s`",
4837 cldec.toPrettyChars(), b.sym.toPrettyChars());
4838 }
4839 }
4840 interfaceSemantic(cldec);
4841 }
4842 Lancestorsdone:
4843 //printf("\tClassDeclaration.dsymbolSemantic(%s) baseok = %d\n", toChars(), baseok);
4844
4845 if (!cldec.members) // if opaque declaration
4846 {
4847 cldec.semanticRun = PASS.semanticdone;
4848 return;
4849 }
4850 if (!cldec.symtab)
4851 {
4852 cldec.symtab = new DsymbolTable();
4853
4854 /* https://issues.dlang.org/show_bug.cgi?id=12152
4855 * The semantic analysis of base classes should be finished
4856 * before the members semantic analysis of this class, in order to determine
4857 * vtbl in this class. However if a base class refers the member of this class,
4858 * it can be resolved as a normal forward reference.
4859 * Call addMember() and setScope() to make this class members visible from the base classes.
4860 */
4861 cldec.members.foreachDsymbol( s => s.addMember(sc, cldec) );
4862
4863 auto sc2 = cldec.newScope(sc);
4864
4865 /* Set scope so if there are forward references, we still might be able to
4866 * resolve individual members like enums.
4867 */
4868 cldec.members.foreachDsymbol( s => s.setScope(sc2) );
4869
4870 sc2.pop();
4871 }
4872
4873 for (size_t i = 0; i < cldec.baseclasses.dim; i++)
4874 {
4875 BaseClass* b = (*cldec.baseclasses)[i];
4876 Type tb = b.type.toBasetype();
4877 TypeClass tc = tb.isTypeClass();
4878 if (tc.sym.semanticRun < PASS.semanticdone)
4879 {
4880 // Forward referencee of one or more bases, try again later
4881 if (tc.sym._scope)
4882 Module.addDeferredSemantic(tc.sym);
4883 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
4884 return deferDsymbolSemantic(cldec, scx);
4885 }
4886 }
4887
4888 if (cldec.baseok == Baseok.done)
4889 {
4890 cldec.baseok = Baseok.semanticdone;
4891 objc.setMetaclass(cldec, sc);
4892
4893 // initialize vtbl
4894 if (cldec.baseClass)
4895 {
4896 if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.dim == 0)
4897 {
4898 cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars());
4899 }
4900
4901 // Copy vtbl[] from base class
4902 cldec.vtbl.setDim(cldec.baseClass.vtbl.dim);
4903 memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.dim);
4904
4905 cldec.vthis = cldec.baseClass.vthis;
4906 cldec.vthis2 = cldec.baseClass.vthis2;
4907 }
4908 else
4909 {
4910 // No base class, so this is the root of the class hierarchy
4911 cldec.vtbl.setDim(0);
4912 if (cldec.vtblOffset())
4913 cldec.vtbl.push(cldec); // leave room for classinfo as first member
4914 }
4915
4916 /* If this is a nested class, add the hidden 'this'
4917 * member which is a pointer to the enclosing scope.
4918 */
4919 if (cldec.vthis) // if inheriting from nested class
4920 {
4921 // Use the base class's 'this' member
4922 if (cldec.storage_class & STC.static_)
4923 cldec.error("static class cannot inherit from nested class `%s`", cldec.baseClass.toChars());
4924 if (cldec.toParentLocal() != cldec.baseClass.toParentLocal() &&
4925 (!cldec.toParentLocal() ||
4926 !cldec.baseClass.toParentLocal().getType() ||
4927 !cldec.baseClass.toParentLocal().getType().isBaseOf(cldec.toParentLocal().getType(), null)))
4928 {
4929 if (cldec.toParentLocal())
4930 {
4931 cldec.error("is nested within `%s`, but super class `%s` is nested within `%s`",
4932 cldec.toParentLocal().toChars(),
4933 cldec.baseClass.toChars(),
4934 cldec.baseClass.toParentLocal().toChars());
4935 }
4936 else
4937 {
4938 cldec.error("is not nested, but super class `%s` is nested within `%s`",
4939 cldec.baseClass.toChars(),
4940 cldec.baseClass.toParentLocal().toChars());
4941 }
4942 cldec.enclosing = null;
4943 }
4944 if (cldec.vthis2)
4945 {
4946 if (cldec.toParent2() != cldec.baseClass.toParent2() &&
4947 (!cldec.toParent2() ||
4948 !cldec.baseClass.toParent2().getType() ||
4949 !cldec.baseClass.toParent2().getType().isBaseOf(cldec.toParent2().getType(), null)))
4950 {
4951 if (cldec.toParent2() && cldec.toParent2() != cldec.toParentLocal())
4952 {
4953 cldec.error("needs the frame pointer of `%s`, but super class `%s` needs the frame pointer of `%s`",
4954 cldec.toParent2().toChars(),
4955 cldec.baseClass.toChars(),
4956 cldec.baseClass.toParent2().toChars());
4957 }
4958 else
4959 {
4960 cldec.error("doesn't need a frame pointer, but super class `%s` needs the frame pointer of `%s`",
4961 cldec.baseClass.toChars(),
4962 cldec.baseClass.toParent2().toChars());
4963 }
4964 }
4965 }
4966 else
4967 cldec.makeNested2();
4968 }
4969 else
4970 cldec.makeNested();
4971 }
4972
4973 auto sc2 = cldec.newScope(sc);
4974
4975 cldec.members.foreachDsymbol( s => s.importAll(sc2) );
4976
4977 // Note that members.dim can grow due to tuple expansion during semantic()
4978 cldec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
4979
4980 if (!cldec.determineFields())
4981 {
4982 assert(cldec.type == Type.terror);
4983 sc2.pop();
4984 return;
4985 }
4986 /* Following special member functions creation needs semantic analysis
4987 * completion of sub-structs in each field types.
4988 */
4989 foreach (v; cldec.fields)
4990 {
4991 Type tb = v.type.baseElemOf();
4992 if (tb.ty != Tstruct)
4993 continue;
4994 auto sd = (cast(TypeStruct)tb).sym;
4995 if (sd.semanticRun >= PASS.semanticdone)
4996 continue;
4997
4998 sc2.pop();
4999
5000 //printf("\tdeferring %s\n", toChars());
5001 return deferDsymbolSemantic(cldec, scx);
5002 }
5003
5004 /* Look for special member functions.
5005 * They must be in this class, not in a base class.
5006 */
5007 // Can be in base class
5008 cldec.disableNew = cldec.search(Loc.initial, Id.classNew) !is null;
5009
5010 // Look for the constructor
5011 cldec.ctor = cldec.searchCtor();
5012
5013 if (!cldec.ctor && cldec.noDefaultCtor)
5014 {
5015 // A class object is always created by constructor, so this check is legitimate.
5016 foreach (v; cldec.fields)
5017 {
5018 if (v.storage_class & STC.nodefaultctor)
5019 error(v.loc, "field `%s` must be initialized in constructor", v.toChars());
5020 }
5021 }
5022
5023 // If this class has no constructor, but base class has a default
5024 // ctor, create a constructor:
5025 // this() { }
5026 if (!cldec.ctor && cldec.baseClass && cldec.baseClass.ctor)
5027 {
5028 auto fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type, null, FuncResolveFlag.quiet);
5029 if (!fd) // try shared base ctor instead
5030 fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type.sharedOf, null, FuncResolveFlag.quiet);
5031 if (fd && !fd.errors)
5032 {
5033 //printf("Creating default this(){} for class %s\n", toChars());
5034 auto btf = fd.type.toTypeFunction();
5035 auto tf = new TypeFunction(ParameterList(), null, LINK.d, fd.storage_class);
5036 tf.mod = btf.mod;
5037 // Don't copy @safe, ... from the base class constructor and let it be inferred instead
5038 // This is required if other lowerings add code to the generated constructor which
5039 // is less strict (e.g. `preview=dtorfields` might introduce a call to a less qualified dtor)
5040
5041 auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf);
5042 ctor.storage_class |= STC.inference;
5043 ctor.generated = true;
5044 ctor.fbody = new CompoundStatement(Loc.initial, new Statements());
5045
5046 cldec.members.push(ctor);
5047 ctor.addMember(sc, cldec);
5048 ctor.dsymbolSemantic(sc2);
5049
5050 cldec.ctor = ctor;
5051 cldec.defaultCtor = ctor;
5052 }
5053 else
5054 {
5055 cldec.error("cannot implicitly generate a default constructor when base class `%s` is missing a default constructor",
5056 cldec.baseClass.toPrettyChars());
5057 }
5058 }
5059
5060 cldec.dtor = buildDtor(cldec, sc2);
5061 cldec.tidtor = buildExternDDtor(cldec, sc2);
5062
5063 if (cldec.classKind == ClassKind.cpp && cldec.cppDtorVtblIndex != -1)
5064 {
5065 // now we've built the aggregate destructor, we'll make it virtual and assign it to the reserved vtable slot
5066 cldec.dtor.vtblIndex = cldec.cppDtorVtblIndex;
5067 cldec.vtbl[cldec.cppDtorVtblIndex] = cldec.dtor;
5068
5069 if (target.cpp.twoDtorInVtable)
5070 {
5071 // TODO: create a C++ compatible deleting destructor (call out to `operator delete`)
5072 // for the moment, we'll call the non-deleting destructor and leak
5073 cldec.vtbl[cldec.cppDtorVtblIndex + 1] = cldec.dtor;
5074 }
5075 }
5076
5077 if (auto f = hasIdentityOpAssign(cldec, sc2))
5078 {
5079 if (!(f.storage_class & STC.disable))
5080 cldec.error(f.loc, "identity assignment operator overload is illegal");
5081 }
5082
5083 cldec.inv = buildInv(cldec, sc2);
5084
5085 Module.dprogress++;
5086 cldec.semanticRun = PASS.semanticdone;
5087 //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5088
5089 sc2.pop();
5090
5091 /* isAbstract() is undecidable in some cases because of circular dependencies.
5092 * Now that semantic is finished, get a definitive result, and error if it is not the same.
5093 */
5094 if (cldec.isabstract != ThreeState.none) // if evaluated it before completion
5095 {
5096 const isabstractsave = cldec.isabstract;
5097 cldec.isabstract = ThreeState.none;
5098 cldec.isAbstract(); // recalculate
5099 if (cldec.isabstract != isabstractsave)
5100 {
5101 cldec.error("cannot infer `abstract` attribute due to circular dependencies");
5102 }
5103 }
5104
5105 if (cldec.type.ty == Tclass && (cast(TypeClass)cldec.type).sym != cldec)
5106 {
5107 // https://issues.dlang.org/show_bug.cgi?id=17492
5108 ClassDeclaration cd = (cast(TypeClass)cldec.type).sym;
5109 version (none)
5110 {
5111 printf("this = %p %s\n", cldec, cldec.toPrettyChars());
5112 printf("type = %d sym = %p, %s\n", cldec.type.ty, cd, cd.toPrettyChars());
5113 }
5114 cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars());
5115 }
5116
5117 if (global.errors != errors)
5118 {
5119 // The type is no good.
5120 cldec.type = Type.terror;
5121 cldec.errors = true;
5122 if (cldec.deferred)
5123 cldec.deferred.errors = true;
5124 }
5125
5126 // Verify fields of a synchronized class are not public
5127 if (cldec.storage_class & STC.synchronized_)
5128 {
5129 foreach (vd; cldec.fields)
5130 {
5131 if (!vd.isThisDeclaration() &&
5132 vd.visible() >= Visibility(Visibility.Kind.public_))
5133 {
5134 vd.error("Field members of a `synchronized` class cannot be `%s`",
5135 visibilityToChars(vd.visible().kind));
5136 }
5137 }
5138 }
5139
5140 if (cldec.deferred && !global.gag)
5141 {
5142 cldec.deferred.semantic2(sc);
5143 cldec.deferred.semantic3(sc);
5144 }
5145 //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
5146
5147 // @@@DEPRECATED@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5148 // Deprecated in 2.087
5149 // Make an error in 2.091
5150 // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5151 if (0 && // deprecation disabled for now to accommodate existing extensive use
5152 cldec.storage_class & STC.scope_)
5153 deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
5154 }
5155
visit(InterfaceDeclaration idec)5156 override void visit(InterfaceDeclaration idec)
5157 {
5158 /// Returns: `true` is this is an anonymous Objective-C metaclass
5159 static bool isAnonymousMetaclass(InterfaceDeclaration idec)
5160 {
5161 return idec.classKind == ClassKind.objc &&
5162 idec.objc.isMeta &&
5163 idec.isAnonymous;
5164 }
5165
5166 //printf("InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5167 if (idec.semanticRun >= PASS.semanticdone)
5168 return;
5169 int errors = global.errors;
5170
5171 //printf("+InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5172
5173 Scope* scx = null;
5174 if (idec._scope)
5175 {
5176 sc = idec._scope;
5177 scx = idec._scope; // save so we don't make redundant copies
5178 idec._scope = null;
5179 }
5180
5181 if (!idec.parent)
5182 {
5183 assert(sc.parent && sc.func);
5184 idec.parent = sc.parent;
5185 }
5186 // Objective-C metaclasses are anonymous
5187 assert(idec.parent && !idec.isAnonymous || isAnonymousMetaclass(idec));
5188
5189 if (idec.errors)
5190 idec.type = Type.terror;
5191 idec.type = idec.type.typeSemantic(idec.loc, sc);
5192 if (idec.type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5193 {
5194 auto ti = (cast(TypeClass)idec.type).sym.isInstantiated();
5195 if (ti && isError(ti))
5196 (cast(TypeClass)idec.type).sym = idec;
5197 }
5198
5199 // Ungag errors when not speculative
5200 Ungag ungag = idec.ungagSpeculative();
5201
5202 if (idec.semanticRun == PASS.init)
5203 {
5204 idec.visibility = sc.visibility;
5205
5206 idec.storage_class |= sc.stc;
5207 idec.userAttribDecl = sc.userAttribDecl;
5208 }
5209 else if (idec.symtab)
5210 {
5211 if (idec.sizeok == Sizeok.done || !scx)
5212 {
5213 idec.semanticRun = PASS.semanticdone;
5214 return;
5215 }
5216 }
5217 idec.semanticRun = PASS.semantic;
5218
5219 if (idec.baseok < Baseok.done)
5220 {
5221 T resolveBase(T)(lazy T exp)
5222 {
5223 if (!scx)
5224 {
5225 scx = sc.copy();
5226 scx.setNoFree();
5227 }
5228 static if (!is(T == void))
5229 {
5230 idec._scope = scx;
5231 auto r = exp();
5232 idec._scope = null;
5233 return r;
5234 }
5235 else
5236 {
5237 idec._scope = scx;
5238 exp();
5239 idec._scope = null;
5240 }
5241 }
5242
5243 idec.baseok = Baseok.start;
5244
5245 // Expand any tuples in baseclasses[]
5246 for (size_t i = 0; i < idec.baseclasses.dim;)
5247 {
5248 auto b = (*idec.baseclasses)[i];
5249 b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));
5250
5251 Type tb = b.type.toBasetype();
5252 if (auto tup = tb.isTypeTuple())
5253 {
5254 idec.baseclasses.remove(i);
5255 size_t dim = Parameter.dim(tup.arguments);
5256 for (size_t j = 0; j < dim; j++)
5257 {
5258 Parameter arg = Parameter.getNth(tup.arguments, j);
5259 b = new BaseClass(arg.type);
5260 idec.baseclasses.insert(i + j, b);
5261 }
5262 }
5263 else
5264 i++;
5265 }
5266
5267 if (idec.baseok >= Baseok.done)
5268 {
5269 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
5270 if (idec.semanticRun >= PASS.semanticdone)
5271 return;
5272 goto Lancestorsdone;
5273 }
5274
5275 if (!idec.baseclasses.dim && sc.linkage == LINK.cpp)
5276 idec.classKind = ClassKind.cpp;
5277 idec.cppnamespace = sc.namespace;
5278 UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
5279
5280 if (sc.linkage == LINK.objc)
5281 objc.setObjc(idec);
5282
5283 // Check for errors, handle forward references
5284 BCLoop:
5285 for (size_t i = 0; i < idec.baseclasses.dim;)
5286 {
5287 BaseClass* b = (*idec.baseclasses)[i];
5288 Type tb = b.type.toBasetype();
5289 TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;
5290 if (!tc || !tc.sym.isInterfaceDeclaration())
5291 {
5292 if (b.type != Type.terror)
5293 idec.error("base type must be `interface`, not `%s`", b.type.toChars());
5294 idec.baseclasses.remove(i);
5295 continue;
5296 }
5297
5298 // Check for duplicate interfaces
5299 for (size_t j = 0; j < i; j++)
5300 {
5301 BaseClass* b2 = (*idec.baseclasses)[j];
5302 if (b2.sym == tc.sym)
5303 {
5304 idec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
5305 idec.baseclasses.remove(i);
5306 continue BCLoop;
5307 }
5308 }
5309 if (tc.sym == idec || idec.isBaseOf2(tc.sym))
5310 {
5311 idec.error("circular inheritance of interface");
5312 idec.baseclasses.remove(i);
5313 continue;
5314 }
5315 if (tc.sym.isDeprecated())
5316 {
5317 if (!idec.isDeprecated())
5318 {
5319 // Deriving from deprecated interface makes this one deprecated too
5320 idec.setDeprecated();
5321 tc.checkDeprecated(idec.loc, sc);
5322 }
5323 }
5324
5325 b.sym = tc.sym;
5326
5327 if (tc.sym.baseok < Baseok.done)
5328 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5329 if (tc.sym.baseok < Baseok.done)
5330 {
5331 //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
5332 if (tc.sym._scope)
5333 Module.addDeferredSemantic(tc.sym);
5334 idec.baseok = Baseok.none;
5335 }
5336 i++;
5337 }
5338 if (idec.baseok == Baseok.none)
5339 {
5340 // Forward referencee of one or more bases, try again later
5341 return deferDsymbolSemantic(idec, scx);
5342 }
5343 idec.baseok = Baseok.done;
5344
5345 idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.dim];
5346 foreach (b; idec.interfaces)
5347 {
5348 // If this is an interface, and it derives from a COM interface,
5349 // then this is a COM interface too.
5350 if (b.sym.isCOMinterface())
5351 idec.com = true;
5352 if (b.sym.isCPPinterface())
5353 idec.classKind = ClassKind.cpp;
5354 }
5355
5356 interfaceSemantic(idec);
5357 }
5358 Lancestorsdone:
5359
5360 if (!idec.members) // if opaque declaration
5361 {
5362 idec.semanticRun = PASS.semanticdone;
5363 return;
5364 }
5365 if (!idec.symtab)
5366 idec.symtab = new DsymbolTable();
5367
5368 for (size_t i = 0; i < idec.baseclasses.dim; i++)
5369 {
5370 BaseClass* b = (*idec.baseclasses)[i];
5371 Type tb = b.type.toBasetype();
5372 TypeClass tc = tb.isTypeClass();
5373 if (tc.sym.semanticRun < PASS.semanticdone)
5374 {
5375 // Forward referencee of one or more bases, try again later
5376 if (tc.sym._scope)
5377 Module.addDeferredSemantic(tc.sym);
5378 return deferDsymbolSemantic(idec, scx);
5379 }
5380 }
5381
5382 if (idec.baseok == Baseok.done)
5383 {
5384 idec.baseok = Baseok.semanticdone;
5385 objc.setMetaclass(idec, sc);
5386
5387 // initialize vtbl
5388 if (idec.vtblOffset())
5389 idec.vtbl.push(idec); // leave room at vtbl[0] for classinfo
5390
5391 // Cat together the vtbl[]'s from base interfaces
5392 foreach (i, b; idec.interfaces)
5393 {
5394 // Skip if b has already appeared
5395 for (size_t k = 0; k < i; k++)
5396 {
5397 if (b == idec.interfaces[k])
5398 goto Lcontinue;
5399 }
5400
5401 // Copy vtbl[] from base class
5402 if (b.sym.vtblOffset())
5403 {
5404 size_t d = b.sym.vtbl.dim;
5405 if (d > 1)
5406 {
5407 idec.vtbl.pushSlice(b.sym.vtbl[1 .. d]);
5408 }
5409 }
5410 else
5411 {
5412 idec.vtbl.append(&b.sym.vtbl);
5413 }
5414
5415 Lcontinue:
5416 }
5417 }
5418
5419 idec.members.foreachDsymbol( s => s.addMember(sc, idec) );
5420
5421 auto sc2 = idec.newScope(sc);
5422
5423 /* Set scope so if there are forward references, we still might be able to
5424 * resolve individual members like enums.
5425 */
5426 idec.members.foreachDsymbol( s => s.setScope(sc2) );
5427
5428 idec.members.foreachDsymbol( s => s.importAll(sc2) );
5429
5430 idec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
5431
5432 Module.dprogress++;
5433 idec.semanticRun = PASS.semanticdone;
5434 //printf("-InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5435
5436 sc2.pop();
5437
5438 if (global.errors != errors)
5439 {
5440 // The type is no good.
5441 idec.type = Type.terror;
5442 }
5443
5444 version (none)
5445 {
5446 if (type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5447 {
5448 printf("this = %p %s\n", idec, idec.toChars());
5449 printf("type = %d sym = %p\n", idec.type.ty, (cast(TypeClass)idec.type).sym);
5450 }
5451 }
5452 assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec);
5453
5454 // @@@DEPRECATED@@@https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5455 // Deprecated in 2.087
5456 // Remove in 2.091
5457 // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5458 if (idec.storage_class & STC.scope_)
5459 deprecation(idec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
5460 }
5461 }
5462
5463 /*******************************************
5464 * Add members of EnumDeclaration to the symbol table(s).
5465 * Params:
5466 * ed = EnumDeclaration
5467 * sc = context of `ed`
5468 * sds = symbol table that `ed` resides in
5469 */
addEnumMembers(EnumDeclaration ed,Scope * sc,ScopeDsymbol sds)5470 void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
5471 {
5472 if (ed.added)
5473 return;
5474 ed.added = true;
5475
5476 if (!ed.members)
5477 return;
5478
5479 const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum
5480 const bool isAnon = ed.isAnonymous();
5481
5482 if ((isCEnum || isAnon) && !sds.symtab)
5483 sds.symtab = new DsymbolTable();
5484
5485 if ((isCEnum || !isAnon) && !ed.symtab)
5486 ed.symtab = new DsymbolTable();
5487
5488 ed.members.foreachDsymbol( (s)
5489 {
5490 if (EnumMember em = s.isEnumMember())
5491 {
5492 em.ed = ed;
5493 if (isCEnum)
5494 {
5495 em.addMember(sc, ed); // add em to ed's symbol table
5496 em.addMember(sc, sds); // add em to symbol table that ed is in
5497 em.parent = ed; // restore it after previous addMember() changed it
5498 }
5499 else
5500 {
5501 em.addMember(sc, isAnon ? sds : ed);
5502 }
5503 }
5504 });
5505 }
5506
templateInstanceSemantic(TemplateInstance tempinst,Scope * sc,Expressions * fargs)5507 void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, Expressions* fargs)
5508 {
5509 //printf("[%s] TemplateInstance.dsymbolSemantic('%s', this=%p, gag = %d, sc = %p)\n", tempinst.loc.toChars(), tempinst.toChars(), tempinst, global.gag, sc);
5510 version (none)
5511 {
5512 for (Dsymbol s = tempinst; s; s = s.parent)
5513 {
5514 printf("\t%s\n", s.toChars());
5515 }
5516 printf("Scope\n");
5517 for (Scope* scx = sc; scx; scx = scx.enclosing)
5518 {
5519 printf("\t%s parent %s\n", scx._module ? scx._module.toChars() : "null", scx.parent ? scx.parent.toChars() : "null");
5520 }
5521 }
5522
5523 static if (LOG)
5524 {
5525 printf("\n+TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
5526 }
5527 if (tempinst.inst) // if semantic() was already run
5528 {
5529 static if (LOG)
5530 {
5531 printf("-TemplateInstance.dsymbolSemantic('%s', this=%p) already run\n",
5532 tempinst.inst.toChars(), tempinst.inst);
5533 }
5534 return;
5535 }
5536 if (tempinst.semanticRun != PASS.init)
5537 {
5538 static if (LOG)
5539 {
5540 printf("Recursive template expansion\n");
5541 }
5542 auto ungag = Ungag(global.gag);
5543 if (!tempinst.gagged)
5544 global.gag = 0;
5545 tempinst.error(tempinst.loc, "recursive template expansion");
5546 if (tempinst.gagged)
5547 tempinst.semanticRun = PASS.init;
5548 else
5549 tempinst.inst = tempinst;
5550 tempinst.errors = true;
5551 return;
5552 }
5553
5554 // Get the enclosing template instance from the scope tinst
5555 tempinst.tinst = sc.tinst;
5556
5557 // Get the instantiating module from the scope minst
5558 tempinst.minst = sc.minst;
5559 // https://issues.dlang.org/show_bug.cgi?id=10920
5560 // If the enclosing function is non-root symbol,
5561 // this instance should be speculative.
5562 if (!tempinst.tinst && sc.func && sc.func.inNonRoot())
5563 {
5564 tempinst.minst = null;
5565 }
5566
5567 tempinst.gagged = (global.gag > 0);
5568
5569 tempinst.semanticRun = PASS.semantic;
5570
5571 static if (LOG)
5572 {
5573 printf("\tdo semantic\n");
5574 }
5575 /* Find template declaration first,
5576 * then run semantic on each argument (place results in tiargs[]),
5577 * last find most specialized template from overload list/set.
5578 */
5579 if (!tempinst.findTempDecl(sc, null) || !tempinst.semanticTiargs(sc) || !tempinst.findBestMatch(sc, fargs))
5580 {
5581 Lerror:
5582 if (tempinst.gagged)
5583 {
5584 // https://issues.dlang.org/show_bug.cgi?id=13220
5585 // Roll back status for later semantic re-running
5586 tempinst.semanticRun = PASS.init;
5587 }
5588 else
5589 tempinst.inst = tempinst;
5590 tempinst.errors = true;
5591 return;
5592 }
5593 TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();
5594 assert(tempdecl);
5595
5596 TemplateStats.incInstance(tempdecl, tempinst);
5597
5598 tempdecl.checkDeprecated(tempinst.loc, sc);
5599
5600 // If tempdecl is a mixin, disallow it
5601 if (tempdecl.ismixin)
5602 {
5603 tempinst.error("mixin templates are not regular templates");
5604 goto Lerror;
5605 }
5606
5607 tempinst.hasNestedArgs(tempinst.tiargs, tempdecl.isstatic);
5608 if (tempinst.errors)
5609 goto Lerror;
5610
5611 // Copy the tempdecl namespace (not the scope one)
5612 tempinst.cppnamespace = tempdecl.cppnamespace;
5613 if (tempinst.cppnamespace)
5614 tempinst.cppnamespace.dsymbolSemantic(sc);
5615
5616 /* Greatly simplified semantic processing for AliasSeq templates
5617 */
5618 if (tempdecl.isTrivialAliasSeq)
5619 {
5620 tempinst.inst = tempinst;
5621 return aliasSeqInstanceSemantic(tempinst, sc, tempdecl);
5622 }
5623
5624 /* Greatly simplified semantic processing for Alias templates
5625 */
5626 else if (tempdecl.isTrivialAlias)
5627 {
5628 tempinst.inst = tempinst;
5629 return aliasInstanceSemantic(tempinst, sc, tempdecl);
5630 }
5631
5632 /* See if there is an existing TemplateInstantiation that already
5633 * implements the typeargs. If so, just refer to that one instead.
5634 */
5635 tempinst.inst = tempdecl.findExistingInstance(tempinst, fargs);
5636 TemplateInstance errinst = null;
5637 if (!tempinst.inst)
5638 {
5639 // So, we need to implement 'this' instance.
5640 }
5641 else if (tempinst.inst.gagged && !tempinst.gagged && tempinst.inst.errors)
5642 {
5643 // If the first instantiation had failed, re-run semantic,
5644 // so that error messages are shown.
5645 errinst = tempinst.inst;
5646 }
5647 else
5648 {
5649 // It's a match
5650 tempinst.parent = tempinst.inst.parent;
5651 tempinst.errors = tempinst.inst.errors;
5652
5653 // If both this and the previous instantiation were gagged,
5654 // use the number of errors that happened last time.
5655 global.errors += tempinst.errors;
5656 global.gaggedErrors += tempinst.errors;
5657
5658 // If the first instantiation was gagged, but this is not:
5659 if (tempinst.inst.gagged)
5660 {
5661 // It had succeeded, mark it is a non-gagged instantiation,
5662 // and reuse it.
5663 tempinst.inst.gagged = tempinst.gagged;
5664 }
5665
5666 tempinst.tnext = tempinst.inst.tnext;
5667 tempinst.inst.tnext = tempinst;
5668
5669 /* A module can have explicit template instance and its alias
5670 * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).
5671 * If the first instantiation 'inst' had happened in non-root module,
5672 * compiler can assume that its instantiated code would be included
5673 * in the separately compiled obj/lib file (e.g. phobos.lib).
5674 *
5675 * However, if 'this' second instantiation happened in root module,
5676 * compiler might need to invoke its codegen
5677 * (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang.org/show_bug.cgi?id=2644).
5678 * But whole import graph is not determined until all semantic pass finished,
5679 * so 'inst' should conservatively finish the semantic3 pass for the codegen.
5680 */
5681 if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst && tempinst.inst.minst.isRoot()))
5682 {
5683 /* Swap the position of 'inst' and 'this' in the instantiation graph.
5684 * Then, the primary instance `inst` will be changed to a root instance,
5685 * along with all members of `inst` having their scopes updated.
5686 *
5687 * Before:
5688 * non-root -> A!() -> B!()[inst] -> C!() { members[non-root] }
5689 * |
5690 * root -> D!() -> B!()[this]
5691 *
5692 * After:
5693 * non-root -> A!() -> B!()[this]
5694 * |
5695 * root -> D!() -> B!()[inst] -> C!() { members[root] }
5696 */
5697 Module mi = tempinst.minst;
5698 TemplateInstance ti = tempinst.tinst;
5699 tempinst.minst = tempinst.inst.minst;
5700 tempinst.tinst = tempinst.inst.tinst;
5701 tempinst.inst.minst = mi;
5702 tempinst.inst.tinst = ti;
5703
5704 /* https://issues.dlang.org/show_bug.cgi?id=21299
5705 `minst` has been updated on the primary instance `inst` so it is
5706 now coming from a root module, however all Dsymbol `inst.members`
5707 of the instance still have their `_scope.minst` pointing at the
5708 original non-root module. We must now propagate `minst` to all
5709 members so that forward referenced dependencies that get
5710 instantiated will also be appended to the root module, otherwise
5711 there will be undefined references at link-time. */
5712 extern (C++) final class InstMemberWalker : Visitor
5713 {
5714 alias visit = Visitor.visit;
5715 TemplateInstance inst;
5716
5717 extern (D) this(TemplateInstance inst)
5718 {
5719 this.inst = inst;
5720 }
5721
5722 override void visit(Dsymbol d)
5723 {
5724 if (d._scope)
5725 d._scope.minst = inst.minst;
5726 }
5727
5728 override void visit(ScopeDsymbol sds)
5729 {
5730 sds.members.foreachDsymbol( s => s.accept(this) );
5731 visit(cast(Dsymbol)sds);
5732 }
5733
5734 override void visit(AttribDeclaration ad)
5735 {
5736 ad.include(null).foreachDsymbol( s => s.accept(this) );
5737 visit(cast(Dsymbol)ad);
5738 }
5739
5740 override void visit(ConditionalDeclaration cd)
5741 {
5742 if (cd.condition.inc)
5743 visit(cast(AttribDeclaration)cd);
5744 else
5745 visit(cast(Dsymbol)cd);
5746 }
5747 }
5748 scope v = new InstMemberWalker(tempinst.inst);
5749 tempinst.inst.accept(v);
5750
5751 if (tempinst.minst) // if inst was not speculative
5752 {
5753 /* Add 'inst' once again to the root module members[], then the
5754 * instance members will get codegen chances.
5755 */
5756 tempinst.inst.appendToModuleMember();
5757 }
5758 }
5759
5760 // modules imported by an existing instance should be added to the module
5761 // that instantiates the instance.
5762 if (tempinst.minst)
5763 foreach(imp; tempinst.inst.importedModules)
5764 if (!tempinst.minst.aimports.contains(imp))
5765 tempinst.minst.aimports.push(imp);
5766
5767 static if (LOG)
5768 {
5769 printf("\tit's a match with instance %p, %d\n", tempinst.inst, tempinst.inst.semanticRun);
5770 }
5771 return;
5772 }
5773 static if (LOG)
5774 {
5775 printf("\timplement template instance %s '%s'\n", tempdecl.parent.toChars(), tempinst.toChars());
5776 printf("\ttempdecl %s\n", tempdecl.toChars());
5777 }
5778 uint errorsave = global.errors;
5779
5780 tempinst.inst = tempinst;
5781 tempinst.parent = tempinst.enclosing ? tempinst.enclosing : tempdecl.parent;
5782 //printf("parent = '%s'\n", parent.kind());
5783
5784 TemplateStats.incUnique(tempdecl, tempinst);
5785
5786 TemplateInstance tempdecl_instance_idx = tempdecl.addInstance(tempinst);
5787
5788 //getIdent();
5789
5790 // Store the place we added it to in target_symbol_list(_idx) so we can
5791 // remove it later if we encounter an error.
5792 Dsymbols* target_symbol_list = tempinst.appendToModuleMember();
5793 size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.dim - 1 : 0;
5794
5795 // Copy the syntax trees from the TemplateDeclaration
5796 tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
5797
5798 // resolve TemplateThisParameter
5799 for (size_t i = 0; i < tempdecl.parameters.dim; i++)
5800 {
5801 if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)
5802 continue;
5803 Type t = isType((*tempinst.tiargs)[i]);
5804 assert(t);
5805 if (StorageClass stc = ModToStc(t.mod))
5806 {
5807 //printf("t = %s, stc = x%llx\n", t.toChars(), stc);
5808 auto s = new Dsymbols();
5809 s.push(new StorageClassDeclaration(stc, tempinst.members));
5810 tempinst.members = s;
5811 }
5812 break;
5813 }
5814
5815 // Create our own scope for the template parameters
5816 Scope* _scope = tempdecl._scope;
5817 if (tempdecl.semanticRun == PASS.init)
5818 {
5819 tempinst.error("template instantiation `%s` forward references template declaration `%s`", tempinst.toChars(), tempdecl.toChars());
5820 return;
5821 }
5822
5823 static if (LOG)
5824 {
5825 printf("\tcreate scope for template parameters '%s'\n", tempinst.toChars());
5826 }
5827 tempinst.argsym = new ScopeDsymbol();
5828 tempinst.argsym.parent = _scope.parent;
5829 _scope = _scope.push(tempinst.argsym);
5830 _scope.tinst = tempinst;
5831 _scope.minst = tempinst.minst;
5832 //scope.stc = 0;
5833
5834 // Declare each template parameter as an alias for the argument type
5835 Scope* paramscope = _scope.push();
5836 paramscope.stc = 0;
5837 paramscope.visibility = Visibility(Visibility.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=14169
5838 // template parameters should be public
5839 tempinst.declareParameters(paramscope);
5840 paramscope.pop();
5841
5842 // Add members of template instance to template instance symbol table
5843 //parent = scope.scopesym;
5844 tempinst.symtab = new DsymbolTable();
5845
5846 tempinst.members.foreachDsymbol( (s)
5847 {
5848 static if (LOG)
5849 {
5850 printf("\t adding member '%s' %p kind %s to '%s'\n", s.toChars(), s, s.kind(), tempinst.toChars());
5851 }
5852 s.addMember(_scope, tempinst);
5853 });
5854
5855 static if (LOG)
5856 {
5857 printf("adding members done\n");
5858 }
5859
5860 /* See if there is only one member of template instance, and that
5861 * member has the same name as the template instance.
5862 * If so, this template instance becomes an alias for that member.
5863 */
5864 //printf("members.dim = %d\n", tempinst.members.dim);
5865 if (tempinst.members.dim)
5866 {
5867 Dsymbol s;
5868 if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
5869 {
5870 //printf("tempdecl.ident = %s, s = '%s'\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
5871 //printf("setting aliasdecl\n");
5872 tempinst.aliasdecl = s;
5873 }
5874 }
5875
5876 /* If function template declaration
5877 */
5878 if (fargs && tempinst.aliasdecl)
5879 {
5880 if (auto fd = tempinst.aliasdecl.isFuncDeclaration())
5881 {
5882 /* Transmit fargs to type so that TypeFunction.dsymbolSemantic() can
5883 * resolve any "auto ref" storage classes.
5884 */
5885 if (fd.type)
5886 if (auto tf = fd.type.isTypeFunction())
5887 tf.fargs = fargs;
5888 }
5889 }
5890
5891 // Do semantic() analysis on template instance members
5892 static if (LOG)
5893 {
5894 printf("\tdo semantic() on template instance members '%s'\n", tempinst.toChars());
5895 }
5896 Scope* sc2;
5897 sc2 = _scope.push(tempinst);
5898 //printf("enclosing = %d, sc.parent = %s\n", tempinst.enclosing, sc.parent.toChars());
5899 sc2.parent = tempinst;
5900 sc2.tinst = tempinst;
5901 sc2.minst = tempinst.minst;
5902 sc2.stc &= ~STC.deprecated_;
5903 tempinst.tryExpandMembers(sc2);
5904
5905 tempinst.semanticRun = PASS.semanticdone;
5906
5907 /* ConditionalDeclaration may introduce eponymous declaration,
5908 * so we should find it once again after semantic.
5909 */
5910 if (tempinst.members.dim)
5911 {
5912 Dsymbol s;
5913 if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
5914 {
5915 if (!tempinst.aliasdecl || tempinst.aliasdecl != s)
5916 {
5917 //printf("tempdecl.ident = %s, s = '%s'\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
5918 //printf("setting aliasdecl 2\n");
5919 tempinst.aliasdecl = s;
5920 }
5921 }
5922 }
5923
5924 if (global.errors != errorsave)
5925 goto Laftersemantic;
5926
5927 /* If any of the instantiation members didn't get semantic() run
5928 * on them due to forward references, we cannot run semantic2()
5929 * or semantic3() yet.
5930 */
5931 {
5932 bool found_deferred_ad = false;
5933 for (size_t i = 0; i < Module.deferred.dim; i++)
5934 {
5935 Dsymbol sd = Module.deferred[i];
5936 AggregateDeclaration ad = sd.isAggregateDeclaration();
5937 if (ad && ad.parent && ad.parent.isTemplateInstance())
5938 {
5939 //printf("deferred template aggregate: %s %s\n",
5940 // sd.parent.toChars(), sd.toChars());
5941 found_deferred_ad = true;
5942 if (ad.parent == tempinst)
5943 {
5944 ad.deferred = tempinst;
5945 break;
5946 }
5947 }
5948 }
5949 if (found_deferred_ad || Module.deferred.dim)
5950 goto Laftersemantic;
5951 }
5952
5953 /* The problem is when to parse the initializer for a variable.
5954 * Perhaps VarDeclaration.dsymbolSemantic() should do it like it does
5955 * for initializers inside a function.
5956 */
5957 //if (sc.parent.isFuncDeclaration())
5958 {
5959 /* https://issues.dlang.org/show_bug.cgi?id=782
5960 * this has problems if the classes this depends on
5961 * are forward referenced. Find a way to defer semantic()
5962 * on this template.
5963 */
5964 tempinst.semantic2(sc2);
5965 }
5966 if (global.errors != errorsave)
5967 goto Laftersemantic;
5968
5969 if ((sc.func || (sc.flags & SCOPE.fullinst)) && !tempinst.tinst)
5970 {
5971 /* If a template is instantiated inside function, the whole instantiation
5972 * should be done at that position. But, immediate running semantic3 of
5973 * dependent templates may cause unresolved forward reference.
5974 * https://issues.dlang.org/show_bug.cgi?id=9050
5975 * To avoid the issue, don't run semantic3 until semantic and semantic2 done.
5976 */
5977 TemplateInstances deferred;
5978 tempinst.deferred = &deferred;
5979
5980 //printf("Run semantic3 on %s\n", toChars());
5981 tempinst.trySemantic3(sc2);
5982
5983 for (size_t i = 0; i < deferred.dim; i++)
5984 {
5985 //printf("+ run deferred semantic3 on %s\n", deferred[i].toChars());
5986 deferred[i].semantic3(null);
5987 }
5988
5989 tempinst.deferred = null;
5990 }
5991 else if (tempinst.tinst)
5992 {
5993 bool doSemantic3 = false;
5994 FuncDeclaration fd;
5995 if (tempinst.aliasdecl)
5996 fd = tempinst.aliasdecl.toAlias2().isFuncDeclaration();
5997
5998 if (fd)
5999 {
6000 /* Template function instantiation should run semantic3 immediately
6001 * for attribute inference.
6002 */
6003 scope fld = fd.isFuncLiteralDeclaration();
6004 if (fld && fld.tok == TOK.reserved)
6005 doSemantic3 = true;
6006 else if (sc.func)
6007 doSemantic3 = true;
6008 }
6009 else if (sc.func)
6010 {
6011 /* A lambda function in template arguments might capture the
6012 * instantiated scope context. For the correct context inference,
6013 * all instantiated functions should run the semantic3 immediately.
6014 * See also compilable/test14973.d
6015 */
6016 foreach (oarg; tempinst.tdtypes)
6017 {
6018 auto s = getDsymbol(oarg);
6019 if (!s)
6020 continue;
6021
6022 if (auto td = s.isTemplateDeclaration())
6023 {
6024 if (!td.literal)
6025 continue;
6026 assert(td.members && td.members.dim == 1);
6027 s = (*td.members)[0];
6028 }
6029 if (auto fld = s.isFuncLiteralDeclaration())
6030 {
6031 if (fld.tok == TOK.reserved)
6032 {
6033 doSemantic3 = true;
6034 break;
6035 }
6036 }
6037 }
6038 //printf("[%s] %s doSemantic3 = %d\n", tempinst.tinst.loc.toChars(), tempinst.tinst.toChars(), doSemantic3);
6039 }
6040 if (doSemantic3)
6041 tempinst.trySemantic3(sc2);
6042
6043 TemplateInstance ti = tempinst.tinst;
6044 int nest = 0;
6045 while (ti && !ti.deferred && ti.tinst)
6046 {
6047 ti = ti.tinst;
6048 if (++nest > global.recursionLimit)
6049 {
6050 global.gag = 0; // ensure error message gets printed
6051 tempinst.error("recursive expansion");
6052 fatal();
6053 }
6054 }
6055 if (ti && ti.deferred)
6056 {
6057 //printf("deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\n", this, toChars(), ti.toChars());
6058 for (size_t i = 0;; i++)
6059 {
6060 if (i == ti.deferred.dim)
6061 {
6062 ti.deferred.push(tempinst);
6063 break;
6064 }
6065 if ((*ti.deferred)[i] == tempinst)
6066 break;
6067 }
6068 }
6069 }
6070
6071 if (tempinst.aliasdecl)
6072 {
6073 /* https://issues.dlang.org/show_bug.cgi?id=13816
6074 * AliasDeclaration tries to resolve forward reference
6075 * twice (See inuse check in AliasDeclaration.toAlias()). It's
6076 * necessary to resolve mutual references of instantiated symbols, but
6077 * it will left a true recursive alias in tuple declaration - an
6078 * AliasDeclaration A refers TupleDeclaration B, and B contains A
6079 * in its elements. To correctly make it an error, we strictly need to
6080 * resolve the alias of eponymous member.
6081 */
6082 tempinst.aliasdecl = tempinst.aliasdecl.toAlias2();
6083 }
6084
6085 Laftersemantic:
6086 sc2.pop();
6087 _scope.pop();
6088
6089 // Give additional context info if error occurred during instantiation
6090 if (global.errors != errorsave)
6091 {
6092 if (!tempinst.errors)
6093 {
6094 if (!tempdecl.literal)
6095 tempinst.error(tempinst.loc, "error instantiating");
6096 if (tempinst.tinst)
6097 tempinst.tinst.printInstantiationTrace();
6098 }
6099 tempinst.errors = true;
6100 if (tempinst.gagged)
6101 {
6102 // Errors are gagged, so remove the template instance from the
6103 // instance/symbol lists we added it to and reset our state to
6104 // finish clean and so we can try to instantiate it again later
6105 // (see https://issues.dlang.org/show_bug.cgi?id=4302 and https://issues.dlang.org/show_bug.cgi?id=6602).
6106 tempdecl.removeInstance(tempdecl_instance_idx);
6107 if (target_symbol_list)
6108 {
6109 // Because we added 'this' in the last position above, we
6110 // should be able to remove it without messing other indices up.
6111 assert((*target_symbol_list)[target_symbol_list_idx] == tempinst);
6112 target_symbol_list.remove(target_symbol_list_idx);
6113 tempinst.memberOf = null; // no longer a member
6114 }
6115 tempinst.semanticRun = PASS.init;
6116 tempinst.inst = null;
6117 tempinst.symtab = null;
6118 }
6119 }
6120 else if (errinst)
6121 {
6122 /* https://issues.dlang.org/show_bug.cgi?id=14541
6123 * If the previous gagged instance had failed by
6124 * circular references, currrent "error reproduction instantiation"
6125 * might succeed, because of the difference of instantiated context.
6126 * On such case, the cached error instance needs to be overridden by the
6127 * succeeded instance.
6128 */
6129 //printf("replaceInstance()\n");
6130 assert(errinst.errors);
6131 auto ti1 = TemplateInstanceBox(errinst);
6132 tempdecl.instances.remove(ti1);
6133
6134 auto ti2 = TemplateInstanceBox(tempinst);
6135 tempdecl.instances[ti2] = tempinst;
6136 }
6137
6138 static if (LOG)
6139 {
6140 printf("-TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
6141 }
6142 }
6143
6144 /******************************************************
6145 * Do template instance semantic for isAliasSeq templates.
6146 * This is a greatly simplified version of templateInstanceSemantic().
6147 */
6148 private
aliasSeqInstanceSemantic(TemplateInstance tempinst,Scope * sc,TemplateDeclaration tempdecl)6149 void aliasSeqInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclaration tempdecl)
6150 {
6151 //printf("[%s] aliasSeqInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6152 Scope* paramscope = sc.push();
6153 paramscope.stc = 0;
6154 paramscope.visibility = Visibility(Visibility.Kind.public_);
6155
6156 TemplateTupleParameter ttp = (*tempdecl.parameters)[0].isTemplateTupleParameter();
6157 Tuple va = tempinst.tdtypes[0].isTuple();
6158 Declaration d = new TupleDeclaration(tempinst.loc, ttp.ident, &va.objects);
6159 d.storage_class |= STC.templateparameter;
6160 d.dsymbolSemantic(sc);
6161
6162 paramscope.pop();
6163
6164 tempinst.aliasdecl = d;
6165
6166 tempinst.semanticRun = PASS.semanticdone;
6167 }
6168
6169 /******************************************************
6170 * Do template instance semantic for isAlias templates.
6171 * This is a greatly simplified version of templateInstanceSemantic().
6172 */
6173 private
aliasInstanceSemantic(TemplateInstance tempinst,Scope * sc,TemplateDeclaration tempdecl)6174 void aliasInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclaration tempdecl)
6175 {
6176 //printf("[%s] aliasInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6177 Scope* paramscope = sc.push();
6178 paramscope.stc = 0;
6179 paramscope.visibility = Visibility(Visibility.Kind.public_);
6180
6181 TemplateTypeParameter ttp = (*tempdecl.parameters)[0].isTemplateTypeParameter();
6182 Type ta = tempinst.tdtypes[0].isType();
6183 auto ad = tempdecl.onemember.isAliasDeclaration();
6184
6185 // Note: qualifiers can be in both 'ad.type.mod' and 'ad.storage_class'
6186 Declaration d = new AliasDeclaration(tempinst.loc, ttp.ident, ta.addMod(ad.type.mod));
6187 d.storage_class |= STC.templateparameter | ad.storage_class;
6188 d.dsymbolSemantic(sc);
6189
6190 paramscope.pop();
6191
6192 tempinst.aliasdecl = d;
6193
6194 tempinst.semanticRun = PASS.semanticdone;
6195 }
6196
6197 // function used to perform semantic on AliasDeclaration
aliasSemantic(AliasDeclaration ds,Scope * sc)6198 void aliasSemantic(AliasDeclaration ds, Scope* sc)
6199 {
6200 //printf("AliasDeclaration::semantic() %s\n", ds.toChars());
6201
6202 // as DsymbolSemanticVisitor::visit(AliasDeclaration), in case we're called first.
6203 // see https://issues.dlang.org/show_bug.cgi?id=21001
6204 ds.storage_class |= sc.stc & STC.deprecated_;
6205 ds.visibility = sc.visibility;
6206 ds.userAttribDecl = sc.userAttribDecl;
6207
6208 // TypeTraits needs to know if it's located in an AliasDeclaration
6209 const oldflags = sc.flags;
6210 sc.flags |= SCOPE.alias_;
6211
6212 void normalRet()
6213 {
6214 sc.flags = oldflags;
6215 ds.inuse = 0;
6216 ds.semanticRun = PASS.semanticdone;
6217
6218 if (auto sx = ds.overnext)
6219 {
6220 ds.overnext = null;
6221 if (!ds.overloadInsert(sx))
6222 ScopeDsymbol.multiplyDefined(Loc.initial, sx, ds);
6223 }
6224 }
6225
6226 void errorRet()
6227 {
6228 ds.aliassym = null;
6229 ds.type = Type.terror;
6230 ds.inuse = 0;
6231 normalRet();
6232 }
6233
6234 // preserve the original type
6235 if (!ds.originalType && ds.type)
6236 ds.originalType = ds.type.syntaxCopy();
6237
6238 if (ds.aliassym)
6239 {
6240 auto fd = ds.aliassym.isFuncLiteralDeclaration();
6241 auto td = ds.aliassym.isTemplateDeclaration();
6242 if (fd || td && td.literal)
6243 {
6244 if (fd && fd.semanticRun >= PASS.semanticdone)
6245 return normalRet();
6246
6247 Expression e = new FuncExp(ds.loc, ds.aliassym);
6248 e = e.expressionSemantic(sc);
6249 if (auto fe = e.isFuncExp())
6250 {
6251 ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;
6252 return normalRet();
6253 }
6254 else
6255 return errorRet();
6256 }
6257
6258 if (ds.aliassym.isTemplateInstance())
6259 ds.aliassym.dsymbolSemantic(sc);
6260 return normalRet();
6261 }
6262 ds.inuse = 1;
6263
6264 // Given:
6265 // alias foo.bar.abc def;
6266 // it is not knowable from the syntax whether `def` is an alias
6267 // for type `foo.bar.abc` or an alias for symbol `foo.bar.abc`. It is up to the semantic()
6268 // pass to distinguish.
6269 // If it is a type, then `.type` is set and getType() will return that
6270 // type. If it is a symbol, then `.aliassym` is set and type is `null` -
6271 // toAlias() will return `.aliassym`
6272
6273 const errors = global.errors;
6274 Type oldtype = ds.type;
6275
6276 // Ungag errors when not instantiated DeclDefs scope alias
6277 auto ungag = Ungag(global.gag);
6278 //printf("%s parent = %s, gag = %d, instantiated = %d\n", toChars(), parent, global.gag, isInstantiated());
6279 if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration())
6280 {
6281 //printf("%s type = %s\n", toPrettyChars(), type.toChars());
6282 global.gag = 0;
6283 }
6284
6285 // https://issues.dlang.org/show_bug.cgi?id=18480
6286 // Detect `alias sym = sym;` to prevent creating loops in overload overnext lists.
6287 if (auto tident = ds.type.isTypeIdentifier())
6288 {
6289 // Selective imports are allowed to alias to the same name `import mod : sym=sym`.
6290 if (!ds._import)
6291 {
6292 if (tident.ident is ds.ident && !tident.idents.dim)
6293 {
6294 error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set",
6295 ds.ident.toChars(), tident.ident.toChars());
6296 ds.type = Type.terror;
6297 }
6298 }
6299 }
6300 /* This section is needed because Type.resolve() will:
6301 * const x = 3;
6302 * alias y = x;
6303 * try to convert identifier x to 3.
6304 */
6305 auto s = ds.type.toDsymbol(sc);
6306 if (errors != global.errors)
6307 return errorRet();
6308 if (s == ds)
6309 {
6310 ds.error("cannot resolve");
6311 return errorRet();
6312 }
6313 if (!s || !s.isEnumMember())
6314 {
6315 Type t;
6316 Expression e;
6317 Scope* sc2 = sc;
6318 if (ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.disable))
6319 {
6320 // For 'ref' to be attached to function types, and picked
6321 // up by Type.resolve(), it has to go into sc.
6322 sc2 = sc.push();
6323 sc2.stc |= ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6324 }
6325 ds.type = ds.type.addSTC(ds.storage_class);
6326 ds.type.resolve(ds.loc, sc2, e, t, s);
6327 if (sc2 != sc)
6328 sc2.pop();
6329
6330 if (e) // Try to convert Expression to Dsymbol
6331 {
6332 // TupleExp is naturally converted to a TupleDeclaration
6333 if (auto te = e.isTupleExp())
6334 s = new TupleDeclaration(te.loc, ds.ident, cast(Objects*)te.exps);
6335 else
6336 {
6337 s = getDsymbol(e);
6338 if (!s)
6339 {
6340 if (e.op != TOK.error)
6341 ds.error("cannot alias an expression `%s`", e.toChars());
6342 return errorRet();
6343 }
6344 }
6345 }
6346 ds.type = t;
6347 }
6348 if (s == ds)
6349 {
6350 assert(global.errors);
6351 return errorRet();
6352 }
6353 if (s) // it's a symbolic alias
6354 {
6355 //printf("alias %s resolved to %s %s\n", toChars(), s.kind(), s.toChars());
6356 ds.type = null;
6357 ds.aliassym = s;
6358 }
6359 else // it's a type alias
6360 {
6361 //printf("alias %s resolved to type %s\n", toChars(), type.toChars());
6362 ds.type = ds.type.typeSemantic(ds.loc, sc);
6363 ds.aliassym = null;
6364 }
6365
6366 if (global.gag && errors != global.errors)
6367 return errorRet();
6368
6369 normalRet();
6370 }
6371
6372 /********************
6373 * Perform semantic on AliasAssignment.
6374 * Has a lot of similarities to aliasSemantic(). Perhaps they should share code.
6375 */
aliasAssignSemantic(AliasAssign ds,Scope * sc)6376 private void aliasAssignSemantic(AliasAssign ds, Scope* sc)
6377 {
6378 //printf("AliasAssign::semantic() %p, %s\n", ds, ds.ident.toChars());
6379
6380 void errorRet()
6381 {
6382 ds.errors = true;
6383 ds.type = Type.terror;
6384 ds.semanticRun = PASS.semanticdone;
6385 return;
6386 }
6387
6388 /* Find the AliasDeclaration corresponding to ds.
6389 * Returns: AliasDeclaration if found, null if error
6390 */
6391 AliasDeclaration findAliasDeclaration(AliasAssign ds, Scope* sc)
6392 {
6393 Dsymbol scopesym;
6394 Dsymbol as = sc.search(ds.loc, ds.ident, &scopesym);
6395 if (!as)
6396 {
6397 ds.error("undefined identifier `%s`", ds.ident.toChars());
6398 return null;
6399 }
6400 if (as.errors)
6401 return null;
6402
6403 auto ad = as.isAliasDeclaration();
6404 if (!ad)
6405 {
6406 ds.error("identifier `%s` must be an alias declaration", as.toChars());
6407 return null;
6408 }
6409
6410 if (ad.overnext)
6411 {
6412 ds.error("cannot reassign overloaded alias");
6413 return null;
6414 }
6415
6416 // Check constraints on the parent
6417 auto adParent = ad.toParent();
6418 if (adParent != ds.toParent())
6419 {
6420 if (!adParent)
6421 adParent = ds.toParent();
6422 error(ds.loc, "`%s` must have same parent `%s` as alias `%s`", ds.ident.toChars(), adParent.toChars(), ad.toChars());
6423 return null;
6424 }
6425 if (!adParent.isTemplateInstance())
6426 {
6427 ds.error("must be a member of a template");
6428 return null;
6429 }
6430
6431 return ad;
6432 }
6433
6434 auto aliassym = findAliasDeclaration(ds, sc);
6435 if (!aliassym)
6436 return errorRet();
6437
6438 if (aliassym.adFlags & Declaration.wasRead)
6439 {
6440 if (!aliassym.errors)
6441 error(ds.loc, "%s was read, so cannot reassign", aliassym.toChars());
6442 aliassym.errors = true;
6443 return errorRet();
6444 }
6445
6446 aliassym.adFlags |= Declaration.ignoreRead; // temporarilly allow reads of aliassym
6447
6448 const storage_class = sc.stc & (STC.deprecated_ | STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6449
6450 if (ds.aliassym)
6451 {
6452 auto fd = ds.aliassym.isFuncLiteralDeclaration();
6453 auto td = ds.aliassym.isTemplateDeclaration();
6454 if (fd && fd.semanticRun >= PASS.semanticdone)
6455 {
6456 }
6457 else if (fd || td && td.literal)
6458 {
6459
6460 Expression e = new FuncExp(ds.loc, ds.aliassym);
6461 e = e.expressionSemantic(sc);
6462 auto fe = e.isFuncExp();
6463 if (!fe)
6464 return errorRet();
6465 ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;
6466 }
6467 else if (ds.aliassym.isTemplateInstance())
6468 ds.aliassym.dsymbolSemantic(sc);
6469
6470 aliassym.type = null;
6471 aliassym.aliassym = ds.aliassym;
6472 return;
6473 }
6474
6475 /* Given:
6476 * abc = def;
6477 * it is not knownable from the syntax whether `def` is a type or a symbol.
6478 * It appears here as `ds.type`. Do semantic analysis on `def` to disambiguate.
6479 */
6480
6481 const errors = global.errors;
6482
6483 /* This section is needed because Type.resolve() will:
6484 * const x = 3;
6485 * alias y = x;
6486 * try to convert identifier x to 3.
6487 */
6488 auto s = ds.type.toDsymbol(sc);
6489 if (errors != global.errors)
6490 return errorRet();
6491 if (s == aliassym)
6492 {
6493 ds.error("cannot resolve");
6494 return errorRet();
6495 }
6496
6497 if (!s || !s.isEnumMember())
6498 {
6499 Type t;
6500 Expression e;
6501 Scope* sc2 = sc;
6502 if (storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable))
6503 {
6504 // For 'ref' to be attached to function types, and picked
6505 // up by Type.resolve(), it has to go into sc.
6506 sc2 = sc.push();
6507 sc2.stc |= storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6508 }
6509 ds.type = ds.type.addSTC(storage_class);
6510 ds.type.resolve(ds.loc, sc2, e, t, s);
6511 if (sc2 != sc)
6512 sc2.pop();
6513
6514 if (e) // Try to convert Expression to Dsymbol
6515 {
6516 // TupleExp is naturally converted to a TupleDeclaration
6517 if (auto te = e.isTupleExp())
6518 s = new TupleDeclaration(te.loc, ds.ident, cast(Objects*)te.exps);
6519 else
6520 {
6521 s = getDsymbol(e);
6522 if (!s)
6523 {
6524 if (e.op != TOK.error)
6525 ds.error("cannot alias an expression `%s`", e.toChars());
6526 return errorRet();
6527 }
6528 }
6529 }
6530 ds.type = t;
6531 }
6532 if (s == aliassym)
6533 {
6534 assert(global.errors);
6535 return errorRet();
6536 }
6537
6538 if (s) // it's a symbolic alias
6539 {
6540 //printf("alias %s resolved to %s %s\n", toChars(), s.kind(), s.toChars());
6541 aliassym.type = null;
6542 aliassym.aliassym = s;
6543 aliassym.storage_class |= sc.stc & STC.deprecated_;
6544 aliassym.visibility = sc.visibility;
6545 aliassym.userAttribDecl = sc.userAttribDecl;
6546 }
6547 else // it's a type alias
6548 {
6549 //printf("alias %s resolved to type %s\n", toChars(), type.toChars());
6550 aliassym.type = ds.type.typeSemantic(ds.loc, sc);
6551 aliassym.aliassym = null;
6552 }
6553
6554
6555 aliassym.adFlags &= ~Declaration.ignoreRead;
6556
6557 if (aliassym.type && aliassym.type.ty == Terror ||
6558 global.gag && errors != global.errors)
6559 {
6560 aliassym.type = Type.terror;
6561 aliassym.aliassym = null;
6562 return errorRet();
6563 }
6564
6565 ds.semanticRun = PASS.semanticdone;
6566 }
6567
6568 /***************************************
6569 * Find all instance fields in `ad`, then push them into `fields`.
6570 *
6571 * Runs semantic() for all instance field variables, but also
6572 * the field types can remain yet not resolved forward references,
6573 * except direct recursive definitions.
6574 * After the process sizeok is set to Sizeok.fwd.
6575 *
6576 * Params:
6577 * ad = the AggregateDeclaration to examine
6578 * Returns:
6579 * false if any errors occur.
6580 */
determineFields(AggregateDeclaration ad)6581 bool determineFields(AggregateDeclaration ad)
6582 {
6583 if (ad._scope)
6584 dsymbolSemantic(ad, null);
6585 if (ad.sizeok != Sizeok.none)
6586 return true;
6587
6588 //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim);
6589 // determineFields can be called recursively from one of the fields's v.semantic
6590 ad.fields.setDim(0);
6591
6592 static int func(Dsymbol s, AggregateDeclaration ad)
6593 {
6594 auto v = s.isVarDeclaration();
6595 if (!v)
6596 return 0;
6597 if (v.storage_class & STC.manifest)
6598 return 0;
6599
6600 if (v.semanticRun < PASS.semanticdone)
6601 v.dsymbolSemantic(null);
6602 // Return in case a recursive determineFields triggered by v.semantic already finished
6603 if (ad.sizeok != Sizeok.none)
6604 return 1;
6605
6606 if (v.aliassym)
6607 return 0; // If this variable was really a tuple, skip it.
6608
6609 if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
6610 return 0;
6611 if (!v.isField() || v.semanticRun < PASS.semanticdone)
6612 return 1; // unresolvable forward reference
6613
6614 ad.fields.push(v);
6615
6616 if (v.storage_class & STC.ref_)
6617 return 0;
6618 auto tv = v.type.baseElemOf();
6619 if (auto tvs = tv.isTypeStruct())
6620 {
6621 if (ad == tvs.sym)
6622 {
6623 const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? "static array of " : "";
6624 ad.error("cannot have field `%s` with %ssame struct type", v.toChars(), psz);
6625 ad.type = Type.terror;
6626 ad.errors = true;
6627 return 1;
6628 }
6629 }
6630 return 0;
6631 }
6632
6633 if (ad.members)
6634 {
6635 for (size_t i = 0; i < ad.members.dim; i++)
6636 {
6637 auto s = (*ad.members)[i];
6638 if (s.apply(&func, ad))
6639 {
6640 if (ad.sizeok != Sizeok.none)
6641 {
6642 // recursive determineFields already finished
6643 return true;
6644 }
6645 return false;
6646 }
6647 }
6648 }
6649
6650 if (ad.sizeok != Sizeok.done)
6651 ad.sizeok = Sizeok.fwd;
6652
6653 return true;
6654 }
6655