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