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