2 * Does the semantic 1 pass on the AST, which looks at symbol declarations but not initializers
5 * Copyright: Copyright (C) 1999-2023 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)
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
13 module dmd.dsymbolsem;
15 import core.stdc.stdio;
16 import core.stdc.string;
21 import dmd.arraytypes;
22 import dmd.astcodegen;
30 import dmd.declaration;
33 import dmd.dinterpret;
43 import dmd.expression;
44 import dmd.expressionsem;
48 import dmd.identifier;
62 import dmd.root.array;
63 import dmd.root.filename;
64 import dmd.common.outbuffer;
66 import dmd.root.rootobject;
70 import dmd.sideeffect;
71 import dmd.statementsem;
72 import dmd.staticassert;
77 import dmd.templateparamsem;
83 private uint setMangleOverride(Dsymbol s, const(char)[] sym)
85 if (s.isFuncDeclaration() || s.isVarDeclaration())
87 s.isDeclaration().mangleOverride = sym;
91 if (auto ad = s.isAttribDeclaration())
95 ad.include(null).foreachDsymbol( (s) { nestedCount += setMangleOverride(s, sym); } );
103 * Apply pragma printf/scanf to FuncDeclarations under `s`,
104 * poking through attribute declarations such as `extern(C)`
105 * but not through aggregates or function bodies.
108 * s = symbol to apply
109 * printf = `true` for printf, `false` for scanf
111 private void setPragmaPrintf(Dsymbol s, bool printf)
113 if (auto fd = s.isFuncDeclaration())
119 if (auto ad = s.isAttribDeclaration())
121 ad.include(null).foreachDsymbol( (s) { setPragmaPrintf(s, printf); } );
125 /*************************************
126 * Does semantic analysis on the public face of declarations.
128 extern(C++) void dsymbolSemantic(Dsymbol dsym, Scope* sc)
130 scope v = new DsymbolSemanticVisitor(sc);
134 /***************************************************
135 * Determine the numerical value of the AlignmentDeclaration
137 * ad = AlignmentDeclaration
140 * ad with alignment value determined
142 AlignDeclaration getAlignment(AlignDeclaration ad, Scope* sc)
144 if (!ad.salign.isUnknown()) // UNKNOWN is 0
149 ad.salign.setDefault();
153 dinteger_t strictest = 0; // strictest alignment
155 foreach (ref exp; (*ad.exps)[])
158 auto e = exp.expressionSemantic(sc);
159 e = resolveProperties(sc, e);
161 e = e.ctfeInterpret();
162 exp = e; // could be re-evaluated if exps are assigned to more than one AlignDeclaration by CParser.applySpecifier(),
163 // e.g. `_Alignas(8) int a, b;`
164 if (e.op == EXP.error)
168 auto n = e.toInteger();
169 if (sc.flags & SCOPE.Cfile && n == 0) // C11 6.7.5-6 allows 0 for alignment
172 if (n < 1 || n & (n - 1) || ushort.max < n || !e.type.isintegral())
174 error(ad.loc, "alignment must be an integer positive power of 2, not 0x%llx", cast(ulong)n);
177 if (n > strictest) // C11 6.7.5-6
182 if (errors || strictest == 0) // C11 6.7.5-6 says alignment of 0 means no effect
183 ad.salign.setDefault();
185 ad.salign.set(cast(uint) strictest);
190 const(char)* getMessage(DeprecatedDeclaration dd)
192 if (auto sc = dd._scope)
197 dd.msg = dd.msg.expressionSemantic(sc);
198 dd.msg = resolveProperties(sc, dd.msg);
200 dd.msg = dd.msg.ctfeInterpret();
202 if (auto se = dd.msg.toStringExp())
203 dd.msgstr = se.toStringz().ptr;
205 dd.msg.error("compile time constant expected, not `%s`", dd.msg.toChars());
211 // Returns true if a contract can appear without a function body.
212 package bool allowsContractWithoutBody(FuncDeclaration funcdecl)
214 assert(!funcdecl.fbody);
216 /* Contracts can only appear without a body when they are virtual
217 * interface functions or abstract.
219 Dsymbol parent = funcdecl.toParent();
220 InterfaceDeclaration id = parent.isInterfaceDeclaration();
222 if (!funcdecl.isAbstract() &&
223 (funcdecl.fensures || funcdecl.frequires) &&
224 !(id && funcdecl.isVirtual()))
226 auto cd = parent.isClassDeclaration();
227 if (!(cd && cd.isAbstract()))
234 Tests whether the `ctor` that is part of `ti` is an rvalue constructor
235 (i.e. a constructor that receives a single parameter of the same type as
236 `Unqual!typeof(this)`). If that is the case and `sd` contains a copy
237 constructor, than an error is issued.
240 sd = struct declaration that may contin both an rvalue and copy constructor
241 ctor = constructor that will be checked if it is an evalue constructor
242 ti = template instance the ctor is part of
245 `false` if ctor is not an rvalue constructor or if `sd` does not contain a
246 copy constructor. `true` otherwise
248 bool checkHasBothRvalueAndCpCtor(StructDeclaration sd, CtorDeclaration ctor, TemplateInstance ti)
251 auto tf = cast(TypeFunction)ctor.type;
252 auto dim = tf.parameterList.length;
253 if (sd && sd.hasCopyCtor && (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
255 auto param = tf.parameterList[0];
256 if (!(param.storageClass & STC.ref_) && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
258 .error(loc, "cannot define both an rvalue constructor and a copy constructor for `struct %s`", sd.toChars());
259 .errorSupplemental(ti.loc, "Template instance `%s` creates an rvalue constructor for `struct %s`",
260 ti.toPrettyChars(), sd.toChars());
269 private extern(C++) final class DsymbolSemanticVisitor : Visitor
271 alias visit = Visitor.visit;
274 this(Scope* sc) scope
279 // Save the scope and defer semantic analysis on the Dsymbol.
280 private void deferDsymbolSemantic(Dsymbol s, Scope *scx)
282 s._scope = scx ? scx : sc.copy();
283 s._scope.setNoFree();
284 Module.addDeferredSemantic(s);
287 override void visit(Dsymbol dsym)
289 dsym.error("%p has no semantic routine", dsym);
292 override void visit(ScopeDsymbol) { }
293 override void visit(Declaration) { }
295 override void visit(AliasThis dsym)
297 if (dsym.semanticRun != PASS.initial)
309 dsym.semanticRun = PASS.semantic;
310 dsym.isDeprecated_ = !!(sc.stc & STC.deprecated_);
312 Dsymbol p = sc.parent.pastMixin();
313 AggregateDeclaration ad = p.isAggregateDeclaration();
316 error(dsym.loc, "alias this can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
320 // @@@DEPRECATED_2.121@@@
321 // Deprecated in 2.101 - Can be removed in 2.121
322 if (ad.isClassDeclaration() || ad.isInterfaceDeclaration())
323 deprecation(dsym.loc, "alias this for classes/interfaces is deprecated");
326 Dsymbol s = ad.search(dsym.loc, dsym.ident);
329 s = sc.search(dsym.loc, dsym.ident, null);
331 error(dsym.loc, "`%s` is not a member of `%s`", s.toChars(), ad.toChars());
333 error(dsym.loc, "undefined identifier `%s`", dsym.ident.toChars());
336 if (ad.aliasthis && s != ad.aliasthis)
338 error(dsym.loc, "there can be only one alias this");
342 /* disable the alias this conversion so the implicit conversion check
348 if (sx.isAliasDeclaration())
350 Declaration d = sx.isDeclaration();
351 if (d && !d.isTupleDeclaration())
353 /* https://issues.dlang.org/show_bug.cgi?id=18429
355 * If the identifier in the AliasThis declaration
356 * is defined later and is a voldemort type, we must
357 * perform semantic on the declaration to deduce the type.
360 d.dsymbolSemantic(sc);
364 if (ad.type.implicitConvTo(t) > MATCH.nomatch)
366 error(dsym.loc, "alias this is not reachable as `%s` already converts to `%s`", ad.toChars(), t.toChars());
371 // Restore alias this
373 dsym.semanticRun = PASS.semanticdone;
376 override void visit(AliasDeclaration dsym)
378 if (dsym.semanticRun >= PASS.semanticdone)
380 assert(dsym.semanticRun <= PASS.semantic);
385 dsym.semanticRun = PASS.semantic;
387 dsym.storage_class |= sc.stc & STC.deprecated_;
388 dsym.visibility = sc.visibility;
389 dsym.userAttribDecl = sc.userAttribDecl;
391 if (!sc.func && dsym.inNonRoot())
394 aliasSemantic(dsym, sc);
397 override void visit(AliasAssign dsym)
399 //printf("visit(AliasAssign)\n");
400 if (dsym.semanticRun >= PASS.semanticdone)
402 assert(dsym.semanticRun <= PASS.semantic);
404 if (!sc.func && dsym.inNonRoot())
407 aliasAssignSemantic(dsym, sc);
410 override void visit(VarDeclaration dsym)
414 printf("VarDeclaration::semantic('%s', parent = '%s') sem = %d\n",
415 dsym.toChars(), sc.parent ? sc.parent.toChars() : null, dsym.semanticRun);
416 printf(" type = %s\n", dsym.type ? dsym.type.toChars() : "null");
417 printf(" stc = x%llx\n", dsym.storage_class);
418 printf(" storage_class = x%llx\n", dsym.storage_class);
419 printf("linkage = %d\n", dsym.linkage);
420 //if (strcmp(toChars(), "mul") == 0) assert(0);
422 //if (semanticRun > PASS.initial)
424 //semanticRun = PSSsemantic;
426 if (dsym.semanticRun >= PASS.semanticdone)
429 if (sc && sc.inunion && sc.inunion.isAnonDeclaration())
430 dsym.overlapped = true;
432 dsym.sequenceNumber = global.varSequenceNumber++;
434 dsym.maybeScope = true;
447 dsym.semanticRun = PASS.semantic;
449 // 'static foreach' variables should not inherit scope properties
450 // https://issues.dlang.org/show_bug.cgi?id=19482
451 if ((dsym.storage_class & (STC.foreach_ | STC.local)) == (STC.foreach_ | STC.local))
453 dsym._linkage = LINK.d;
454 dsym.visibility = Visibility(Visibility.Kind.public_);
455 dsym.overlapped = false; // unset because it is modified early on this function
456 dsym.userAttribDecl = null; // unset because it is set by Dsymbol.setScope()
460 /* Pick up storage classes from context, but except synchronized,
461 * override, abstract, and final.
463 dsym.storage_class |= (sc.stc & ~(STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_));
464 dsym.userAttribDecl = sc.userAttribDecl;
465 dsym.cppnamespace = sc.namespace;
466 dsym._linkage = sc.linkage;
467 dsym.visibility = sc.visibility;
468 dsym.alignment = sc.alignment();
471 if (dsym.storage_class & STC.extern_ && dsym._init)
472 dsym.error("extern symbols cannot have initializers");
474 AggregateDeclaration ad = dsym.isThis();
476 dsym.storage_class |= ad.storage_class & STC.TYPECTOR;
478 /* If auto type inference, do the inference
485 // Infering the type requires running semantic,
486 // so mark the scope as ctfe if required
487 bool needctfe = (dsym.storage_class & (STC.manifest | STC.static_)) != 0;
490 sc.flags |= SCOPE.condition;
493 //printf("inferring type for %s with init %s\n", dsym.toChars(), dsym._init.toChars());
494 dsym._init = dsym._init.inferType(sc);
495 dsym.type = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0).type;
502 /* This is a kludge to support the existing syntax for RAII
505 dsym.storage_class &= ~STC.auto_;
506 dsym.originalType = dsym.type.syntaxCopy();
510 if (!dsym.originalType)
511 dsym.originalType = dsym.type.syntaxCopy();
513 /* Prefix function attributes of variable declaration can affect
515 * pure nothrow void function() fp;
516 * static assert(is(typeof(fp) == void function() pure nothrow));
518 Scope* sc2 = sc.push();
519 sc2.stc |= (dsym.storage_class & STC.FUNCATTR);
521 dsym.type = dsym.type.typeSemantic(dsym.loc, sc2);
525 //printf(" semantic type = %s\n", dsym.type ? dsym.type.toChars() : "null");
526 if (dsym.type.ty == Terror)
529 dsym.type.checkDeprecated(dsym.loc, sc);
530 dsym.parent = sc.parent;
531 //printf("this = %p, parent = %p, '%s'\n", dsym, dsym.parent, dsym.parent.toChars());
533 /* If scope's alignment is the default, use the type's alignment,
534 * otherwise the scope overrrides.
536 if (dsym.alignment.isDefault())
537 dsym.alignment = dsym.type.alignment(); // use type's alignment
539 //printf("sc.stc = %x\n", sc.stc);
540 //printf("storage_class = x%x\n", storage_class);
542 dsym.type.checkComplexTransition(dsym.loc, sc);
544 // Calculate type size + safety checks
545 if (dsym.storage_class & STC.gshared && !dsym.isMember())
547 sc.setUnsafe(false, dsym.loc, "__gshared not allowed in safe functions; use shared");
550 Dsymbol parent = dsym.toParent();
552 Type tb = dsym.type.toBasetype();
553 Type tbn = tb.baseElemOf();
554 if (tb.ty == Tvoid && !(dsym.storage_class & STC.lazy_))
558 dsym.error("- type `%s` is inferred from initializer `%s`, and variables cannot be of type `void`", dsym.type.toChars(), dsym._init.toChars());
561 dsym.error("- variables cannot be of type `void`");
562 dsym.type = Type.terror;
565 if (tb.ty == Tfunction)
567 dsym.error("cannot be declared to be a function");
568 dsym.type = Type.terror;
571 if (auto ts = tb.isTypeStruct())
573 // Require declarations, except when it's just a reference (as done for pointers)
574 // or when the variable is defined externally
575 if (!ts.sym.members && !(dsym.storage_class & (STC.ref_ | STC.extern_)))
577 dsym.error("- no definition of struct `%s`", ts.toChars());
579 // Explain why the definition is required when it's part of another type
580 if (!dsym.type.isTypeStruct())
582 // Prefer Loc of the dependant type
583 const s = dsym.type.toDsymbol(sc);
584 const loc = (s ? s : dsym).loc;
585 loc.errorSupplemental("required by type `%s`", dsym.type.toChars());
588 // Flag variable as error to avoid invalid error messages due to unknown size
589 dsym.type = Type.terror;
592 if ((dsym.storage_class & STC.auto_) && !inferred)
593 dsym.error("- storage class `auto` has no effect if type is not inferred, did you mean `scope`?");
595 if (auto tt = tb.isTypeTuple())
597 /* Instead, declare variables for each of the tuple elements
600 size_t nelems = Parameter.dim(tt.arguments);
601 Expression ie = (dsym._init && !dsym._init.isVoidInitializer()) ? dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0) : null;
603 ie = ie.expressionSemantic(sc);
604 if (nelems > 0 && ie)
606 auto iexps = new Expressions();
608 auto exps = new Expressions();
609 for (size_t pos = 0; pos < iexps.length; pos++)
612 Expression e = (*iexps)[pos];
613 Parameter arg = Parameter.getNth(tt.arguments, pos);
614 arg.type = arg.type.typeSemantic(dsym.loc, sc);
615 //printf("[%d] iexps.length = %d, ", pos, iexps.length);
616 //printf("e = (%s %s, %s), ", Token.tochars[e.op], e.toChars(), e.type.toChars());
617 //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
621 if (iexps.length > nelems)
623 if (e.type.implicitConvTo(arg.type))
627 if (auto te = e.isTupleExp())
629 if (iexps.length - 1 + te.exps.length > nelems)
633 iexps.insert(pos, te.exps);
634 (*iexps)[pos] = Expression.combine(te.e0, (*iexps)[pos]);
637 else if (isAliasThisTuple(e))
639 auto v = copyToTemp(0, "__tup", e);
640 v.dsymbolSemantic(sc);
641 auto ve = new VarExp(dsym.loc, v);
646 expandAliasThisTuples(exps, 0);
648 for (size_t u = 0; u < exps.length; u++)
651 Expression ee = (*exps)[u];
652 arg = Parameter.getNth(tt.arguments, pos + u);
653 arg.type = arg.type.typeSemantic(dsym.loc, sc);
654 //printf("[%d+%d] exps.length = %d, ", pos, u, exps.length);
655 //printf("ee = (%s %s, %s), ", Token.tochars[ee.op], ee.toChars(), ee.type.toChars());
656 //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
658 size_t iexps_dim = iexps.length - 1 + exps.length;
659 if (iexps_dim > nelems)
661 if (ee.type.implicitConvTo(arg.type))
664 if (expandAliasThisTuples(exps, u) != -1)
668 if ((*exps)[0] != ve)
670 Expression e0 = (*exps)[0];
671 (*exps)[0] = new CommaExp(dsym.loc, new DeclarationExp(dsym.loc, v), e0);
672 (*exps)[0].type = e0.type;
675 iexps.insert(pos, exps);
680 if (iexps.length < nelems)
683 ie = new TupleExp(dsym._init.loc, iexps);
687 if (ie && ie.op == EXP.tuple)
689 auto te = ie.isTupleExp();
690 size_t tedim = te.exps.length;
693 error(dsym.loc, "tuple of %d elements cannot be assigned to tuple of %d elements", cast(int)tedim, cast(int)nelems);
694 for (size_t u = tedim; u < nelems; u++) // fill dummy expression
695 te.exps.push(ErrorExp.get());
699 auto exps = new Objects(nelems);
700 for (size_t i = 0; i < nelems; i++)
702 Parameter arg = Parameter.getNth(tt.arguments, i);
705 buf.printf("__%s_field_%llu", dsym.ident.toChars(), cast(ulong)i);
706 auto id = Identifier.idPool(buf[]);
711 Expression einit = ie;
712 if (auto te = ie.isTupleExp())
714 einit = (*te.exps)[i];
716 einit = Expression.combine(te.e0, einit);
718 ti = new ExpInitializer(einit.loc, einit);
721 ti = dsym._init ? dsym._init.syntaxCopy() : null;
723 StorageClass storage_class = STC.temp | dsym.storage_class;
724 if ((dsym.storage_class & STC.parameter) && (arg.storageClass & STC.parameter))
725 storage_class |= arg.storageClass;
726 auto v = new VarDeclaration(dsym.loc, arg.type, id, ti, storage_class);
727 //printf("declaring field %s of type %s\n", v.toChars(), v.type.toChars());
728 v.overlapped = dsym.overlapped;
730 v.dsymbolSemantic(sc);
732 Expression e = new VarExp(dsym.loc, v);
735 auto v2 = new TupleDeclaration(dsym.loc, dsym.ident, exps);
736 v2.parent = dsym.parent;
738 dsym.aliasTuple = v2;
739 dsym.semanticRun = PASS.semanticdone;
743 /* Storage class can modify the type
745 dsym.type = dsym.type.addStorageClass(dsym.storage_class);
747 /* Adjust storage class to reflect type
749 if (dsym.type.isConst())
751 dsym.storage_class |= STC.const_;
752 if (dsym.type.isShared())
753 dsym.storage_class |= STC.shared_;
755 else if (dsym.type.isImmutable())
756 dsym.storage_class |= STC.immutable_;
757 else if (dsym.type.isShared())
758 dsym.storage_class |= STC.shared_;
759 else if (dsym.type.isWild())
760 dsym.storage_class |= STC.wild;
762 if (StorageClass stc = dsym.storage_class & (STC.synchronized_ | STC.override_ | STC.abstract_ | STC.final_))
764 if (stc == STC.final_)
765 dsym.error("cannot be `final`, perhaps you meant `const`?");
769 stcToBuffer(&buf, stc);
770 dsym.error("cannot be `%s`", buf.peekChars());
772 dsym.storage_class &= ~stc; // strip off
775 // At this point we can add `scope` to the STC instead of `in`,
776 // because we are never going to use this variable's STC for user messages
777 if (dsym.storage_class & STC.in_ && global.params.previewIn)
778 dsym.storage_class |= STC.scope_;
780 if (dsym.storage_class & STC.scope_)
782 StorageClass stc = dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.gshared);
786 stcToBuffer(&buf, stc);
787 dsym.error("cannot be `scope` and `%s`", buf.peekChars());
789 else if (dsym.isMember())
791 error(dsym.loc, "field `%s` cannot be `scope`", dsym.toChars());
793 else if (!dsym.type.hasPointers())
795 dsym.storage_class &= ~STC.scope_; // silently ignore; may occur in generic code
796 // https://issues.dlang.org/show_bug.cgi?id=23168
797 if (dsym.storage_class & STC.returnScope)
799 dsym.storage_class &= ~(STC.return_ | STC.returnScope);
804 if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.gshared | STC.ctfe))
809 AggregateDeclaration aad = parent.isAggregateDeclaration();
812 if (global.params.vfield && dsym.storage_class & (STC.const_ | STC.immutable_) && dsym._init && !dsym._init.isVoidInitializer())
814 const(char)* s = (dsym.storage_class & STC.immutable_) ? "immutable" : "const";
815 message(dsym.loc, "`%s.%s` is `%s` field", ad.toPrettyChars(), dsym.toChars(), s);
817 dsym.storage_class |= STC.field;
818 if (auto ts = tbn.isTypeStruct())
819 if (ts.sym.noDefaultCtor)
821 if (!dsym.isThisDeclaration() && !dsym._init)
822 aad.noDefaultCtor = true;
826 InterfaceDeclaration id = parent.isInterfaceDeclaration();
829 error(dsym.loc, "field `%s` not allowed in interface", dsym.toChars());
831 else if (aad && aad.sizeok == Sizeok.done)
833 error(dsym.loc, "cannot declare field `%s` because it will change the determined size of `%s`", dsym.toChars(), aad.toChars());
836 /* Templates cannot add fields to aggregates
838 TemplateInstance ti = parent.isTemplateInstance();
841 // Take care of nested templates
844 TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
849 // If it's a member template
850 AggregateDeclaration ad2 = ti.tempdecl.isMember();
851 if (ad2 && dsym.storage_class != STC.undefined_)
853 dsym.error("- cannot use template to add field to aggregate `%s`", ad2.toChars());
858 /* If the alignment of a stack local is greater than the stack alignment,
859 * note it in the enclosing function's alignSectionVars
863 if (!dsym.alignment.isDefault() && sc.func &&
864 dsym.alignment.get() > target.stackAlign() &&
865 sc.func && !dsym.isDataseg() && !dsym.isParameter() && !dsym.isField())
868 if (!fd.alignSectionVars)
869 fd.alignSectionVars = new VarDeclarations();
870 fd.alignSectionVars.push(dsym);
874 if ((dsym.storage_class & (STC.ref_ | STC.parameter | STC.foreach_ | STC.temp | STC.result)) == STC.ref_ && dsym.ident != Id.This)
876 dsym.error("- only parameters, functions and `foreach` declarations can be `ref`");
879 if (dsym.type.hasWild())
881 if (dsym.storage_class & (STC.static_ | STC.extern_ | STC.gshared | STC.manifest | STC.field) || dsym.isDataseg())
883 dsym.error("- only parameters or stack-based variables can be `inout`");
885 FuncDeclaration func = sc.func;
889 func = func.fes.func;
891 for (FuncDeclaration fd = func; fd; fd = fd.toParentDecl().isFuncDeclaration())
893 if (fd.type.isTypeFunction().iswild)
901 dsym.error("- `inout` variables can only be declared inside `inout` functions");
906 if (!(dsym.storage_class & (STC.ctfe | STC.extern_ | STC.ref_ | STC.result)) &&
907 tbn.ty == Tstruct && tbn.isTypeStruct().sym.noDefaultCtor)
913 /* For fields, we'll check the constructor later to make sure it is initialized
915 dsym.storage_class |= STC.nodefaultctor;
917 else if (dsym.storage_class & STC.parameter)
921 dsym.error("- default construction is disabled for type `%s`", dsym.type.toChars());
925 FuncDeclaration fd = parent.isFuncDeclaration();
926 if (dsym.type.isscope() && !(dsym.storage_class & STC.nodtor))
928 if (dsym.storage_class & (STC.field | STC.out_ | STC.ref_ | STC.static_ | STC.manifest | STC.gshared) || !fd)
930 dsym.error("globals, statics, fields, manifest constants, ref and out parameters cannot be `scope`");
933 // @@@DEPRECATED_2.097@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
934 // Deprecated in 2.087
935 // Remove this when the feature is removed from the language
936 if (!(dsym.storage_class & STC.scope_))
938 if (!(dsym.storage_class & STC.parameter) && dsym.ident != Id.withSym)
939 dsym.error("reference to `scope class` must be `scope`");
943 // Calculate type size + safety checks
946 if (dsym._init && dsym._init.isVoidInitializer())
949 if (dsym.type.hasPointers()) // also computes type size
950 sc.setUnsafe(false, dsym.loc,
951 "`void` initializers for pointers not allowed in safe functions");
952 else if (dsym.type.hasInvariant())
953 sc.setUnsafe(false, dsym.loc,
954 "`void` initializers for structs with invariants are not allowed in safe functions");
955 else if (dsym.type.hasSystemFields())
956 sc.setUnsafePreview(global.params.systemVariables, false, dsym.loc,
957 "`void` initializers for `@system` variables not allowed in safe functions");
959 else if (!dsym._init &&
960 !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.gshared | STC.manifest | STC.field | STC.parameter)) &&
961 dsym.type.hasVoidInitPointers())
963 sc.setUnsafe(false, dsym.loc, "`void` initializers for pointers not allowed in safe functions");
967 if ((!dsym._init || dsym._init.isVoidInitializer) && !fd)
969 // If not mutable, initializable by constructor only
970 dsym.setInCtorOnly = true;
974 { } // remember we had an explicit initializer
975 else if (dsym.storage_class & STC.manifest)
976 dsym.error("- manifest constants must have initializers");
978 // Don't allow non-extern, non-__gshared variables to be interfaced with C++
979 if (dsym._linkage == LINK.cpp && !(dsym.storage_class & (STC.ctfe | STC.extern_ | STC.gshared)) && dsym.isDataseg())
981 const char* p = (dsym.storage_class & STC.shared_) ? "shared" : "static";
982 dsym.error("cannot have `extern(C++)` linkage because it is `%s`", p);
983 errorSupplemental(dsym.loc, "perhaps declare it as `__gshared` instead");
989 if (sc.flags & SCOPE.Cfile && !dsym._init)
991 addDefaultCInitializer(dsym);
994 !(dsym.storage_class & (STC.static_ | STC.gshared | STC.extern_)) &&
996 (!(dsym.storage_class & (STC.field | STC.in_ | STC.foreach_ | STC.parameter | STC.result)) ||
997 (dsym.storage_class & STC.out_)) &&
998 (sz = dsym.type.size()) != 0)
1000 // Provide a default initializer
1002 //printf("Providing default initializer for '%s'\n", dsym.toChars());
1003 if (sz == SIZE_INVALID && dsym.type.ty != Terror)
1004 dsym.error("- size of type `%s` is invalid", dsym.type.toChars());
1006 Type tv = dsym.type;
1007 while (tv.ty == Tsarray) // Don't skip Tenum
1009 if (tv.needsNested())
1011 /* Nested struct requires valid enclosing frame pointer.
1012 * In StructLiteralExp::toElem(), it's calculated.
1014 assert(tbn.ty == Tstruct);
1015 checkFrameAccess(dsym.loc, sc, tbn.isTypeStruct().sym);
1017 Expression e = tv.defaultInitLiteral(dsym.loc);
1018 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
1019 e = e.expressionSemantic(sc);
1020 dsym._init = new ExpInitializer(dsym.loc, e);
1023 if (tv.ty == Tstruct && tv.isTypeStruct().sym.zeroInit)
1025 /* If a struct is all zeros, as a special case
1026 * set its initializer to the integer 0.
1027 * In AssignExp::toElem(), we check for this and issue
1028 * a memset() to initialize the struct.
1029 * Must do same check in interpreter.
1031 Expression e = IntegerExp.literal!0;
1032 e = new BlitExp(dsym.loc, new VarExp(dsym.loc, dsym), e);
1033 e.type = dsym.type; // don't type check this, it would fail
1034 dsym._init = new ExpInitializer(dsym.loc, e);
1037 if (dsym.type.baseElemOf().ty == Tvoid)
1039 dsym.error("of type `%s` does not have a default initializer", dsym.type.toChars());
1041 else if (auto e = dsym.type.defaultInit(dsym.loc))
1043 dsym._init = new ExpInitializer(dsym.loc, e);
1046 // Default initializer is always a blit
1052 sc.stc &= ~(STC.TYPECTOR | STC.pure_ | STC.nothrow_ | STC.nogc | STC.ref_ | STC.disable);
1054 if (sc.flags & SCOPE.Cfile &&
1055 dsym.type.isTypeSArray() &&
1056 dsym.type.isTypeSArray().isIncomplete() &&
1057 dsym._init.isVoidInitializer() &&
1058 !(dsym.storage_class & STC.field))
1060 dsym.error("- incomplete array type must have initializer");
1063 ExpInitializer ei = dsym._init.isExpInitializer();
1065 if (ei) // https://issues.dlang.org/show_bug.cgi?id=13424
1066 // Preset the required type to fail in FuncLiteralDeclaration::semantic3
1067 ei.exp = inferType(ei.exp, dsym.type);
1069 // If inside function, there is no semantic3() call
1070 if (sc.func || sc.intypeof == 1)
1072 // If local variable, use AssignExp to handle all the various
1074 if (fd && !(dsym.storage_class & (STC.manifest | STC.static_ | STC.gshared | STC.extern_)) && !dsym._init.isVoidInitializer())
1076 //printf("fd = '%s', var = '%s'\n", fd.toChars(), dsym.toChars());
1079 ArrayInitializer ai = dsym._init.isArrayInitializer();
1081 if (ai && tb.ty == Taarray)
1082 e = ai.toAssocArrayLiteral();
1084 e = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0);
1087 // Run semantic, but don't need to interpret
1088 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITnointerpret);
1089 e = dsym._init.initializerToExpression(null, (sc.flags & SCOPE.Cfile) != 0);
1092 dsym.error("is not a static and cannot have static initializer");
1096 ei = new ExpInitializer(dsym._init.loc, e);
1099 else if (sc.flags & SCOPE.Cfile && dsym.type.isTypeSArray() &&
1100 dsym.type.isTypeSArray().isIncomplete())
1102 // C11 6.7.9-22 determine the size of the incomplete array,
1103 // or issue an error that the initializer is invalid.
1104 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
1107 if (ei && dsym.isScope())
1109 Expression ex = ei.exp.lastComma();
1110 if (ex.op == EXP.blit || ex.op == EXP.construct)
1111 ex = (cast(AssignExp)ex).e2;
1112 if (auto ne = ex.isNewExp())
1114 /* See if initializer is a NewExp that can be allocated on the stack.
1116 if (dsym.type.toBasetype().ty == Tclass)
1118 /* Unsafe to allocate on stack if constructor is not `scope` because the `this` can leak.
1119 * https://issues.dlang.org/show_bug.cgi?id=23145
1121 if (ne.member && !(ne.member.storage_class & STC.scope_))
1123 if (sc.func.isSafe())
1125 // @@@DEPRECATED_2.112@@@
1126 deprecation(dsym.loc,
1127 "`scope` allocation of `%s` requires that constructor be annotated with `scope`",
1129 deprecationSupplemental(ne.member.loc, "is the location of the constructor");
1132 sc.func.setUnsafe();
1135 dsym.onstack = true;
1138 else if (auto fe = ex.isFuncExp())
1140 // or a delegate that doesn't escape a reference to the function
1141 FuncDeclaration f = fe.fd;
1142 if (f.tookAddressOf)
1145 else if (auto ale = ex.isArrayLiteralExp())
1147 // or an array literal assigned to a `scope` variable
1148 if (global.params.useDIP1000 == FeatureState.enabled
1149 && !dsym.type.nextOf().needsDestruction())
1154 Expression exp = ei.exp;
1155 Expression e1 = new VarExp(dsym.loc, dsym);
1157 exp = new BlitExp(dsym.loc, e1, exp);
1159 exp = new ConstructExp(dsym.loc, e1, exp);
1161 exp = exp.expressionSemantic(sc);
1163 exp = exp.optimize(WANTvalue);
1164 if (exp.op == EXP.error)
1166 dsym._init = new ErrorInitializer();
1174 // https://issues.dlang.org/show_bug.cgi?id=14166
1175 // Don't run CTFE for the temporary variables inside typeof
1176 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, sc.intypeof == 1 ? INITnointerpret : INITinterpret);
1177 const init_err = dsym._init.isExpInitializer();
1178 if (init_err && init_err.exp.op == EXP.showCtfeContext)
1180 errorSupplemental(dsym.loc, "compile time context created here");
1184 else if (parent.isAggregateDeclaration())
1186 dsym._scope = scx ? scx : sc.copy();
1187 dsym._scope.setNoFree();
1189 else if (dsym.storage_class & (STC.const_ | STC.immutable_ | STC.manifest) ||
1190 dsym.type.isConst() || dsym.type.isImmutable() ||
1191 sc.flags & SCOPE.Cfile)
1193 /* Because we may need the results of a const declaration in a
1194 * subsequent type, such as an array dimension, before semantic2()
1195 * gets ordinarily run, try to run semantic2() now.
1196 * If a C array is of unknown size, the initializer can provide the size. Do this
1197 * eagerly because C does it eagerly.
1202 uint errors = global.errors;
1204 // Bug 20549. Don't try this on modules or packages, syntaxCopy
1205 // could crash (inf. recursion) on a mod/pkg referencing itself
1206 if (ei && (ei.exp.op != EXP.scope_ ? true : !ei.exp.isScopeExp().sds.isPackage()))
1210 // If exp is already resolved we are done, our original init exp
1211 // could have a type painting that we need to respect
1212 // e.g. ['a'] typed as string, or [['z'], ""] as string[]
1213 // See https://issues.dlang.org/show_bug.cgi?id=15711
1217 Expression exp = ei.exp.syntaxCopy();
1219 bool needctfe = dsym.isDataseg() || (dsym.storage_class & STC.manifest);
1221 sc = sc.startCTFE();
1222 exp = exp.expressionSemantic(sc);
1223 exp = resolveProperties(sc, exp);
1229 Type tb2 = dsym.type.toBasetype();
1230 Type ti = ei.exp.type.toBasetype();
1232 /* The problem is the following code:
1235 * this(double a) { x = a * 10.0;}
1236 * this(this) { x += 2.0; }
1238 * const CopyTest z = CopyTest(5.3); // ok
1239 * const CopyTest w = z; // not ok, postblit not run
1240 * static assert(w.x == 55.0);
1241 * because the postblit doesn't get run on the initialization of w.
1243 if (auto ts = ti.isTypeStruct())
1245 StructDeclaration sd = ts.sym;
1246 /* Look to see if initializer involves a copy constructor
1247 * (which implies a postblit)
1249 // there is a copy constructor
1250 // and exp is the same struct
1251 if (sd.postblit && tb2.toDsymbol(null) == sd)
1253 // The only allowable initializer is a (non-copy) constructor
1254 if (ei.exp.isLvalue())
1255 dsym.error("of type struct `%s` uses `this(this)`, which is not allowed in static initialization", tb2.toChars());
1260 dsym._init = dsym._init.initializerSemantic(sc, dsym.type, INITinterpret);
1262 if (global.errors > errors)
1264 dsym._init = new ErrorInitializer();
1265 dsym.type = Type.terror;
1270 dsym._scope = scx ? scx : sc.copy();
1271 dsym._scope.setNoFree();
1278 /* Build code to execute destruction, if necessary
1280 dsym.edtor = dsym.callScopeDtor(sc);
1283 if (sc.func && dsym.storage_class & (STC.static_ | STC.gshared))
1284 dsym.edtor = dsym.edtor.expressionSemantic(sc._module._scope);
1286 dsym.edtor = dsym.edtor.expressionSemantic(sc);
1290 // currently disabled because of std.stdio.stdin, stdout and stderr
1291 if (dsym.isDataseg() && !(dsym.storage_class & STC.extern_))
1292 dsym.error("static storage variables cannot have destructors");
1296 dsym.semanticRun = PASS.semanticdone;
1298 if (dsym.type.toBasetype().ty == Terror)
1301 if(sc.scopesym && !sc.scopesym.isAggregateDeclaration())
1303 for (ScopeDsymbol sym = sc.scopesym; sym && dsym.endlinnum == 0;
1304 sym = sym.parent ? sym.parent.isScopeDsymbol() : null)
1305 dsym.endlinnum = sym.endlinnum;
1309 override void visit(TypeInfoDeclaration dsym)
1311 assert(dsym._linkage == LINK.c);
1314 override void visit(BitFieldDeclaration dsym)
1316 //printf("BitField::semantic('%s')\n", dsym.toChars());
1317 if (dsym.semanticRun >= PASS.semanticdone)
1320 visit(cast(VarDeclaration)dsym);
1324 if (!dsym.parent.isStructDeclaration() && !dsym.parent.isClassDeclaration())
1326 dsym.error("- bit-field must be member of struct, union, or class");
1329 sc = sc.startCTFE();
1330 auto width = dsym.width.expressionSemantic(sc);
1332 width = width.ctfeInterpret();
1333 if (!dsym.type.isintegral())
1336 width.error("bit-field type `%s` is not an integer type", dsym.type.toChars());
1339 if (!width.isIntegerExp())
1341 width.error("bit-field width `%s` is not an integer constant", dsym.width.toChars());
1344 const uwidth = width.toInteger(); // uwidth is unsigned
1345 if (uwidth == 0 && !dsym.isAnonymous())
1347 width.error("bit-field `%s` has zero width", dsym.toChars());
1350 const sz = dsym.type.size();
1351 if (sz == SIZE_INVALID)
1353 const max_width = sz * 8;
1354 if (uwidth > max_width)
1356 width.error("width `%lld` of bit-field `%s` does not fit in type `%s`", cast(long)uwidth, dsym.toChars(), dsym.type.toChars());
1359 dsym.fieldWidth = cast(uint)uwidth;
1362 override void visit(Import imp)
1366 printf("Import::semantic('%s') %s\n", toPrettyChars(), id.toChars());
1368 printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
1370 if (imp.semanticRun > PASS.initial)
1381 imp.parent = sc.parent;
1383 imp.semanticRun = PASS.semantic;
1385 // Load if not already done so
1386 bool loadErrored = false;
1389 loadErrored = imp.load(sc);
1392 imp.mod.importAll(null);
1393 imp.mod.checkImportDeprecation(imp.loc, sc);
1398 // Modules need a list of each imported module
1400 // if inside a template instantiation, the instantianting
1401 // module gets the import.
1402 // https://issues.dlang.org/show_bug.cgi?id=17181
1403 Module importer = sc._module;
1404 if (sc.minst && sc.tinst)
1406 importer = sc.minst;
1407 if (!sc.tinst.importedModules.contains(imp.mod))
1408 sc.tinst.importedModules.push(imp.mod);
1410 //printf("%s imports %s\n", importer.toChars(), imp.mod.toChars());
1411 if (!importer.aimports.contains(imp.mod))
1412 importer.aimports.push(imp.mod);
1414 if (sc.explicitVisibility)
1415 imp.visibility = sc.visibility;
1417 if (!imp.aliasId && !imp.names.length) // neither a selective nor a renamed import
1419 ScopeDsymbol scopesym = sc.getScopesym();
1423 scopesym.importScope(imp.mod, imp.visibility);
1427 imp.addPackageAccess(scopesym);
1432 imp.mod.dsymbolSemantic(null);
1435 if (imp.mod.needmoduleinfo)
1437 //printf("module4 %s because of %s\n", importer.toChars(), imp.mod.toChars());
1438 importer.needmoduleinfo = 1;
1441 sc = sc.push(imp.mod);
1442 sc.visibility = imp.visibility;
1443 for (size_t i = 0; i < imp.aliasdecls.length; i++)
1445 AliasDeclaration ad = imp.aliasdecls[i];
1446 //printf("\tImport %s alias %s = %s, scope = %p\n", toPrettyChars(), aliases[i].toChars(), names[i].toChars(), ad._scope);
1447 Dsymbol sym = imp.mod.search(imp.loc, imp.names[i], IgnorePrivateImports);
1450 import dmd.access : symbolIsVisible;
1451 if (!symbolIsVisible(sc, sym))
1452 imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`",
1453 imp.names[i].toChars(), sc._module.toChars());
1454 ad.dsymbolSemantic(sc);
1455 // If the import declaration is in non-root module,
1456 // analysis of the aliased symbol is deferred.
1457 // Therefore, don't see the ad.aliassym or ad.type here.
1461 Dsymbol s = imp.mod.search_correct(imp.names[i]);
1463 imp.mod.error(imp.loc, "import `%s` not found, did you mean %s `%s`?", imp.names[i].toChars(), s.kind(), s.toPrettyChars());
1465 imp.mod.error(imp.loc, "import `%s` not found", imp.names[i].toChars());
1466 ad.type = Type.terror;
1472 imp.semanticRun = PASS.semanticdone;
1474 // object self-imports itself, so skip that
1475 // https://issues.dlang.org/show_bug.cgi?id=7547
1476 // don't list pseudo modules __entrypoint.d, __main.d
1477 // https://issues.dlang.org/show_bug.cgi?id=11117
1478 // https://issues.dlang.org/show_bug.cgi?id=11164
1479 if (global.params.moduleDeps.buffer is null || (imp.id == Id.object && sc._module.ident == Id.object) ||
1480 strcmp(sc._module.ident.toChars(), "__main") == 0)
1483 /* The grammar of the file is:
1485 * ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
1486 * ModuleAliasIdentifier ] "\n"
1488 * BasicImportDeclaration
1489 * ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection|"string"
1490 * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
1493 * - any string with '(', ')' and '\' escaped with the '\' character
1495 OutBuffer* ob = global.params.moduleDeps.buffer;
1496 Module imod = sc._module;
1497 if (!global.params.moduleDeps.name)
1498 ob.writestring("depsImport ");
1499 ob.writestring(imod.toPrettyChars());
1500 ob.writestring(" (");
1501 escapePath(ob, imod.srcfile.toChars());
1502 ob.writestring(") : ");
1503 // use visibility instead of sc.visibility because it couldn't be
1504 // resolved yet, see the comment above
1505 visibilityToBuffer(ob, imp.visibility);
1509 stcToBuffer(ob, STC.static_);
1512 ob.writestring(": ");
1513 foreach (pid; imp.packages)
1515 ob.printf("%s.", pid.toChars());
1517 ob.writestring(imp.id.toString());
1518 ob.writestring(" (");
1520 escapePath(ob, imp.mod.srcfile.toChars());
1522 ob.writestring("???");
1524 foreach (i, name; imp.names)
1530 Identifier _alias = imp.aliases[i];
1533 ob.printf("%s", name.toChars());
1537 ob.printf("%s=%s", _alias.toChars(), name.toChars());
1540 ob.printf(" -> %s", imp.aliasId.toChars());
1544 void attribSemantic(AttribDeclaration ad)
1546 if (ad.semanticRun != PASS.initial)
1548 ad.semanticRun = PASS.semantic;
1549 Dsymbols* d = ad.include(sc);
1550 //printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
1553 Scope* sc2 = ad.newScope(sc);
1555 for (size_t i = 0; i < d.length; i++)
1557 Dsymbol s = (*d)[i];
1558 s.dsymbolSemantic(sc2);
1561 ad.errors |= errors;
1565 ad.semanticRun = PASS.semanticdone;
1568 override void visit(AttribDeclaration atd)
1570 attribSemantic(atd);
1573 override void visit(AnonDeclaration scd)
1575 //printf("\tAnonDeclaration::semantic isunion:%d ptr:%p\n", scd.isunion, scd);
1577 auto p = sc.parent.pastMixin();
1578 auto ad = p.isAggregateDeclaration();
1581 error(scd.loc, "%s can only be a part of an aggregate, not %s `%s`", scd.kind(), p.kind(), p.toChars());
1590 sc.stc &= ~(STC.auto_ | STC.scope_ | STC.static_ | STC.gshared);
1591 sc.inunion = scd.isunion ? scd : null;
1593 for (size_t i = 0; i < scd.decl.length; i++)
1595 Dsymbol s = (*scd.decl)[i];
1596 if (auto var = s.isVarDeclaration)
1599 var.overlapped = true;
1601 s.dsymbolSemantic(sc);
1606 override void visit(PragmaDeclaration pd)
1608 StringExp verifyMangleString(ref Expression e)
1610 auto se = semanticString(sc, e, "mangled name");
1616 pd.error("- zero-length string not allowed for mangled name");
1621 pd.error("- mangled name characters can only be of type `char`");
1626 /* Note: D language specification should not have any assumption about backend
1627 * implementation. Ideally pragma(mangle) can accept a string of any content.
1629 * Therefore, this validation is compiler implementation specific.
1631 auto slice = se.peekString();
1632 for (size_t i = 0; i < se.len;)
1637 if (c.isValidMangling)
1644 pd.error("char 0x%02x not allowed in mangled name", c);
1648 if (const msg = utf_decodeChar(slice, i, c))
1650 pd.error("%.*s", cast(int)msg.length, msg.ptr);
1655 pd.error("char `0x%04x` not allowed in mangled name", c);
1667 Scope* sc2 = pd.newScope(sc);
1672 foreach (s; (*pd.decl)[])
1674 if (pd.ident == Id.printf || pd.ident == Id.scanf)
1676 s.setPragmaPrintf(pd.ident == Id.printf);
1677 s.dsymbolSemantic(sc2);
1681 s.dsymbolSemantic(sc2);
1682 if (pd.ident != Id.mangle)
1685 if (auto ad = s.isAggregateDeclaration())
1687 Expression e = (*pd.args)[0];
1688 sc2 = sc2.startCTFE();
1689 e = e.expressionSemantic(sc);
1690 e = resolveProperties(sc2, e);
1691 sc2 = sc2.endCTFE();
1692 AggregateDeclaration agg;
1693 if (auto tc = e.type.isTypeClass())
1695 else if (auto ts = e.type.isTypeStruct())
1697 ad.pMangleOverride = new MangleOverride;
1698 void setString(ref Expression e)
1700 if (auto se = verifyMangleString(e))
1702 const name = (cast(const(char)[])se.peekData()).xarraydup;
1703 ad.pMangleOverride.id = Identifier.idPool(name);
1707 e.error("must be a string");
1711 ad.pMangleOverride.agg = agg;
1712 if (pd.args.length == 2)
1714 setString((*pd.args)[1]);
1717 ad.pMangleOverride.id = agg.ident;
1720 setString((*pd.args)[0]);
1722 else if (auto td = s.isTemplateDeclaration())
1724 pd.error("cannot apply to a template declaration");
1725 errorSupplemental(pd.loc, "use `template Class(Args...){ pragma(mangle, \"other_name\") class Class {} }`");
1727 else if (auto se = verifyMangleString((*pd.args)[0]))
1729 const name = (cast(const(char)[])se.peekData()).xarraydup;
1730 uint cnt = setMangleOverride(s, name);
1732 pd.error("can only apply to a single declaration");
1737 void noDeclarations()
1741 pd.error("is missing a terminating `;`");
1743 // do them anyway, to avoid segfaults.
1747 // Should be merged with PragmaStatement
1748 //printf("\tPragmaDeclaration::semantic '%s'\n", pd.toChars());
1749 if (target.supportsLinkerDirective())
1751 if (pd.ident == Id.linkerDirective)
1753 if (!pd.args || pd.args.length != 1)
1754 pd.error("one string argument expected for pragma(linkerDirective)");
1757 auto se = semanticString(sc, (*pd.args)[0], "linker directive");
1759 return noDeclarations();
1761 if (global.params.verbose)
1762 message("linkopt %.*s", cast(int)se.len, se.peekString().ptr);
1764 return noDeclarations();
1767 if (pd.ident == Id.msg)
1770 return noDeclarations();
1772 if (!pragmaMsgSemantic(pd.loc, sc, pd.args))
1775 return noDeclarations();
1777 else if (pd.ident == Id.lib)
1779 if (!pd.args || pd.args.length != 1)
1780 pd.error("string expected for library name");
1783 auto se = semanticString(sc, (*pd.args)[0], "library name");
1785 return noDeclarations();
1788 auto name = se.peekString().xarraydup;
1789 if (global.params.verbose)
1790 message("library %s", name.ptr);
1791 if (global.params.moduleDeps.buffer && !global.params.moduleDeps.name)
1793 OutBuffer* ob = global.params.moduleDeps.buffer;
1794 Module imod = sc._module;
1795 ob.writestring("depsLib ");
1796 ob.writestring(imod.toPrettyChars());
1797 ob.writestring(" (");
1798 escapePath(ob, imod.srcfile.toChars());
1799 ob.writestring(") : ");
1800 ob.writestring(name);
1803 mem.xfree(name.ptr);
1805 return noDeclarations();
1807 else if (pd.ident == Id.startaddress)
1809 pragmaStartAddressSemantic(pd.loc, sc, pd.args);
1810 return noDeclarations();
1812 else if (pd.ident == Id.Pinline)
1814 // this pragma now gets evaluated on demand in function semantic
1816 return declarations();
1818 else if (pd.ident == Id.mangle)
1821 pd.args = new Expressions();
1822 if (pd.args.length == 0 || pd.args.length > 2)
1824 pd.error(pd.args.length == 0 ? "- string expected for mangled name"
1825 : "expected 1 or 2 arguments");
1827 (*pd.args)[0] = ErrorExp.get(); // error recovery
1829 return declarations();
1831 else if (pd.ident == Id.crt_constructor || pd.ident == Id.crt_destructor)
1833 if (pd.args && pd.args.length != 0)
1834 pd.error("takes no argument");
1837 immutable isCtor = pd.ident == Id.crt_constructor;
1839 static uint recurse(Dsymbol s, bool isCtor)
1841 if (auto ad = s.isAttribDeclaration())
1844 auto decls = ad.include(null);
1847 for (size_t i = 0; i < decls.length; ++i)
1848 nestedCount += recurse((*decls)[i], isCtor);
1852 else if (auto f = s.isFuncDeclaration())
1866 if (recurse(pd, isCtor) > 1)
1867 pd.error("can only apply to a single declaration");
1869 return declarations();
1871 else if (pd.ident == Id.printf || pd.ident == Id.scanf)
1873 if (pd.args && pd.args.length != 0)
1874 pd.error("takes no argument");
1875 return declarations();
1877 else if (!global.params.ignoreUnsupportedPragmas)
1879 error(pd.loc, "unrecognized `pragma(%s)`", pd.ident.toChars());
1880 return declarations();
1883 if (!global.params.verbose)
1884 return declarations();
1886 /* Print unrecognized pragmas
1889 buf.writestring(pd.ident.toString());
1892 const errors_save = global.startGagging();
1893 for (size_t i = 0; i < pd.args.length; i++)
1895 Expression e = (*pd.args)[i];
1896 sc = sc.startCTFE();
1897 e = e.expressionSemantic(sc);
1898 e = resolveProperties(sc, e);
1900 e = e.ctfeInterpret();
1902 buf.writestring(" (");
1905 buf.writestring(e.toChars());
1909 global.endGagging(errors_save);
1911 message("pragma %s", buf.peekChars());
1912 return declarations();
1915 override void visit(StaticIfDeclaration sid)
1917 attribSemantic(sid);
1920 override void visit(StaticForeachDeclaration sfd)
1922 attribSemantic(sfd);
1925 private Dsymbols* compileIt(CompileDeclaration cd)
1927 //printf("CompileDeclaration::compileIt(loc = %d) %s\n", cd.loc.linnum, cd.exp.toChars());
1929 if (expressionsToString(buf, sc, cd.exps))
1932 const errors = global.errors;
1933 const len = buf.length;
1935 const str = buf.extractSlice()[0 .. len];
1936 scope p = new Parser!ASTCodegen(cd.loc, sc._module, str, false, global.errorSink);
1939 auto d = p.parseDeclDefs(0);
1940 if (global.errors != errors)
1943 if (p.token.value != TOK.endOfFile)
1945 cd.error("incomplete mixin declaration `%s`", str.ptr);
1951 /***********************************************************
1952 * https://dlang.org/spec/module.html#mixin-declaration
1954 override void visit(CompileDeclaration cd)
1956 //printf("CompileDeclaration::semantic()\n");
1959 cd.decl = compileIt(cd);
1960 cd.AttribDeclaration.addMember(sc, cd.scopesym);
1963 if (cd._scope && cd.decl)
1965 for (size_t i = 0; i < cd.decl.length; i++)
1967 Dsymbol s = (*cd.decl)[i];
1968 s.setScope(cd._scope);
1975 override void visit(CPPNamespaceDeclaration ns)
1977 Identifier identFromSE (StringExp se)
1979 const sident = se.toStringz();
1980 if (!sident.length || !Identifier.isValidIdentifier(sident))
1982 ns.exp.error("expected valid identifier for C++ namespace but got `%.*s`",
1983 cast(int)sident.length, sident.ptr);
1987 return Identifier.idPool(sident);
1990 if (ns.ident !is null)
1991 return attribSemantic(ns);
1993 ns.cppnamespace = sc.namespace;
1994 sc = sc.startCTFE();
1995 ns.exp = ns.exp.expressionSemantic(sc);
1996 ns.exp = resolveProperties(sc, ns.exp);
1998 ns.exp = ns.exp.ctfeInterpret();
1999 // Can be either a tuple of strings or a string itself
2000 if (auto te = ns.exp.isTupleExp())
2002 expandTuples(te.exps);
2003 CPPNamespaceDeclaration current = ns.cppnamespace;
2004 for (size_t d = 0; d < te.exps.length; ++d)
2006 auto exp = (*te.exps)[d];
2007 auto prev = d ? current : ns.cppnamespace;
2008 current = (d + 1) != te.exps.length
2009 ? new CPPNamespaceDeclaration(ns.loc, exp, null)
2012 current.cppnamespace = prev;
2013 if (auto se = exp.toStringExp())
2015 current.ident = identFromSE(se);
2016 if (current.ident is null)
2017 return; // An error happened in `identFromSE`
2020 ns.exp.error("`%s`: index %llu is not a string constant, it is a `%s`",
2021 ns.exp.toChars(), cast(ulong) d, ns.exp.type.toChars());
2024 else if (auto se = ns.exp.toStringExp())
2025 ns.ident = identFromSE(se);
2027 else if (ns.exp.isTypeExp() && ns.exp.isTypeExp().type.toBasetype().isTypeTuple())
2031 ns.exp.error("compile time string constant (or tuple) expected, not `%s`",
2036 override void visit(UserAttributeDeclaration uad)
2038 //printf("UserAttributeDeclaration::semantic() %p\n", this);
2039 if (uad.decl && !uad._scope)
2040 uad.Dsymbol.setScope(sc); // for function local symbols
2041 arrayExpressionSemantic(uad.atts.peekSlice(), sc, true);
2042 return attribSemantic(uad);
2045 override void visit(StaticAssert sa)
2047 if (sa.semanticRun < PASS.semanticdone)
2048 sa.semanticRun = PASS.semanticdone;
2051 override void visit(DebugSymbol ds)
2053 //printf("DebugSymbol::semantic() %s\n", toChars());
2054 if (ds.semanticRun < PASS.semanticdone)
2055 ds.semanticRun = PASS.semanticdone;
2058 override void visit(VersionSymbol vs)
2060 if (vs.semanticRun < PASS.semanticdone)
2061 vs.semanticRun = PASS.semanticdone;
2064 override void visit(Package pkg)
2066 if (pkg.semanticRun < PASS.semanticdone)
2067 pkg.semanticRun = PASS.semanticdone;
2070 override void visit(Module m)
2072 if (m.semanticRun != PASS.initial)
2074 //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
2075 m.semanticRun = PASS.semantic;
2076 // Note that modules get their own scope, from scratch.
2077 // This is so regardless of where in the syntax a module
2078 // gets imported, it is unaffected by context.
2079 Scope* sc = m._scope; // see if already got one from importAll()
2082 sc = Scope.createGlobal(m); // create root scope
2085 //printf("Module = %p, linkage = %d\n", sc.scopesym, sc.linkage);
2086 // Pass 1 semantic routines: do public side of the definition
2087 m.members.foreachDsymbol( (s)
2089 //printf("\tModule('%s'): '%s'.dsymbolSemantic()\n", toChars(), s.toChars());
2090 s.dsymbolSemantic(sc);
2091 m.runDeferredSemantic();
2094 if (m.userAttribDecl)
2096 m.userAttribDecl.dsymbolSemantic(sc);
2101 sc.pop(); // 2 pops because Scope.createGlobal() created 2
2103 m.semanticRun = PASS.semanticdone;
2104 //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
2107 override void visit(EnumDeclaration ed)
2109 //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc.scopesym, sc.scopesym.toChars(), ed.toChars());
2110 //printf("EnumDeclaration::semantic() %p %s\n", ed, ed.toChars());
2111 if (ed.semanticRun >= PASS.semanticdone)
2112 return; // semantic() already completed
2113 if (ed.semanticRun == PASS.semantic)
2116 error(ed.loc, "circular reference to enum base type `%s`", ed.memtype.toChars());
2118 ed.semanticRun = PASS.semanticdone;
2125 scx = ed._scope; // save so we don't make redundant copies
2132 ed.parent = sc.parent;
2133 ed.type = ed.type.typeSemantic(ed.loc, sc);
2135 ed.visibility = sc.visibility;
2136 if (sc.stc & STC.deprecated_)
2137 ed.isdeprecated = true;
2138 ed.userAttribDecl = sc.userAttribDecl;
2139 ed.cppnamespace = sc.namespace;
2141 ed.semanticRun = PASS.semantic;
2142 UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
2143 checkMustUseReserved(ed);
2145 if (!ed.members && !ed.memtype) // enum ident;
2147 ed.semanticRun = PASS.semanticdone;
2152 ed.symtab = new DsymbolTable();
2154 /* The separate, and distinct, cases are:
2156 * 2. enum : memtype { ... }
2157 * 3. enum ident { ... }
2158 * 4. enum ident : memtype { ... }
2159 * 5. enum ident : memtype;
2165 ed.memtype = ed.memtype.typeSemantic(ed.loc, sc);
2167 /* Check to see if memtype is forward referenced
2169 if (auto te = ed.memtype.isTypeEnum())
2171 auto sym = te.toDsymbol(sc).isEnumDeclaration();
2172 // Special enums like __c_[u]long[long] are fine to forward reference
2173 // see https://issues.dlang.org/show_bug.cgi?id=20599
2174 if (!sym.isSpecial() && (!sym.memtype || !sym.members || !sym.symtab || sym._scope))
2176 // memtype is forward referenced, so try again later
2177 deferDsymbolSemantic(ed, scx);
2178 //printf("\tdeferring %s\n", toChars());
2179 ed.semanticRun = PASS.initial;
2183 // Ensure that semantic is run to detect. e.g. invalid forward references
2184 sym.dsymbolSemantic(sc);
2186 if (ed.memtype.ty == Tvoid)
2188 ed.error("base type must not be `void`");
2189 ed.memtype = Type.terror;
2191 if (ed.memtype.ty == Terror)
2194 // poison all the members
2195 ed.members.foreachDsymbol( (s) { s.errors = true; } );
2196 ed.semanticRun = PASS.semanticdone;
2201 if (!ed.members) // enum ident : memtype;
2203 ed.semanticRun = PASS.semanticdone;
2207 if (ed.members.length == 0)
2209 ed.error("enum `%s` must have at least one member", ed.toChars());
2211 ed.semanticRun = PASS.semanticdone;
2215 if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done
2216 ed.semanticRun = PASS.semanticdone;
2218 // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
2219 // Deprecated in 2.100
2220 // Make an error in 2.110
2221 if (sc.stc & STC.scope_)
2222 deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
2225 if (ed.isAnonymous())
2232 sce = sce.startCTFE();
2233 sce.setNoFree(); // needed for getMaxMinValue()
2235 /* Each enum member gets the sce scope
2237 ed.members.foreachDsymbol( (s)
2239 EnumMember em = s.isEnumMember();
2244 /* addMember() is not called when the EnumDeclaration appears as a function statement,
2245 * so we have to do what addMember() does and install the enum members in the right symbol
2248 addEnumMembers(ed, sc, sc.getScopesym());
2250 if (sc.flags & SCOPE.Cfile)
2255 int nextValue = 0; // C11 6.7.2.2-3 first member value defaults to 0
2257 // C11 6.7.2.2-2 value must be representable as an int.
2258 // The sizemask represents all values that int will fit into,
2259 // from 0..uint.max. We want to cover int.min..uint.max.
2260 const mask = Type.tint32.sizemask();
2261 IntRange ir = IntRange(SignExtendedNumber(~(mask >> 1), true),
2262 SignExtendedNumber(mask));
2264 void emSemantic(EnumMember em, ref int nextValue)
2266 static void errorReturn(EnumMember em)
2269 em.semanticRun = PASS.semanticdone;
2272 em.semanticRun = PASS.semantic;
2273 em.type = Type.tint32;
2274 em._linkage = LINK.c;
2275 em.storage_class |= STC.manifest;
2278 Expression e = em.value;
2279 assert(e.dyncast() == DYNCAST.expression);
2280 e = e.expressionSemantic(sc);
2281 e = resolveProperties(sc, e);
2282 e = e.integralPromotions(sc);
2283 e = e.ctfeInterpret();
2284 if (e.op == EXP.error)
2285 return errorReturn(em);
2286 auto ie = e.isIntegerExp();
2290 em.error("enum member must be an integral constant expression, not `%s` of type `%s`", e.toChars(), e.type.toChars());
2291 return errorReturn(em);
2293 if (!ir.contains(getIntRange(ie)))
2296 em.error("enum member value `%s` does not fit in an `int`", e.toChars());
2297 return errorReturn(em);
2299 nextValue = cast(int)ie.toInteger();
2300 em.value = new IntegerExp(em.loc, nextValue, Type.tint32);
2304 // C11 6.7.2.2-3 add 1 to value of previous enumeration constant
2305 bool first = (em == (*em.ed.members)[0]);
2308 import core.checkedint : adds;
2310 nextValue = adds(nextValue, 1, overflow);
2313 em.error("initialization with `%d+1` causes overflow for type `int`", nextValue - 1);
2314 return errorReturn(em);
2317 em.value = new IntegerExp(em.loc, nextValue, Type.tint32);
2319 em.semanticRun = PASS.semanticdone;
2322 ed.members.foreachDsymbol( (s)
2324 if (EnumMember em = s.isEnumMember())
2325 emSemantic(em, nextValue);
2327 ed.semanticRun = PASS.semanticdone;
2331 ed.members.foreachDsymbol( (s)
2333 if (EnumMember em = s.isEnumMember())
2334 em.dsymbolSemantic(em._scope);
2336 //printf("defaultval = %lld\n", defaultval);
2338 //if (defaultval) printf("defaultval: %s %s\n", defaultval.toChars(), defaultval.type.toChars());
2339 //printf("members = %s\n", members.toChars());
2342 override void visit(EnumMember em)
2344 //printf("EnumMember::semantic() %s\n", em.toChars());
2349 em.semanticRun = PASS.semanticdone;
2352 if (em.errors || em.semanticRun >= PASS.semanticdone)
2354 if (em.semanticRun == PASS.semantic)
2356 em.error("circular reference to `enum` member");
2357 return errorReturn();
2361 em.ed.dsymbolSemantic(sc);
2363 return errorReturn();
2364 if (em.errors || em.semanticRun >= PASS.semanticdone)
2372 em.semanticRun = PASS.semantic;
2374 em.visibility = em.ed.isAnonymous() ? em.ed.visibility : Visibility(Visibility.Kind.public_);
2375 em._linkage = LINK.d;
2376 em.storage_class |= STC.manifest;
2378 // https://issues.dlang.org/show_bug.cgi?id=9701
2379 if (em.ed.isAnonymous())
2381 if (em.userAttribDecl)
2382 em.userAttribDecl.userAttribDecl = em.ed.userAttribDecl;
2384 em.userAttribDecl = em.ed.userAttribDecl;
2387 // Eval UDA in this same scope. Issues 19344, 20835, 21122
2388 if (em.userAttribDecl)
2390 // Set scope but avoid extra sc.uda attachment inside setScope()
2391 auto inneruda = em.userAttribDecl.userAttribDecl;
2392 em.userAttribDecl.setScope(sc);
2393 em.userAttribDecl.userAttribDecl = inneruda;
2394 em.userAttribDecl.dsymbolSemantic(sc);
2397 // The first enum member is special
2398 bool first = (em == (*em.ed.members)[0]);
2402 em.origType = em.origType.typeSemantic(em.loc, sc);
2403 em.type = em.origType;
2404 assert(em.value); // "type id;" is not a valid enum member declaration
2409 Expression e = em.value;
2410 assert(e.dyncast() == DYNCAST.expression);
2411 e = e.expressionSemantic(sc);
2412 e = resolveProperties(sc, e);
2413 e = e.ctfeInterpret();
2414 if (e.op == EXP.error)
2415 return errorReturn();
2416 if (first && !em.ed.memtype && !em.ed.isAnonymous())
2418 em.ed.memtype = e.type;
2419 if (em.ed.memtype.ty == Terror)
2421 em.ed.errors = true;
2422 return errorReturn();
2424 if (em.ed.memtype.ty != Terror)
2426 /* https://issues.dlang.org/show_bug.cgi?id=11746
2427 * All of named enum members should have same type
2428 * with the first member. If the following members were referenced
2429 * during the first member semantic, their types should be unified.
2431 em.ed.members.foreachDsymbol( (s)
2433 EnumMember enm = s.isEnumMember();
2434 if (!enm || enm == em || enm.semanticRun < PASS.semanticdone || enm.origType)
2437 //printf("[%d] em = %s, em.semanticRun = %d\n", i, toChars(), em.semanticRun);
2438 Expression ev = enm.value;
2439 ev = ev.implicitCastTo(sc, em.ed.memtype);
2440 ev = ev.ctfeInterpret();
2441 ev = ev.castTo(sc, em.ed.type);
2442 if (ev.op == EXP.error)
2443 em.ed.errors = true;
2449 em.ed.memtype = Type.terror;
2450 return errorReturn();
2455 if (em.ed.memtype && !em.origType)
2457 e = e.implicitCastTo(sc, em.ed.memtype);
2458 e = e.ctfeInterpret();
2460 // save origValue for better json output
2463 if (!em.ed.isAnonymous())
2465 e = e.castTo(sc, em.ed.type.addMod(e.type.mod)); // https://issues.dlang.org/show_bug.cgi?id=12385
2466 e = e.ctfeInterpret();
2469 else if (em.origType)
2471 e = e.implicitCastTo(sc, em.origType);
2472 e = e.ctfeInterpret();
2473 assert(em.ed.isAnonymous());
2475 // save origValue for better json output
2488 if (!em.ed.isAnonymous())
2491 Expression e = new IntegerExp(em.loc, 0, t);
2492 e = e.ctfeInterpret();
2494 // save origValue for better json output
2497 if (!em.ed.isAnonymous())
2499 e = e.castTo(sc, em.ed.type);
2500 e = e.ctfeInterpret();
2506 /* Find the previous enum member,
2507 * and set this to be the previous value + 1
2509 EnumMember emprev = null;
2510 em.ed.members.foreachDsymbol( (s)
2512 if (auto enm = s.isEnumMember())
2518 return 0; // continue
2522 if (emprev.semanticRun < PASS.semanticdone) // if forward reference
2523 emprev.dsymbolSemantic(emprev._scope); // resolve it
2525 return errorReturn();
2527 Expression eprev = emprev.value;
2528 // .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
2529 Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
2533 https://issues.dlang.org/show_bug.cgi?id=20777
2534 Previously this used getProperty, which doesn't consider anything user defined,
2535 this construct does do that and thus fixes the bug.
2537 Expression emax = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
2538 emax = emax.expressionSemantic(sc);
2539 emax = emax.ctfeInterpret();
2541 // Set value to (eprev + 1).
2542 // But first check that (eprev != emax)
2544 Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
2545 e = e.expressionSemantic(sc);
2546 e = e.ctfeInterpret();
2549 auto mt = em.ed.memtype;
2552 em.error("initialization with `%s.%s+1` causes overflow for type `%s`",
2553 emprev.ed.toChars(), emprev.toChars(), mt.toChars());
2554 return errorReturn();
2557 // Now set e to (eprev + 1)
2558 e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
2559 e = e.expressionSemantic(sc);
2560 e = e.castTo(sc, eprev.type);
2561 e = e.ctfeInterpret();
2563 // save origValue (without cast) for better json output
2564 if (e.op != EXP.error) // avoid duplicate diagnostics
2566 assert(emprev.origValue);
2567 em.origValue = new AddExp(em.loc, emprev.origValue, IntegerExp.literal!1);
2568 em.origValue = em.origValue.expressionSemantic(sc);
2569 em.origValue = em.origValue.ctfeInterpret();
2572 if (e.op == EXP.error)
2573 return errorReturn();
2574 if (e.type.isfloating())
2576 // Check that e != eprev (not always true for floats)
2577 Expression etest = new EqualExp(EXP.equal, em.loc, e, eprev);
2578 etest = etest.expressionSemantic(sc);
2579 etest = etest.ctfeInterpret();
2580 if (etest.toInteger())
2582 em.error("has inexact value due to loss of precision");
2583 return errorReturn();
2589 em.type = em.value.type;
2591 assert(em.origValue);
2592 em.semanticRun = PASS.semanticdone;
2595 override void visit(TemplateDeclaration tempdecl)
2599 printf("TemplateDeclaration.dsymbolSemantic(this = %p, id = '%s')\n", this, tempdecl.ident.toChars());
2600 printf("sc.stc = %llx\n", sc.stc);
2601 printf("sc.module = %s\n", sc._module.toChars());
2603 if (tempdecl.semanticRun != PASS.initial)
2604 return; // semantic() already run
2606 if (tempdecl._scope)
2608 sc = tempdecl._scope;
2609 tempdecl._scope = null;
2614 // Remember templates defined in module object that we need to know about
2615 if (sc._module && sc._module.ident == Id.object)
2617 if (tempdecl.ident == Id.RTInfo)
2618 Type.rtinfo = tempdecl;
2621 /* Remember Scope for later instantiations, but make
2622 * a copy since attributes can change.
2624 if (!tempdecl._scope)
2626 tempdecl._scope = sc.copy();
2627 tempdecl._scope.setNoFree();
2630 tempdecl.semanticRun = PASS.semantic;
2632 tempdecl.parent = sc.parent;
2633 tempdecl.visibility = sc.visibility;
2634 tempdecl.userAttribDecl = sc.userAttribDecl;
2635 tempdecl.cppnamespace = sc.namespace;
2636 tempdecl.isstatic = tempdecl.toParent().isModule() || (tempdecl._scope.stc & STC.static_);
2637 tempdecl.deprecated_ = !!(sc.stc & STC.deprecated_);
2639 UserAttributeDeclaration.checkGNUABITag(tempdecl, sc.linkage);
2641 if (!tempdecl.isstatic)
2643 if (auto ad = tempdecl.parent.pastMixin().isAggregateDeclaration())
2647 // Set up scope for parameters
2648 auto paramsym = new ScopeDsymbol();
2649 paramsym.parent = tempdecl.parent;
2650 Scope* paramscope = sc.push(paramsym);
2653 if (global.params.ddoc.doOutput)
2655 tempdecl.origParameters = new TemplateParameters(tempdecl.parameters.length);
2656 for (size_t i = 0; i < tempdecl.parameters.length; i++)
2658 TemplateParameter tp = (*tempdecl.parameters)[i];
2659 (*tempdecl.origParameters)[i] = tp.syntaxCopy();
2663 for (size_t i = 0; i < tempdecl.parameters.length; i++)
2665 TemplateParameter tp = (*tempdecl.parameters)[i];
2666 if (!tp.declareParameter(paramscope))
2668 error(tp.loc, "parameter `%s` multiply defined", tp.ident.toChars());
2669 tempdecl.errors = true;
2671 if (!tp.tpsemantic(paramscope, tempdecl.parameters))
2673 tempdecl.errors = true;
2675 if (i + 1 != tempdecl.parameters.length && tp.isTemplateTupleParameter())
2677 tempdecl.error("template tuple parameter must be last one");
2678 tempdecl.errors = true;
2682 /* Calculate TemplateParameter.dependent
2684 TemplateParameters tparams = TemplateParameters(1);
2685 for (size_t i = 0; i < tempdecl.parameters.length; i++)
2687 TemplateParameter tp = (*tempdecl.parameters)[i];
2690 for (size_t j = 0; j < tempdecl.parameters.length; j++)
2692 // Skip cases like: X(T : T)
2696 if (TemplateTypeParameter ttp = (*tempdecl.parameters)[j].isTemplateTypeParameter())
2698 if (reliesOnTident(ttp.specType, &tparams))
2699 tp.dependent = true;
2701 else if (TemplateAliasParameter tap = (*tempdecl.parameters)[j].isTemplateAliasParameter())
2703 if (reliesOnTident(tap.specType, &tparams) ||
2704 reliesOnTident(isType(tap.specAlias), &tparams))
2706 tp.dependent = true;
2715 tempdecl.onemember = null;
2716 if (tempdecl.members)
2719 if (Dsymbol.oneMembers(tempdecl.members, &s, tempdecl.ident) && s)
2721 tempdecl.onemember = s;
2722 s.parent = tempdecl;
2726 /* BUG: should check:
2727 * 1. template functions must not introduce virtual functions, as they
2728 * cannot be accomodated in the vtbl[]
2729 * 2. templates cannot introduce non-static data members (i.e. fields)
2730 * as they would change the instance size of the aggregate.
2733 tempdecl.semanticRun = PASS.semanticdone;
2736 override void visit(TemplateInstance ti)
2738 templateInstanceSemantic(ti, sc, ArgumentList());
2741 override void visit(TemplateMixin tm)
2745 printf("+TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
2748 if (tm.semanticRun != PASS.initial)
2750 // When a class/struct contains mixin members, and is done over
2751 // because of forward references, never reach here so semanticRun
2752 // has been reset to PASS.initial.
2755 printf("\tsemantic done\n");
2759 tm.semanticRun = PASS.semantic;
2762 printf("\tdo semantic\n");
2769 scx = tm._scope; // save so we don't make redundant copies
2773 /* Run semantic on each argument, place results in tiargs[],
2774 * then find best match template with tiargs
2776 if (!tm.findTempDecl(sc) || !tm.semanticTiargs(sc) || !tm.findBestMatch(sc, ArgumentList()))
2778 if (tm.semanticRun == PASS.initial) // forward reference had occurred
2780 //printf("forward reference - deferring\n");
2781 return deferDsymbolSemantic(tm, scx);
2786 return; // error recovery
2789 auto tempdecl = tm.tempdecl.isTemplateDeclaration();
2794 /* Assign scope local unique identifier, as same as lambdas.
2796 const(char)[] s = "__mixin";
2798 if (FuncDeclaration func = sc.parent.isFuncDeclaration())
2800 tm.symtab = func.localsymtab;
2803 // Inside template constraint, symtab is not set yet.
2809 tm.symtab = sc.parent.isScopeDsymbol().symtab;
2812 tm.ident = Identifier.generateId(s, tm.symtab.length + 1);
2813 tm.symtab.insert(tm);
2818 tm.parent = sc.parent;
2820 /* Detect recursive mixin instantiations.
2822 for (Dsymbol s = tm.parent; s; s = s.parent)
2824 //printf("\ts = '%s'\n", s.toChars());
2825 TemplateMixin tmix = s.isTemplateMixin();
2826 if (!tmix || tempdecl != tmix.tempdecl)
2829 /* Different argument list lengths happen with variadic args
2831 if (tm.tiargs.length != tmix.tiargs.length)
2834 for (size_t i = 0; i < tm.tiargs.length; i++)
2836 RootObject o = (*tm.tiargs)[i];
2837 Type ta = isType(o);
2838 Expression ea = isExpression(o);
2839 Dsymbol sa = isDsymbol(o);
2840 RootObject tmo = (*tmix.tiargs)[i];
2843 Type tmta = isType(tmo);
2846 if (!ta.equals(tmta))
2851 Expression tme = isExpression(tmo);
2852 if (!tme || !ea.equals(tme))
2857 Dsymbol tmsa = isDsymbol(tmo);
2864 tm.error("recursive mixin instantiation");
2871 // Copy the syntax trees from the TemplateDeclaration
2872 tm.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
2876 tm.symtab = new DsymbolTable();
2878 sc.getScopesym().importScope(tm, Visibility(Visibility.Kind.public_));
2882 printf("\tcreate scope for template parameters '%s'\n", tm.toChars());
2884 Scope* scy = sc.push(tm);
2887 /* https://issues.dlang.org/show_bug.cgi?id=930
2889 * If the template that is to be mixed in is in the scope of a template
2890 * instance, we have to also declare the type aliases in the new mixin scope.
2892 auto parentInstance = tempdecl.parent ? tempdecl.parent.isTemplateInstance() : null;
2894 parentInstance.declareParameters(scy);
2896 tm.argsym = new ScopeDsymbol();
2897 tm.argsym.parent = scy.parent;
2898 Scope* argscope = scy.push(tm.argsym);
2900 uint errorsave = global.errors;
2902 // Declare each template parameter as an alias for the argument type
2903 tm.declareParameters(argscope);
2905 // Add members to enclosing scope, as well as this scope
2906 tm.members.foreachDsymbol(s => s.addMember(argscope, tm));
2908 // Do semantic() analysis on template instance members
2911 printf("\tdo semantic() on template instance members '%s'\n", tm.toChars());
2913 Scope* sc2 = argscope.push(tm);
2914 //size_t deferred_dim = Module.deferred.length;
2917 //printf("%d\n", nest);
2918 if (++nest > global.recursionLimit)
2920 global.gag = 0; // ensure error message gets printed
2921 tm.error("recursive expansion");
2925 tm.members.foreachDsymbol( s => s.setScope(sc2) );
2927 tm.members.foreachDsymbol( s => s.importAll(sc2) );
2929 tm.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
2933 /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols.
2934 * Because the members would already call Module.addDeferredSemantic() for themselves.
2935 * See Struct, Class, Interface, and EnumDeclaration.dsymbolSemantic().
2937 //if (!sc.func && Module.deferred.length > deferred_dim) {}
2939 AggregateDeclaration ad = tm.isMember();
2946 // Give additional context info if error occurred during instantiation
2947 if (global.errors != errorsave)
2949 tm.error("error instantiating");
2959 printf("-TemplateMixin.dsymbolSemantic('%s', this=%p)\n", tm.toChars(), tm);
2963 override void visit(Nspace ns)
2965 if (ns.semanticRun != PASS.initial)
2969 printf("+Nspace::semantic('%s')\n", ns.toChars());
2970 scope(exit) printf("-Nspace::semantic('%s')\n", ns.toChars());
2980 bool repopulateMembers = false;
2983 // resolve the namespace identifier
2984 sc = sc.startCTFE();
2985 Expression resolved = ns.identExp.expressionSemantic(sc);
2986 resolved = resolveProperties(sc, resolved);
2988 resolved = resolved.ctfeInterpret();
2989 StringExp name = resolved.toStringExp();
2990 TupleExp tup = name ? null : resolved.isTupleExp();
2993 error(ns.loc, "expected string expression for namespace name, got `%s`", ns.identExp.toChars());
2996 ns.identExp = resolved; // we don't need to keep the old AST around
2999 const(char)[] ident = name.toStringz();
3000 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
3002 error(ns.loc, "expected valid identifier for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
3005 ns.ident = Identifier.idPool(ident);
3009 // create namespace stack from the tuple
3010 Nspace parentns = ns;
3011 foreach (i, exp; *tup.exps)
3013 name = exp.toStringExp();
3016 error(ns.loc, "expected string expression for namespace name, got `%s`", exp.toChars());
3019 const(char)[] ident = name.toStringz();
3020 if (ident.length == 0 || !Identifier.isValidIdentifier(ident))
3022 error(ns.loc, "expected valid identifier for C++ namespace but got `%.*s`", cast(int)ident.length, ident.ptr);
3027 ns.ident = Identifier.idPool(ident);
3031 // insert the new namespace
3032 Nspace childns = new Nspace(ns.loc, Identifier.idPool(ident), null, parentns.members);
3033 parentns.members = new Dsymbols;
3034 parentns.members.push(childns);
3036 repopulateMembers = true;
3042 ns.semanticRun = PASS.semantic;
3043 ns.parent = sc.parent;
3044 // Link does not matter here, if the UDA is present it will error
3045 UserAttributeDeclaration.checkGNUABITag(ns, LINK.cpp);
3049 ns.semanticRun = PASS.semanticdone;
3054 sc.linkage = LINK.cpp; // note that namespaces imply C++ linkage
3056 foreach (s; *ns.members)
3058 if (repopulateMembers)
3060 s.addMember(sc, sc.scopesym);
3065 foreach (s; *ns.members)
3069 printf("\tmember '%s', kind = '%s'\n", s.toChars(), s.kind());
3071 s.dsymbolSemantic(sc);
3074 ns.semanticRun = PASS.semanticdone;
3077 void funcDeclarationSemantic(FuncDeclaration funcdecl)
3081 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, funcdecl, funcdecl.toPrettyChars(), sc.linkage);
3082 if (funcdecl.isFuncLiteralDeclaration())
3083 printf("\tFuncLiteralDeclaration()\n");
3084 printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), funcdecl.parent ? funcdecl.parent.toChars() : "");
3085 printf("type: %p, %s\n", funcdecl.type, funcdecl.type.toChars());
3088 if (funcdecl.semanticRun != PASS.initial && funcdecl.isFuncLiteralDeclaration())
3090 /* Member functions that have return types that are
3091 * forward references can have semantic() run more than
3093 * See test\interface2.d, test20
3098 if (funcdecl.semanticRun >= PASS.semanticdone)
3100 assert(funcdecl.semanticRun <= PASS.semantic);
3101 funcdecl.semanticRun = PASS.semantic;
3103 if (funcdecl._scope)
3105 sc = funcdecl._scope;
3106 funcdecl._scope = null;
3109 if (!sc || funcdecl.errors)
3112 funcdecl.cppnamespace = sc.namespace;
3113 funcdecl.parent = sc.parent;
3114 Dsymbol parent = funcdecl.toParent();
3116 funcdecl.foverrides.setDim(0); // reset in case semantic() is being retried for this function
3118 funcdecl.storage_class |= sc.stc & ~STC.ref_;
3119 AggregateDeclaration ad = funcdecl.isThis();
3120 // Don't nest structs b/c of generated methods which should not access the outer scopes.
3121 // https://issues.dlang.org/show_bug.cgi?id=16627
3122 if (ad && !funcdecl.isGenerated())
3124 funcdecl.storage_class |= ad.storage_class & (STC.TYPECTOR | STC.synchronized_);
3128 funcdecl.storage_class |= sc.func.storage_class & STC.disable;
3129 // Remove prefix storage classes silently.
3130 if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
3131 funcdecl.storage_class &= ~STC.TYPECTOR;
3133 //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration.isFinal());
3135 if (sc.flags & SCOPE.compile)
3136 funcdecl.skipCodegen = true;
3138 funcdecl._linkage = sc.linkage;
3139 if (auto fld = funcdecl.isFuncLiteralDeclaration())
3143 Type treq = fld.treq;
3144 assert(treq.nextOf().ty == Tfunction);
3145 if (treq.ty == Tdelegate)
3146 fld.tok = TOK.delegate_;
3147 else if (treq.isPtrToFunction())
3148 fld.tok = TOK.function_;
3151 funcdecl._linkage = treq.nextOf().toTypeFunction().linkage;
3155 // evaluate pragma(inline)
3156 if (auto pragmadecl = sc.inlining)
3157 funcdecl.inlining = evalPragmaInline(pragmadecl.loc, sc, pragmadecl.args);
3159 funcdecl.visibility = sc.visibility;
3160 funcdecl.userAttribDecl = sc.userAttribDecl;
3161 UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl._linkage);
3162 checkMustUseReserved(funcdecl);
3164 if (!funcdecl.originalType)
3165 funcdecl.originalType = funcdecl.type.syntaxCopy();
3167 static TypeFunction getFunctionType(FuncDeclaration fd)
3169 if (auto tf = fd.type.isTypeFunction())
3172 if (!fd.type.isTypeError())
3174 fd.error("`%s` must be a function instead of `%s`", fd.toChars(), fd.type.toChars());
3175 fd.type = Type.terror;
3181 if (sc.flags & SCOPE.Cfile)
3183 /* C11 allows a function to be declared with a typedef, D does not.
3185 if (auto ti = funcdecl.type.isTypeIdentifier())
3187 auto tj = ti.typeSemantic(funcdecl.loc, sc);
3188 if (auto tjf = tj.isTypeFunction())
3190 /* Copy the type instead of just pointing to it,
3191 * as we don't merge function types
3193 auto tjf2 = new TypeFunction(tjf.parameterList, tjf.next, tjf.linkage);
3194 funcdecl.type = tjf2;
3195 funcdecl.originalType = tjf2;
3200 if (!getFunctionType(funcdecl))
3203 if (!funcdecl.type.deco)
3206 sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
3208 TypeFunction tf = funcdecl.type.toTypeFunction();
3211 /* If the nesting parent is pure without inference,
3212 * then this function defaults to pure too.
3215 * auto bar() {} // become a weak purity function
3216 * class C { // nested class
3217 * auto baz() {} // become a weak purity function
3220 * static auto boo() {} // typed as impure
3221 * // Even though, boo cannot call any impure functions.
3222 * // See also Expression::checkPurity().
3225 if (tf.purity == PURE.impure && (funcdecl.isNested() || funcdecl.isThis()))
3227 FuncDeclaration fd = null;
3228 for (Dsymbol p = funcdecl.toParent2(); p; p = p.toParent2())
3230 if (AggregateDeclaration adx = p.isAggregateDeclaration())
3236 if ((fd = p.isFuncDeclaration()) !is null)
3240 /* If the parent's purity is inferred, then this function's purity needs
3241 * to be inferred first.
3243 if (fd && fd.isPureBypassingInference() >= PURE.weak && !funcdecl.isInstantiated())
3245 tf.purity = PURE.fwdref; // default to pure
3253 sc.stc |= STC.scope_;
3255 sc.stc |= STC.nothrow_;
3259 sc.stc |= STC.property;
3260 if (tf.purity == PURE.fwdref)
3261 sc.stc |= STC.pure_;
3263 if (tf.trust != TRUST.default_)
3265 sc.stc &= ~STC.safeGroup;
3266 if (tf.trust == TRUST.safe)
3268 else if (tf.trust == TRUST.system)
3269 sc.stc |= STC.system;
3270 else if (tf.trust == TRUST.trusted)
3271 sc.stc |= STC.trusted;
3274 if (funcdecl.isCtorDeclaration())
3277 Type tret = ad.handleType();
3279 tret = tret.addStorageClass(funcdecl.storage_class | sc.stc);
3280 tret = tret.addMod(funcdecl.type.mod);
3282 if (ad.isStructDeclaration())
3286 // 'return' on a non-static class member function implies 'scope' as well
3287 if (ad && ad.isClassDeclaration() && (tf.isreturn || sc.stc & STC.return_) && !(sc.stc & STC.static_))
3288 sc.stc |= STC.scope_;
3290 // If 'this' has no pointers, remove 'scope' as it has no meaning
3291 // Note: this is already covered by semantic of `VarDeclaration` and `TypeFunction`,
3292 // but existing code relies on `hasPointers()` being called here to resolve forward references:
3293 // https://github.com/dlang/dmd/pull/14232#issuecomment-1162906573
3294 if (sc.stc & STC.scope_ && ad && ad.isStructDeclaration() && !ad.type.hasPointers())
3296 sc.stc &= ~STC.scope_;
3297 tf.isScopeQual = false;
3298 if (tf.isreturnscope)
3300 sc.stc &= ~(STC.return_ | STC.returnScope);
3301 tf.isreturn = false;
3302 tf.isreturnscope = false;
3306 sc.linkage = funcdecl._linkage;
3308 if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
3311 MODtoBuffer(&buf, tf.mod);
3312 funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
3313 tf.mod = 0; // remove qualifiers
3316 /* Apply const, immutable, wild and shared storage class
3317 * to the function type. Do this before type semantic.
3319 auto stc = funcdecl.storage_class;
3320 if (funcdecl.type.isImmutable())
3321 stc |= STC.immutable_;
3322 if (funcdecl.type.isConst())
3324 if (funcdecl.type.isShared() || funcdecl.storage_class & STC.synchronized_)
3326 if (funcdecl.type.isWild())
3328 funcdecl.type = funcdecl.type.addSTC(stc);
3330 funcdecl.type = funcdecl.type.typeSemantic(funcdecl.loc, sc);
3334 auto f = getFunctionType(funcdecl);
3336 return; // funcdecl's type is not a function
3339 // Merge back function attributes into 'originalType'.
3340 // It's used for mangling, ddoc, and json output.
3341 TypeFunction tfo = funcdecl.originalType.toTypeFunction();
3343 tfo.isScopeQual = f.isScopeQual;
3344 tfo.isreturninferred = f.isreturninferred;
3345 tfo.isscopeinferred = f.isscopeinferred;
3346 tfo.isref = f.isref;
3347 tfo.isnothrow = f.isnothrow;
3348 tfo.isnogc = f.isnogc;
3349 tfo.isproperty = f.isproperty;
3350 tfo.purity = f.purity;
3351 tfo.trust = f.trust;
3353 funcdecl.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR);
3356 // check pragma(crt_constructor) signature
3357 if (funcdecl.isCrtCtor || funcdecl.isCrtDtor)
3359 const idStr = funcdecl.isCrtCtor ? "crt_constructor" : "crt_destructor";
3360 if (f.nextOf().ty != Tvoid)
3361 funcdecl.error("must return `void` for `pragma(%s)`", idStr.ptr);
3362 if (funcdecl._linkage != LINK.c && f.parameterList.length != 0)
3363 funcdecl.error("must be `extern(C)` for `pragma(%s)` when taking parameters", idStr.ptr);
3364 if (funcdecl.isThis())
3365 funcdecl.error("cannot be a non-static member function for `pragma(%s)`", idStr.ptr);
3368 if (funcdecl.overnext && funcdecl.isCsymbol())
3370 /* C does not allow function overloading, but it does allow
3371 * redeclarations of the same function. If .overnext points
3372 * to a redeclaration, ok. Error if it is an overload.
3374 auto fnext = funcdecl.overnext.isFuncDeclaration();
3375 funcDeclarationSemantic(fnext);
3376 auto fn = fnext.type.isTypeFunction();
3377 if (!fn || !cFuncEquivalence(f, fn))
3379 funcdecl.error("redeclaration with different type");
3380 //printf("t1: %s\n", f.toChars());
3381 //printf("t2: %s\n", fn.toChars());
3383 funcdecl.overnext = null; // don't overload the redeclarations
3386 if ((funcdecl.storage_class & STC.auto_) && !f.isref && !funcdecl.inferRetType)
3387 funcdecl.error("storage class `auto` has no effect if return type is not inferred");
3389 if (f.isreturn && !funcdecl.needThis() && !funcdecl.isNested())
3391 /* Non-static nested functions have a hidden 'this' pointer to which
3392 * the 'return' applies
3394 if (sc.scopesym && sc.scopesym.isAggregateDeclaration())
3395 funcdecl.error("`static` member has no `this` to which `return` can apply");
3397 error(funcdecl.loc, "top-level function `%s` has no `this` to which `return` can apply", funcdecl.toChars());
3400 if (funcdecl.isAbstract() && !funcdecl.isVirtual())
3403 if (funcdecl.isStatic())
3405 else if (funcdecl.visibility.kind == Visibility.Kind.private_ || funcdecl.visibility.kind == Visibility.Kind.package_)
3406 sfunc = visibilityToChars(funcdecl.visibility.kind);
3409 funcdecl.error("`%s` functions cannot be `abstract`", sfunc);
3412 if (funcdecl.isOverride() && !funcdecl.isVirtual() && !funcdecl.isFuncLiteralDeclaration())
3414 Visibility.Kind kind = funcdecl.visible().kind;
3415 if ((kind == Visibility.Kind.private_ || kind == Visibility.Kind.package_) && funcdecl.isMember())
3416 funcdecl.error("`%s` method is not virtual and cannot override", visibilityToChars(kind));
3418 funcdecl.error("cannot override a non-virtual function");
3421 if (funcdecl.isAbstract() && funcdecl.isFinalFunc())
3422 funcdecl.error("cannot be both `final` and `abstract`");
3425 if (funcdecl.isAbstract() && funcdecl.fbody)
3426 funcdecl.error("`abstract` functions cannot have bodies");
3431 if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor())
3433 if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid)
3434 funcdecl.error("static constructors / destructors must be `static void`");
3435 if (f.arguments && f.arguments.length)
3436 funcdecl.error("static constructors / destructors must have empty parameter list");
3437 // BUG: check for invalid storage classes
3441 if (funcdecl.printf || funcdecl.scanf)
3443 /* printf/scanf-like functions must be of the form:
3444 * extern (C/C++) T printf([parameters...], const(char)* format, ...);
3446 * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
3449 static bool isPointerToChar(Parameter p)
3451 if (auto tptr = p.type.isTypePointer())
3453 return tptr.next.ty == Tchar;
3458 bool isVa_list(Parameter p)
3460 return p.type.equals(target.va_listType(funcdecl.loc, sc));
3463 const nparams = f.parameterList.length;
3464 if ((f.linkage == LINK.c || f.linkage == LINK.cpp) &&
3466 (f.parameterList.varargs == VarArg.variadic &&
3468 isPointerToChar(f.parameterList[nparams - 1]) ||
3470 f.parameterList.varargs == VarArg.none &&
3472 isPointerToChar(f.parameterList[nparams - 2]) &&
3473 isVa_list(f.parameterList[nparams - 1])
3477 // the signature is valid for printf/scanf, no error
3481 const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars();
3482 if (f.parameterList.varargs == VarArg.variadic)
3484 funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`"
3486 p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
3490 funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`",
3491 p, f.next.toChars(), funcdecl.toChars());
3496 if (auto id = parent.isInterfaceDeclaration())
3498 funcdecl.storage_class |= STC.abstract_;
3499 if (funcdecl.isCtorDeclaration() || funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration() || funcdecl.isNewDeclaration() || funcdecl.isDelete())
3500 funcdecl.error("constructors, destructors, postblits, invariants, new and delete functions are not allowed in interface `%s`", id.toChars());
3501 if (funcdecl.fbody && funcdecl.isVirtual())
3502 funcdecl.error("function body only allowed in `final` functions in interface `%s`", id.toChars());
3505 if (UnionDeclaration ud = parent.isUnionDeclaration())
3507 if (funcdecl.isPostBlitDeclaration() || funcdecl.isDtorDeclaration() || funcdecl.isInvariantDeclaration())
3508 funcdecl.error("destructors, postblits and invariants are not allowed in union `%s`", ud.toChars());
3511 if (StructDeclaration sd = parent.isStructDeclaration())
3513 if (funcdecl.isCtorDeclaration())
3519 if (ClassDeclaration cd = parent.isClassDeclaration())
3521 parent = cd = objc.getParent(funcdecl, cd);
3523 if (funcdecl.isCtorDeclaration())
3528 if (funcdecl.storage_class & STC.abstract_)
3529 cd.isabstract = ThreeState.yes;
3531 // if static function, do not put in vtbl[]
3532 if (!funcdecl.isVirtual())
3534 //printf("\tnot virtual\n");
3537 // Suppress further errors if the return type is an error
3538 if (funcdecl.type.nextOf() == Type.terror)
3541 bool may_override = false;
3542 for (size_t i = 0; i < cd.baseclasses.length; i++)
3544 BaseClass* b = (*cd.baseclasses)[i];
3545 ClassDeclaration cbd = b.type.toBasetype().isClassHandle();
3548 for (size_t j = 0; j < cbd.vtbl.length; j++)
3550 FuncDeclaration f2 = cbd.vtbl[j].isFuncDeclaration();
3551 if (!f2 || f2.ident != funcdecl.ident)
3553 if (cbd.parent && cbd.parent.isTemplateInstance())
3555 if (!f2.functionSemantic())
3558 may_override = true;
3561 if (may_override && funcdecl.type.nextOf() is null)
3563 /* If same name function exists in base class but 'this' is auto return,
3564 * cannot find index of base class's vtbl[] to override.
3566 funcdecl.error("return type inference is not supported if may override base class function");
3569 /* Find index of existing function in base class's vtbl[] to override
3570 * (the index will be the same as in cd's current vtbl[])
3572 int vi = cd.baseClass ? funcdecl.findVtblIndex(&cd.baseClass.vtbl, cast(int)cd.baseClass.vtbl.length) : -1;
3574 bool doesoverride = false;
3579 /* Didn't find one, so
3580 * This is an 'introducing' function which gets a new
3581 * slot in the vtbl[].
3584 // Verify this doesn't override previous final function
3587 Dsymbol s = cd.baseClass.search(funcdecl.loc, funcdecl.ident);
3590 if (auto f2 = s.isFuncDeclaration())
3592 f2 = f2.overloadExactMatch(funcdecl.type);
3593 if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
3594 funcdecl.error("cannot override `final` function `%s`", f2.toPrettyChars());
3599 /* These quirky conditions mimic what happens when virtual
3600 inheritance is implemented by producing a virtual base table
3601 with offsets to each of the virtual bases.
3603 if (target.cpp.splitVBasetable && cd.classKind == ClassKind.cpp &&
3604 cd.baseClass && cd.baseClass.vtbl.length)
3606 /* if overriding an interface function, then this is not
3607 * introducing and don't put it in the class vtbl[]
3609 funcdecl.interfaceVirtual = funcdecl.overrideInterface();
3610 if (funcdecl.interfaceVirtual)
3612 //printf("\tinterface function %s\n", toChars());
3613 cd.vtblFinal.push(funcdecl);
3618 if (funcdecl.isFinalFunc())
3620 // Don't check here, as it may override an interface function
3622 // error("is marked as override, but does not override any function");
3623 cd.vtblFinal.push(funcdecl);
3627 //printf("\tintroducing function %s\n", funcdecl.toChars());
3628 funcdecl.isIntroducing = true;
3629 if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads)
3631 /* Overloaded functions with same name are grouped and in reverse order.
3632 * Search for first function of overload group, and insert
3633 * funcdecl into vtbl[] immediately before it.
3635 funcdecl.vtblIndex = cast(int)cd.vtbl.length;
3637 foreach (const i, s; cd.vtbl)
3640 // the rest get shifted forward
3641 ++s.isFuncDeclaration().vtblIndex;
3642 else if (s.ident == funcdecl.ident && s.parent == parent)
3644 // found first function of overload group
3645 funcdecl.vtblIndex = cast(int)i;
3647 ++s.isFuncDeclaration().vtblIndex;
3650 cd.vtbl.insert(funcdecl.vtblIndex, funcdecl);
3652 debug foreach (const i, s; cd.vtbl)
3654 // a C++ dtor gets its vtblIndex later (and might even be added twice to the vtbl),
3655 // e.g. when compiling druntime with a debug compiler, namely with core.stdcpp.exception.
3656 if (auto fd = s.isFuncDeclaration())
3657 assert(fd.vtblIndex == i ||
3658 (cd.classKind == ClassKind.cpp && fd.isDtorDeclaration) ||
3659 funcdecl.parent.isInterfaceDeclaration); // interface functions can be in multiple vtbls
3664 // Append to end of vtbl[]
3665 vi = cast(int)cd.vtbl.length;
3666 cd.vtbl.push(funcdecl);
3667 funcdecl.vtblIndex = vi;
3673 // can't determine because of forward references
3674 funcdecl.errors = true;
3679 if (vi >= cd.vtbl.length)
3681 /* the derived class cd doesn't have its vtbl[] allocated yet.
3682 * https://issues.dlang.org/show_bug.cgi?id=21008
3684 funcdecl.error("circular reference to class `%s`", cd.toChars());
3685 funcdecl.errors = true;
3688 FuncDeclaration fdv = cd.baseClass.vtbl[vi].isFuncDeclaration();
3689 FuncDeclaration fdc = cd.vtbl[vi].isFuncDeclaration();
3690 // This function is covariant with fdv
3692 if (fdc == funcdecl)
3694 doesoverride = true;
3698 auto vtf = getFunctionType(fdv);
3699 if (vtf.trust > TRUST.system && f.trust == TRUST.system)
3700 funcdecl.error("cannot override `@safe` method `%s` with a `@system` attribute",
3703 if (fdc.toParent() == parent)
3705 //printf("vi = %d,\tthis = %p %s %s @ [%s]\n\tfdc = %p %s %s @ [%s]\n\tfdv = %p %s %s @ [%s]\n",
3706 // vi, this, this.toChars(), this.type.toChars(), this.loc.toChars(),
3707 // fdc, fdc .toChars(), fdc .type.toChars(), fdc .loc.toChars(),
3708 // fdv, fdv .toChars(), fdv .type.toChars(), fdv .loc.toChars());
3710 // fdc overrides fdv exactly, then this introduces new function.
3711 if (fdc.type.mod == fdv.type.mod && funcdecl.type.mod != fdv.type.mod)
3715 if (fdv.isDeprecated && !funcdecl.isDeprecated)
3716 deprecation(funcdecl.loc, "`%s` is overriding the deprecated method `%s`",
3717 funcdecl.toPrettyChars, fdv.toPrettyChars);
3719 // This function overrides fdv
3720 if (fdv.isFinalFunc())
3721 funcdecl.error("cannot override `final` function `%s`", fdv.toPrettyChars());
3723 if (!funcdecl.isOverride())
3727 deprecation(funcdecl.loc, "`@__future` base class method `%s` is being overridden by `%s`; rename the latter", fdv.toPrettyChars(), funcdecl.toPrettyChars());
3728 // Treat 'this' as an introducing function, giving it a separate hierarchy in the vtbl[]
3733 // https://issues.dlang.org/show_bug.cgi?id=17349
3734 error(funcdecl.loc, "cannot implicitly override base class method `%s` with `%s`; add `override` attribute",
3735 fdv.toPrettyChars(), funcdecl.toPrettyChars());
3738 doesoverride = true;
3739 if (fdc.toParent() == parent)
3741 // If both are mixins, or both are not, then error.
3742 // If either is not, the one that is not overrides the other.
3743 bool thismixin = funcdecl.parent.isClassDeclaration() !is null;
3744 bool fdcmixin = fdc.parent.isClassDeclaration() !is null;
3745 if (thismixin == fdcmixin)
3747 funcdecl.error("multiple overrides of same function");
3750 * https://issues.dlang.org/show_bug.cgi?id=711
3752 * If an overriding method is introduced through a mixin,
3753 * we need to update the vtbl so that both methods are
3758 /* if the mixin introduced the overriding method, then reintroduce it
3759 * in the vtbl. The initial entry for the mixined method
3760 * will be updated at the end of the enclosing `if` block
3761 * to point to the current (non-mixined) function.
3763 auto vitmp = cast(int)cd.vtbl.length;
3765 fdc.vtblIndex = vitmp;
3769 /* if the current overriding function is coming from a
3770 * mixined block, then push the current function in the
3771 * vtbl, but keep the previous (non-mixined) function as
3772 * the overriding one.
3774 auto vitmp = cast(int)cd.vtbl.length;
3775 cd.vtbl.push(funcdecl);
3776 funcdecl.vtblIndex = vitmp;
3779 else // fdc overrides fdv
3781 // this doesn't override any function
3785 cd.vtbl[vi] = funcdecl;
3786 funcdecl.vtblIndex = vi;
3788 /* Remember which functions this overrides
3790 funcdecl.foverrides.push(fdv);
3792 /* This works by whenever this function is called,
3793 * it actually returns tintro, which gets dynamically
3794 * cast to type. But we know that tintro is a base
3795 * of type, so we could optimize it by not doing a
3796 * dynamic cast, but just subtracting the isBaseOf()
3797 * offset if the value is != null.
3801 funcdecl.tintro = fdv.tintro;
3802 else if (!funcdecl.type.equals(fdv.type))
3804 auto tnext = funcdecl.type.nextOf();
3805 if (auto handle = tnext.isClassHandle())
3807 if (handle.semanticRun < PASS.semanticdone && !handle.isBaseInfoComplete())
3808 handle.dsymbolSemantic(null);
3810 /* Only need to have a tintro if the vptr
3814 if (fdv.type.nextOf().isBaseOf(tnext, &offset))
3816 funcdecl.tintro = fdv.type;
3823 /* Go through all the interface bases.
3824 * If this function is covariant with any members of those interface
3825 * functions, set the tintro.
3828 bool foundVtblMatch = false;
3830 for (ClassDeclaration bcd = cd; !foundVtblMatch && bcd; bcd = bcd.baseClass)
3832 foreach (b; bcd.interfaces)
3834 vi = funcdecl.findVtblIndex(&b.sym.vtbl, cast(int)b.sym.vtbl.length);
3841 // can't determine because of forward references
3842 funcdecl.errors = true;
3847 auto fdv = cast(FuncDeclaration)b.sym.vtbl[vi];
3850 foundVtblMatch = true;
3852 /* Remember which functions this overrides
3854 funcdecl.foverrides.push(fdv);
3856 /* Should we really require 'override' when implementing
3857 * an interface function?
3859 //if (!isOverride())
3860 // warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
3864 else if (!funcdecl.type.equals(fdv.type))
3866 /* Only need to have a tintro if the vptr
3870 if (fdv.type.nextOf().isBaseOf(funcdecl.type.nextOf(), &offset))
3877 if (funcdecl.tintro)
3879 if (!funcdecl.tintro.nextOf().equals(ti.nextOf()) && !funcdecl.tintro.nextOf().isBaseOf(ti.nextOf(), null) && !ti.nextOf().isBaseOf(funcdecl.tintro.nextOf(), null))
3881 funcdecl.error("incompatible covariant types `%s` and `%s`", funcdecl.tintro.toChars(), ti.toChars());
3886 funcdecl.tintro = ti;
3898 if (!doesoverride && funcdecl.isOverride() && (funcdecl.type.nextOf() || !may_override))
3900 BaseClass* bc = null;
3902 for (size_t i = 0; i < cd.baseclasses.length; i++)
3904 bc = (*cd.baseclasses)[i];
3905 s = bc.sym.search_correct(funcdecl.ident);
3915 auto fd = s.isFuncDeclaration();
3916 functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
3917 new Identifier(funcdecl.toPrettyChars()), &hgs, null);
3918 const(char)* funcdeclToChars = buf.peekChars();
3924 if (fd.ident == funcdecl.ident)
3925 hgs.fullQual = true;
3927 // https://issues.dlang.org/show_bug.cgi?id=23745
3928 // If the potentially overriden function contains errors,
3929 // inform the user to fix that one first
3932 error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
3933 funcdecl.toChars(), fd.toPrettyChars());
3934 errorSupplemental(fd.loc, "Function `%s` contains errors in its declaration, therefore it cannot be correctly overriden",
3935 fd.toPrettyChars());
3939 functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
3940 new Identifier(fd.toPrettyChars()), &hgs, null);
3942 error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
3943 funcdeclToChars, buf1.peekChars());
3948 error(funcdecl.loc, "function `%s` does not override any function, did you mean to override %s `%s`?",
3949 funcdeclToChars, s.kind, s.toPrettyChars());
3950 errorSupplemental(funcdecl.loc, "Functions are the only declarations that may be overriden");
3954 funcdecl.error("does not override any function");
3958 objc.setSelector(funcdecl, sc);
3959 objc.checkLinkage(funcdecl);
3960 objc.addToClassMethodList(funcdecl, cd);
3961 objc.setAsOptional(funcdecl, sc);
3963 /* Go through all the interface bases.
3964 * Disallow overriding any final functions in the interface(s).
3966 foreach (b; cd.interfaces)
3970 if (auto s = search_function(b.sym, funcdecl.ident))
3972 if (auto f2 = s.isFuncDeclaration())
3974 f2 = f2.overloadExactMatch(funcdecl.type);
3975 if (f2 && f2.isFinalFunc() && f2.visible().kind != Visibility.Kind.private_)
3976 funcdecl.error("cannot override `final` function `%s.%s`", b.sym.toChars(), f2.toPrettyChars());
3982 if (funcdecl.isOverride)
3984 if (funcdecl.storage_class & STC.disable)
3985 deprecation(funcdecl.loc,
3986 "`%s` cannot be annotated with `@disable` because it is overriding a function in the base class",
3987 funcdecl.toPrettyChars);
3989 if (funcdecl.isDeprecated && !(funcdecl.foverrides.length && funcdecl.foverrides[0].isDeprecated))
3990 deprecation(funcdecl.loc,
3991 "`%s` cannot be marked as `deprecated` because it is overriding a function in the base class",
3992 funcdecl.toPrettyChars);
3996 else if (funcdecl.isOverride() && !parent.isTemplateInstance())
3997 funcdecl.error("`override` only applies to class member functions");
3999 if (auto ti = parent.isTemplateInstance)
4001 objc.setSelector(funcdecl, sc);
4002 objc.setAsOptional(funcdecl, sc);
4005 objc.validateSelector(funcdecl);
4006 objc.validateOptional(funcdecl);
4007 // Reflect this.type to f because it could be changed by findVtblIndex
4008 f = funcdecl.type.toTypeFunction();
4011 if (!funcdecl.fbody && !funcdecl.allowsContractWithoutBody())
4012 funcdecl.error("`in` and `out` contracts can only appear without a body when they are virtual interface functions or abstract");
4014 /* Do not allow template instances to add virtual functions
4017 if (funcdecl.isVirtual())
4019 if (auto ti = parent.isTemplateInstance())
4021 // Take care of nested templates
4024 TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
4030 // If it's a member template
4031 ClassDeclaration cd = ti.tempdecl.isClassMember();
4034 funcdecl.error("cannot use template to add virtual function to class `%s`", cd.toChars());
4039 funcdecl.checkMain(); // Check main() parameters and return type
4041 /* Purity and safety can be inferred for some functions by examining
4042 * the function body.
4044 if (funcdecl.canInferAttributes(sc))
4045 funcdecl.initInferAttributes();
4047 funcdecl.semanticRun = PASS.semanticdone;
4049 /* Save scope for possible later use (if we need the
4050 * function internals)
4052 funcdecl._scope = sc.copy();
4053 funcdecl._scope.setNoFree();
4055 __gshared bool printedMain = false; // semantic might run more than once
4056 if (global.params.verbose && !printedMain)
4058 const(char)* type = funcdecl.isMain() ? "main" : funcdecl.isWinMain() ? "winmain" : funcdecl.isDllMain() ? "dllmain" : cast(const(char)*)null;
4059 Module mod = sc._module;
4064 auto name = mod.srcfile.toChars();
4065 auto path = FileName.searchPath(global.path, name, true);
4066 message("entry %-10s\t%s", type, path ? path : name);
4070 if (funcdecl.fbody && sc._module.isRoot() &&
4071 (funcdecl.isMain() || funcdecl.isWinMain() || funcdecl.isDllMain() || funcdecl.isCMain()))
4072 global.hasMainFunction = true;
4074 if (funcdecl.fbody && funcdecl.isMain() && sc._module.isRoot())
4076 // check if `_d_cmain` is defined
4077 bool cmainTemplateExists()
4079 auto rootSymbol = sc.search(funcdecl.loc, Id.empty, null);
4080 if (auto moduleSymbol = rootSymbol.search(funcdecl.loc, Id.object))
4081 if (moduleSymbol.search(funcdecl.loc, Id.CMain))
4087 // Only mixin `_d_cmain` if it is defined
4088 if (cmainTemplateExists())
4090 // add `mixin _d_cmain!();` to the declaring module
4091 auto tqual = new TypeIdentifier(funcdecl.loc, Id.CMain);
4092 auto tm = new TemplateMixin(funcdecl.loc, null, tqual, null);
4093 sc._module.members.push(tm);
4097 assert(funcdecl.type.ty != Terror || funcdecl.errors);
4099 // semantic for parameters' UDAs
4100 foreach (i, param; f.parameterList)
4102 if (param && param.userAttribDecl)
4103 param.userAttribDecl.dsymbolSemantic(sc);
4107 /// Do the semantic analysis on the external interface to the function.
4108 override void visit(FuncDeclaration funcdecl)
4110 funcDeclarationSemantic(funcdecl);
4113 override void visit(CtorDeclaration ctd)
4115 //printf("CtorDeclaration::semantic() %s\n", toChars());
4116 if (ctd.semanticRun >= PASS.semanticdone)
4124 ctd.parent = sc.parent;
4125 Dsymbol p = ctd.toParentDecl();
4126 AggregateDeclaration ad = p.isAggregateDeclaration();
4129 error(ctd.loc, "constructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4130 ctd.type = Type.terror;
4137 if (sc.stc & STC.static_)
4139 if (sc.stc & STC.shared_)
4140 error(ctd.loc, "`shared static` has no effect on a constructor inside a `shared static` block. Use `shared static this()`");
4142 error(ctd.loc, "`static` has no effect on a constructor inside a `static` block. Use `static this()`");
4145 sc.stc &= ~STC.static_; // not a static constructor
4147 funcDeclarationSemantic(ctd);
4154 TypeFunction tf = ctd.type.toTypeFunction();
4155 immutable dim = tf.parameterList.length;
4156 auto sd = ad.isStructDeclaration();
4158 /* See if it's the default constructor
4159 * But, template constructor should not become a default constructor.
4161 if (ad && (!ctd.parent.isTemplateInstance() || ctd.parent.isTemplateMixin()))
4165 if (dim == 0 && tf.parameterList.varargs == VarArg.none)
4166 ad.defaultCtor = ctd;
4170 if (dim == 0 && tf.parameterList.varargs == VarArg.none) // empty default ctor w/o any varargs
4172 if (ctd.fbody || !(ctd.storage_class & STC.disable))
4174 ctd.error("default constructor for structs only allowed " ~
4175 "with `@disable`, no body, and no parameters");
4176 ctd.storage_class |= STC.disable;
4179 sd.noDefaultCtor = true;
4181 else if (dim == 0 && tf.parameterList.varargs != VarArg.none) // allow varargs only ctor
4184 else if (dim && !tf.parameterList.hasArgsWithoutDefault)
4186 if (ctd.storage_class & STC.disable)
4188 ctd.error("is marked `@disable`, so it cannot have default "~
4189 "arguments for all parameters.");
4190 errorSupplemental(ctd.loc, "Use `@disable this();` if you want to disable default initialization.");
4193 ctd.error("all parameters have default arguments, "~
4194 "but structs cannot have default constructors.");
4196 else if ((dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg)))
4198 //printf("tf: %s\n", tf.toChars());
4199 auto param = tf.parameterList[0];
4200 if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
4202 //printf("copy constructor\n");
4203 ctd.isCpCtor = true;
4207 // https://issues.dlang.org/show_bug.cgi?id=22593
4208 else if (auto ti = ctd.parent.isTemplateInstance())
4210 checkHasBothRvalueAndCpCtor(sd, ctd, ti);
4214 override void visit(PostBlitDeclaration pbd)
4216 //printf("PostBlitDeclaration::semantic() %s\n", toChars());
4217 //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id.dtor.toChars(), ident, Id.dtor);
4218 //printf("stc = x%llx\n", sc.stc);
4219 if (pbd.semanticRun >= PASS.semanticdone)
4227 pbd.parent = sc.parent;
4228 Dsymbol p = pbd.toParent2();
4229 StructDeclaration ad = p.isStructDeclaration();
4232 error(pbd.loc, "postblit can only be a member of struct, not %s `%s`", p.kind(), p.toChars());
4233 pbd.type = Type.terror;
4237 if (pbd.ident == Id.postblit && pbd.semanticRun < PASS.semantic)
4238 ad.postblits.push(pbd);
4240 pbd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, pbd.storage_class);
4243 sc.stc &= ~STC.static_; // not static
4244 sc.linkage = LINK.d;
4246 funcDeclarationSemantic(pbd);
4251 override void visit(DtorDeclaration dd)
4253 //printf("DtorDeclaration::semantic() %s\n", dd.toChars());
4254 //printf("ident: %s, %s, %p, %p\n", dd.ident.toChars(), Id.dtor.toChars(), dd.ident, Id.dtor);
4255 if (dd.semanticRun >= PASS.semanticdone)
4263 dd.parent = sc.parent;
4264 Dsymbol p = dd.toParent2();
4265 AggregateDeclaration ad = p.isAggregateDeclaration();
4268 error(dd.loc, "destructor can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4269 dd.type = Type.terror;
4274 if (ad.isClassDeclaration() && ad.classKind == ClassKind.d)
4276 // Class destructors are implicitly `scope`
4277 dd.storage_class |= STC.scope_;
4280 if (dd.ident == Id.dtor && dd.semanticRun < PASS.semantic)
4281 ad.userDtors.push(dd);
4284 dd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, dd.storage_class);
4285 if (ad.classKind == ClassKind.cpp && dd.ident == Id.dtor)
4287 if (auto cldec = ad.isClassDeclaration())
4289 assert (cldec.cppDtorVtblIndex == -1); // double-call check already by dd.type
4290 if (cldec.baseClass && cldec.baseClass.cppDtorVtblIndex != -1)
4292 // override the base virtual
4293 cldec.cppDtorVtblIndex = cldec.baseClass.cppDtorVtblIndex;
4295 else if (!dd.isFinal())
4297 // reserve the dtor slot for the destructor (which we'll create later)
4298 cldec.cppDtorVtblIndex = cast(int)cldec.vtbl.length;
4299 cldec.vtbl.push(dd);
4300 if (target.cpp.twoDtorInVtable)
4301 cldec.vtbl.push(dd); // deleting destructor uses a second slot
4308 sc.stc &= ~STC.static_; // not a static destructor
4309 if (sc.linkage != LINK.cpp)
4310 sc.linkage = LINK.d;
4312 funcDeclarationSemantic(dd);
4317 override void visit(StaticCtorDeclaration scd)
4319 //printf("StaticCtorDeclaration::semantic()\n");
4320 if (scd.semanticRun >= PASS.semanticdone)
4328 scd.parent = sc.parent;
4329 Dsymbol p = scd.parent.pastMixin();
4330 if (!p.isScopeDsymbol())
4332 const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4333 error(scd.loc, "`%sstatic` constructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4334 scd.type = Type.terror;
4339 scd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, scd.storage_class);
4341 /* If the static ctor appears within a template instantiation,
4342 * it could get called multiple times by the module constructors
4343 * for different modules. Thus, protect it with a gate.
4345 if (scd.isInstantiated() && scd.semanticRun < PASS.semantic)
4347 /* Add this prefix to the constructor:
4350 * if (++gate != 1) return;
4352 * or, for shared constructor:
4355 * if (core.atomic.atomicOp!"+="(gate, 1) != 1) return;
4358 const bool isShared = !!scd.isSharedStaticCtorDeclaration();
4359 auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4360 v.storage_class = STC.temp | STC.static_ | (isShared ? STC.shared_ : 0);
4362 auto sa = new Statements();
4363 Statement s = new ExpStatement(Loc.initial, v);
4369 e = doAtomicOp("+=", v.ident, IntegerExp.literal!(1));
4372 scd.error("shared static constructor within a template require `core.atomic : atomicOp` to be present");
4378 e = new AddAssignExp(
4379 Loc.initial, new IdentifierExp(Loc.initial, v.ident), IntegerExp.literal!1);
4382 e = new EqualExp(EXP.notEqual, Loc.initial, e, IntegerExp.literal!1);
4383 s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4389 scd.fbody = new CompoundStatement(Loc.initial, sa);
4392 const LINK save = sc.linkage;
4395 const(char)* s = (scd.isSharedStaticCtorDeclaration() ? "shared " : "");
4396 deprecation(scd.loc, "`%sstatic` constructor can only be of D linkage", s);
4398 sc.linkage = LINK.d;
4400 funcDeclarationSemantic(scd);
4403 // We're going to need ModuleInfo
4404 Module m = scd.getModule();
4409 m.needmoduleinfo = 1;
4410 //printf("module1 %s needs moduleinfo\n", m.toChars());
4414 override void visit(StaticDtorDeclaration sdd)
4416 if (sdd.semanticRun >= PASS.semanticdone)
4424 sdd.parent = sc.parent;
4425 Dsymbol p = sdd.parent.pastMixin();
4426 if (!p.isScopeDsymbol())
4428 const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4429 error(sdd.loc, "`%sstatic` destructor can only be member of module/aggregate/template, not %s `%s`", s, p.kind(), p.toChars());
4430 sdd.type = Type.terror;
4435 sdd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, sdd.storage_class);
4437 /* If the static ctor appears within a template instantiation,
4438 * it could get called multiple times by the module constructors
4439 * for different modules. Thus, protect it with a gate.
4441 if (sdd.isInstantiated() && sdd.semanticRun < PASS.semantic)
4443 /* Add this prefix to the constructor:
4446 * if (--gate != 0) return;
4448 * or, for shared constructor:
4451 * if (core.atomic.atomicOp!"-="(gate, 1) != 0) return;
4454 const bool isShared = !!sdd.isSharedStaticDtorDeclaration();
4455 auto v = new VarDeclaration(Loc.initial, Type.tint32, Id.gate, null);
4456 v.storage_class = STC.temp | STC.static_ | (isShared ? STC.shared_ : 0);
4458 auto sa = new Statements();
4459 Statement s = new ExpStatement(Loc.initial, v);
4465 e = doAtomicOp("-=", v.ident, IntegerExp.literal!(1));
4468 sdd.error("shared static destructo within a template require `core.atomic : atomicOp` to be present");
4474 e = new AddAssignExp(
4475 Loc.initial, new IdentifierExp(Loc.initial, v.ident), IntegerExp.literal!(-1));
4478 e = new EqualExp(EXP.notEqual, Loc.initial, e, IntegerExp.literal!0);
4479 s = new IfStatement(Loc.initial, null, e, new ReturnStatement(Loc.initial, null), null, Loc.initial);
4485 sdd.fbody = new CompoundStatement(Loc.initial, sa);
4490 const LINK save = sc.linkage;
4493 const(char)* s = (sdd.isSharedStaticDtorDeclaration() ? "shared " : "");
4494 deprecation(sdd.loc, "`%sstatic` destructor can only be of D linkage", s);
4496 sc.linkage = LINK.d;
4498 funcDeclarationSemantic(sdd);
4501 // We're going to need ModuleInfo
4502 Module m = sdd.getModule();
4507 m.needmoduleinfo = 1;
4508 //printf("module2 %s needs moduleinfo\n", m.toChars());
4512 override void visit(InvariantDeclaration invd)
4514 if (invd.semanticRun >= PASS.semanticdone)
4522 invd.parent = sc.parent;
4523 Dsymbol p = invd.parent.pastMixin();
4524 AggregateDeclaration ad = p.isAggregateDeclaration();
4527 error(invd.loc, "`invariant` can only be a member of aggregate, not %s `%s`", p.kind(), p.toChars());
4528 invd.type = Type.terror;
4532 if (invd.ident != Id.classInvariant &&
4533 invd.semanticRun < PASS.semantic &&
4534 !ad.isUnionDeclaration() // users are on their own with union fields
4537 invd.fixupInvariantIdent(ad.invs.length);
4541 invd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, invd.storage_class);
4544 sc.stc &= ~STC.static_; // not a static invariant
4545 sc.stc |= STC.const_; // invariant() is always const
4546 sc.flags = (sc.flags & ~SCOPE.contract) | SCOPE.invariant_;
4547 sc.linkage = LINK.d;
4549 funcDeclarationSemantic(invd);
4554 override void visit(UnitTestDeclaration utd)
4556 if (utd.semanticRun >= PASS.semanticdone)
4564 utd.visibility = sc.visibility;
4566 utd.parent = sc.parent;
4567 Dsymbol p = utd.parent.pastMixin();
4568 if (!p.isScopeDsymbol())
4570 error(utd.loc, "`unittest` can only be a member of module/aggregate/template, not %s `%s`", p.kind(), p.toChars());
4571 utd.type = Type.terror;
4576 if (global.params.useUnitTests)
4579 utd.type = new TypeFunction(ParameterList(), Type.tvoid, LINK.d, utd.storage_class);
4580 Scope* sc2 = sc.push();
4581 sc2.linkage = LINK.d;
4582 funcDeclarationSemantic(utd);
4588 // We're going to need ModuleInfo even if the unit tests are not
4589 // compiled in, because other modules may import this module and refer
4590 // to this ModuleInfo.
4591 // (This doesn't make sense to me?)
4592 Module m = utd.getModule();
4597 //printf("module3 %s needs moduleinfo\n", m.toChars());
4598 m.needmoduleinfo = 1;
4603 override void visit(NewDeclaration nd)
4605 //printf("NewDeclaration::semantic()\n");
4606 if (nd.semanticRun >= PASS.semanticdone)
4609 nd.type = new TypeFunction(ParameterList(), Type.tvoid.pointerTo(), LINK.d, nd.storage_class);
4611 funcDeclarationSemantic(nd);
4614 override void visit(StructDeclaration sd)
4617 if (log) printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4619 //static int count; if (++count == 20) assert(0);
4621 if (sd.semanticRun >= PASS.semanticdone)
4623 int errors = global.errors;
4625 //printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4630 scx = sd._scope; // save so we don't make redundant copies
4636 assert(sc.parent && sc.func);
4637 sd.parent = sc.parent;
4639 assert(sd.parent && !sd.isAnonymous());
4642 sd.type = Type.terror;
4643 if (sd.semanticRun == PASS.initial)
4644 sd.type = sd.type.addSTC(sc.stc | sd.storage_class);
4645 sd.type = sd.type.typeSemantic(sd.loc, sc);
4646 auto ts = sd.type.isTypeStruct();
4651 auto ti = ts.sym.isInstantiated();
4652 if (ti && isError(ti))
4657 // Ungag errors when not speculative
4658 Ungag ungag = sd.ungagSpeculative();
4660 if (sd.semanticRun == PASS.initial)
4662 sd.visibility = sc.visibility;
4664 sd.alignment = sc.alignment();
4666 sd.storage_class |= sc.stc;
4667 if (sd.storage_class & STC.abstract_)
4668 sd.error("structs, unions cannot be `abstract`");
4670 sd.userAttribDecl = sc.userAttribDecl;
4672 if (sc.linkage == LINK.cpp)
4673 sd.classKind = ClassKind.cpp;
4674 else if (sc.linkage == LINK.c)
4675 sd.classKind = ClassKind.c;
4676 sd.cppnamespace = sc.namespace;
4677 sd.cppmangle = sc.cppmangle;
4679 else if (sd.symtab && !scx)
4682 sd.semanticRun = PASS.semantic;
4683 UserAttributeDeclaration.checkGNUABITag(sd, sc.linkage);
4685 if (!sd.members) // if opaque declaration
4687 if (log) printf("\topaque declaration %s\n", sd.toChars());
4688 sd.semanticRun = PASS.semanticdone;
4693 sd.symtab = new DsymbolTable();
4695 sd.members.foreachDsymbol( s => s.addMember(sc, sd) );
4698 auto sc2 = sd.newScope(sc);
4700 /* Set scope so if there are forward references, we still might be able to
4701 * resolve individual members like enums.
4703 sd.members.foreachDsymbol( s => s.setScope(sc2) );
4704 sd.members.foreachDsymbol( s => s.importAll(sc2) );
4705 sd.members.foreachDsymbol( (s) { s.dsymbolSemantic(sc2); sd.errors |= s.errors; } );
4708 sd.type = Type.terror;
4710 if (!sd.determineFields())
4712 if (sd.type.ty != Terror)
4714 sd.error(sd.loc, "circular or forward reference");
4716 sd.type = Type.terror;
4720 sd.semanticRun = PASS.semanticdone;
4723 /* Following special member functions creation needs semantic analysis
4724 * completion of sub-structs in each field types. For example, buildDtor
4725 * needs to check existence of elaborate dtor in type of each fields.
4726 * See the case in compilable/test14838.d
4728 foreach (v; sd.fields)
4730 Type tb = v.type.baseElemOf();
4731 if (tb.ty != Tstruct)
4733 auto sdec = (cast(TypeStruct)tb).sym;
4734 if (sdec.semanticRun >= PASS.semanticdone)
4739 if (log) printf("\tdeferring %s\n", sd.toChars());
4740 return deferDsymbolSemantic(sd, scx);
4743 /* Look for special member functions.
4745 sd.disableNew = sd.search(Loc.initial, Id.classNew) !is null;
4747 // Look for the constructor
4748 sd.ctor = sd.searchCtor();
4750 buildDtors(sd, sc2);
4752 sd.hasCopyCtor = buildCopyCtor(sd, sc2);
4753 sd.postblit = buildPostBlit(sd, sc2);
4755 buildOpAssign(sd, sc2);
4756 buildOpEquals(sd, sc2);
4758 if (!(sc2.flags & SCOPE.Cfile) &&
4759 global.params.useTypeInfo && Type.dtypeinfo) // these functions are used for TypeInfo
4761 sd.xeq = buildXopEquals(sd, sc2);
4762 sd.xcmp = buildXopCmp(sd, sc2);
4763 sd.xhash = buildXtoHash(sd, sc2);
4766 sd.inv = buildInv(sd, sc2);
4768 sd.semanticRun = PASS.semanticdone;
4769 if (log) printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4775 Dsymbol scall = sd.search(Loc.initial, Id.call);
4778 uint xerrors = global.startGagging();
4782 auto fcall = resolveFuncCall(sd.loc, sc, scall, null, null, ArgumentList(), FuncResolveFlag.quiet);
4784 global.endGagging(xerrors);
4786 if (fcall && fcall.isStatic())
4788 sd.error(fcall.loc, "`static opCall` is hidden by constructors and can never be called");
4789 errorSupplemental(fcall.loc, "Please use a factory method instead, or replace all constructors with `static opCall`.");
4794 if (ts && ts.sym != sd)
4796 StructDeclaration sym = ts.sym;
4797 if (sd.isCsymbol() && sym.isCsymbol())
4799 /* This is two structs imported from different C files.
4800 * Just ignore sd, the second one. The first one will always
4801 * be found when going through the type.
4808 printf("this = %p %s\n", sd, sd.toChars());
4809 printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars());
4811 // https://issues.dlang.org/show_bug.cgi?id=19024
4812 sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars());
4816 if (global.errors != errors)
4818 // The type is no good.
4819 sd.type = Type.terror;
4822 sd.deferred.errors = true;
4825 if (sd.deferred && !global.gag)
4827 sd.deferred.semantic2(sc);
4828 sd.deferred.semantic3(sc);
4831 // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
4832 // Deprecated in 2.100
4833 // Make an error in 2.110
4834 if (sd.storage_class & STC.scope_)
4835 deprecation(sd.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
4836 //printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok);
4839 void interfaceSemantic(ClassDeclaration cd)
4841 cd.vtblInterfaces = new BaseClasses();
4842 cd.vtblInterfaces.reserve(cd.interfaces.length);
4843 foreach (b; cd.interfaces)
4845 cd.vtblInterfaces.push(b);
4846 b.copyBaseInterfaces(cd.vtblInterfaces);
4850 override void visit(ClassDeclaration cldec)
4852 //printf("ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", cldec.toChars(), cldec.type, cldec.sizeok, this);
4853 //printf("\tparent = %p, '%s'\n", sc.parent, sc.parent ? sc.parent.toChars() : "");
4854 //printf("sc.stc = %x\n", sc.stc);
4856 //{ static int n; if (++n == 20) *(char*)0=0; }
4858 if (cldec.semanticRun >= PASS.semanticdone)
4860 int errors = global.errors;
4862 //printf("+ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
4868 scx = cldec._scope; // save so we don't make redundant copies
4869 cldec._scope = null;
4875 cldec.parent = sc.parent;
4879 cldec.type = Type.terror;
4880 if (cldec.semanticRun == PASS.initial)
4881 cldec.type = cldec.type.addSTC(sc.stc | cldec.storage_class);
4882 cldec.type = cldec.type.typeSemantic(cldec.loc, sc);
4883 if (auto tc = cldec.type.isTypeClass())
4884 if (tc.sym != cldec)
4886 auto ti = tc.sym.isInstantiated();
4887 if (ti && isError(ti))
4891 // Ungag errors when not speculative
4892 Ungag ungag = cldec.ungagSpeculative();
4894 if (cldec.semanticRun == PASS.initial)
4896 cldec.visibility = sc.visibility;
4898 cldec.storage_class |= sc.stc;
4899 if (cldec.storage_class & STC.auto_)
4900 cldec.error("storage class `auto` is invalid when declaring a class, did you mean to use `scope`?");
4901 if (cldec.storage_class & STC.scope_)
4903 if (cldec.storage_class & STC.abstract_)
4904 cldec.isabstract = ThreeState.yes;
4906 cldec.userAttribDecl = sc.userAttribDecl;
4908 if (sc.linkage == LINK.cpp)
4909 cldec.classKind = ClassKind.cpp;
4910 cldec.cppnamespace = sc.namespace;
4911 cldec.cppmangle = sc.cppmangle;
4912 if (sc.linkage == LINK.objc)
4913 objc.setObjc(cldec);
4915 else if (cldec.symtab && !scx)
4919 cldec.semanticRun = PASS.semantic;
4920 UserAttributeDeclaration.checkGNUABITag(cldec, sc.linkage);
4921 checkMustUseReserved(cldec);
4923 if (cldec.baseok < Baseok.done)
4925 /* https://issues.dlang.org/show_bug.cgi?id=12078
4926 * https://issues.dlang.org/show_bug.cgi?id=12143
4927 * https://issues.dlang.org/show_bug.cgi?id=15733
4928 * While resolving base classes and interfaces, a base may refer
4929 * the member of this derived class. In that time, if all bases of
4930 * this class can be determined, we can go forward the semantc process
4931 * beyond the Lancestorsdone. To do the recursive semantic analysis,
4932 * temporarily set and unset `_scope` around exp().
4934 T resolveBase(T)(lazy T exp)
4941 static if (!is(T == void))
4945 cldec._scope = null;
4952 cldec._scope = null;
4956 cldec.baseok = Baseok.start;
4958 // Expand any tuples in baseclasses[]
4959 for (size_t i = 0; i < cldec.baseclasses.length;)
4961 auto b = (*cldec.baseclasses)[i];
4962 b.type = resolveBase(b.type.typeSemantic(cldec.loc, sc));
4964 Type tb = b.type.toBasetype();
4965 if (auto tup = tb.isTypeTuple())
4967 cldec.baseclasses.remove(i);
4968 size_t dim = Parameter.dim(tup.arguments);
4969 for (size_t j = 0; j < dim; j++)
4971 Parameter arg = Parameter.getNth(tup.arguments, j);
4972 b = new BaseClass(arg.type);
4973 cldec.baseclasses.insert(i + j, b);
4980 if (cldec.baseok >= Baseok.done)
4982 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
4983 if (cldec.semanticRun >= PASS.semanticdone)
4985 goto Lancestorsdone;
4988 // See if there's a base class as first in baseclasses[]
4989 if (cldec.baseclasses.length)
4991 BaseClass* b = (*cldec.baseclasses)[0];
4992 Type tb = b.type.toBasetype();
4993 TypeClass tc = tb.isTypeClass();
4996 if (b.type != Type.terror)
4997 cldec.error("base type must be `class` or `interface`, not `%s`", b.type.toChars());
4998 cldec.baseclasses.remove(0);
5001 if (tc.sym.isDeprecated())
5003 if (!cldec.isDeprecated())
5005 // Deriving from deprecated class makes this one deprecated too
5006 cldec.setDeprecated();
5007 tc.checkDeprecated(cldec.loc, sc);
5010 if (tc.sym.isInterfaceDeclaration())
5013 for (ClassDeclaration cdb = tc.sym; cdb; cdb = cdb.baseClass)
5017 cldec.error("circular inheritance");
5018 cldec.baseclasses.remove(0);
5023 /* https://issues.dlang.org/show_bug.cgi?id=11034
5024 * Class inheritance hierarchy
5025 * and instance size of each classes are orthogonal information.
5026 * Therefore, even if tc.sym.sizeof == Sizeok.none,
5027 * we need to set baseClass field for class covariance check.
5029 cldec.baseClass = tc.sym;
5030 b.sym = cldec.baseClass;
5032 if (tc.sym.baseok < Baseok.done)
5033 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5034 if (tc.sym.baseok < Baseok.done)
5036 //printf("\ttry later, forward reference of base class %s\n", tc.sym.toChars());
5038 Module.addDeferredSemantic(tc.sym);
5039 cldec.baseok = Baseok.none;
5044 // Treat the remaining entries in baseclasses as interfaces
5045 // Check for errors, handle forward references
5046 int multiClassError = cldec.baseClass is null ? 0 : 1;
5049 for (size_t i = (cldec.baseClass ? 1 : 0); i < cldec.baseclasses.length;)
5051 BaseClass* b = (*cldec.baseclasses)[i];
5052 Type tb = b.type.toBasetype();
5053 TypeClass tc = tb.isTypeClass();
5054 if (!tc || !tc.sym.isInterfaceDeclaration())
5059 if (multiClassError == 0)
5061 error(cldec.loc,"`%s`: base class must be specified first, " ~
5062 "before any interfaces.", cldec.toPrettyChars());
5063 multiClassError += 1;
5065 else if (multiClassError >= 1)
5067 if(multiClassError == 1)
5068 error(cldec.loc,"`%s`: multiple class inheritance is not supported." ~
5069 " Use multiple interface inheritance and/or composition.", cldec.toPrettyChars());
5070 multiClassError += 1;
5072 if (tc.sym.fields.length)
5073 errorSupplemental(cldec.loc,"`%s` has fields, consider making it a member of `%s`",
5074 b.type.toChars(), cldec.type.toChars());
5076 errorSupplemental(cldec.loc,"`%s` has no fields, consider making it an `interface`",
5080 // It's something else: e.g. `int` in `class Foo : Bar, int { ... }`
5081 else if (b.type != Type.terror)
5083 error(cldec.loc,"`%s`: base type must be `interface`, not `%s`",
5084 cldec.toPrettyChars(), b.type.toChars());
5086 cldec.baseclasses.remove(i);
5090 // Check for duplicate interfaces
5091 for (size_t j = (cldec.baseClass ? 1 : 0); j < i; j++)
5093 BaseClass* b2 = (*cldec.baseclasses)[j];
5094 if (b2.sym == tc.sym)
5096 cldec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
5097 cldec.baseclasses.remove(i);
5101 if (tc.sym.isDeprecated())
5103 if (!cldec.isDeprecated())
5105 // Deriving from deprecated class makes this one deprecated too
5106 cldec.setDeprecated();
5107 tc.checkDeprecated(cldec.loc, sc);
5113 if (tc.sym.baseok < Baseok.done)
5114 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5115 if (tc.sym.baseok < Baseok.done)
5117 //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
5119 Module.addDeferredSemantic(tc.sym);
5120 cldec.baseok = Baseok.none;
5124 if (cldec.baseok == Baseok.none)
5126 // Forward referencee of one or more bases, try again later
5127 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
5128 return deferDsymbolSemantic(cldec, scx);
5130 cldec.baseok = Baseok.done;
5132 if (cldec.classKind == ClassKind.objc || (cldec.baseClass && cldec.baseClass.classKind == ClassKind.objc))
5133 cldec.classKind = ClassKind.objc; // Objective-C classes do not inherit from Object
5135 // If no base class, and this is not an Object, use Object as base class
5136 if (!cldec.baseClass && cldec.ident != Id.Object && cldec.object && cldec.classKind == ClassKind.d)
5138 void badObjectDotD()
5140 cldec.error("missing or corrupt object.d");
5144 if (!cldec.object || cldec.object.errors)
5147 Type t = cldec.object.type;
5148 t = t.typeSemantic(cldec.loc, sc).toBasetype();
5151 TypeClass tc = t.isTypeClass();
5154 auto b = new BaseClass(tc);
5155 cldec.baseclasses.shift(b);
5157 cldec.baseClass = tc.sym;
5158 assert(!cldec.baseClass.isInterfaceDeclaration());
5159 b.sym = cldec.baseClass;
5161 if (cldec.baseClass)
5163 if (cldec.baseClass.storage_class & STC.final_)
5164 cldec.error("cannot inherit from class `%s` because it is `final`", cldec.baseClass.toChars());
5166 // Inherit properties from base class
5167 if (cldec.baseClass.isCOMclass())
5169 if (cldec.baseClass.isCPPclass())
5170 cldec.classKind = ClassKind.cpp;
5171 if (cldec.classKind != cldec.baseClass.classKind)
5172 cldec.error("with %s linkage cannot inherit from class `%s` with %s linkage",
5173 cldec.classKind.toChars(), cldec.baseClass.toChars(), cldec.baseClass.classKind.toChars());
5175 if (cldec.baseClass.stack)
5177 cldec.enclosing = cldec.baseClass.enclosing;
5178 cldec.storage_class |= cldec.baseClass.storage_class & STC.TYPECTOR;
5181 cldec.interfaces = cldec.baseclasses.tdata()[(cldec.baseClass ? 1 : 0) .. cldec.baseclasses.length];
5182 foreach (b; cldec.interfaces)
5184 // If this is an interface, and it derives from a COM interface,
5185 // then this is a COM interface too.
5186 if (b.sym.isCOMinterface())
5188 if (cldec.classKind == ClassKind.cpp && !b.sym.isCPPinterface())
5190 error(cldec.loc, "C++ class `%s` cannot implement D interface `%s`",
5191 cldec.toPrettyChars(), b.sym.toPrettyChars());
5194 interfaceSemantic(cldec);
5197 //printf("\tClassDeclaration.dsymbolSemantic(%s) baseok = %d\n", toChars(), baseok);
5199 if (!cldec.members) // if opaque declaration
5201 cldec.semanticRun = PASS.semanticdone;
5206 cldec.symtab = new DsymbolTable();
5208 /* https://issues.dlang.org/show_bug.cgi?id=12152
5209 * The semantic analysis of base classes should be finished
5210 * before the members semantic analysis of this class, in order to determine
5211 * vtbl in this class. However if a base class refers the member of this class,
5212 * it can be resolved as a normal forward reference.
5213 * Call addMember() and setScope() to make this class members visible from the base classes.
5215 cldec.members.foreachDsymbol( s => s.addMember(sc, cldec) );
5217 auto sc2 = cldec.newScope(sc);
5219 /* Set scope so if there are forward references, we still might be able to
5220 * resolve individual members like enums.
5222 cldec.members.foreachDsymbol( s => s.setScope(sc2) );
5227 for (size_t i = 0; i < cldec.baseclasses.length; i++)
5229 BaseClass* b = (*cldec.baseclasses)[i];
5230 Type tb = b.type.toBasetype();
5231 TypeClass tc = tb.isTypeClass();
5232 if (tc.sym.semanticRun < PASS.semanticdone)
5234 // Forward referencee of one or more bases, try again later
5236 Module.addDeferredSemantic(tc.sym);
5237 //printf("\tL%d semantic('%s') failed due to forward references\n", __LINE__, toChars());
5238 return deferDsymbolSemantic(cldec, scx);
5242 if (cldec.baseok == Baseok.done)
5244 cldec.baseok = Baseok.semanticdone;
5245 objc.setMetaclass(cldec, sc);
5248 if (cldec.baseClass)
5250 if (cldec.classKind == ClassKind.cpp && cldec.baseClass.vtbl.length == 0)
5252 cldec.error("C++ base class `%s` needs at least one virtual function", cldec.baseClass.toChars());
5255 // Copy vtbl[] from base class
5256 assert(cldec.vtbl.length == 0);
5257 cldec.vtbl.setDim(cldec.baseClass.vtbl.length);
5258 memcpy(cldec.vtbl.tdata(), cldec.baseClass.vtbl.tdata(), (void*).sizeof * cldec.vtbl.length);
5260 cldec.vthis = cldec.baseClass.vthis;
5261 cldec.vthis2 = cldec.baseClass.vthis2;
5265 // No base class, so this is the root of the class hierarchy
5266 cldec.vtbl.setDim(0);
5267 if (cldec.vtblOffset())
5268 cldec.vtbl.push(cldec); // leave room for classinfo as first member
5271 /* If this is a nested class, add the hidden 'this'
5272 * member which is a pointer to the enclosing scope.
5274 if (cldec.vthis) // if inheriting from nested class
5276 // Use the base class's 'this' member
5277 if (cldec.storage_class & STC.static_)
5278 cldec.error("static class cannot inherit from nested class `%s`", cldec.baseClass.toChars());
5279 if (cldec.toParentLocal() != cldec.baseClass.toParentLocal() &&
5280 (!cldec.toParentLocal() ||
5281 !cldec.baseClass.toParentLocal().getType() ||
5282 !cldec.baseClass.toParentLocal().getType().isBaseOf(cldec.toParentLocal().getType(), null)))
5284 if (cldec.toParentLocal())
5286 cldec.error("is nested within `%s`, but super class `%s` is nested within `%s`",
5287 cldec.toParentLocal().toChars(),
5288 cldec.baseClass.toChars(),
5289 cldec.baseClass.toParentLocal().toChars());
5293 cldec.error("is not nested, but super class `%s` is nested within `%s`",
5294 cldec.baseClass.toChars(),
5295 cldec.baseClass.toParentLocal().toChars());
5300 if (cldec.toParent2() != cldec.baseClass.toParent2() &&
5301 (!cldec.toParent2() ||
5302 !cldec.baseClass.toParent2().getType() ||
5303 !cldec.baseClass.toParent2().getType().isBaseOf(cldec.toParent2().getType(), null)))
5305 if (cldec.toParent2() && cldec.toParent2() != cldec.toParentLocal())
5307 cldec.error("needs the frame pointer of `%s`, but super class `%s` needs the frame pointer of `%s`",
5308 cldec.toParent2().toChars(),
5309 cldec.baseClass.toChars(),
5310 cldec.baseClass.toParent2().toChars());
5314 cldec.error("doesn't need a frame pointer, but super class `%s` needs the frame pointer of `%s`",
5315 cldec.baseClass.toChars(),
5316 cldec.baseClass.toParent2().toChars());
5321 cldec.makeNested2();
5327 auto sc2 = cldec.newScope(sc);
5329 cldec.members.foreachDsymbol( s => s.importAll(sc2) );
5331 // Note that members.length can grow due to tuple expansion during semantic()
5332 cldec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
5334 if (!cldec.determineFields())
5336 assert(cldec.type == Type.terror);
5340 /* Following special member functions creation needs semantic analysis
5341 * completion of sub-structs in each field types.
5343 foreach (v; cldec.fields)
5345 Type tb = v.type.baseElemOf();
5346 if (tb.ty != Tstruct)
5348 auto sd = (cast(TypeStruct)tb).sym;
5349 if (sd.semanticRun >= PASS.semanticdone)
5354 //printf("\tdeferring %s\n", toChars());
5355 return deferDsymbolSemantic(cldec, scx);
5358 /* Look for special member functions.
5359 * They must be in this class, not in a base class.
5361 // Can be in base class
5362 cldec.disableNew = cldec.search(Loc.initial, Id.classNew) !is null;
5364 // Look for the constructor
5365 cldec.ctor = cldec.searchCtor();
5367 if (!cldec.ctor && cldec.noDefaultCtor)
5369 // A class object is always created by constructor, so this check is legitimate.
5370 foreach (v; cldec.fields)
5372 if (v.storage_class & STC.nodefaultctor)
5373 error(v.loc, "field `%s` must be initialized in constructor", v.toChars());
5377 // If this class has no constructor, but base class has a default
5378 // ctor, create a constructor:
5380 if (!cldec.ctor && cldec.baseClass && cldec.baseClass.ctor)
5382 auto fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type, ArgumentList(), FuncResolveFlag.quiet);
5383 if (!fd) // try shared base ctor instead
5384 fd = resolveFuncCall(cldec.loc, sc2, cldec.baseClass.ctor, null, cldec.type.sharedOf, ArgumentList(), FuncResolveFlag.quiet);
5385 if (fd && !fd.errors)
5387 //printf("Creating default this(){} for class %s\n", toChars());
5388 auto btf = fd.type.toTypeFunction();
5389 auto tf = new TypeFunction(ParameterList(), null, LINK.d, fd.storage_class);
5391 // Don't copy @safe, ... from the base class constructor and let it be inferred instead
5392 // This is required if other lowerings add code to the generated constructor which
5393 // is less strict (e.g. `preview=dtorfields` might introduce a call to a less qualified dtor)
5395 auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf);
5396 ctor.storage_class |= STC.inference | (fd.storage_class & STC.scope_);
5397 ctor.isGenerated = true;
5398 ctor.fbody = new CompoundStatement(Loc.initial, new Statements());
5400 cldec.members.push(ctor);
5401 ctor.addMember(sc, cldec);
5402 ctor.dsymbolSemantic(sc2);
5405 cldec.defaultCtor = ctor;
5409 cldec.error("cannot implicitly generate a default constructor when base class `%s` is missing a default constructor",
5410 cldec.baseClass.toPrettyChars());
5414 buildDtors(cldec, sc2);
5416 if (cldec.classKind == ClassKind.cpp && cldec.cppDtorVtblIndex != -1)
5418 // now we've built the aggregate destructor, we'll make it virtual and assign it to the reserved vtable slot
5419 cldec.dtor.vtblIndex = cldec.cppDtorVtblIndex;
5420 cldec.vtbl[cldec.cppDtorVtblIndex] = cldec.dtor;
5422 if (target.cpp.twoDtorInVtable)
5424 // TODO: create a C++ compatible deleting destructor (call out to `operator delete`)
5425 // for the moment, we'll call the non-deleting destructor and leak
5426 cldec.vtbl[cldec.cppDtorVtblIndex + 1] = cldec.dtor;
5430 if (auto f = hasIdentityOpAssign(cldec, sc2))
5432 if (!(f.storage_class & STC.disable))
5433 cldec.error(f.loc, "identity assignment operator overload is illegal");
5436 cldec.inv = buildInv(cldec, sc2);
5438 cldec.semanticRun = PASS.semanticdone;
5439 //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5443 /* isAbstract() is undecidable in some cases because of circular dependencies.
5444 * Now that semantic is finished, get a definitive result, and error if it is not the same.
5446 if (cldec.isabstract != ThreeState.none) // if evaluated it before completion
5448 const isabstractsave = cldec.isabstract;
5449 cldec.isabstract = ThreeState.none;
5450 cldec.isAbstract(); // recalculate
5451 if (cldec.isabstract != isabstractsave)
5453 cldec.error("cannot infer `abstract` attribute due to circular dependencies");
5457 if (cldec.type.ty == Tclass && (cast(TypeClass)cldec.type).sym != cldec)
5459 // https://issues.dlang.org/show_bug.cgi?id=17492
5460 ClassDeclaration cd = (cast(TypeClass)cldec.type).sym;
5463 printf("this = %p %s\n", cldec, cldec.toPrettyChars());
5464 printf("type = %d sym = %p, %s\n", cldec.type.ty, cd, cd.toPrettyChars());
5466 cldec.error("already exists at %s. Perhaps in another function with the same name?", cd.loc.toChars());
5469 if (global.errors != errors || (cldec.baseClass && cldec.baseClass.errors))
5471 // The type is no good, but we should keep the
5472 // the type so that we have more accurate error messages
5473 // See: https://issues.dlang.org/show_bug.cgi?id=23552
5474 cldec.errors = true;
5476 cldec.deferred.errors = true;
5479 // Verify fields of a synchronized class are not public
5480 if (cldec.storage_class & STC.synchronized_)
5482 foreach (vd; cldec.fields)
5484 if (!vd.isThisDeclaration() &&
5485 vd.visible() >= Visibility(Visibility.Kind.public_))
5487 vd.error("Field members of a `synchronized` class cannot be `%s`",
5488 visibilityToChars(vd.visible().kind));
5493 if (cldec.deferred && !global.gag)
5495 cldec.deferred.semantic2(sc);
5496 cldec.deferred.semantic3(sc);
5498 //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this);
5500 // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5501 // Deprecated in 2.100
5502 // Make an error in 2.110
5503 // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5504 if (cldec.storage_class & STC.scope_)
5505 deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site.");
5508 override void visit(InterfaceDeclaration idec)
5510 /// Returns: `true` is this is an anonymous Objective-C metaclass
5511 static bool isAnonymousMetaclass(InterfaceDeclaration idec)
5513 return idec.classKind == ClassKind.objc &&
5518 //printf("InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5519 if (idec.semanticRun >= PASS.semanticdone)
5521 int errors = global.errors;
5523 //printf("+InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5529 scx = idec._scope; // save so we don't make redundant copies
5535 assert(sc.parent && sc.func);
5536 idec.parent = sc.parent;
5538 // Objective-C metaclasses are anonymous
5539 assert(idec.parent && !idec.isAnonymous || isAnonymousMetaclass(idec));
5542 idec.type = Type.terror;
5543 idec.type = idec.type.typeSemantic(idec.loc, sc);
5544 if (idec.type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5546 auto ti = (cast(TypeClass)idec.type).sym.isInstantiated();
5547 if (ti && isError(ti))
5548 (cast(TypeClass)idec.type).sym = idec;
5551 // Ungag errors when not speculative
5552 Ungag ungag = idec.ungagSpeculative();
5554 if (idec.semanticRun == PASS.initial)
5556 idec.visibility = sc.visibility;
5558 idec.storage_class |= sc.stc;
5559 idec.userAttribDecl = sc.userAttribDecl;
5561 else if (idec.symtab)
5563 if (idec.sizeok == Sizeok.done || !scx)
5565 idec.semanticRun = PASS.semanticdone;
5569 idec.semanticRun = PASS.semantic;
5571 if (idec.baseok < Baseok.done)
5573 T resolveBase(T)(lazy T exp)
5580 static if (!is(T == void))
5595 idec.baseok = Baseok.start;
5597 // Expand any tuples in baseclasses[]
5598 for (size_t i = 0; i < idec.baseclasses.length;)
5600 auto b = (*idec.baseclasses)[i];
5601 b.type = resolveBase(b.type.typeSemantic(idec.loc, sc));
5603 Type tb = b.type.toBasetype();
5604 if (auto tup = tb.isTypeTuple())
5606 idec.baseclasses.remove(i);
5607 size_t dim = Parameter.dim(tup.arguments);
5608 for (size_t j = 0; j < dim; j++)
5610 Parameter arg = Parameter.getNth(tup.arguments, j);
5611 b = new BaseClass(arg.type);
5612 idec.baseclasses.insert(i + j, b);
5619 if (idec.baseok >= Baseok.done)
5621 //printf("%s already semantic analyzed, semanticRun = %d\n", toChars(), semanticRun);
5622 if (idec.semanticRun >= PASS.semanticdone)
5624 goto Lancestorsdone;
5627 if (!idec.baseclasses.length && sc.linkage == LINK.cpp)
5628 idec.classKind = ClassKind.cpp;
5629 idec.cppnamespace = sc.namespace;
5630 UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
5631 checkMustUseReserved(idec);
5633 if (sc.linkage == LINK.objc)
5636 // Check for errors, handle forward references
5638 for (size_t i = 0; i < idec.baseclasses.length;)
5640 BaseClass* b = (*idec.baseclasses)[i];
5641 Type tb = b.type.toBasetype();
5642 TypeClass tc = (tb.ty == Tclass) ? cast(TypeClass)tb : null;
5643 if (!tc || !tc.sym.isInterfaceDeclaration())
5645 if (b.type != Type.terror)
5646 idec.error("base type must be `interface`, not `%s`", b.type.toChars());
5647 idec.baseclasses.remove(i);
5651 // Check for duplicate interfaces
5652 for (size_t j = 0; j < i; j++)
5654 BaseClass* b2 = (*idec.baseclasses)[j];
5655 if (b2.sym == tc.sym)
5657 idec.error("inherits from duplicate interface `%s`", b2.sym.toChars());
5658 idec.baseclasses.remove(i);
5662 if (tc.sym == idec || idec.isBaseOf2(tc.sym))
5664 idec.error("circular inheritance of interface");
5665 idec.baseclasses.remove(i);
5668 if (tc.sym.isDeprecated())
5670 if (!idec.isDeprecated())
5672 // Deriving from deprecated interface makes this one deprecated too
5673 idec.setDeprecated();
5674 tc.checkDeprecated(idec.loc, sc);
5680 if (tc.sym.baseok < Baseok.done)
5681 resolveBase(tc.sym.dsymbolSemantic(null)); // Try to resolve forward reference
5682 if (tc.sym.baseok < Baseok.done)
5684 //printf("\ttry later, forward reference of base %s\n", tc.sym.toChars());
5686 Module.addDeferredSemantic(tc.sym);
5687 idec.baseok = Baseok.none;
5691 if (idec.baseok == Baseok.none)
5693 // Forward referencee of one or more bases, try again later
5694 return deferDsymbolSemantic(idec, scx);
5696 idec.baseok = Baseok.done;
5698 idec.interfaces = idec.baseclasses.tdata()[0 .. idec.baseclasses.length];
5699 foreach (b; idec.interfaces)
5701 // If this is an interface, and it derives from a COM interface,
5702 // then this is a COM interface too.
5703 if (b.sym.isCOMinterface())
5705 if (b.sym.isCPPinterface())
5706 idec.classKind = ClassKind.cpp;
5709 interfaceSemantic(idec);
5713 if (!idec.members) // if opaque declaration
5715 idec.semanticRun = PASS.semanticdone;
5719 idec.symtab = new DsymbolTable();
5721 for (size_t i = 0; i < idec.baseclasses.length; i++)
5723 BaseClass* b = (*idec.baseclasses)[i];
5724 Type tb = b.type.toBasetype();
5725 TypeClass tc = tb.isTypeClass();
5726 if (tc.sym.semanticRun < PASS.semanticdone)
5728 // Forward referencee of one or more bases, try again later
5730 Module.addDeferredSemantic(tc.sym);
5731 return deferDsymbolSemantic(idec, scx);
5735 if (idec.baseok == Baseok.done)
5737 idec.baseok = Baseok.semanticdone;
5738 objc.setMetaclass(idec, sc);
5741 if (idec.vtblOffset())
5742 idec.vtbl.push(idec); // leave room at vtbl[0] for classinfo
5744 // Cat together the vtbl[]'s from base interfaces
5745 foreach (i, b; idec.interfaces)
5747 // Skip if b has already appeared
5748 for (size_t k = 0; k < i; k++)
5750 if (b == idec.interfaces[k])
5754 // Copy vtbl[] from base class
5755 if (b.sym.vtblOffset())
5757 size_t d = b.sym.vtbl.length;
5760 idec.vtbl.pushSlice(b.sym.vtbl[1 .. d]);
5765 idec.vtbl.append(&b.sym.vtbl);
5772 idec.members.foreachDsymbol( s => s.addMember(sc, idec) );
5774 auto sc2 = idec.newScope(sc);
5776 /* Set scope so if there are forward references, we still might be able to
5777 * resolve individual members like enums.
5779 idec.members.foreachDsymbol( s => s.setScope(sc2) );
5781 idec.members.foreachDsymbol( s => s.importAll(sc2) );
5783 idec.members.foreachDsymbol( s => s.dsymbolSemantic(sc2) );
5785 idec.semanticRun = PASS.semanticdone;
5786 //printf("-InterfaceDeclaration.dsymbolSemantic(%s), type = %p\n", toChars(), type);
5790 if (global.errors != errors)
5792 // The type is no good.
5793 idec.type = Type.terror;
5798 if (type.ty == Tclass && (cast(TypeClass)idec.type).sym != idec)
5800 printf("this = %p %s\n", idec, idec.toChars());
5801 printf("type = %d sym = %p\n", idec.type.ty, (cast(TypeClass)idec.type).sym);
5804 assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec);
5806 // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint
5807 // Deprecated in 2.087
5808 // Made an error in 2.100, but removal depends on `scope class` being removed too
5809 // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036
5810 if (idec.storage_class & STC.scope_)
5811 error(idec.loc, "`scope` as a type constraint is obsolete. Use `scope` at the usage site.");
5815 /*******************************************
5816 * Add members of EnumDeclaration to the symbol table(s).
5818 * ed = EnumDeclaration
5819 * sc = context of `ed`
5820 * sds = symbol table that `ed` resides in
5822 void addEnumMembers(EnumDeclaration ed, Scope* sc, ScopeDsymbol sds)
5824 //printf("addEnumMembers(ed: %p)\n", ed);
5832 const bool isCEnum = (sc.flags & SCOPE.Cfile) != 0; // it's an ImportC enum
5833 const bool isAnon = ed.isAnonymous();
5835 if ((isCEnum || isAnon) && !sds.symtab)
5836 sds.symtab = new DsymbolTable();
5838 if ((isCEnum || !isAnon) && !ed.symtab)
5839 ed.symtab = new DsymbolTable();
5841 ed.members.foreachDsymbol( (s)
5843 if (EnumMember em = s.isEnumMember())
5848 //printf("adding EnumMember %s to %p\n", em.toChars(), ed);
5849 em.addMember(sc, ed); // add em to ed's symbol table
5850 em.addMember(sc, sds); // add em to symbol table that ed is in
5851 em.parent = ed; // restore it after previous addMember() changed it
5855 em.addMember(sc, isAnon ? sds : ed);
5861 void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList argumentList)
5863 //printf("[%s] TemplateInstance.dsymbolSemantic('%s', this=%p, gag = %d, sc = %p)\n", tempinst.loc.toChars(), tempinst.toChars(), tempinst, global.gag, sc);
5866 for (Dsymbol s = tempinst; s; s = s.parent)
5868 printf("\t%s\n", s.toChars());
5871 for (Scope* scx = sc; scx; scx = scx.enclosing)
5873 printf("\t%s parent %s\n", scx._module ? scx._module.toChars() : "null", scx.parent ? scx.parent.toChars() : "null");
5879 printf("\n+TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
5881 if (tempinst.inst) // if semantic() was already run
5885 printf("-TemplateInstance.dsymbolSemantic('%s', this=%p) already run\n",
5886 tempinst.inst.toChars(), tempinst.inst);
5890 if (tempinst.semanticRun != PASS.initial)
5894 printf("Recursive template expansion\n");
5896 auto ungag = Ungag(global.gag);
5897 if (!tempinst.gagged)
5899 tempinst.error(tempinst.loc, "recursive template expansion");
5900 if (tempinst.gagged)
5901 tempinst.semanticRun = PASS.initial;
5903 tempinst.inst = tempinst;
5904 tempinst.errors = true;
5908 // Get the enclosing template instance from the scope tinst
5909 tempinst.tinst = sc.tinst;
5911 // Get the instantiating module from the scope minst
5912 tempinst.minst = sc.minst;
5913 // https://issues.dlang.org/show_bug.cgi?id=10920
5914 // If the enclosing function is non-root symbol,
5915 // this instance should be speculative.
5916 if (!tempinst.tinst && sc.func && sc.func.inNonRoot())
5918 tempinst.minst = null;
5921 tempinst.gagged = (global.gag > 0);
5923 tempinst.semanticRun = PASS.semantic;
5927 printf("\tdo semantic\n");
5929 /* Find template declaration first,
5930 * then run semantic on each argument (place results in tiargs[]),
5931 * last find most specialized template from overload list/set.
5933 if (!tempinst.findTempDecl(sc, null) || !tempinst.semanticTiargs(sc) || !tempinst.findBestMatch(sc, argumentList))
5936 if (tempinst.gagged)
5938 // https://issues.dlang.org/show_bug.cgi?id=13220
5939 // Roll back status for later semantic re-running
5940 tempinst.semanticRun = PASS.initial;
5943 tempinst.inst = tempinst;
5944 tempinst.errors = true;
5947 TemplateDeclaration tempdecl = tempinst.tempdecl.isTemplateDeclaration();
5950 TemplateStats.incInstance(tempdecl, tempinst);
5952 tempdecl.checkDeprecated(tempinst.loc, sc);
5954 // If tempdecl is a mixin, disallow it
5955 if (tempdecl.ismixin)
5957 tempinst.error("mixin templates are not regular templates");
5961 tempinst.hasNestedArgs(tempinst.tiargs, tempdecl.isstatic);
5962 if (tempinst.errors)
5965 // Copy the tempdecl namespace (not the scope one)
5966 tempinst.cppnamespace = tempdecl.cppnamespace;
5967 if (tempinst.cppnamespace)
5968 tempinst.cppnamespace.dsymbolSemantic(sc);
5970 /* Greatly simplified semantic processing for AliasSeq templates
5972 if (tempdecl.isTrivialAliasSeq)
5974 tempinst.inst = tempinst;
5975 return aliasSeqInstanceSemantic(tempinst, sc, tempdecl);
5978 /* Greatly simplified semantic processing for Alias templates
5980 else if (tempdecl.isTrivialAlias)
5982 tempinst.inst = tempinst;
5983 return aliasInstanceSemantic(tempinst, sc, tempdecl);
5986 Expressions* fargs = argumentList.arguments; // TODO: resolve named args
5988 /* See if there is an existing TemplateInstantiation that already
5989 * implements the typeargs. If so, just refer to that one instead.
5991 tempinst.inst = tempdecl.findExistingInstance(tempinst, fargs);
5992 TemplateInstance errinst = null;
5995 // So, we need to implement 'this' instance.
5997 else if (tempinst.inst.gagged && !tempinst.gagged && tempinst.inst.errors)
5999 // If the first instantiation had failed, re-run semantic,
6000 // so that error messages are shown.
6001 errinst = tempinst.inst;
6006 tempinst.parent = tempinst.inst.parent;
6007 tempinst.errors = tempinst.inst.errors;
6009 // If both this and the previous instantiation were gagged,
6010 // use the number of errors that happened last time.
6011 global.errors += tempinst.errors;
6012 global.gaggedErrors += tempinst.errors;
6014 // If the first instantiation was gagged, but this is not:
6015 if (tempinst.inst.gagged)
6017 // It had succeeded, mark it is a non-gagged instantiation,
6019 tempinst.inst.gagged = tempinst.gagged;
6022 tempinst.tnext = tempinst.inst.tnext;
6023 tempinst.inst.tnext = tempinst;
6025 /* A module can have explicit template instance and its alias
6026 * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`).
6027 * If the first instantiation 'inst' had happened in non-root module,
6028 * compiler can assume that its instantiated code would be included
6029 * in the separately compiled obj/lib file (e.g. phobos.lib).
6031 * However, if 'this' second instantiation happened in root module,
6032 * compiler might need to invoke its codegen
6033 * (https://issues.dlang.org/show_bug.cgi?id=2500 & https://issues.dlang.org/show_bug.cgi?id=2644).
6034 * But whole import graph is not determined until all semantic pass finished,
6035 * so 'inst' should conservatively finish the semantic3 pass for the codegen.
6037 if (tempinst.minst && tempinst.minst.isRoot() && !(tempinst.inst.minst && tempinst.inst.minst.isRoot()))
6039 /* Swap the position of 'inst' and 'this' in the instantiation graph.
6040 * Then, the primary instance `inst` will be changed to a root instance,
6041 * along with all members of `inst` having their scopes updated.
6044 * non-root -> A!() -> B!()[inst] -> C!() { members[non-root] }
6046 * root -> D!() -> B!()[this]
6049 * non-root -> A!() -> B!()[this]
6051 * root -> D!() -> B!()[inst] -> C!() { members[root] }
6053 Module mi = tempinst.minst;
6054 TemplateInstance ti = tempinst.tinst;
6055 tempinst.minst = tempinst.inst.minst;
6056 tempinst.tinst = tempinst.inst.tinst;
6057 tempinst.inst.minst = mi;
6058 tempinst.inst.tinst = ti;
6060 /* https://issues.dlang.org/show_bug.cgi?id=21299
6061 `minst` has been updated on the primary instance `inst` so it is
6062 now coming from a root module, however all Dsymbol `inst.members`
6063 of the instance still have their `_scope.minst` pointing at the
6064 original non-root module. We must now propagate `minst` to all
6065 members so that forward referenced dependencies that get
6066 instantiated will also be appended to the root module, otherwise
6067 there will be undefined references at link-time. */
6068 extern (C++) final class InstMemberWalker : Visitor
6070 alias visit = Visitor.visit;
6071 TemplateInstance inst;
6073 extern (D) this(TemplateInstance inst) scope
6078 override void visit(Dsymbol d)
6081 d._scope.minst = inst.minst;
6084 override void visit(ScopeDsymbol sds)
6086 sds.members.foreachDsymbol( s => s.accept(this) );
6087 visit(cast(Dsymbol)sds);
6090 override void visit(AttribDeclaration ad)
6092 ad.include(null).foreachDsymbol( s => s.accept(this) );
6093 visit(cast(Dsymbol)ad);
6096 override void visit(ConditionalDeclaration cd)
6098 if (cd.condition.inc)
6099 visit(cast(AttribDeclaration)cd);
6101 visit(cast(Dsymbol)cd);
6104 scope v = new InstMemberWalker(tempinst.inst);
6105 tempinst.inst.accept(v);
6107 if (!global.params.allInst &&
6108 tempinst.minst) // if inst was not speculative...
6110 assert(!tempinst.minst.isRoot()); // ... it was previously appended to a non-root module
6111 // Append again to the root module members[], so that the instance will
6112 // get codegen chances (depending on `tempinst.inst.needsCodegen()`).
6113 tempinst.inst.appendToModuleMember();
6116 assert(tempinst.inst.memberOf && tempinst.inst.memberOf.isRoot(), "no codegen chances");
6119 // modules imported by an existing instance should be added to the module
6120 // that instantiates the instance.
6122 foreach(imp; tempinst.inst.importedModules)
6123 if (!tempinst.minst.aimports.contains(imp))
6124 tempinst.minst.aimports.push(imp);
6128 printf("\tit's a match with instance %p, %d\n", tempinst.inst, tempinst.inst.semanticRun);
6134 printf("\timplement template instance %s '%s'\n", tempdecl.parent.toChars(), tempinst.toChars());
6135 printf("\ttempdecl %s\n", tempdecl.toChars());
6137 uint errorsave = global.errors;
6139 tempinst.inst = tempinst;
6140 tempinst.parent = tempinst.enclosing ? tempinst.enclosing : tempdecl.parent;
6141 //printf("parent = '%s'\n", parent.kind());
6143 TemplateStats.incUnique(tempdecl, tempinst);
6145 TemplateInstance tempdecl_instance_idx = tempdecl.addInstance(tempinst);
6149 // Store the place we added it to in target_symbol_list(_idx) so we can
6150 // remove it later if we encounter an error.
6151 Dsymbols* target_symbol_list = tempinst.appendToModuleMember();
6152 size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list.length - 1 : 0;
6154 // Copy the syntax trees from the TemplateDeclaration
6155 tempinst.members = Dsymbol.arraySyntaxCopy(tempdecl.members);
6157 // resolve TemplateThisParameter
6158 for (size_t i = 0; i < tempdecl.parameters.length; i++)
6160 if ((*tempdecl.parameters)[i].isTemplateThisParameter() is null)
6162 Type t = isType((*tempinst.tiargs)[i]);
6164 if (StorageClass stc = ModToStc(t.mod))
6166 //printf("t = %s, stc = x%llx\n", t.toChars(), stc);
6167 auto s = new Dsymbols();
6168 s.push(new StorageClassDeclaration(stc, tempinst.members));
6169 tempinst.members = s;
6174 // Create our own scope for the template parameters
6175 Scope* _scope = tempdecl._scope;
6176 if (tempdecl.semanticRun == PASS.initial)
6178 tempinst.error("template instantiation `%s` forward references template declaration `%s`", tempinst.toChars(), tempdecl.toChars());
6184 printf("\tcreate scope for template parameters '%s'\n", tempinst.toChars());
6186 tempinst.argsym = new ScopeDsymbol();
6187 tempinst.argsym.parent = _scope.parent;
6188 _scope = _scope.push(tempinst.argsym);
6189 _scope.tinst = tempinst;
6190 _scope.minst = tempinst.minst;
6193 // Declare each template parameter as an alias for the argument type
6194 Scope* paramscope = _scope.push();
6196 paramscope.visibility = Visibility(Visibility.Kind.public_); // https://issues.dlang.org/show_bug.cgi?id=14169
6197 // template parameters should be public
6198 tempinst.declareParameters(paramscope);
6201 // Add members of template instance to template instance symbol table
6202 //parent = scope.scopesym;
6203 tempinst.symtab = new DsymbolTable();
6205 tempinst.members.foreachDsymbol( (s)
6209 printf("\t adding member '%s' %p kind %s to '%s'\n", s.toChars(), s, s.kind(), tempinst.toChars());
6211 s.addMember(_scope, tempinst);
6216 printf("adding members done\n");
6219 /* See if there is only one member of template instance, and that
6220 * member has the same name as the template instance.
6221 * If so, this template instance becomes an alias for that member.
6223 //printf("members.length = %d\n", tempinst.members.length);
6224 if (tempinst.members.length)
6227 if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
6229 //printf("tempdecl.ident = %s, s = `%s %s`\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
6230 //printf("setting aliasdecl\n");
6231 tempinst.aliasdecl = s;
6235 /* If function template declaration
6237 if (fargs && tempinst.aliasdecl)
6239 if (auto fd = tempinst.aliasdecl.isFuncDeclaration())
6241 /* Transmit fargs to type so that TypeFunction.dsymbolSemantic() can
6242 * resolve any "auto ref" storage classes.
6245 if (auto tf = fd.type.isTypeFunction())
6250 // Do semantic() analysis on template instance members
6253 printf("\tdo semantic() on template instance members '%s'\n", tempinst.toChars());
6256 sc2 = _scope.push(tempinst);
6257 //printf("enclosing = %d, sc.parent = %s\n", tempinst.enclosing, sc.parent.toChars());
6258 sc2.parent = tempinst;
6259 sc2.tinst = tempinst;
6260 sc2.minst = tempinst.minst;
6261 sc2.stc &= ~STC.deprecated_;
6262 tempinst.tryExpandMembers(sc2);
6264 tempinst.semanticRun = PASS.semanticdone;
6266 /* ConditionalDeclaration may introduce eponymous declaration,
6267 * so we should find it once again after semantic.
6269 if (tempinst.members.length)
6272 if (Dsymbol.oneMembers(tempinst.members, &s, tempdecl.ident) && s)
6274 if (!tempinst.aliasdecl || tempinst.aliasdecl != s)
6276 //printf("tempdecl.ident = %s, s = `%s %s`\n", tempdecl.ident.toChars(), s.kind(), s.toPrettyChars());
6277 //printf("setting aliasdecl 2\n");
6278 tempinst.aliasdecl = s;
6283 if (global.errors != errorsave)
6284 goto Laftersemantic;
6286 /* If any of the instantiation members didn't get semantic() run
6287 * on them due to forward references, we cannot run semantic2()
6288 * or semantic3() yet.
6291 bool found_deferred_ad = false;
6292 for (size_t i = 0; i < Module.deferred.length; i++)
6294 Dsymbol sd = Module.deferred[i];
6295 AggregateDeclaration ad = sd.isAggregateDeclaration();
6296 if (ad && ad.parent && ad.parent.isTemplateInstance())
6298 //printf("deferred template aggregate: %s %s\n",
6299 // sd.parent.toChars(), sd.toChars());
6300 found_deferred_ad = true;
6301 if (ad.parent == tempinst)
6303 ad.deferred = tempinst;
6308 if (found_deferred_ad || Module.deferred.length)
6309 goto Laftersemantic;
6312 /* The problem is when to parse the initializer for a variable.
6313 * Perhaps VarDeclaration.dsymbolSemantic() should do it like it does
6314 * for initializers inside a function.
6316 //if (sc.parent.isFuncDeclaration())
6318 /* https://issues.dlang.org/show_bug.cgi?id=782
6319 * this has problems if the classes this depends on
6320 * are forward referenced. Find a way to defer semantic()
6323 tempinst.semantic2(sc2);
6325 if (global.errors != errorsave)
6326 goto Laftersemantic;
6328 if ((sc.func || (sc.flags & SCOPE.fullinst)) && !tempinst.tinst)
6330 /* If a template is instantiated inside function, the whole instantiation
6331 * should be done at that position. But, immediate running semantic3 of
6332 * dependent templates may cause unresolved forward reference.
6333 * https://issues.dlang.org/show_bug.cgi?id=9050
6334 * To avoid the issue, don't run semantic3 until semantic and semantic2 done.
6336 TemplateInstances deferred;
6337 tempinst.deferred = &deferred;
6339 //printf("Run semantic3 on %s\n", toChars());
6340 tempinst.trySemantic3(sc2);
6342 for (size_t i = 0; i < deferred.length; i++)
6344 //printf("+ run deferred semantic3 on %s\n", deferred[i].toChars());
6345 deferred[i].semantic3(null);
6348 tempinst.deferred = null;
6350 else if (tempinst.tinst)
6352 bool doSemantic3 = false;
6354 if (tempinst.aliasdecl)
6355 fd = tempinst.aliasdecl.toAlias2().isFuncDeclaration();
6359 /* Template function instantiation should run semantic3 immediately
6360 * for attribute inference.
6362 scope fld = fd.isFuncLiteralDeclaration();
6363 if (fld && fld.tok == TOK.reserved)
6370 /* A lambda function in template arguments might capture the
6371 * instantiated scope context. For the correct context inference,
6372 * all instantiated functions should run the semantic3 immediately.
6373 * See also compilable/test14973.d
6375 foreach (oarg; tempinst.tdtypes)
6377 auto s = getDsymbol(oarg);
6381 if (auto td = s.isTemplateDeclaration())
6385 assert(td.members && td.members.length == 1);
6386 s = (*td.members)[0];
6388 if (auto fld = s.isFuncLiteralDeclaration())
6390 if (fld.tok == TOK.reserved)
6397 //printf("[%s] %s doSemantic3 = %d\n", tempinst.tinst.loc.toChars(), tempinst.tinst.toChars(), doSemantic3);
6400 tempinst.trySemantic3(sc2);
6402 TemplateInstance ti = tempinst.tinst;
6404 while (ti && !ti.deferred && ti.tinst)
6407 if (++nest > global.recursionLimit)
6409 global.gag = 0; // ensure error message gets printed
6410 tempinst.error("recursive expansion");
6414 if (ti && ti.deferred)
6416 //printf("deferred semantic3 of %p %s, ti = %s, ti.deferred = %p\n", this, toChars(), ti.toChars());
6417 for (size_t i = 0;; i++)
6419 if (i == ti.deferred.length)
6421 ti.deferred.push(tempinst);
6424 if ((*ti.deferred)[i] == tempinst)
6430 if (tempinst.aliasdecl)
6432 /* https://issues.dlang.org/show_bug.cgi?id=13816
6433 * AliasDeclaration tries to resolve forward reference
6434 * twice (See inuse check in AliasDeclaration.toAlias()). It's
6435 * necessary to resolve mutual references of instantiated symbols, but
6436 * it will left a true recursive alias in tuple declaration - an
6437 * AliasDeclaration A refers TupleDeclaration B, and B contains A
6438 * in its elements. To correctly make it an error, we strictly need to
6439 * resolve the alias of eponymous member.
6441 tempinst.aliasdecl = tempinst.aliasdecl.toAlias2();
6443 // stop AliasAssign tuple building
6444 if (auto td = tempinst.aliasdecl.isTupleDeclaration())
6445 td.building = false;
6452 // Give additional context info if error occurred during instantiation
6453 if (global.errors != errorsave)
6455 if (!tempinst.errors)
6457 if (!tempdecl.literal)
6458 tempinst.error(tempinst.loc, "error instantiating");
6460 tempinst.tinst.printInstantiationTrace();
6462 tempinst.errors = true;
6463 if (tempinst.gagged)
6465 // Errors are gagged, so remove the template instance from the
6466 // instance/symbol lists we added it to and reset our state to
6467 // finish clean and so we can try to instantiate it again later
6468 // (see https://issues.dlang.org/show_bug.cgi?id=4302 and https://issues.dlang.org/show_bug.cgi?id=6602).
6469 tempdecl.removeInstance(tempdecl_instance_idx);
6470 if (target_symbol_list)
6472 // Because we added 'this' in the last position above, we
6473 // should be able to remove it without messing other indices up.
6474 assert((*target_symbol_list)[target_symbol_list_idx] == tempinst);
6475 target_symbol_list.remove(target_symbol_list_idx);
6476 tempinst.memberOf = null; // no longer a member
6478 tempinst.semanticRun = PASS.initial;
6479 tempinst.inst = null;
6480 tempinst.symtab = null;
6485 /* https://issues.dlang.org/show_bug.cgi?id=14541
6486 * If the previous gagged instance had failed by
6487 * circular references, currrent "error reproduction instantiation"
6488 * might succeed, because of the difference of instantiated context.
6489 * On such case, the cached error instance needs to be overridden by the
6490 * succeeded instance.
6492 //printf("replaceInstance()\n");
6493 assert(errinst.errors);
6494 auto ti1 = TemplateInstanceBox(errinst);
6495 tempdecl.instances.remove(ti1);
6497 auto ti2 = TemplateInstanceBox(tempinst);
6498 tempdecl.instances[ti2] = tempinst;
6503 printf("-TemplateInstance.dsymbolSemantic('%s', this=%p)\n", tempinst.toChars(), tempinst);
6507 /******************************************************
6508 * Do template instance semantic for isAliasSeq templates.
6509 * This is a greatly simplified version of templateInstanceSemantic().
6512 void aliasSeqInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclaration tempdecl)
6514 //printf("[%s] aliasSeqInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6515 Scope* paramscope = sc.push();
6517 paramscope.visibility = Visibility(Visibility.Kind.public_);
6519 TemplateTupleParameter ttp = (*tempdecl.parameters)[0].isTemplateTupleParameter();
6520 Tuple va = tempinst.tdtypes[0].isTuple();
6521 Declaration d = new TupleDeclaration(tempinst.loc, ttp.ident, &va.objects);
6522 d.storage_class |= STC.templateparameter;
6523 d.dsymbolSemantic(sc);
6527 tempinst.aliasdecl = d;
6529 tempinst.semanticRun = PASS.semanticdone;
6532 /******************************************************
6533 * Do template instance semantic for isAlias templates.
6534 * This is a greatly simplified version of templateInstanceSemantic().
6537 void aliasInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclaration tempdecl)
6539 //printf("[%s] aliasInstance.dsymbolSemantic('%s')\n", tempinst.loc.toChars(), tempinst.toChars());
6540 Scope* paramscope = sc.push();
6542 paramscope.visibility = Visibility(Visibility.Kind.public_);
6544 TemplateTypeParameter ttp = (*tempdecl.parameters)[0].isTemplateTypeParameter();
6545 Type ta = tempinst.tdtypes[0].isType();
6546 auto ad = tempdecl.onemember.isAliasDeclaration();
6548 // Note: qualifiers can be in both 'ad.type.mod' and 'ad.storage_class'
6549 Declaration d = new AliasDeclaration(tempinst.loc, ttp.ident, ta.addMod(ad.type.mod));
6550 d.storage_class |= STC.templateparameter | ad.storage_class;
6551 d.dsymbolSemantic(sc);
6555 tempinst.aliasdecl = d;
6557 tempinst.semanticRun = PASS.semanticdone;
6560 // function used to perform semantic on AliasDeclaration
6561 void aliasSemantic(AliasDeclaration ds, Scope* sc)
6563 //printf("AliasDeclaration::semantic() %s\n", ds.toChars());
6565 // as DsymbolSemanticVisitor::visit(AliasDeclaration), in case we're called first.
6566 // see https://issues.dlang.org/show_bug.cgi?id=21001
6567 ds.storage_class |= sc.stc & STC.deprecated_;
6568 ds.visibility = sc.visibility;
6569 ds.userAttribDecl = sc.userAttribDecl;
6574 ds.semanticRun = PASS.semanticdone;
6576 if (auto sx = ds.overnext)
6579 if (!ds.overloadInsert(sx))
6580 ScopeDsymbol.multiplyDefined(Loc.initial, sx, ds);
6587 ds.type = Type.terror;
6592 // preserve the original type
6593 if (!ds.originalType && ds.type)
6594 ds.originalType = ds.type.syntaxCopy();
6598 auto fd = ds.aliassym.isFuncLiteralDeclaration();
6599 auto td = ds.aliassym.isTemplateDeclaration();
6600 if (fd || td && td.literal)
6602 if (fd && fd.semanticRun >= PASS.semanticdone)
6605 Expression e = new FuncExp(ds.loc, ds.aliassym);
6606 e = e.expressionSemantic(sc);
6607 if (auto fe = e.isFuncExp())
6609 ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;
6616 if (ds.aliassym.isTemplateInstance())
6617 ds.aliassym.dsymbolSemantic(sc);
6623 // alias foo.bar.abc def;
6624 // it is not knowable from the syntax whether `def` is an alias
6625 // for type `foo.bar.abc` or an alias for symbol `foo.bar.abc`. It is up to the semantic()
6626 // pass to distinguish.
6627 // If it is a type, then `.type` is set and getType() will return that
6628 // type. If it is a symbol, then `.aliassym` is set and type is `null` -
6629 // toAlias() will return `.aliassym`
6631 const errors = global.errors;
6632 Type oldtype = ds.type;
6634 // Ungag errors when not instantiated DeclDefs scope alias
6635 auto ungag = Ungag(global.gag);
6636 //printf("%s parent = %s, gag = %d, instantiated = %d\n", ds.toChars(), ds.parent.toChars(), global.gag, ds.isInstantiated() !is null);
6637 if (ds.parent && global.gag && !ds.isInstantiated() && !ds.toParent2().isFuncDeclaration() && (sc.minst || sc.tinst))
6639 //printf("%s type = %s\n", ds.toPrettyChars(), ds.type.toChars());
6643 // https://issues.dlang.org/show_bug.cgi?id=18480
6644 // Detect `alias sym = sym;` to prevent creating loops in overload overnext lists.
6645 if (auto tident = ds.type.isTypeIdentifier())
6647 // Selective imports are allowed to alias to the same name `import mod : sym=sym`.
6650 if (tident.ident is ds.ident && !tident.idents.length)
6652 error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set",
6653 ds.ident.toChars(), tident.ident.toChars());
6654 ds.type = Type.terror;
6658 /* This section is needed because Type.resolve() will:
6661 * try to convert identifier x to 3.
6663 auto s = ds.type.toDsymbol(sc);
6664 if (errors != global.errors)
6668 ds.error("cannot resolve");
6671 if (!s || !s.isEnumMember())
6676 if (ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.disable))
6678 // For 'ref' to be attached to function types, and picked
6679 // up by Type.resolve(), it has to go into sc.
6681 sc2.stc |= ds.storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6683 ds.type = ds.type.addSTC(ds.storage_class);
6684 ds.type.resolve(ds.loc, sc2, e, t, s);
6688 if (e) // Try to convert Expression to Dsymbol
6690 // TupleExp is naturally converted to a TupleDeclaration
6691 if (auto te = e.isTupleExp())
6692 s = new TupleDeclaration(te.loc, ds.ident, cast(Objects*)te.exps);
6698 if (e.op != EXP.error)
6699 ds.error("cannot alias an expression `%s`", e.toChars());
6708 assert(global.errors);
6711 if (s) // it's a symbolic alias
6713 //printf("alias %s resolved to %s %s\n", ds.toChars(), s.kind(), s.toChars());
6717 else // it's a type alias
6719 //printf("alias %s resolved to type %s\n", ds.toChars(), ds.type.toChars());
6720 ds.type = ds.type.typeSemantic(ds.loc, sc);
6724 if (global.gag && errors != global.errors)
6730 /********************
6731 * Perform semantic on AliasAssignment.
6732 * Has a lot of similarities to aliasSemantic(). Perhaps they should share code.
6734 private void aliasAssignSemantic(AliasAssign ds, Scope* sc)
6736 //printf("AliasAssign::semantic() %p, %s\n", ds, ds.ident.toChars());
6741 ds.type = Type.terror;
6742 ds.semanticRun = PASS.semanticdone;
6746 /* Find the AliasDeclaration corresponding to ds.
6747 * Returns: AliasDeclaration if found, null if error
6749 AliasDeclaration findAliasDeclaration(AliasAssign ds, Scope* sc)
6752 Dsymbol as = sc.search(ds.loc, ds.ident, &scopesym);
6755 ds.error("undefined identifier `%s`", ds.ident.toChars());
6761 auto ad = as.isAliasDeclaration();
6764 ds.error("identifier `%s` must be an alias declaration", as.toChars());
6770 ds.error("cannot reassign overloaded alias");
6774 // Check constraints on the parent
6775 auto adParent = ad.toParent();
6776 if (adParent != ds.toParent())
6779 adParent = ds.toParent();
6780 error(ds.loc, "`%s` must have same parent `%s` as alias `%s`", ds.ident.toChars(), adParent.toChars(), ad.toChars());
6783 if (!adParent.isTemplateInstance())
6785 ds.error("must be a member of a template");
6792 auto aliassym = findAliasDeclaration(ds, sc);
6796 if (aliassym.adFlags & Declaration.wasRead)
6798 if (!aliassym.errors)
6799 error(ds.loc, "%s was read, so cannot reassign", aliassym.toChars());
6800 aliassym.errors = true;
6804 aliassym.adFlags |= Declaration.ignoreRead; // temporarilly allow reads of aliassym
6806 const storage_class = sc.stc & (STC.deprecated_ | STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6810 auto fd = ds.aliassym.isFuncLiteralDeclaration();
6811 auto td = ds.aliassym.isTemplateDeclaration();
6812 if (fd && fd.semanticRun >= PASS.semanticdone)
6815 else if (fd || td && td.literal)
6818 Expression e = new FuncExp(ds.loc, ds.aliassym);
6819 e = e.expressionSemantic(sc);
6820 auto fe = e.isFuncExp();
6823 ds.aliassym = fe.td ? cast(Dsymbol)fe.td : fe.fd;
6825 else if (ds.aliassym.isTemplateInstance())
6826 ds.aliassym.dsymbolSemantic(sc);
6828 aliassym.type = null;
6829 aliassym.aliassym = ds.aliassym;
6835 * it is not knownable from the syntax whether `def` is a type or a symbol.
6836 * It appears here as `ds.type`. Do semantic analysis on `def` to disambiguate.
6839 const errors = global.errors;
6842 // Try AliasSeq optimization
6843 if (auto ti = ds.type.isTypeInstance())
6845 if (!ti.tempinst.findTempDecl(sc, null))
6847 if (auto tempinst = isAliasSeq(sc, ti))
6849 s = aliasAssignInPlace(sc, tempinst, aliassym);
6856 /* This section is needed because Type.resolve() will:
6859 * try to convert identifier x to 3.
6861 s = ds.type.toDsymbol(sc);
6862 if (errors != global.errors)
6866 ds.error("cannot resolve");
6870 if (!s || !s.isEnumMember())
6875 if (storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable))
6877 // For 'ref' to be attached to function types, and picked
6878 // up by Type.resolve(), it has to go into sc.
6880 sc2.stc |= storage_class & (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
6882 ds.type = ds.type.addSTC(storage_class);
6883 ds.type.resolve(ds.loc, sc2, e, t, s);
6887 if (e) // Try to convert Expression to Dsymbol
6889 // TupleExp is naturally converted to a TupleDeclaration
6890 if (auto te = e.isTupleExp())
6891 s = new TupleDeclaration(te.loc, ds.ident, cast(Objects*)te.exps);
6897 if (e.op != EXP.error)
6898 ds.error("cannot alias an expression `%s`", e.toChars());
6907 assert(global.errors);
6911 if (s) // it's a symbolic alias
6914 //printf("alias %s resolved to %s %s\n", toChars(), s.kind(), s.toChars());
6915 aliassym.type = null;
6916 aliassym.aliassym = s;
6917 aliassym.storage_class |= sc.stc & STC.deprecated_;
6918 aliassym.visibility = sc.visibility;
6919 aliassym.userAttribDecl = sc.userAttribDecl;
6921 else // it's a type alias
6923 //printf("alias %s resolved to type %s\n", toChars(), type.toChars());
6924 aliassym.type = ds.type.typeSemantic(ds.loc, sc);
6925 aliassym.aliassym = null;
6929 aliassym.adFlags &= ~Declaration.ignoreRead;
6931 if (aliassym.type && aliassym.type.ty == Terror ||
6932 global.gag && errors != global.errors)
6934 aliassym.type = Type.terror;
6935 aliassym.aliassym = null;
6939 ds.semanticRun = PASS.semanticdone;
6942 /***************************************
6943 * Expands template instance arguments inside 'alias assign' target declaration (aliassym),
6944 * instead of inside 'tempinst.tiargs' every time.
6946 * tempinst = AliasSeq instance
6947 * aliassym = the AliasDeclaration corresponding to AliasAssign
6951 private TupleDeclaration aliasAssignInPlace(Scope* sc, TemplateInstance tempinst,
6952 AliasDeclaration aliassym)
6954 // Mark instance with semantic done, not needed but just in case.
6955 tempinst.inst = tempinst;
6956 tempinst.semanticRun = PASS.semanticdone;
6957 TupleDeclaration td;
6960 // Convert TypeTuple to TupleDeclaration to avoid back and forth allocations
6961 // in the assignment process
6962 if (auto tt = aliassym.type.isTypeTuple())
6964 auto objs = new Objects(tt.arguments.length);
6965 foreach (i, p; *tt.arguments)
6966 (*objs)[i] = p.type;
6967 td = new TupleDeclaration(tempinst.loc, aliassym.ident, objs);
6968 td.storage_class |= STC.templateparameter;
6970 aliassym.type = null;
6972 else if (aliassym.type.isTypeError())
6976 else if (auto otd = aliassym.aliassym.isTupleDeclaration())
6982 td = new TupleDeclaration(tempinst.loc, aliassym.ident, otd.objects.copy());
6983 td.storage_class |= STC.templateparameter;
6987 // If starting from single element in aliassym (td == null) we need to build the tuple
6988 // after semanticTiargs to keep same semantics (for example a FuncLiteraldeclaration
6989 // template argument is converted to FuncExp)
6991 aliassym.aliassym = td;
6992 aliassym.semanticRun = PASS.semanticdone;
6993 if (!TemplateInstance.semanticTiargs(tempinst.loc, sc, tempinst.tiargs, 0, td))
6995 tempinst.errors = true;
6998 // The alias will stop tuple 'building' mode when used (in AliasDeclaration.toAlias(),
6999 // then TupleDeclaration.getType() will work again)
7000 aliassym.semanticRun = PASS.initial;
7003 td = new TupleDeclaration(tempinst.loc, aliassym.ident, tempinst.tiargs);
7004 td.storage_class |= STC.templateparameter;
7009 auto tiargs = tempinst.tiargs;
7010 size_t oldlen = td.objects.length;
7014 foreach (i, o; *tiargs)
7021 // tuple contains itself (tuple = AliasSeq!(..., tuple, ...))
7022 if (insertlen) // insert any left element before
7024 td.objects.insert(insertidx, (*tiargs)[i - insertlen .. i]);
7025 if (insertidx == 0) // reset original tuple start point
7026 origstart = insertlen;
7029 if (insertidx) // insert tuple if found more than one time
7031 td.objects.reserve(oldlen); // reserve first to assert a valid slice
7032 td.objects.pushSlice((*td.objects)[origstart .. origstart + oldlen]);
7034 insertidx = td.objects.length;
7038 if (insertlen != tiargs.length) // insert any left element
7039 td.objects.pushSlice((*tiargs)[$ - insertlen .. $]);
7041 // just assign tiargs if tuple = AliasSeq!(nottuple, nottuple...)
7042 td.objects = tempinst.tiargs;
7047 /***************************************
7048 * Check if a template instance is a trivial AliasSeq but without other overloads.
7049 * We can only be 100% sure of being AliasSeq after running semanticTiargs()
7050 * and findBestMatch() but this optimization must happen before that.
7052 private TemplateInstance isAliasSeq(Scope* sc, TypeInstance ti)
7054 auto tovers = ti.tempinst.tempdecl.isOverloadSet();
7055 foreach (size_t oi; 0 .. tovers ? tovers.a.length : 1)
7057 Dsymbol dstart = tovers ? tovers.a[oi] : ti.tempinst.tempdecl;
7058 int r = overloadApply(dstart, (Dsymbol s)
7060 auto td = s.isTemplateDeclaration();
7061 if (!td || !td.isTrivialAliasSeq)
7071 /***************************************
7072 * Find all instance fields in `ad`, then push them into `fields`.
7074 * Runs semantic() for all instance field variables, but also
7075 * the field types can remain yet not resolved forward references,
7076 * except direct recursive definitions.
7077 * After the process sizeok is set to Sizeok.fwd.
7080 * ad = the AggregateDeclaration to examine
7082 * false if any errors occur.
7084 bool determineFields(AggregateDeclaration ad)
7087 dsymbolSemantic(ad, null);
7088 if (ad.sizeok != Sizeok.none)
7091 //printf("determineFields() %s, fields.length = %d\n", toChars(), fields.length);
7092 // determineFields can be called recursively from one of the fields's v.semantic
7093 ad.fields.setDim(0);
7095 static int func(Dsymbol s, AggregateDeclaration ad)
7097 auto v = s.isVarDeclaration();
7100 if (v.storage_class & STC.manifest)
7103 if (v.semanticRun < PASS.semanticdone)
7104 v.dsymbolSemantic(null);
7105 // Return in case a recursive determineFields triggered by v.semantic already finished
7106 if (ad.sizeok != Sizeok.none)
7111 // If this variable was really a tuple, process each element.
7112 return v.aliasTuple.foreachVar(tv => tv.apply(&func, ad));
7115 if (v.storage_class & (STC.static_ | STC.extern_ | STC.tls | STC.gshared | STC.manifest | STC.ctfe | STC.templateparameter))
7117 if (!v.isField() || v.semanticRun < PASS.semanticdone)
7118 return 1; // unresolvable forward reference
7122 if (v.storage_class & STC.ref_)
7124 auto tv = v.type.baseElemOf();
7125 if (auto tvs = tv.isTypeStruct())
7129 const(char)* psz = (v.type.toBasetype().ty == Tsarray) ? "static array of " : "";
7130 ad.error("cannot have field `%s` with %ssame struct type", v.toChars(), psz);
7131 ad.type = Type.terror;
7141 for (size_t i = 0; i < ad.members.length; i++)
7143 auto s = (*ad.members)[i];
7144 if (s.apply(&func, ad))
7146 if (ad.sizeok != Sizeok.none)
7148 // recursive determineFields already finished
7156 if (ad.sizeok != Sizeok.done)
7157 ad.sizeok = Sizeok.fwd;
7162 /// Do an atomic operation (currently tailored to [shared] static ctors|dtors) needs
7163 private CallExp doAtomicOp (string op, Identifier var, Expression arg)
7165 assert(op == "-=" || op == "+=");
7167 Module mod = Module.loadCoreAtomic();
7169 return null; // core.atomic couldn't be loaded
7171 const loc = Loc.initial;
7173 Objects* tiargs = new Objects(1);
7174 (*tiargs)[0] = new StringExp(loc, op);
7176 Expressions* args = new Expressions(2);
7177 (*args)[0] = new IdentifierExp(loc, var);
7180 auto sc = new ScopeExp(loc, mod);
7181 auto dti = new DotTemplateInstanceExp(
7182 loc, sc, Id.atomicOp, tiargs);
7184 return CallExp.create(loc, dti, args);
7187 /***************************************
7188 * Interpret a `pragma(inline, x)`
7191 * loc = location for error messages
7192 * sc = scope for evaluation of argument
7193 * args = pragma arguments
7194 * Returns: corresponding `PINLINE` state
7196 PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args)
7198 if (!args || args.length == 0)
7199 return PINLINE.default_;
7201 if (args && args.length > 1)
7203 .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.length);
7205 (*args)[0] = ErrorExp.get();
7208 Expression e = (*args)[0];
7211 sc = sc.startCTFE();
7212 e = e.expressionSemantic(sc);
7213 e = resolveProperties(sc, e);
7215 e = e.ctfeInterpret();
7216 e = e.toBoolean(sc);
7218 .error(loc, "pragma(`inline`, `true` or `false`) expected, not `%s`", (*args)[0].toChars());
7222 const opt = e.toBool();
7224 return PINLINE.default_;
7226 return PINLINE.always;
7228 return PINLINE.never;