declaration.d revision 1.1 1 1.1 mrg /**
2 1.1 mrg * Miscellaneous declarations, including typedef, alias, variable declarations including the
3 1.1 mrg * implicit this declaration, type tuples, ClassInfo, ModuleInfo and various TypeInfos.
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/declaration.d, _declaration.d)
9 1.1 mrg * Documentation: https://dlang.org/phobos/dmd_declaration.html
10 1.1 mrg * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/declaration.d
11 1.1 mrg */
12 1.1 mrg
13 1.1 mrg module dmd.declaration;
14 1.1 mrg
15 1.1 mrg import core.stdc.stdio;
16 1.1 mrg import dmd.aggregate;
17 1.1 mrg import dmd.arraytypes;
18 1.1 mrg import dmd.astenums;
19 1.1 mrg import dmd.attrib;
20 1.1 mrg import dmd.ctorflow;
21 1.1 mrg import dmd.dclass;
22 1.1 mrg import dmd.delegatize;
23 1.1 mrg import dmd.dscope;
24 1.1 mrg import dmd.dstruct;
25 1.1 mrg import dmd.dsymbol;
26 1.1 mrg import dmd.dsymbolsem;
27 1.1 mrg import dmd.dtemplate;
28 1.1 mrg import dmd.errors;
29 1.1 mrg import dmd.expression;
30 1.1 mrg import dmd.func;
31 1.1 mrg import dmd.globals;
32 1.1 mrg import dmd.gluelayer;
33 1.1 mrg import dmd.id;
34 1.1 mrg import dmd.identifier;
35 1.1 mrg import dmd.init;
36 1.1 mrg import dmd.initsem;
37 1.1 mrg import dmd.intrange;
38 1.1 mrg import dmd.mtype;
39 1.1 mrg import dmd.common.outbuffer;
40 1.1 mrg import dmd.root.rootobject;
41 1.1 mrg import dmd.target;
42 1.1 mrg import dmd.tokens;
43 1.1 mrg import dmd.typesem;
44 1.1 mrg import dmd.visitor;
45 1.1 mrg
46 1.1 mrg /************************************
47 1.1 mrg * Check to see the aggregate type is nested and its context pointer is
48 1.1 mrg * accessible from the current scope.
49 1.1 mrg * Returns true if error occurs.
50 1.1 mrg */
51 1.1 mrg bool checkFrameAccess(Loc loc, Scope* sc, AggregateDeclaration ad, size_t iStart = 0)
52 1.1 mrg {
53 1.1 mrg Dsymbol sparent = ad.toParentLocal();
54 1.1 mrg Dsymbol sparent2 = ad.toParent2();
55 1.1 mrg Dsymbol s = sc.func;
56 1.1 mrg if (ad.isNested() && s)
57 1.1 mrg {
58 1.1 mrg //printf("ad = %p %s [%s], parent:%p\n", ad, ad.toChars(), ad.loc.toChars(), ad.parent);
59 1.1 mrg //printf("sparent = %p %s [%s], parent: %s\n", sparent, sparent.toChars(), sparent.loc.toChars(), sparent.parent,toChars());
60 1.1 mrg //printf("sparent2 = %p %s [%s], parent: %s\n", sparent2, sparent2.toChars(), sparent2.loc.toChars(), sparent2.parent,toChars());
61 1.1 mrg if (!ensureStaticLinkTo(s, sparent) || sparent != sparent2 && !ensureStaticLinkTo(s, sparent2))
62 1.1 mrg {
63 1.1 mrg error(loc, "cannot access frame pointer of `%s`", ad.toPrettyChars());
64 1.1 mrg return true;
65 1.1 mrg }
66 1.1 mrg }
67 1.1 mrg
68 1.1 mrg bool result = false;
69 1.1 mrg for (size_t i = iStart; i < ad.fields.dim; i++)
70 1.1 mrg {
71 1.1 mrg VarDeclaration vd = ad.fields[i];
72 1.1 mrg Type tb = vd.type.baseElemOf();
73 1.1 mrg if (tb.ty == Tstruct)
74 1.1 mrg {
75 1.1 mrg result |= checkFrameAccess(loc, sc, (cast(TypeStruct)tb).sym);
76 1.1 mrg }
77 1.1 mrg }
78 1.1 mrg return result;
79 1.1 mrg }
80 1.1 mrg
81 1.1 mrg /***********************************************
82 1.1 mrg * Mark variable v as modified if it is inside a constructor that var
83 1.1 mrg * is a field in.
84 1.1 mrg */
85 1.1 mrg bool modifyFieldVar(Loc loc, Scope* sc, VarDeclaration var, Expression e1)
86 1.1 mrg {
87 1.1 mrg //printf("modifyFieldVar(var = %s)\n", var.toChars());
88 1.1 mrg Dsymbol s = sc.func;
89 1.1 mrg while (1)
90 1.1 mrg {
91 1.1 mrg FuncDeclaration fd = null;
92 1.1 mrg if (s)
93 1.1 mrg fd = s.isFuncDeclaration();
94 1.1 mrg if (fd &&
95 1.1 mrg ((fd.isCtorDeclaration() && var.isField()) ||
96 1.1 mrg (fd.isStaticCtorDeclaration() && !var.isField())) &&
97 1.1 mrg fd.toParentDecl() == var.toParent2() &&
98 1.1 mrg (!e1 || e1.op == EXP.this_))
99 1.1 mrg {
100 1.1 mrg bool result = true;
101 1.1 mrg
102 1.1 mrg var.ctorinit = true;
103 1.1 mrg //printf("setting ctorinit\n");
104 1.1 mrg
105 1.1 mrg if (var.isField() && sc.ctorflow.fieldinit.length && !sc.intypeof)
106 1.1 mrg {
107 1.1 mrg assert(e1);
108 1.1 mrg auto mustInit = ((var.storage_class & STC.nodefaultctor) != 0 ||
109 1.1 mrg var.type.needsNested());
110 1.1 mrg
111 1.1 mrg const dim = sc.ctorflow.fieldinit.length;
112 1.1 mrg auto ad = fd.isMemberDecl();
113 1.1 mrg assert(ad);
114 1.1 mrg size_t i;
115 1.1 mrg for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ?
116 1.1 mrg {
117 1.1 mrg if (ad.fields[i] == var)
118 1.1 mrg break;
119 1.1 mrg }
120 1.1 mrg assert(i < dim);
121 1.1 mrg auto fieldInit = &sc.ctorflow.fieldinit[i];
122 1.1 mrg const fi = fieldInit.csx;
123 1.1 mrg
124 1.1 mrg if (fi & CSX.this_ctor)
125 1.1 mrg {
126 1.1 mrg if (var.type.isMutable() && e1.type.isMutable())
127 1.1 mrg result = false;
128 1.1 mrg else
129 1.1 mrg {
130 1.1 mrg const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
131 1.1 mrg .error(loc, "%s field `%s` initialized multiple times", modStr, var.toChars());
132 1.1 mrg .errorSupplemental(fieldInit.loc, "Previous initialization is here.");
133 1.1 mrg }
134 1.1 mrg }
135 1.1 mrg else if (sc.inLoop || (fi & CSX.label))
136 1.1 mrg {
137 1.1 mrg if (!mustInit && var.type.isMutable() && e1.type.isMutable())
138 1.1 mrg result = false;
139 1.1 mrg else
140 1.1 mrg {
141 1.1 mrg const(char)* modStr = !var.type.isMutable() ? MODtoChars(var.type.mod) : MODtoChars(e1.type.mod);
142 1.1 mrg .error(loc, "%s field `%s` initialization is not allowed in loops or after labels", modStr, var.toChars());
143 1.1 mrg }
144 1.1 mrg }
145 1.1 mrg
146 1.1 mrg fieldInit.csx |= CSX.this_ctor;
147 1.1 mrg fieldInit.loc = e1.loc;
148 1.1 mrg if (var.overlapped) // https://issues.dlang.org/show_bug.cgi?id=15258
149 1.1 mrg {
150 1.1 mrg foreach (j, v; ad.fields)
151 1.1 mrg {
152 1.1 mrg if (v is var || !var.isOverlappedWith(v))
153 1.1 mrg continue;
154 1.1 mrg v.ctorinit = true;
155 1.1 mrg sc.ctorflow.fieldinit[j].csx = CSX.this_ctor;
156 1.1 mrg }
157 1.1 mrg }
158 1.1 mrg }
159 1.1 mrg else if (fd != sc.func)
160 1.1 mrg {
161 1.1 mrg if (var.type.isMutable())
162 1.1 mrg result = false;
163 1.1 mrg else if (sc.func.fes)
164 1.1 mrg {
165 1.1 mrg const(char)* p = var.isField() ? "field" : var.kind();
166 1.1 mrg .error(loc, "%s %s `%s` initialization is not allowed in foreach loop",
167 1.1 mrg MODtoChars(var.type.mod), p, var.toChars());
168 1.1 mrg }
169 1.1 mrg else
170 1.1 mrg {
171 1.1 mrg const(char)* p = var.isField() ? "field" : var.kind();
172 1.1 mrg .error(loc, "%s %s `%s` initialization is not allowed in nested function `%s`",
173 1.1 mrg MODtoChars(var.type.mod), p, var.toChars(), sc.func.toChars());
174 1.1 mrg }
175 1.1 mrg }
176 1.1 mrg else if (fd.isStaticCtorDeclaration() && !fd.isSharedStaticCtorDeclaration() &&
177 1.1 mrg var.type.isImmutable())
178 1.1 mrg {
179 1.1 mrg .error(loc, "%s %s `%s` initialization is not allowed in `static this`",
180 1.1 mrg MODtoChars(var.type.mod), var.kind(), var.toChars());
181 1.1 mrg errorSupplemental(loc, "Use `shared static this` instead.");
182 1.1 mrg }
183 1.1 mrg return result;
184 1.1 mrg }
185 1.1 mrg else
186 1.1 mrg {
187 1.1 mrg if (s)
188 1.1 mrg {
189 1.1 mrg s = s.toParentP(var.toParent2());
190 1.1 mrg continue;
191 1.1 mrg }
192 1.1 mrg }
193 1.1 mrg break;
194 1.1 mrg }
195 1.1 mrg return false;
196 1.1 mrg }
197 1.1 mrg
198 1.1 mrg /******************************************
199 1.1 mrg */
200 1.1 mrg extern (C++) void ObjectNotFound(Identifier id)
201 1.1 mrg {
202 1.1 mrg error(Loc.initial, "`%s` not found. object.d may be incorrectly installed or corrupt.", id.toChars());
203 1.1 mrg fatal();
204 1.1 mrg }
205 1.1 mrg
206 1.1 mrg /* Accumulator for successive matches.
207 1.1 mrg */
208 1.1 mrg struct MatchAccumulator
209 1.1 mrg {
210 1.1 mrg int count; // number of matches found so far
211 1.1 mrg MATCH last = MATCH.nomatch; // match level of lastf
212 1.1 mrg FuncDeclaration lastf; // last matching function we found
213 1.1 mrg FuncDeclaration nextf; // if ambiguous match, this is the "other" function
214 1.1 mrg }
215 1.1 mrg
216 1.1 mrg /***********************************************************
217 1.1 mrg */
218 1.1 mrg extern (C++) abstract class Declaration : Dsymbol
219 1.1 mrg {
220 1.1 mrg Type type;
221 1.1 mrg Type originalType; // before semantic analysis
222 1.1 mrg StorageClass storage_class = STC.undefined_;
223 1.1 mrg Visibility visibility;
224 1.1 mrg LINK _linkage = LINK.default_; // may be `LINK.system`; use `resolvedLinkage()` to resolve it
225 1.1 mrg short inuse; // used to detect cycles
226 1.1 mrg
227 1.1 mrg ubyte adFlags; // control re-assignment of AliasDeclaration (put here for packing reasons)
228 1.1 mrg enum wasRead = 1; // set if AliasDeclaration was read
229 1.1 mrg enum ignoreRead = 2; // ignore any reads of AliasDeclaration
230 1.1 mrg
231 1.1 mrg Symbol* isym; // import version of csym
232 1.1 mrg
233 1.1 mrg // overridden symbol with pragma(mangle, "...")
234 1.1 mrg const(char)[] mangleOverride;
235 1.1 mrg
236 1.1 mrg final extern (D) this(Identifier ident)
237 1.1 mrg {
238 1.1 mrg super(ident);
239 1.1 mrg visibility = Visibility(Visibility.Kind.undefined);
240 1.1 mrg }
241 1.1 mrg
242 1.1 mrg final extern (D) this(const ref Loc loc, Identifier ident)
243 1.1 mrg {
244 1.1 mrg super(loc, ident);
245 1.1 mrg visibility = Visibility(Visibility.Kind.undefined);
246 1.1 mrg }
247 1.1 mrg
248 1.1 mrg override const(char)* kind() const
249 1.1 mrg {
250 1.1 mrg return "declaration";
251 1.1 mrg }
252 1.1 mrg
253 1.1 mrg override final uinteger_t size(const ref Loc loc)
254 1.1 mrg {
255 1.1 mrg assert(type);
256 1.1 mrg const sz = type.size();
257 1.1 mrg if (sz == SIZE_INVALID)
258 1.1 mrg errors = true;
259 1.1 mrg return sz;
260 1.1 mrg }
261 1.1 mrg
262 1.1 mrg /**
263 1.1 mrg * Issue an error if an attempt to call a disabled method is made
264 1.1 mrg *
265 1.1 mrg * If the declaration is disabled but inside a disabled function,
266 1.1 mrg * returns `true` but do not issue an error message.
267 1.1 mrg *
268 1.1 mrg * Params:
269 1.1 mrg * loc = Location information of the call
270 1.1 mrg * sc = Scope in which the call occurs
271 1.1 mrg * isAliasedDeclaration = if `true` searches overload set
272 1.1 mrg *
273 1.1 mrg * Returns:
274 1.1 mrg * `true` if this `Declaration` is `@disable`d, `false` otherwise.
275 1.1 mrg */
276 1.1 mrg extern (D) final bool checkDisabled(Loc loc, Scope* sc, bool isAliasedDeclaration = false)
277 1.1 mrg {
278 1.1 mrg if (!(storage_class & STC.disable))
279 1.1 mrg return false;
280 1.1 mrg
281 1.1 mrg if (sc.func && sc.func.storage_class & STC.disable)
282 1.1 mrg return true;
283 1.1 mrg
284 1.1 mrg if (auto p = toParent())
285 1.1 mrg {
286 1.1 mrg if (auto postblit = isPostBlitDeclaration())
287 1.1 mrg {
288 1.1 mrg /* https://issues.dlang.org/show_bug.cgi?id=21885
289 1.1 mrg *
290 1.1 mrg * If the generated postblit is disabled, it
291 1.1 mrg * means that one of the fields has a disabled
292 1.1 mrg * postblit. Print the first field that has
293 1.1 mrg * a disabled postblit.
294 1.1 mrg */
295 1.1 mrg if (postblit.isGenerated())
296 1.1 mrg {
297 1.1 mrg auto sd = p.isStructDeclaration();
298 1.1 mrg assert(sd);
299 1.1 mrg for (size_t i = 0; i < sd.fields.dim; i++)
300 1.1 mrg {
301 1.1 mrg auto structField = sd.fields[i];
302 1.1 mrg if (structField.overlapped)
303 1.1 mrg continue;
304 1.1 mrg Type tv = structField.type.baseElemOf();
305 1.1 mrg if (tv.ty != Tstruct)
306 1.1 mrg continue;
307 1.1 mrg auto sdv = (cast(TypeStruct)tv).sym;
308 1.1 mrg if (!sdv.postblit)
309 1.1 mrg continue;
310 1.1 mrg if (sdv.postblit.isDisabled())
311 1.1 mrg {
312 1.1 mrg p.error(loc, "is not copyable because field `%s` is not copyable", structField.toChars());
313 1.1 mrg return true;
314 1.1 mrg }
315 1.1 mrg }
316 1.1 mrg }
317 1.1 mrg p.error(loc, "is not copyable because it has a disabled postblit");
318 1.1 mrg return true;
319 1.1 mrg }
320 1.1 mrg }
321 1.1 mrg
322 1.1 mrg // if the function is @disabled, maybe there
323 1.1 mrg // is an overload in the overload set that isn't
324 1.1 mrg if (isAliasedDeclaration)
325 1.1 mrg {
326 1.1 mrg FuncDeclaration fd = isFuncDeclaration();
327 1.1 mrg if (fd)
328 1.1 mrg {
329 1.1 mrg for (FuncDeclaration ovl = fd; ovl; ovl = cast(FuncDeclaration)ovl.overnext)
330 1.1 mrg if (!(ovl.storage_class & STC.disable))
331 1.1 mrg return false;
332 1.1 mrg }
333 1.1 mrg }
334 1.1 mrg
335 1.1 mrg if (auto ctor = isCtorDeclaration())
336 1.1 mrg {
337 1.1 mrg if (ctor.isCpCtor && ctor.isGenerated())
338 1.1 mrg {
339 1.1 mrg .error(loc, "Generating an `inout` copy constructor for `struct %s` failed, therefore instances of it are uncopyable", parent.toPrettyChars());
340 1.1 mrg return true;
341 1.1 mrg }
342 1.1 mrg }
343 1.1 mrg error(loc, "cannot be used because it is annotated with `@disable`");
344 1.1 mrg return true;
345 1.1 mrg }
346 1.1 mrg
347 1.1 mrg /*************************************
348 1.1 mrg * Check to see if declaration can be modified in this context (sc).
349 1.1 mrg * Issue error if not.
350 1.1 mrg * Params:
351 1.1 mrg * loc = location for error messages
352 1.1 mrg * e1 = `null` or `this` expression when this declaration is a field
353 1.1 mrg * sc = context
354 1.1 mrg * flag = if the first bit is set it means do not issue error message for
355 1.1 mrg * invalid modification; if the second bit is set, it means that
356 1.1 mrg this declaration is a field and a subfield of it is modified.
357 1.1 mrg * Returns:
358 1.1 mrg * Modifiable.yes or Modifiable.initialization
359 1.1 mrg */
360 1.1 mrg extern (D) final Modifiable checkModify(Loc loc, Scope* sc, Expression e1, ModifyFlags flag)
361 1.1 mrg {
362 1.1 mrg VarDeclaration v = isVarDeclaration();
363 1.1 mrg if (v && v.canassign)
364 1.1 mrg return Modifiable.initialization;
365 1.1 mrg
366 1.1 mrg if (isParameter() || isResult())
367 1.1 mrg {
368 1.1 mrg for (Scope* scx = sc; scx; scx = scx.enclosing)
369 1.1 mrg {
370 1.1 mrg if (scx.func == parent && (scx.flags & SCOPE.contract))
371 1.1 mrg {
372 1.1 mrg const(char)* s = isParameter() && parent.ident != Id.ensure ? "parameter" : "result";
373 1.1 mrg if (!(flag & ModifyFlags.noError))
374 1.1 mrg error(loc, "cannot modify %s `%s` in contract", s, toChars());
375 1.1 mrg return Modifiable.initialization; // do not report type related errors
376 1.1 mrg }
377 1.1 mrg }
378 1.1 mrg }
379 1.1 mrg
380 1.1 mrg if (e1 && e1.op == EXP.this_ && isField())
381 1.1 mrg {
382 1.1 mrg VarDeclaration vthis = e1.isThisExp().var;
383 1.1 mrg for (Scope* scx = sc; scx; scx = scx.enclosing)
384 1.1 mrg {
385 1.1 mrg if (scx.func == vthis.parent && (scx.flags & SCOPE.contract))
386 1.1 mrg {
387 1.1 mrg if (!(flag & ModifyFlags.noError))
388 1.1 mrg error(loc, "cannot modify parameter `this` in contract");
389 1.1 mrg return Modifiable.initialization; // do not report type related errors
390 1.1 mrg }
391 1.1 mrg }
392 1.1 mrg }
393 1.1 mrg
394 1.1 mrg if (v && (v.isCtorinit() || isField()))
395 1.1 mrg {
396 1.1 mrg // It's only modifiable if inside the right constructor
397 1.1 mrg if ((storage_class & (STC.foreach_ | STC.ref_)) == (STC.foreach_ | STC.ref_))
398 1.1 mrg return Modifiable.initialization;
399 1.1 mrg if (flag & ModifyFlags.fieldAssign)
400 1.1 mrg return Modifiable.yes;
401 1.1 mrg return modifyFieldVar(loc, sc, v, e1) ? Modifiable.initialization : Modifiable.yes;
402 1.1 mrg }
403 1.1 mrg return Modifiable.yes;
404 1.1 mrg }
405 1.1 mrg
406 1.1 mrg override final Dsymbol search(const ref Loc loc, Identifier ident, int flags = SearchLocalsOnly)
407 1.1 mrg {
408 1.1 mrg Dsymbol s = Dsymbol.search(loc, ident, flags);
409 1.1 mrg if (!s && type)
410 1.1 mrg {
411 1.1 mrg s = type.toDsymbol(_scope);
412 1.1 mrg if (s)
413 1.1 mrg s = s.search(loc, ident, flags);
414 1.1 mrg }
415 1.1 mrg return s;
416 1.1 mrg }
417 1.1 mrg
418 1.1 mrg final bool isStatic() const pure nothrow @nogc @safe
419 1.1 mrg {
420 1.1 mrg return (storage_class & STC.static_) != 0;
421 1.1 mrg }
422 1.1 mrg
423 1.1 mrg /// Returns the linkage, resolving the target-specific `System` one.
424 1.1 mrg final LINK resolvedLinkage() const
425 1.1 mrg {
426 1.1 mrg return _linkage == LINK.system ? target.systemLinkage() : _linkage;
427 1.1 mrg }
428 1.1 mrg
429 1.1 mrg bool isDelete()
430 1.1 mrg {
431 1.1 mrg return false;
432 1.1 mrg }
433 1.1 mrg
434 1.1 mrg bool isDataseg()
435 1.1 mrg {
436 1.1 mrg return false;
437 1.1 mrg }
438 1.1 mrg
439 1.1 mrg bool isThreadlocal()
440 1.1 mrg {
441 1.1 mrg return false;
442 1.1 mrg }
443 1.1 mrg
444 1.1 mrg bool isCodeseg() const pure nothrow @nogc @safe
445 1.1 mrg {
446 1.1 mrg return false;
447 1.1 mrg }
448 1.1 mrg
449 1.1 mrg final bool isFinal() const pure nothrow @nogc @safe
450 1.1 mrg {
451 1.1 mrg return (storage_class & STC.final_) != 0;
452 1.1 mrg }
453 1.1 mrg
454 1.1 mrg bool isAbstract()
455 1.1 mrg {
456 1.1 mrg return (storage_class & STC.abstract_) != 0;
457 1.1 mrg }
458 1.1 mrg
459 1.1 mrg final bool isConst() const pure nothrow @nogc @safe
460 1.1 mrg {
461 1.1 mrg return (storage_class & STC.const_) != 0;
462 1.1 mrg }
463 1.1 mrg
464 1.1 mrg final bool isImmutable() const pure nothrow @nogc @safe
465 1.1 mrg {
466 1.1 mrg return (storage_class & STC.immutable_) != 0;
467 1.1 mrg }
468 1.1 mrg
469 1.1 mrg final bool isWild() const pure nothrow @nogc @safe
470 1.1 mrg {
471 1.1 mrg return (storage_class & STC.wild) != 0;
472 1.1 mrg }
473 1.1 mrg
474 1.1 mrg final bool isAuto() const pure nothrow @nogc @safe
475 1.1 mrg {
476 1.1 mrg return (storage_class & STC.auto_) != 0;
477 1.1 mrg }
478 1.1 mrg
479 1.1 mrg final bool isScope() const pure nothrow @nogc @safe
480 1.1 mrg {
481 1.1 mrg return (storage_class & STC.scope_) != 0;
482 1.1 mrg }
483 1.1 mrg
484 1.1 mrg final bool isSynchronized() const pure nothrow @nogc @safe
485 1.1 mrg {
486 1.1 mrg return (storage_class & STC.synchronized_) != 0;
487 1.1 mrg }
488 1.1 mrg
489 1.1 mrg final bool isParameter() const pure nothrow @nogc @safe
490 1.1 mrg {
491 1.1 mrg return (storage_class & STC.parameter) != 0;
492 1.1 mrg }
493 1.1 mrg
494 1.1 mrg override final bool isDeprecated() const pure nothrow @nogc @safe
495 1.1 mrg {
496 1.1 mrg return (storage_class & STC.deprecated_) != 0;
497 1.1 mrg }
498 1.1 mrg
499 1.1 mrg final bool isDisabled() const pure nothrow @nogc @safe
500 1.1 mrg {
501 1.1 mrg return (storage_class & STC.disable) != 0;
502 1.1 mrg }
503 1.1 mrg
504 1.1 mrg final bool isOverride() const pure nothrow @nogc @safe
505 1.1 mrg {
506 1.1 mrg return (storage_class & STC.override_) != 0;
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg final bool isResult() const pure nothrow @nogc @safe
510 1.1 mrg {
511 1.1 mrg return (storage_class & STC.result) != 0;
512 1.1 mrg }
513 1.1 mrg
514 1.1 mrg final bool isField() const pure nothrow @nogc @safe
515 1.1 mrg {
516 1.1 mrg return (storage_class & STC.field) != 0;
517 1.1 mrg }
518 1.1 mrg
519 1.1 mrg final bool isIn() const pure nothrow @nogc @safe
520 1.1 mrg {
521 1.1 mrg return (storage_class & STC.in_) != 0;
522 1.1 mrg }
523 1.1 mrg
524 1.1 mrg final bool isOut() const pure nothrow @nogc @safe
525 1.1 mrg {
526 1.1 mrg return (storage_class & STC.out_) != 0;
527 1.1 mrg }
528 1.1 mrg
529 1.1 mrg final bool isRef() const pure nothrow @nogc @safe
530 1.1 mrg {
531 1.1 mrg return (storage_class & STC.ref_) != 0;
532 1.1 mrg }
533 1.1 mrg
534 1.1 mrg /// Returns: Whether the variable is a reference, annotated with `out` or `ref`
535 1.1 mrg final bool isReference() const pure nothrow @nogc @safe
536 1.1 mrg {
537 1.1 mrg return (storage_class & (STC.ref_ | STC.out_)) != 0;
538 1.1 mrg }
539 1.1 mrg
540 1.1 mrg final bool isFuture() const pure nothrow @nogc @safe
541 1.1 mrg {
542 1.1 mrg return (storage_class & STC.future) != 0;
543 1.1 mrg }
544 1.1 mrg
545 1.1 mrg override final Visibility visible() pure nothrow @nogc @safe
546 1.1 mrg {
547 1.1 mrg return visibility;
548 1.1 mrg }
549 1.1 mrg
550 1.1 mrg override final inout(Declaration) isDeclaration() inout pure nothrow @nogc @safe
551 1.1 mrg {
552 1.1 mrg return this;
553 1.1 mrg }
554 1.1 mrg
555 1.1 mrg override void accept(Visitor v)
556 1.1 mrg {
557 1.1 mrg v.visit(this);
558 1.1 mrg }
559 1.1 mrg }
560 1.1 mrg
561 1.1 mrg /***********************************************************
562 1.1 mrg */
563 1.1 mrg extern (C++) final class TupleDeclaration : Declaration
564 1.1 mrg {
565 1.1 mrg Objects* objects;
566 1.1 mrg bool isexp; // true: expression tuple
567 1.1 mrg TypeTuple tupletype; // !=null if this is a type tuple
568 1.1 mrg
569 1.1 mrg extern (D) this(const ref Loc loc, Identifier ident, Objects* objects)
570 1.1 mrg {
571 1.1 mrg super(loc, ident);
572 1.1 mrg this.objects = objects;
573 1.1 mrg }
574 1.1 mrg
575 1.1 mrg override TupleDeclaration syntaxCopy(Dsymbol s)
576 1.1 mrg {
577 1.1 mrg assert(0);
578 1.1 mrg }
579 1.1 mrg
580 1.1 mrg override const(char)* kind() const
581 1.1 mrg {
582 1.1 mrg return "tuple";
583 1.1 mrg }
584 1.1 mrg
585 1.1 mrg override Type getType()
586 1.1 mrg {
587 1.1 mrg /* If this tuple represents a type, return that type
588 1.1 mrg */
589 1.1 mrg
590 1.1 mrg //printf("TupleDeclaration::getType() %s\n", toChars());
591 1.1 mrg if (isexp)
592 1.1 mrg return null;
593 1.1 mrg if (!tupletype)
594 1.1 mrg {
595 1.1 mrg /* It's only a type tuple if all the Object's are types
596 1.1 mrg */
597 1.1 mrg for (size_t i = 0; i < objects.dim; i++)
598 1.1 mrg {
599 1.1 mrg RootObject o = (*objects)[i];
600 1.1 mrg if (o.dyncast() != DYNCAST.type)
601 1.1 mrg {
602 1.1 mrg //printf("\tnot[%d], %p, %d\n", i, o, o.dyncast());
603 1.1 mrg return null;
604 1.1 mrg }
605 1.1 mrg }
606 1.1 mrg
607 1.1 mrg /* We know it's a type tuple, so build the TypeTuple
608 1.1 mrg */
609 1.1 mrg Types* types = cast(Types*)objects;
610 1.1 mrg auto args = new Parameters(objects.dim);
611 1.1 mrg OutBuffer buf;
612 1.1 mrg int hasdeco = 1;
613 1.1 mrg for (size_t i = 0; i < types.dim; i++)
614 1.1 mrg {
615 1.1 mrg Type t = (*types)[i];
616 1.1 mrg //printf("type = %s\n", t.toChars());
617 1.1 mrg version (none)
618 1.1 mrg {
619 1.1 mrg buf.printf("_%s_%d", ident.toChars(), i);
620 1.1 mrg const len = buf.offset;
621 1.1 mrg const name = buf.extractSlice().ptr;
622 1.1 mrg auto id = Identifier.idPool(name, len);
623 1.1 mrg auto arg = new Parameter(STC.in_, t, id, null);
624 1.1 mrg }
625 1.1 mrg else
626 1.1 mrg {
627 1.1 mrg auto arg = new Parameter(0, t, null, null, null);
628 1.1 mrg }
629 1.1 mrg (*args)[i] = arg;
630 1.1 mrg if (!t.deco)
631 1.1 mrg hasdeco = 0;
632 1.1 mrg }
633 1.1 mrg
634 1.1 mrg tupletype = new TypeTuple(args);
635 1.1 mrg if (hasdeco)
636 1.1 mrg return tupletype.typeSemantic(Loc.initial, null);
637 1.1 mrg }
638 1.1 mrg return tupletype;
639 1.1 mrg }
640 1.1 mrg
641 1.1 mrg override Dsymbol toAlias2()
642 1.1 mrg {
643 1.1 mrg //printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects.toChars());
644 1.1 mrg for (size_t i = 0; i < objects.dim; i++)
645 1.1 mrg {
646 1.1 mrg RootObject o = (*objects)[i];
647 1.1 mrg if (Dsymbol s = isDsymbol(o))
648 1.1 mrg {
649 1.1 mrg s = s.toAlias2();
650 1.1 mrg (*objects)[i] = s;
651 1.1 mrg }
652 1.1 mrg }
653 1.1 mrg return this;
654 1.1 mrg }
655 1.1 mrg
656 1.1 mrg override bool needThis()
657 1.1 mrg {
658 1.1 mrg //printf("TupleDeclaration::needThis(%s)\n", toChars());
659 1.1 mrg return isexp ? foreachVar((s) { return s.needThis(); }) != 0 : false;
660 1.1 mrg }
661 1.1 mrg
662 1.1 mrg /***********************************************************
663 1.1 mrg * Calls dg(Dsymbol) for each Dsymbol, which should be a VarDeclaration
664 1.1 mrg * inside DsymbolExp (isexp == true).
665 1.1 mrg * Params:
666 1.1 mrg * dg = delegate to call for each Dsymbol
667 1.1 mrg */
668 1.1 mrg extern (D) void foreachVar(scope void delegate(Dsymbol) dg)
669 1.1 mrg {
670 1.1 mrg assert(isexp);
671 1.1 mrg foreach (o; *objects)
672 1.1 mrg {
673 1.1 mrg if (auto e = o.isExpression())
674 1.1 mrg if (auto se = e.isDsymbolExp())
675 1.1 mrg dg(se.s);
676 1.1 mrg }
677 1.1 mrg }
678 1.1 mrg
679 1.1 mrg /***********************************************************
680 1.1 mrg * Calls dg(Dsymbol) for each Dsymbol, which should be a VarDeclaration
681 1.1 mrg * inside DsymbolExp (isexp == true).
682 1.1 mrg * If dg returns !=0, stops and returns that value else returns 0.
683 1.1 mrg * Params:
684 1.1 mrg * dg = delegate to call for each Dsymbol
685 1.1 mrg * Returns:
686 1.1 mrg * last value returned by dg()
687 1.1 mrg */
688 1.1 mrg extern (D) int foreachVar(scope int delegate(Dsymbol) dg)
689 1.1 mrg {
690 1.1 mrg assert(isexp);
691 1.1 mrg foreach (o; *objects)
692 1.1 mrg {
693 1.1 mrg if (auto e = o.isExpression())
694 1.1 mrg if (auto se = e.isDsymbolExp())
695 1.1 mrg if(auto ret = dg(se.s))
696 1.1 mrg return ret;
697 1.1 mrg }
698 1.1 mrg return 0;
699 1.1 mrg }
700 1.1 mrg
701 1.1 mrg override inout(TupleDeclaration) isTupleDeclaration() inout
702 1.1 mrg {
703 1.1 mrg return this;
704 1.1 mrg }
705 1.1 mrg
706 1.1 mrg override void accept(Visitor v)
707 1.1 mrg {
708 1.1 mrg v.visit(this);
709 1.1 mrg }
710 1.1 mrg }
711 1.1 mrg
712 1.1 mrg /***********************************************************
713 1.1 mrg * https://dlang.org/spec/declaration.html#AliasDeclaration
714 1.1 mrg */
715 1.1 mrg extern (C++) final class AliasDeclaration : Declaration
716 1.1 mrg {
717 1.1 mrg Dsymbol aliassym; // alias ident = aliassym;
718 1.1 mrg
719 1.1 mrg Dsymbol overnext; // next in overload list
720 1.1 mrg Dsymbol _import; // !=null if unresolved internal alias for selective import
721 1.1 mrg
722 1.1 mrg extern (D) this(const ref Loc loc, Identifier ident, Type type)
723 1.1 mrg {
724 1.1 mrg super(loc, ident);
725 1.1 mrg //printf("AliasDeclaration(id = '%s', type = %p)\n", id.toChars(), type);
726 1.1 mrg //printf("type = '%s'\n", type.toChars());
727 1.1 mrg this.type = type;
728 1.1 mrg assert(type);
729 1.1 mrg }
730 1.1 mrg
731 1.1 mrg extern (D) this(const ref Loc loc, Identifier ident, Dsymbol s)
732 1.1 mrg {
733 1.1 mrg super(loc, ident);
734 1.1 mrg //printf("AliasDeclaration(id = '%s', s = %p)\n", id.toChars(), s);
735 1.1 mrg assert(s != this);
736 1.1 mrg this.aliassym = s;
737 1.1 mrg assert(s);
738 1.1 mrg }
739 1.1 mrg
740 1.1 mrg static AliasDeclaration create(const ref Loc loc, Identifier id, Type type)
741 1.1 mrg {
742 1.1 mrg return new AliasDeclaration(loc, id, type);
743 1.1 mrg }
744 1.1 mrg
745 1.1 mrg override AliasDeclaration syntaxCopy(Dsymbol s)
746 1.1 mrg {
747 1.1 mrg //printf("AliasDeclaration::syntaxCopy()\n");
748 1.1 mrg assert(!s);
749 1.1 mrg AliasDeclaration sa = type ? new AliasDeclaration(loc, ident, type.syntaxCopy()) : new AliasDeclaration(loc, ident, aliassym.syntaxCopy(null));
750 1.1 mrg sa.comment = comment;
751 1.1 mrg sa.storage_class = storage_class;
752 1.1 mrg return sa;
753 1.1 mrg }
754 1.1 mrg
755 1.1 mrg override bool overloadInsert(Dsymbol s)
756 1.1 mrg {
757 1.1 mrg //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n",
758 1.1 mrg // loc.toChars(), toChars(), s.kind(), s.toChars(), s.loc.toChars());
759 1.1 mrg
760 1.1 mrg /** Aliases aren't overloadable themselves, but if their Aliasee is
761 1.1 mrg * overloadable they are converted to an overloadable Alias (either
762 1.1 mrg * FuncAliasDeclaration or OverDeclaration).
763 1.1 mrg *
764 1.1 mrg * This is done by moving the Aliasee into such an overloadable alias
765 1.1 mrg * which is then used to replace the existing Aliasee. The original
766 1.1 mrg * Alias (_this_) remains a useless shell.
767 1.1 mrg *
768 1.1 mrg * This is a horrible mess. It was probably done to avoid replacing
769 1.1 mrg * existing AST nodes and references, but it needs a major
770 1.1 mrg * simplification b/c it's too complex to maintain.
771 1.1 mrg *
772 1.1 mrg * A simpler approach might be to merge any colliding symbols into a
773 1.1 mrg * simple Overload class (an array) and then later have that resolve
774 1.1 mrg * all collisions.
775 1.1 mrg */
776 1.1 mrg if (semanticRun >= PASS.semanticdone)
777 1.1 mrg {
778 1.1 mrg /* Semantic analysis is already finished, and the aliased entity
779 1.1 mrg * is not overloadable.
780 1.1 mrg */
781 1.1 mrg if (type)
782 1.1 mrg return false;
783 1.1 mrg
784 1.1 mrg /* When s is added in member scope by static if, mixin("code") or others,
785 1.1 mrg * aliassym is determined already. See the case in: test/compilable/test61.d
786 1.1 mrg */
787 1.1 mrg auto sa = aliassym.toAlias();
788 1.1 mrg
789 1.1 mrg if (auto td = s.toAlias().isTemplateDeclaration())
790 1.1 mrg s = td.funcroot ? td.funcroot : td;
791 1.1 mrg
792 1.1 mrg if (auto fd = sa.isFuncDeclaration())
793 1.1 mrg {
794 1.1 mrg auto fa = new FuncAliasDeclaration(ident, fd);
795 1.1 mrg fa.visibility = visibility;
796 1.1 mrg fa.parent = parent;
797 1.1 mrg aliassym = fa;
798 1.1 mrg return aliassym.overloadInsert(s);
799 1.1 mrg }
800 1.1 mrg if (auto td = sa.isTemplateDeclaration())
801 1.1 mrg {
802 1.1 mrg auto od = new OverDeclaration(ident, td.funcroot ? td.funcroot : td);
803 1.1 mrg od.visibility = visibility;
804 1.1 mrg od.parent = parent;
805 1.1 mrg aliassym = od;
806 1.1 mrg return aliassym.overloadInsert(s);
807 1.1 mrg }
808 1.1 mrg if (auto od = sa.isOverDeclaration())
809 1.1 mrg {
810 1.1 mrg if (sa.ident != ident || sa.parent != parent)
811 1.1 mrg {
812 1.1 mrg od = new OverDeclaration(ident, od);
813 1.1 mrg od.visibility = visibility;
814 1.1 mrg od.parent = parent;
815 1.1 mrg aliassym = od;
816 1.1 mrg }
817 1.1 mrg return od.overloadInsert(s);
818 1.1 mrg }
819 1.1 mrg if (auto os = sa.isOverloadSet())
820 1.1 mrg {
821 1.1 mrg if (sa.ident != ident || sa.parent != parent)
822 1.1 mrg {
823 1.1 mrg os = new OverloadSet(ident, os);
824 1.1 mrg // TODO: visibility is lost here b/c OverloadSets have no visibility attribute
825 1.1 mrg // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow.
826 1.1 mrg // ----
827 1.1 mrg // module os1;
828 1.1 mrg // import a, b;
829 1.1 mrg // private alias merged = foo; // private alias to overload set of a.foo and b.foo
830 1.1 mrg // ----
831 1.1 mrg // module os2;
832 1.1 mrg // import a, b;
833 1.1 mrg // public alias merged = bar; // public alias to overload set of a.bar and b.bar
834 1.1 mrg // ----
835 1.1 mrg // module bug;
836 1.1 mrg // import os1, os2;
837 1.1 mrg // void test() { merged(123); } // should only look at os2.merged
838 1.1 mrg //
839 1.1 mrg // os.visibility = visibility;
840 1.1 mrg os.parent = parent;
841 1.1 mrg aliassym = os;
842 1.1 mrg }
843 1.1 mrg os.push(s);
844 1.1 mrg return true;
845 1.1 mrg }
846 1.1 mrg return false;
847 1.1 mrg }
848 1.1 mrg
849 1.1 mrg /* Don't know yet what the aliased symbol is, so assume it can
850 1.1 mrg * be overloaded and check later for correctness.
851 1.1 mrg */
852 1.1 mrg if (overnext)
853 1.1 mrg return overnext.overloadInsert(s);
854 1.1 mrg if (s is this)
855 1.1 mrg return true;
856 1.1 mrg overnext = s;
857 1.1 mrg return true;
858 1.1 mrg }
859 1.1 mrg
860 1.1 mrg override const(char)* kind() const
861 1.1 mrg {
862 1.1 mrg return "alias";
863 1.1 mrg }
864 1.1 mrg
865 1.1 mrg override Type getType()
866 1.1 mrg {
867 1.1 mrg if (type)
868 1.1 mrg return type;
869 1.1 mrg return toAlias().getType();
870 1.1 mrg }
871 1.1 mrg
872 1.1 mrg override Dsymbol toAlias()
873 1.1 mrg {
874 1.1 mrg //printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\n",
875 1.1 mrg // loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym.kind() : "", inuse);
876 1.1 mrg assert(this != aliassym);
877 1.1 mrg //static int count; if (++count == 10) *(char*)0=0;
878 1.1 mrg
879 1.1 mrg // Reading the AliasDeclaration
880 1.1 mrg if (!(adFlags & ignoreRead))
881 1.1 mrg adFlags |= wasRead; // can never assign to this AliasDeclaration again
882 1.1 mrg
883 1.1 mrg if (inuse == 1 && type && _scope)
884 1.1 mrg {
885 1.1 mrg inuse = 2;
886 1.1 mrg uint olderrors = global.errors;
887 1.1 mrg Dsymbol s = type.toDsymbol(_scope);
888 1.1 mrg //printf("[%s] type = %s, s = %p, this = %p\n", loc.toChars(), type.toChars(), s, this);
889 1.1 mrg if (global.errors != olderrors)
890 1.1 mrg goto Lerr;
891 1.1 mrg if (s)
892 1.1 mrg {
893 1.1 mrg s = s.toAlias();
894 1.1 mrg if (global.errors != olderrors)
895 1.1 mrg goto Lerr;
896 1.1 mrg aliassym = s;
897 1.1 mrg inuse = 0;
898 1.1 mrg }
899 1.1 mrg else
900 1.1 mrg {
901 1.1 mrg Type t = type.typeSemantic(loc, _scope);
902 1.1 mrg if (t.ty == Terror)
903 1.1 mrg goto Lerr;
904 1.1 mrg if (global.errors != olderrors)
905 1.1 mrg goto Lerr;
906 1.1 mrg //printf("t = %s\n", t.toChars());
907 1.1 mrg inuse = 0;
908 1.1 mrg }
909 1.1 mrg }
910 1.1 mrg if (inuse)
911 1.1 mrg {
912 1.1 mrg error("recursive alias declaration");
913 1.1 mrg
914 1.1 mrg Lerr:
915 1.1 mrg // Avoid breaking "recursive alias" state during errors gagged
916 1.1 mrg if (global.gag)
917 1.1 mrg return this;
918 1.1 mrg aliassym = new AliasDeclaration(loc, ident, Type.terror);
919 1.1 mrg type = Type.terror;
920 1.1 mrg return aliassym;
921 1.1 mrg }
922 1.1 mrg
923 1.1 mrg if (semanticRun >= PASS.semanticdone)
924 1.1 mrg {
925 1.1 mrg // semantic is already done.
926 1.1 mrg
927 1.1 mrg // Do not see aliassym !is null, because of lambda aliases.
928 1.1 mrg
929 1.1 mrg // Do not see type.deco !is null, even so "alias T = const int;` needs
930 1.1 mrg // semantic analysis to take the storage class `const` as type qualifier.
931 1.1 mrg }
932 1.1 mrg else
933 1.1 mrg {
934 1.1 mrg if (_import && _import._scope)
935 1.1 mrg {
936 1.1 mrg /* If this is an internal alias for selective/renamed import,
937 1.1 mrg * load the module first.
938 1.1 mrg */
939 1.1 mrg _import.dsymbolSemantic(null);
940 1.1 mrg }
941 1.1 mrg if (_scope)
942 1.1 mrg {
943 1.1 mrg aliasSemantic(this, _scope);
944 1.1 mrg }
945 1.1 mrg }
946 1.1 mrg
947 1.1 mrg inuse = 1;
948 1.1 mrg Dsymbol s = aliassym ? aliassym.toAlias() : this;
949 1.1 mrg inuse = 0;
950 1.1 mrg return s;
951 1.1 mrg }
952 1.1 mrg
953 1.1 mrg override Dsymbol toAlias2()
954 1.1 mrg {
955 1.1 mrg if (inuse)
956 1.1 mrg {
957 1.1 mrg error("recursive alias declaration");
958 1.1 mrg return this;
959 1.1 mrg }
960 1.1 mrg inuse = 1;
961 1.1 mrg Dsymbol s = aliassym ? aliassym.toAlias2() : this;
962 1.1 mrg inuse = 0;
963 1.1 mrg return s;
964 1.1 mrg }
965 1.1 mrg
966 1.1 mrg override bool isOverloadable() const
967 1.1 mrg {
968 1.1 mrg // assume overloadable until alias is resolved
969 1.1 mrg return semanticRun < PASS.semanticdone ||
970 1.1 mrg aliassym && aliassym.isOverloadable();
971 1.1 mrg }
972 1.1 mrg
973 1.1 mrg override inout(AliasDeclaration) isAliasDeclaration() inout
974 1.1 mrg {
975 1.1 mrg return this;
976 1.1 mrg }
977 1.1 mrg
978 1.1 mrg /** Returns: `true` if this instance was created to make a template parameter
979 1.1 mrg visible in the scope of a template body, `false` otherwise */
980 1.1 mrg extern (D) bool isAliasedTemplateParameter() const
981 1.1 mrg {
982 1.1 mrg return !!(storage_class & STC.templateparameter);
983 1.1 mrg }
984 1.1 mrg
985 1.1 mrg override void accept(Visitor v)
986 1.1 mrg {
987 1.1 mrg v.visit(this);
988 1.1 mrg }
989 1.1 mrg }
990 1.1 mrg
991 1.1 mrg /***********************************************************
992 1.1 mrg */
993 1.1 mrg extern (C++) final class OverDeclaration : Declaration
994 1.1 mrg {
995 1.1 mrg Dsymbol overnext; // next in overload list
996 1.1 mrg Dsymbol aliassym;
997 1.1 mrg
998 1.1 mrg extern (D) this(Identifier ident, Dsymbol s)
999 1.1 mrg {
1000 1.1 mrg super(ident);
1001 1.1 mrg this.aliassym = s;
1002 1.1 mrg }
1003 1.1 mrg
1004 1.1 mrg override const(char)* kind() const
1005 1.1 mrg {
1006 1.1 mrg return "overload alias"; // todo
1007 1.1 mrg }
1008 1.1 mrg
1009 1.1 mrg override bool equals(const RootObject o) const
1010 1.1 mrg {
1011 1.1 mrg if (this == o)
1012 1.1 mrg return true;
1013 1.1 mrg
1014 1.1 mrg auto s = isDsymbol(o);
1015 1.1 mrg if (!s)
1016 1.1 mrg return false;
1017 1.1 mrg
1018 1.1 mrg if (auto od2 = s.isOverDeclaration())
1019 1.1 mrg return this.aliassym.equals(od2.aliassym);
1020 1.1 mrg return this.aliassym == s;
1021 1.1 mrg }
1022 1.1 mrg
1023 1.1 mrg override bool overloadInsert(Dsymbol s)
1024 1.1 mrg {
1025 1.1 mrg //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s.toChars(), aliassym, overnext);
1026 1.1 mrg if (overnext)
1027 1.1 mrg return overnext.overloadInsert(s);
1028 1.1 mrg if (s == this)
1029 1.1 mrg return true;
1030 1.1 mrg overnext = s;
1031 1.1 mrg return true;
1032 1.1 mrg }
1033 1.1 mrg
1034 1.1 mrg override bool isOverloadable() const
1035 1.1 mrg {
1036 1.1 mrg return true;
1037 1.1 mrg }
1038 1.1 mrg
1039 1.1 mrg Dsymbol isUnique()
1040 1.1 mrg {
1041 1.1 mrg Dsymbol result = null;
1042 1.1 mrg overloadApply(aliassym, (Dsymbol s)
1043 1.1 mrg {
1044 1.1 mrg if (result)
1045 1.1 mrg {
1046 1.1 mrg result = null;
1047 1.1 mrg return 1; // ambiguous, done
1048 1.1 mrg }
1049 1.1 mrg else
1050 1.1 mrg {
1051 1.1 mrg result = s;
1052 1.1 mrg return 0;
1053 1.1 mrg }
1054 1.1 mrg });
1055 1.1 mrg return result;
1056 1.1 mrg }
1057 1.1 mrg
1058 1.1 mrg override inout(OverDeclaration) isOverDeclaration() inout
1059 1.1 mrg {
1060 1.1 mrg return this;
1061 1.1 mrg }
1062 1.1 mrg
1063 1.1 mrg override void accept(Visitor v)
1064 1.1 mrg {
1065 1.1 mrg v.visit(this);
1066 1.1 mrg }
1067 1.1 mrg }
1068 1.1 mrg
1069 1.1 mrg /***********************************************************
1070 1.1 mrg */
1071 1.1 mrg extern (C++) class VarDeclaration : Declaration
1072 1.1 mrg {
1073 1.1 mrg Initializer _init;
1074 1.1 mrg FuncDeclarations nestedrefs; // referenced by these lexically nested functions
1075 1.1 mrg Dsymbol aliassym; // if redone as alias to another symbol
1076 1.1 mrg VarDeclaration lastVar; // Linked list of variables for goto-skips-init detection
1077 1.1 mrg Expression edtor; // if !=null, does the destruction of the variable
1078 1.1 mrg IntRange* range; // if !=null, the variable is known to be within the range
1079 1.1 mrg VarDeclarations* maybes; // STC.maybescope variables that are assigned to this STC.maybescope variable
1080 1.1 mrg
1081 1.1 mrg uint endlinnum; // line number of end of scope that this var lives in
1082 1.1 mrg uint offset;
1083 1.1 mrg uint sequenceNumber; // order the variables are declared
1084 1.1 mrg structalign_t alignment;
1085 1.1 mrg
1086 1.1 mrg // When interpreting, these point to the value (NULL if value not determinable)
1087 1.1 mrg // The index of this variable on the CTFE stack, AdrOnStackNone if not allocated
1088 1.1 mrg enum AdrOnStackNone = ~0u;
1089 1.1 mrg uint ctfeAdrOnStack;
1090 1.1 mrg
1091 1.1 mrg // `bool` fields that are compacted into bit fields in a string mixin
1092 1.1 mrg private extern (D) static struct BitFields
1093 1.1 mrg {
1094 1.1 mrg bool isargptr; /// if parameter that _argptr points to
1095 1.1 mrg bool ctorinit; /// it has been initialized in a ctor
1096 1.1 mrg bool iscatchvar; /// this is the exception object variable in catch() clause
1097 1.1 mrg bool isowner; /// this is an Owner, despite it being `scope`
1098 1.1 mrg bool setInCtorOnly; /// field can only be set in a constructor, as it is const or immutable
1099 1.1 mrg
1100 1.1 mrg /// It is a class that was allocated on the stack
1101 1.1 mrg ///
1102 1.1 mrg /// This means the var is not rebindable once assigned,
1103 1.1 mrg /// and the destructor gets run when it goes out of scope
1104 1.1 mrg bool onstack;
1105 1.1 mrg
1106 1.1 mrg bool overlapped; /// if it is a field and has overlapping
1107 1.1 mrg bool overlapUnsafe; /// if it is an overlapping field and the overlaps are unsafe
1108 1.1 mrg bool doNotInferScope; /// do not infer 'scope' for this variable
1109 1.1 mrg bool doNotInferReturn; /// do not infer 'return' for this variable
1110 1.1 mrg
1111 1.1 mrg bool isArgDtorVar; /// temporary created to handle scope destruction of a function argument
1112 1.1 mrg }
1113 1.1 mrg
1114 1.1 mrg import dmd.common.bitfields : generateBitFields;
1115 1.1 mrg mixin(generateBitFields!(BitFields, ushort));
1116 1.1 mrg
1117 1.1 mrg byte canassign; // it can be assigned to
1118 1.1 mrg ubyte isdataseg; // private data for isDataseg 0 unset, 1 true, 2 false
1119 1.1 mrg
1120 1.1 mrg final extern (D) this(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_)
1121 1.1 mrg in
1122 1.1 mrg {
1123 1.1 mrg assert(ident);
1124 1.1 mrg }
1125 1.1 mrg do
1126 1.1 mrg {
1127 1.1 mrg //printf("VarDeclaration('%s')\n", ident.toChars());
1128 1.1 mrg super(loc, ident);
1129 1.1 mrg debug
1130 1.1 mrg {
1131 1.1 mrg if (!type && !_init)
1132 1.1 mrg {
1133 1.1 mrg //printf("VarDeclaration('%s')\n", ident.toChars());
1134 1.1 mrg //*(char*)0=0;
1135 1.1 mrg }
1136 1.1 mrg }
1137 1.1 mrg
1138 1.1 mrg assert(type || _init);
1139 1.1 mrg this.type = type;
1140 1.1 mrg this._init = _init;
1141 1.1 mrg ctfeAdrOnStack = AdrOnStackNone;
1142 1.1 mrg this.storage_class = storage_class;
1143 1.1 mrg }
1144 1.1 mrg
1145 1.1 mrg static VarDeclaration create(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_)
1146 1.1 mrg {
1147 1.1 mrg return new VarDeclaration(loc, type, ident, _init, storage_class);
1148 1.1 mrg }
1149 1.1 mrg
1150 1.1 mrg override VarDeclaration syntaxCopy(Dsymbol s)
1151 1.1 mrg {
1152 1.1 mrg //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
1153 1.1 mrg assert(!s);
1154 1.1 mrg auto v = new VarDeclaration(loc, type ? type.syntaxCopy() : null, ident, _init ? _init.syntaxCopy() : null, storage_class);
1155 1.1 mrg v.comment = comment;
1156 1.1 mrg return v;
1157 1.1 mrg }
1158 1.1 mrg
1159 1.1 mrg override void setFieldOffset(AggregateDeclaration ad, ref FieldState fieldState, bool isunion)
1160 1.1 mrg {
1161 1.1 mrg //printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad.toChars(), toChars());
1162 1.1 mrg
1163 1.1 mrg if (aliassym)
1164 1.1 mrg {
1165 1.1 mrg // If this variable was really a tuple, set the offsets for the tuple fields
1166 1.1 mrg TupleDeclaration v2 = aliassym.isTupleDeclaration();
1167 1.1 mrg assert(v2);
1168 1.1 mrg v2.foreachVar((s) { s.setFieldOffset(ad, fieldState, isunion); });
1169 1.1 mrg return;
1170 1.1 mrg }
1171 1.1 mrg
1172 1.1 mrg if (!isField())
1173 1.1 mrg return;
1174 1.1 mrg assert(!(storage_class & (STC.static_ | STC.extern_ | STC.parameter)));
1175 1.1 mrg
1176 1.1 mrg //printf("+VarDeclaration::setFieldOffset(ad = %s) %s\n", ad.toChars(), toChars());
1177 1.1 mrg
1178 1.1 mrg /* Fields that are tuples appear both as part of TupleDeclarations and
1179 1.1 mrg * as members. That means ignore them if they are already a field.
1180 1.1 mrg */
1181 1.1 mrg if (offset)
1182 1.1 mrg {
1183 1.1 mrg // already a field
1184 1.1 mrg fieldState.offset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613
1185 1.1 mrg return;
1186 1.1 mrg }
1187 1.1 mrg for (size_t i = 0; i < ad.fields.dim; i++)
1188 1.1 mrg {
1189 1.1 mrg if (ad.fields[i] == this)
1190 1.1 mrg {
1191 1.1 mrg // already a field
1192 1.1 mrg fieldState.offset = ad.structsize; // https://issues.dlang.org/show_bug.cgi?id=13613
1193 1.1 mrg return;
1194 1.1 mrg }
1195 1.1 mrg }
1196 1.1 mrg
1197 1.1 mrg // Check for forward referenced types which will fail the size() call
1198 1.1 mrg Type t = type.toBasetype();
1199 1.1 mrg if (storage_class & STC.ref_)
1200 1.1 mrg {
1201 1.1 mrg // References are the size of a pointer
1202 1.1 mrg t = Type.tvoidptr;
1203 1.1 mrg }
1204 1.1 mrg Type tv = t.baseElemOf();
1205 1.1 mrg if (tv.ty == Tstruct)
1206 1.1 mrg {
1207 1.1 mrg auto ts = cast(TypeStruct)tv;
1208 1.1 mrg assert(ts.sym != ad); // already checked in ad.determineFields()
1209 1.1 mrg if (!ts.sym.determineSize(loc))
1210 1.1 mrg {
1211 1.1 mrg type = Type.terror;
1212 1.1 mrg errors = true;
1213 1.1 mrg return;
1214 1.1 mrg }
1215 1.1 mrg }
1216 1.1 mrg
1217 1.1 mrg // List in ad.fields. Even if the type is error, it's necessary to avoid
1218 1.1 mrg // pointless error diagnostic "more initializers than fields" on struct literal.
1219 1.1 mrg ad.fields.push(this);
1220 1.1 mrg
1221 1.1 mrg if (t.ty == Terror)
1222 1.1 mrg return;
1223 1.1 mrg
1224 1.1 mrg /* If coming after a bit field in progress,
1225 1.1 mrg * advance past the field
1226 1.1 mrg */
1227 1.1 mrg fieldState.inFlight = false;
1228 1.1 mrg
1229 1.1 mrg const sz = t.size(loc);
1230 1.1 mrg assert(sz != SIZE_INVALID && sz < uint.max);
1231 1.1 mrg uint memsize = cast(uint)sz; // size of member
1232 1.1 mrg uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
1233 1.1 mrg offset = AggregateDeclaration.placeField(
1234 1.1 mrg &fieldState.offset,
1235 1.1 mrg memsize, memalignsize, alignment,
1236 1.1 mrg &ad.structsize, &ad.alignsize,
1237 1.1 mrg isunion);
1238 1.1 mrg
1239 1.1 mrg //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize);
1240 1.1 mrg //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad.toChars(), offset, memsize);
1241 1.1 mrg }
1242 1.1 mrg
1243 1.1 mrg override const(char)* kind() const
1244 1.1 mrg {
1245 1.1 mrg return "variable";
1246 1.1 mrg }
1247 1.1 mrg
1248 1.1 mrg override final inout(AggregateDeclaration) isThis() inout
1249 1.1 mrg {
1250 1.1 mrg if (!(storage_class & (STC.static_ | STC.extern_ | STC.manifest | STC.templateparameter | STC.gshared | STC.ctfe)))
1251 1.1 mrg {
1252 1.1 mrg /* The casting is necessary because `s = s.parent` is otherwise rejected
1253 1.1 mrg */
1254 1.1 mrg for (auto s = cast(Dsymbol)this; s; s = s.parent)
1255 1.1 mrg {
1256 1.1 mrg auto ad = (cast(inout)s).isMember();
1257 1.1 mrg if (ad)
1258 1.1 mrg return ad;
1259 1.1 mrg if (!s.parent || !s.parent.isTemplateMixin())
1260 1.1 mrg break;
1261 1.1 mrg }
1262 1.1 mrg }
1263 1.1 mrg return null;
1264 1.1 mrg }
1265 1.1 mrg
1266 1.1 mrg override final bool needThis()
1267 1.1 mrg {
1268 1.1 mrg //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1269 1.1 mrg return isField();
1270 1.1 mrg }
1271 1.1 mrg
1272 1.1 mrg override final bool isExport() const
1273 1.1 mrg {
1274 1.1 mrg return visibility.kind == Visibility.Kind.export_;
1275 1.1 mrg }
1276 1.1 mrg
1277 1.1 mrg override final bool isImportedSymbol() const
1278 1.1 mrg {
1279 1.1 mrg if (visibility.kind == Visibility.Kind.export_ && !_init && (storage_class & STC.static_ || parent.isModule()))
1280 1.1 mrg return true;
1281 1.1 mrg return false;
1282 1.1 mrg }
1283 1.1 mrg
1284 1.1 mrg final bool isCtorinit() const pure nothrow @nogc @safe
1285 1.1 mrg {
1286 1.1 mrg return setInCtorOnly;
1287 1.1 mrg }
1288 1.1 mrg
1289 1.1 mrg /*******************************
1290 1.1 mrg * Does symbol go into data segment?
1291 1.1 mrg * Includes extern variables.
1292 1.1 mrg */
1293 1.1 mrg override final bool isDataseg()
1294 1.1 mrg {
1295 1.1 mrg version (none)
1296 1.1 mrg {
1297 1.1 mrg printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1298 1.1 mrg printf("%llx, isModule: %p, isTemplateInstance: %p, isNspace: %p\n",
1299 1.1 mrg storage_class & (STC.static_ | STC.const_), parent.isModule(), parent.isTemplateInstance(), parent.isNspace());
1300 1.1 mrg printf("parent = '%s'\n", parent.toChars());
1301 1.1 mrg }
1302 1.1 mrg
1303 1.1 mrg if (isdataseg == 0) // the value is not cached
1304 1.1 mrg {
1305 1.1 mrg isdataseg = 2; // The Variables does not go into the datasegment
1306 1.1 mrg
1307 1.1 mrg if (!canTakeAddressOf())
1308 1.1 mrg {
1309 1.1 mrg return false;
1310 1.1 mrg }
1311 1.1 mrg
1312 1.1 mrg Dsymbol parent = toParent();
1313 1.1 mrg if (!parent && !(storage_class & STC.static_))
1314 1.1 mrg {
1315 1.1 mrg error("forward referenced");
1316 1.1 mrg type = Type.terror;
1317 1.1 mrg }
1318 1.1 mrg else if (storage_class & (STC.static_ | STC.extern_ | STC.gshared) ||
1319 1.1 mrg parent.isModule() || parent.isTemplateInstance() || parent.isNspace())
1320 1.1 mrg {
1321 1.1 mrg assert(!isParameter() && !isResult());
1322 1.1 mrg isdataseg = 1; // It is in the DataSegment
1323 1.1 mrg }
1324 1.1 mrg }
1325 1.1 mrg
1326 1.1 mrg return (isdataseg == 1);
1327 1.1 mrg }
1328 1.1 mrg /************************************
1329 1.1 mrg * Does symbol go into thread local storage?
1330 1.1 mrg */
1331 1.1 mrg override final bool isThreadlocal()
1332 1.1 mrg {
1333 1.1 mrg //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars());
1334 1.1 mrg /* Data defaults to being thread-local. It is not thread-local
1335 1.1 mrg * if it is immutable, const or shared.
1336 1.1 mrg */
1337 1.1 mrg bool i = isDataseg() && !(storage_class & (STC.immutable_ | STC.const_ | STC.shared_ | STC.gshared));
1338 1.1 mrg //printf("\treturn %d\n", i);
1339 1.1 mrg return i;
1340 1.1 mrg }
1341 1.1 mrg
1342 1.1 mrg /********************************************
1343 1.1 mrg * Can variable be read and written by CTFE?
1344 1.1 mrg */
1345 1.1 mrg final bool isCTFE()
1346 1.1 mrg {
1347 1.1 mrg return (storage_class & STC.ctfe) != 0; // || !isDataseg();
1348 1.1 mrg }
1349 1.1 mrg
1350 1.1 mrg final bool isOverlappedWith(VarDeclaration v)
1351 1.1 mrg {
1352 1.1 mrg const vsz = v.type.size();
1353 1.1 mrg const tsz = type.size();
1354 1.1 mrg assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);
1355 1.1 mrg
1356 1.1 mrg // Overlap is checked by comparing bit offsets
1357 1.1 mrg auto bitoffset = offset * 8;
1358 1.1 mrg auto vbitoffset = v.offset * 8;
1359 1.1 mrg
1360 1.1 mrg // Bitsize of types are overridden by any bit-field widths.
1361 1.1 mrg ulong tbitsize = void;
1362 1.1 mrg if (auto bf = isBitFieldDeclaration())
1363 1.1 mrg {
1364 1.1 mrg bitoffset += bf.bitOffset;
1365 1.1 mrg tbitsize = bf.fieldWidth;
1366 1.1 mrg }
1367 1.1 mrg else
1368 1.1 mrg tbitsize = tsz * 8;
1369 1.1 mrg
1370 1.1 mrg ulong vbitsize = void;
1371 1.1 mrg if (auto vbf = v.isBitFieldDeclaration())
1372 1.1 mrg {
1373 1.1 mrg vbitoffset += vbf.bitOffset;
1374 1.1 mrg vbitsize = vbf.fieldWidth;
1375 1.1 mrg }
1376 1.1 mrg else
1377 1.1 mrg vbitsize = vsz * 8;
1378 1.1 mrg
1379 1.1 mrg return bitoffset < vbitoffset + vbitsize &&
1380 1.1 mrg vbitoffset < bitoffset + tbitsize;
1381 1.1 mrg }
1382 1.1 mrg
1383 1.1 mrg override final bool hasPointers()
1384 1.1 mrg {
1385 1.1 mrg //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type.ty);
1386 1.1 mrg return (!isDataseg() && type.hasPointers());
1387 1.1 mrg }
1388 1.1 mrg
1389 1.1 mrg /*************************************
1390 1.1 mrg * Return true if we can take the address of this variable.
1391 1.1 mrg */
1392 1.1 mrg final bool canTakeAddressOf()
1393 1.1 mrg {
1394 1.1 mrg return !(storage_class & STC.manifest);
1395 1.1 mrg }
1396 1.1 mrg
1397 1.1 mrg /******************************************
1398 1.1 mrg * Return true if variable needs to call the destructor.
1399 1.1 mrg */
1400 1.1 mrg final bool needsScopeDtor()
1401 1.1 mrg {
1402 1.1 mrg //printf("VarDeclaration::needsScopeDtor() %s\n", toChars());
1403 1.1 mrg return edtor && !(storage_class & STC.nodtor);
1404 1.1 mrg }
1405 1.1 mrg
1406 1.1 mrg /******************************************
1407 1.1 mrg * If a variable has a scope destructor call, return call for it.
1408 1.1 mrg * Otherwise, return NULL.
1409 1.1 mrg */
1410 1.1 mrg extern (D) final Expression callScopeDtor(Scope* sc)
1411 1.1 mrg {
1412 1.1 mrg //printf("VarDeclaration::callScopeDtor() %s\n", toChars());
1413 1.1 mrg
1414 1.1 mrg // Destruction of STC.field's is handled by buildDtor()
1415 1.1 mrg if (storage_class & (STC.nodtor | STC.ref_ | STC.out_ | STC.field))
1416 1.1 mrg {
1417 1.1 mrg return null;
1418 1.1 mrg }
1419 1.1 mrg
1420 1.1 mrg if (iscatchvar)
1421 1.1 mrg return null; // destructor is built by `void semantic(Catch c, Scope* sc)`, not here
1422 1.1 mrg
1423 1.1 mrg Expression e = null;
1424 1.1 mrg // Destructors for structs and arrays of structs
1425 1.1 mrg Type tv = type.baseElemOf();
1426 1.1 mrg if (tv.ty == Tstruct)
1427 1.1 mrg {
1428 1.1 mrg StructDeclaration sd = (cast(TypeStruct)tv).sym;
1429 1.1 mrg if (!sd.dtor || sd.errors)
1430 1.1 mrg return null;
1431 1.1 mrg
1432 1.1 mrg const sz = type.size();
1433 1.1 mrg assert(sz != SIZE_INVALID);
1434 1.1 mrg if (!sz)
1435 1.1 mrg return null;
1436 1.1 mrg
1437 1.1 mrg if (type.toBasetype().ty == Tstruct)
1438 1.1 mrg {
1439 1.1 mrg // v.__xdtor()
1440 1.1 mrg e = new VarExp(loc, this);
1441 1.1 mrg
1442 1.1 mrg /* This is a hack so we can call destructors on const/immutable objects.
1443 1.1 mrg * Need to add things like "const ~this()" and "immutable ~this()" to
1444 1.1 mrg * fix properly.
1445 1.1 mrg */
1446 1.1 mrg e.type = e.type.mutableOf();
1447 1.1 mrg
1448 1.1 mrg // Enable calling destructors on shared objects.
1449 1.1 mrg // The destructor is always a single, non-overloaded function,
1450 1.1 mrg // and must serve both shared and non-shared objects.
1451 1.1 mrg e.type = e.type.unSharedOf;
1452 1.1 mrg
1453 1.1 mrg e = new DotVarExp(loc, e, sd.dtor, false);
1454 1.1 mrg e = new CallExp(loc, e);
1455 1.1 mrg }
1456 1.1 mrg else
1457 1.1 mrg {
1458 1.1 mrg // __ArrayDtor(v[0 .. n])
1459 1.1 mrg e = new VarExp(loc, this);
1460 1.1 mrg
1461 1.1 mrg const sdsz = sd.type.size();
1462 1.1 mrg assert(sdsz != SIZE_INVALID && sdsz != 0);
1463 1.1 mrg const n = sz / sdsz;
1464 1.1 mrg SliceExp se = new SliceExp(loc, e, new IntegerExp(loc, 0, Type.tsize_t),
1465 1.1 mrg new IntegerExp(loc, n, Type.tsize_t));
1466 1.1 mrg
1467 1.1 mrg // Prevent redundant bounds check
1468 1.1 mrg se.upperIsInBounds = true;
1469 1.1 mrg se.lowerIsLessThanUpper = true;
1470 1.1 mrg
1471 1.1 mrg // This is a hack so we can call destructors on const/immutable objects.
1472 1.1 mrg se.type = sd.type.arrayOf();
1473 1.1 mrg
1474 1.1 mrg e = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se);
1475 1.1 mrg }
1476 1.1 mrg return e;
1477 1.1 mrg }
1478 1.1 mrg // Destructors for classes
1479 1.1 mrg if (storage_class & (STC.auto_ | STC.scope_) && !(storage_class & STC.parameter))
1480 1.1 mrg {
1481 1.1 mrg for (ClassDeclaration cd = type.isClassHandle(); cd; cd = cd.baseClass)
1482 1.1 mrg {
1483 1.1 mrg /* We can do better if there's a way with onstack
1484 1.1 mrg * classes to determine if there's no way the monitor
1485 1.1 mrg * could be set.
1486 1.1 mrg */
1487 1.1 mrg //if (cd.isInterfaceDeclaration())
1488 1.1 mrg // error("interface `%s` cannot be scope", cd.toChars());
1489 1.1 mrg
1490 1.1 mrg if (onstack) // if any destructors
1491 1.1 mrg {
1492 1.1 mrg // delete'ing C++ classes crashes (and delete is deprecated anyway)
1493 1.1 mrg if (cd.classKind == ClassKind.cpp)
1494 1.1 mrg {
1495 1.1 mrg // Don't call non-existant dtor
1496 1.1 mrg if (!cd.dtor)
1497 1.1 mrg break;
1498 1.1 mrg
1499 1.1 mrg e = new VarExp(loc, this);
1500 1.1 mrg e.type = e.type.mutableOf().unSharedOf(); // Hack for mutable ctor on immutable instances
1501 1.1 mrg e = new DotVarExp(loc, e, cd.dtor, false);
1502 1.1 mrg e = new CallExp(loc, e);
1503 1.1 mrg break;
1504 1.1 mrg }
1505 1.1 mrg
1506 1.1 mrg // delete this;
1507 1.1 mrg Expression ec;
1508 1.1 mrg ec = new VarExp(loc, this);
1509 1.1 mrg e = new DeleteExp(loc, ec, true);
1510 1.1 mrg e.type = Type.tvoid;
1511 1.1 mrg break;
1512 1.1 mrg }
1513 1.1 mrg }
1514 1.1 mrg }
1515 1.1 mrg return e;
1516 1.1 mrg }
1517 1.1 mrg
1518 1.1 mrg /*******************************************
1519 1.1 mrg * If variable has a constant expression initializer, get it.
1520 1.1 mrg * Otherwise, return null.
1521 1.1 mrg */
1522 1.1 mrg extern (D) final Expression getConstInitializer(bool needFullType = true)
1523 1.1 mrg {
1524 1.1 mrg assert(type && _init);
1525 1.1 mrg
1526 1.1 mrg // Ungag errors when not speculative
1527 1.1 mrg uint oldgag = global.gag;
1528 1.1 mrg if (global.gag)
1529 1.1 mrg {
1530 1.1 mrg Dsymbol sym = toParent().isAggregateDeclaration();
1531 1.1 mrg if (sym && !sym.isSpeculative())
1532 1.1 mrg global.gag = 0;
1533 1.1 mrg }
1534 1.1 mrg
1535 1.1 mrg if (_scope)
1536 1.1 mrg {
1537 1.1 mrg inuse++;
1538 1.1 mrg _init = _init.initializerSemantic(_scope, type, INITinterpret);
1539 1.1 mrg _scope = null;
1540 1.1 mrg inuse--;
1541 1.1 mrg }
1542 1.1 mrg
1543 1.1 mrg Expression e = _init.initializerToExpression(needFullType ? type : null);
1544 1.1 mrg global.gag = oldgag;
1545 1.1 mrg return e;
1546 1.1 mrg }
1547 1.1 mrg
1548 1.1 mrg /*******************************************
1549 1.1 mrg * Helper function for the expansion of manifest constant.
1550 1.1 mrg */
1551 1.1 mrg extern (D) final Expression expandInitializer(Loc loc)
1552 1.1 mrg {
1553 1.1 mrg assert((storage_class & STC.manifest) && _init);
1554 1.1 mrg
1555 1.1 mrg auto e = getConstInitializer();
1556 1.1 mrg if (!e)
1557 1.1 mrg {
1558 1.1 mrg .error(loc, "cannot make expression out of initializer for `%s`", toChars());
1559 1.1 mrg return ErrorExp.get();
1560 1.1 mrg }
1561 1.1 mrg
1562 1.1 mrg e = e.copy();
1563 1.1 mrg e.loc = loc; // for better error message
1564 1.1 mrg return e;
1565 1.1 mrg }
1566 1.1 mrg
1567 1.1 mrg override final void checkCtorConstInit()
1568 1.1 mrg {
1569 1.1 mrg version (none)
1570 1.1 mrg {
1571 1.1 mrg /* doesn't work if more than one static ctor */
1572 1.1 mrg if (ctorinit == 0 && isCtorinit() && !isField())
1573 1.1 mrg error("missing initializer in static constructor for const variable");
1574 1.1 mrg }
1575 1.1 mrg }
1576 1.1 mrg
1577 1.1 mrg /************************************
1578 1.1 mrg * Check to see if this variable is actually in an enclosing function
1579 1.1 mrg * rather than the current one.
1580 1.1 mrg * Update nestedrefs[], closureVars[] and outerVars[].
1581 1.1 mrg * Returns: true if error occurs.
1582 1.1 mrg */
1583 1.1 mrg extern (D) final bool checkNestedReference(Scope* sc, Loc loc)
1584 1.1 mrg {
1585 1.1 mrg //printf("VarDeclaration::checkNestedReference() %s\n", toChars());
1586 1.1 mrg if (sc.intypeof == 1 || (sc.flags & SCOPE.ctfe))
1587 1.1 mrg return false;
1588 1.1 mrg if (!parent || parent == sc.parent)
1589 1.1 mrg return false;
1590 1.1 mrg if (isDataseg() || (storage_class & STC.manifest))
1591 1.1 mrg return false;
1592 1.1 mrg
1593 1.1 mrg // The current function
1594 1.1 mrg FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
1595 1.1 mrg if (!fdthis)
1596 1.1 mrg return false; // out of function scope
1597 1.1 mrg
1598 1.1 mrg Dsymbol p = toParent2();
1599 1.1 mrg
1600 1.1 mrg // Function literals from fdthis to p must be delegates
1601 1.1 mrg ensureStaticLinkTo(fdthis, p);
1602 1.1 mrg
1603 1.1 mrg // The function that this variable is in
1604 1.1 mrg FuncDeclaration fdv = p.isFuncDeclaration();
1605 1.1 mrg if (!fdv || fdv == fdthis)
1606 1.1 mrg return false;
1607 1.1 mrg
1608 1.1 mrg // Add fdthis to nestedrefs[] if not already there
1609 1.1 mrg if (!nestedrefs.contains(fdthis))
1610 1.1 mrg nestedrefs.push(fdthis);
1611 1.1 mrg
1612 1.1 mrg //printf("\tfdv = %s\n", fdv.toChars());
1613 1.1 mrg //printf("\tfdthis = %s\n", fdthis.toChars());
1614 1.1 mrg if (loc.isValid())
1615 1.1 mrg {
1616 1.1 mrg if (fdthis.getLevelAndCheck(loc, sc, fdv, this) == fdthis.LevelError)
1617 1.1 mrg return true;
1618 1.1 mrg }
1619 1.1 mrg
1620 1.1 mrg // Add this VarDeclaration to fdv.closureVars[] if not already there
1621 1.1 mrg if (!sc.intypeof && !(sc.flags & SCOPE.compile) &&
1622 1.1 mrg // https://issues.dlang.org/show_bug.cgi?id=17605
1623 1.1 mrg (fdv.flags & FUNCFLAG.compileTimeOnly || !(fdthis.flags & FUNCFLAG.compileTimeOnly))
1624 1.1 mrg )
1625 1.1 mrg {
1626 1.1 mrg if (!fdv.closureVars.contains(this))
1627 1.1 mrg fdv.closureVars.push(this);
1628 1.1 mrg }
1629 1.1 mrg
1630 1.1 mrg if (!fdthis.outerVars.contains(this))
1631 1.1 mrg fdthis.outerVars.push(this);
1632 1.1 mrg
1633 1.1 mrg //printf("fdthis is %s\n", fdthis.toChars());
1634 1.1 mrg //printf("var %s in function %s is nested ref\n", toChars(), fdv.toChars());
1635 1.1 mrg // __dollar creates problems because it isn't a real variable
1636 1.1 mrg // https://issues.dlang.org/show_bug.cgi?id=3326
1637 1.1 mrg if (ident == Id.dollar)
1638 1.1 mrg {
1639 1.1 mrg .error(loc, "cannnot use `$` inside a function literal");
1640 1.1 mrg return true;
1641 1.1 mrg }
1642 1.1 mrg if (ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759
1643 1.1 mrg {
1644 1.1 mrg ExpInitializer ez = _init.isExpInitializer();
1645 1.1 mrg assert(ez);
1646 1.1 mrg Expression e = ez.exp;
1647 1.1 mrg if (e.op == EXP.construct || e.op == EXP.blit)
1648 1.1 mrg e = (cast(AssignExp)e).e2;
1649 1.1 mrg return lambdaCheckForNestedRef(e, sc);
1650 1.1 mrg }
1651 1.1 mrg
1652 1.1 mrg return false;
1653 1.1 mrg }
1654 1.1 mrg
1655 1.1 mrg override final Dsymbol toAlias()
1656 1.1 mrg {
1657 1.1 mrg //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1658 1.1 mrg if ((!type || !type.deco) && _scope)
1659 1.1 mrg dsymbolSemantic(this, _scope);
1660 1.1 mrg
1661 1.1 mrg assert(this != aliassym);
1662 1.1 mrg Dsymbol s = aliassym ? aliassym.toAlias() : this;
1663 1.1 mrg return s;
1664 1.1 mrg }
1665 1.1 mrg
1666 1.1 mrg // Eliminate need for dynamic_cast
1667 1.1 mrg override final inout(VarDeclaration) isVarDeclaration() inout
1668 1.1 mrg {
1669 1.1 mrg return this;
1670 1.1 mrg }
1671 1.1 mrg
1672 1.1 mrg override void accept(Visitor v)
1673 1.1 mrg {
1674 1.1 mrg v.visit(this);
1675 1.1 mrg }
1676 1.1 mrg }
1677 1.1 mrg
1678 1.1 mrg /*******************************************************
1679 1.1 mrg * C11 6.7.2.1-4 bit fields
1680 1.1 mrg */
1681 1.1 mrg extern (C++) class BitFieldDeclaration : VarDeclaration
1682 1.1 mrg {
1683 1.1 mrg Expression width;
1684 1.1 mrg
1685 1.1 mrg uint fieldWidth;
1686 1.1 mrg uint bitOffset;
1687 1.1 mrg
1688 1.1 mrg final extern (D) this(const ref Loc loc, Type type, Identifier ident, Expression width)
1689 1.1 mrg {
1690 1.1 mrg super(loc, type, ident, null);
1691 1.1 mrg
1692 1.1 mrg this.width = width;
1693 1.1 mrg this.storage_class |= STC.field;
1694 1.1 mrg }
1695 1.1 mrg
1696 1.1 mrg override BitFieldDeclaration syntaxCopy(Dsymbol s)
1697 1.1 mrg {
1698 1.1 mrg //printf("BitFieldDeclaration::syntaxCopy(%s)\n", toChars());
1699 1.1 mrg assert(!s);
1700 1.1 mrg auto bf = new BitFieldDeclaration(loc, type ? type.syntaxCopy() : null, ident, width.syntaxCopy());
1701 1.1 mrg bf.comment = comment;
1702 1.1 mrg return bf;
1703 1.1 mrg }
1704 1.1 mrg
1705 1.1 mrg override final inout(BitFieldDeclaration) isBitFieldDeclaration() inout
1706 1.1 mrg {
1707 1.1 mrg return this;
1708 1.1 mrg }
1709 1.1 mrg
1710 1.1 mrg override void accept(Visitor v)
1711 1.1 mrg {
1712 1.1 mrg v.visit(this);
1713 1.1 mrg }
1714 1.1 mrg
1715 1.1 mrg override final void setFieldOffset(AggregateDeclaration ad, ref FieldState fieldState, bool isunion)
1716 1.1 mrg {
1717 1.1 mrg //printf("BitFieldDeclaration::setFieldOffset(ad: %s, field: %s)\n", ad.toChars(), toChars());
1718 1.1 mrg static void print(const ref FieldState fieldState)
1719 1.1 mrg {
1720 1.1 mrg printf("FieldState.offset = %d bytes\n", fieldState.offset);
1721 1.1 mrg printf(" .fieldOffset = %d bytes\n", fieldState.fieldOffset);
1722 1.1 mrg printf(" .bitOffset = %d bits\n", fieldState.bitOffset);
1723 1.1 mrg printf(" .fieldSize = %d bytes\n", fieldState.fieldSize);
1724 1.1 mrg printf(" .inFlight = %d\n\n", fieldState.inFlight);
1725 1.1 mrg }
1726 1.1 mrg //print(fieldState);
1727 1.1 mrg
1728 1.1 mrg Type t = type.toBasetype();
1729 1.1 mrg const bool anon = isAnonymous();
1730 1.1 mrg
1731 1.1 mrg // List in ad.fields. Even if the type is error, it's necessary to avoid
1732 1.1 mrg // pointless error diagnostic "more initializers than fields" on struct literal.
1733 1.1 mrg if (!anon)
1734 1.1 mrg ad.fields.push(this);
1735 1.1 mrg
1736 1.1 mrg if (t.ty == Terror)
1737 1.1 mrg return;
1738 1.1 mrg
1739 1.1 mrg const sz = t.size(loc);
1740 1.1 mrg assert(sz != SIZE_INVALID && sz < uint.max);
1741 1.1 mrg uint memsize = cast(uint)sz; // size of member
1742 1.1 mrg uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
1743 1.1 mrg
1744 1.1 mrg if (fieldWidth == 0 && !anon)
1745 1.1 mrg error(loc, "named bit fields cannot have 0 width");
1746 1.1 mrg if (fieldWidth > memsize * 8)
1747 1.1 mrg error(loc, "bit field width %d is larger than type", fieldWidth);
1748 1.1 mrg
1749 1.1 mrg const style = target.c.bitFieldStyle;
1750 1.1 mrg
1751 1.1 mrg void startNewField()
1752 1.1 mrg {
1753 1.1 mrg uint alignsize;
1754 1.1 mrg if (style == TargetC.BitFieldStyle.Gcc_Clang)
1755 1.1 mrg {
1756 1.1 mrg if (fieldWidth > 32)
1757 1.1 mrg alignsize = memalignsize;
1758 1.1 mrg else if (fieldWidth > 16)
1759 1.1 mrg alignsize = 4;
1760 1.1 mrg else if (fieldWidth > 8)
1761 1.1 mrg alignsize = 2;
1762 1.1 mrg else
1763 1.1 mrg alignsize = 1;
1764 1.1 mrg }
1765 1.1 mrg else
1766 1.1 mrg alignsize = memsize; // not memalignsize
1767 1.1 mrg
1768 1.1 mrg uint dummy;
1769 1.1 mrg offset = AggregateDeclaration.placeField(
1770 1.1 mrg &fieldState.offset,
1771 1.1 mrg memsize, alignsize, alignment,
1772 1.1 mrg &ad.structsize,
1773 1.1 mrg (anon && style == TargetC.BitFieldStyle.Gcc_Clang) ? &dummy : &ad.alignsize,
1774 1.1 mrg isunion);
1775 1.1 mrg
1776 1.1 mrg fieldState.inFlight = true;
1777 1.1 mrg fieldState.fieldOffset = offset;
1778 1.1 mrg fieldState.bitOffset = 0;
1779 1.1 mrg fieldState.fieldSize = memsize;
1780 1.1 mrg }
1781 1.1 mrg
1782 1.1 mrg if (style == TargetC.BitFieldStyle.Gcc_Clang)
1783 1.1 mrg {
1784 1.1 mrg if (fieldWidth == 0)
1785 1.1 mrg {
1786 1.1 mrg if (!isunion)
1787 1.1 mrg {
1788 1.1 mrg // Use type of zero width field to align to next field
1789 1.1 mrg fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
1790 1.1 mrg ad.structsize = fieldState.offset;
1791 1.1 mrg }
1792 1.1 mrg
1793 1.1 mrg fieldState.inFlight = false;
1794 1.1 mrg return;
1795 1.1 mrg }
1796 1.1 mrg
1797 1.1 mrg if (ad.alignsize == 0)
1798 1.1 mrg ad.alignsize = 1;
1799 1.1 mrg if (!anon &&
1800 1.1 mrg ad.alignsize < memalignsize)
1801 1.1 mrg ad.alignsize = memalignsize;
1802 1.1 mrg }
1803 1.1 mrg else if (style == TargetC.BitFieldStyle.MS)
1804 1.1 mrg {
1805 1.1 mrg if (ad.alignsize == 0)
1806 1.1 mrg ad.alignsize = 1;
1807 1.1 mrg if (fieldWidth == 0)
1808 1.1 mrg {
1809 1.1 mrg if (fieldState.inFlight && !isunion)
1810 1.1 mrg {
1811 1.1 mrg // documentation says align to next int
1812 1.1 mrg //const alsz = cast(uint)Type.tint32.size();
1813 1.1 mrg const alsz = memsize; // but it really does this
1814 1.1 mrg fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
1815 1.1 mrg ad.structsize = fieldState.offset;
1816 1.1 mrg }
1817 1.1 mrg
1818 1.1 mrg fieldState.inFlight = false;
1819 1.1 mrg return;
1820 1.1 mrg }
1821 1.1 mrg }
1822 1.1 mrg else if (style == TargetC.BitFieldStyle.DM)
1823 1.1 mrg {
1824 1.1 mrg if (anon && fieldWidth && (!fieldState.inFlight || fieldState.bitOffset == 0))
1825 1.1 mrg return; // this probably should be a bug in DMC
1826 1.1 mrg if (ad.alignsize == 0)
1827 1.1 mrg ad.alignsize = 1;
1828 1.1 mrg if (fieldWidth == 0)
1829 1.1 mrg {
1830 1.1 mrg if (fieldState.inFlight && !isunion)
1831 1.1 mrg {
1832 1.1 mrg const alsz = memsize;
1833 1.1 mrg fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
1834 1.1 mrg ad.structsize = fieldState.offset;
1835 1.1 mrg }
1836 1.1 mrg
1837 1.1 mrg fieldState.inFlight = false;
1838 1.1 mrg return;
1839 1.1 mrg }
1840 1.1 mrg }
1841 1.1 mrg
1842 1.1 mrg if (!fieldState.inFlight)
1843 1.1 mrg {
1844 1.1 mrg startNewField();
1845 1.1 mrg }
1846 1.1 mrg else if (style == TargetC.BitFieldStyle.Gcc_Clang)
1847 1.1 mrg {
1848 1.1 mrg if (fieldState.bitOffset + fieldWidth > memsize * 8)
1849 1.1 mrg {
1850 1.1 mrg //printf("start1 fieldState.bitOffset:%u fieldWidth:%u memsize:%u\n", fieldState.bitOffset, fieldWidth, memsize);
1851 1.1 mrg startNewField();
1852 1.1 mrg }
1853 1.1 mrg else
1854 1.1 mrg {
1855 1.1 mrg // if alignment boundary is crossed
1856 1.1 mrg uint start = fieldState.fieldOffset * 8 + fieldState.bitOffset;
1857 1.1 mrg uint end = start + fieldWidth;
1858 1.1 mrg //printf("%s start: %d end: %d memalignsize: %d\n", ad.toChars(), start, end, memalignsize);
1859 1.1 mrg if (start / (memalignsize * 8) != (end - 1) / (memalignsize * 8))
1860 1.1 mrg {
1861 1.1 mrg //printf("alignment is crossed\n");
1862 1.1 mrg startNewField();
1863 1.1 mrg }
1864 1.1 mrg }
1865 1.1 mrg }
1866 1.1 mrg else if (style == TargetC.BitFieldStyle.DM ||
1867 1.1 mrg style == TargetC.BitFieldStyle.MS)
1868 1.1 mrg {
1869 1.1 mrg if (memsize != fieldState.fieldSize ||
1870 1.1 mrg fieldState.bitOffset + fieldWidth > fieldState.fieldSize * 8)
1871 1.1 mrg {
1872 1.1 mrg startNewField();
1873 1.1 mrg }
1874 1.1 mrg }
1875 1.1 mrg else
1876 1.1 mrg assert(0);
1877 1.1 mrg
1878 1.1 mrg offset = fieldState.fieldOffset;
1879 1.1 mrg bitOffset = fieldState.bitOffset;
1880 1.1 mrg
1881 1.1 mrg const pastField = bitOffset + fieldWidth;
1882 1.1 mrg if (style == TargetC.BitFieldStyle.Gcc_Clang)
1883 1.1 mrg {
1884 1.1 mrg auto size = (pastField + 7) / 8;
1885 1.1 mrg fieldState.fieldSize = size;
1886 1.1 mrg //printf(" offset: %d, size: %d\n", offset, size);
1887 1.1 mrg ad.structsize = offset + size;
1888 1.1 mrg }
1889 1.1 mrg else
1890 1.1 mrg fieldState.fieldSize = memsize;
1891 1.1 mrg //printf("at end: ad.structsize = %d\n", cast(int)ad.structsize);
1892 1.1 mrg //print(fieldState);
1893 1.1 mrg
1894 1.1 mrg if (!isunion)
1895 1.1 mrg {
1896 1.1 mrg fieldState.offset = offset + fieldState.fieldSize;
1897 1.1 mrg fieldState.bitOffset = pastField;
1898 1.1 mrg }
1899 1.1 mrg
1900 1.1 mrg //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize);
1901 1.1 mrg //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad.toChars(), offset, memsize);
1902 1.1 mrg }
1903 1.1 mrg }
1904 1.1 mrg
1905 1.1 mrg /***********************************************************
1906 1.1 mrg * This is a shell around a back end symbol
1907 1.1 mrg */
1908 1.1 mrg extern (C++) final class SymbolDeclaration : Declaration
1909 1.1 mrg {
1910 1.1 mrg AggregateDeclaration dsym;
1911 1.1 mrg
1912 1.1 mrg extern (D) this(const ref Loc loc, AggregateDeclaration dsym)
1913 1.1 mrg {
1914 1.1 mrg super(loc, dsym.ident);
1915 1.1 mrg this.dsym = dsym;
1916 1.1 mrg storage_class |= STC.const_;
1917 1.1 mrg }
1918 1.1 mrg
1919 1.1 mrg // Eliminate need for dynamic_cast
1920 1.1 mrg override inout(SymbolDeclaration) isSymbolDeclaration() inout
1921 1.1 mrg {
1922 1.1 mrg return this;
1923 1.1 mrg }
1924 1.1 mrg
1925 1.1 mrg override void accept(Visitor v)
1926 1.1 mrg {
1927 1.1 mrg v.visit(this);
1928 1.1 mrg }
1929 1.1 mrg }
1930 1.1 mrg
1931 1.1 mrg /***********************************************************
1932 1.1 mrg */
1933 1.1 mrg extern (C++) class TypeInfoDeclaration : VarDeclaration
1934 1.1 mrg {
1935 1.1 mrg Type tinfo;
1936 1.1 mrg
1937 1.1 mrg final extern (D) this(Type tinfo)
1938 1.1 mrg {
1939 1.1 mrg super(Loc.initial, Type.dtypeinfo.type, tinfo.getTypeInfoIdent(), null);
1940 1.1 mrg this.tinfo = tinfo;
1941 1.1 mrg storage_class = STC.static_ | STC.gshared;
1942 1.1 mrg visibility = Visibility(Visibility.Kind.public_);
1943 1.1 mrg _linkage = LINK.c;
1944 1.1 mrg alignment.set(target.ptrsize);
1945 1.1 mrg }
1946 1.1 mrg
1947 1.1 mrg static TypeInfoDeclaration create(Type tinfo)
1948 1.1 mrg {
1949 1.1 mrg return new TypeInfoDeclaration(tinfo);
1950 1.1 mrg }
1951 1.1 mrg
1952 1.1 mrg override final TypeInfoDeclaration syntaxCopy(Dsymbol s)
1953 1.1 mrg {
1954 1.1 mrg assert(0); // should never be produced by syntax
1955 1.1 mrg }
1956 1.1 mrg
1957 1.1 mrg override final const(char)* toChars() const
1958 1.1 mrg {
1959 1.1 mrg //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo.toChars());
1960 1.1 mrg OutBuffer buf;
1961 1.1 mrg buf.writestring("typeid(");
1962 1.1 mrg buf.writestring(tinfo.toChars());
1963 1.1 mrg buf.writeByte(')');
1964 1.1 mrg return buf.extractChars();
1965 1.1 mrg }
1966 1.1 mrg
1967 1.1 mrg override final inout(TypeInfoDeclaration) isTypeInfoDeclaration() inout @nogc nothrow pure @safe
1968 1.1 mrg {
1969 1.1 mrg return this;
1970 1.1 mrg }
1971 1.1 mrg
1972 1.1 mrg override void accept(Visitor v)
1973 1.1 mrg {
1974 1.1 mrg v.visit(this);
1975 1.1 mrg }
1976 1.1 mrg }
1977 1.1 mrg
1978 1.1 mrg /***********************************************************
1979 1.1 mrg */
1980 1.1 mrg extern (C++) final class TypeInfoStructDeclaration : TypeInfoDeclaration
1981 1.1 mrg {
1982 1.1 mrg extern (D) this(Type tinfo)
1983 1.1 mrg {
1984 1.1 mrg super(tinfo);
1985 1.1 mrg if (!Type.typeinfostruct)
1986 1.1 mrg {
1987 1.1 mrg ObjectNotFound(Id.TypeInfo_Struct);
1988 1.1 mrg }
1989 1.1 mrg type = Type.typeinfostruct.type;
1990 1.1 mrg }
1991 1.1 mrg
1992 1.1 mrg static TypeInfoStructDeclaration create(Type tinfo)
1993 1.1 mrg {
1994 1.1 mrg return new TypeInfoStructDeclaration(tinfo);
1995 1.1 mrg }
1996 1.1 mrg
1997 1.1 mrg override void accept(Visitor v)
1998 1.1 mrg {
1999 1.1 mrg v.visit(this);
2000 1.1 mrg }
2001 1.1 mrg }
2002 1.1 mrg
2003 1.1 mrg /***********************************************************
2004 1.1 mrg */
2005 1.1 mrg extern (C++) final class TypeInfoClassDeclaration : TypeInfoDeclaration
2006 1.1 mrg {
2007 1.1 mrg extern (D) this(Type tinfo)
2008 1.1 mrg {
2009 1.1 mrg super(tinfo);
2010 1.1 mrg if (!Type.typeinfoclass)
2011 1.1 mrg {
2012 1.1 mrg ObjectNotFound(Id.TypeInfo_Class);
2013 1.1 mrg }
2014 1.1 mrg type = Type.typeinfoclass.type;
2015 1.1 mrg }
2016 1.1 mrg
2017 1.1 mrg static TypeInfoClassDeclaration create(Type tinfo)
2018 1.1 mrg {
2019 1.1 mrg return new TypeInfoClassDeclaration(tinfo);
2020 1.1 mrg }
2021 1.1 mrg
2022 1.1 mrg override void accept(Visitor v)
2023 1.1 mrg {
2024 1.1 mrg v.visit(this);
2025 1.1 mrg }
2026 1.1 mrg }
2027 1.1 mrg
2028 1.1 mrg /***********************************************************
2029 1.1 mrg */
2030 1.1 mrg extern (C++) final class TypeInfoInterfaceDeclaration : TypeInfoDeclaration
2031 1.1 mrg {
2032 1.1 mrg extern (D) this(Type tinfo)
2033 1.1 mrg {
2034 1.1 mrg super(tinfo);
2035 1.1 mrg if (!Type.typeinfointerface)
2036 1.1 mrg {
2037 1.1 mrg ObjectNotFound(Id.TypeInfo_Interface);
2038 1.1 mrg }
2039 1.1 mrg type = Type.typeinfointerface.type;
2040 1.1 mrg }
2041 1.1 mrg
2042 1.1 mrg static TypeInfoInterfaceDeclaration create(Type tinfo)
2043 1.1 mrg {
2044 1.1 mrg return new TypeInfoInterfaceDeclaration(tinfo);
2045 1.1 mrg }
2046 1.1 mrg
2047 1.1 mrg override void accept(Visitor v)
2048 1.1 mrg {
2049 1.1 mrg v.visit(this);
2050 1.1 mrg }
2051 1.1 mrg }
2052 1.1 mrg
2053 1.1 mrg /***********************************************************
2054 1.1 mrg */
2055 1.1 mrg extern (C++) final class TypeInfoPointerDeclaration : TypeInfoDeclaration
2056 1.1 mrg {
2057 1.1 mrg extern (D) this(Type tinfo)
2058 1.1 mrg {
2059 1.1 mrg super(tinfo);
2060 1.1 mrg if (!Type.typeinfopointer)
2061 1.1 mrg {
2062 1.1 mrg ObjectNotFound(Id.TypeInfo_Pointer);
2063 1.1 mrg }
2064 1.1 mrg type = Type.typeinfopointer.type;
2065 1.1 mrg }
2066 1.1 mrg
2067 1.1 mrg static TypeInfoPointerDeclaration create(Type tinfo)
2068 1.1 mrg {
2069 1.1 mrg return new TypeInfoPointerDeclaration(tinfo);
2070 1.1 mrg }
2071 1.1 mrg
2072 1.1 mrg override void accept(Visitor v)
2073 1.1 mrg {
2074 1.1 mrg v.visit(this);
2075 1.1 mrg }
2076 1.1 mrg }
2077 1.1 mrg
2078 1.1 mrg /***********************************************************
2079 1.1 mrg */
2080 1.1 mrg extern (C++) final class TypeInfoArrayDeclaration : TypeInfoDeclaration
2081 1.1 mrg {
2082 1.1 mrg extern (D) this(Type tinfo)
2083 1.1 mrg {
2084 1.1 mrg super(tinfo);
2085 1.1 mrg if (!Type.typeinfoarray)
2086 1.1 mrg {
2087 1.1 mrg ObjectNotFound(Id.TypeInfo_Array);
2088 1.1 mrg }
2089 1.1 mrg type = Type.typeinfoarray.type;
2090 1.1 mrg }
2091 1.1 mrg
2092 1.1 mrg static TypeInfoArrayDeclaration create(Type tinfo)
2093 1.1 mrg {
2094 1.1 mrg return new TypeInfoArrayDeclaration(tinfo);
2095 1.1 mrg }
2096 1.1 mrg
2097 1.1 mrg override void accept(Visitor v)
2098 1.1 mrg {
2099 1.1 mrg v.visit(this);
2100 1.1 mrg }
2101 1.1 mrg }
2102 1.1 mrg
2103 1.1 mrg /***********************************************************
2104 1.1 mrg */
2105 1.1 mrg extern (C++) final class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
2106 1.1 mrg {
2107 1.1 mrg extern (D) this(Type tinfo)
2108 1.1 mrg {
2109 1.1 mrg super(tinfo);
2110 1.1 mrg if (!Type.typeinfostaticarray)
2111 1.1 mrg {
2112 1.1 mrg ObjectNotFound(Id.TypeInfo_StaticArray);
2113 1.1 mrg }
2114 1.1 mrg type = Type.typeinfostaticarray.type;
2115 1.1 mrg }
2116 1.1 mrg
2117 1.1 mrg static TypeInfoStaticArrayDeclaration create(Type tinfo)
2118 1.1 mrg {
2119 1.1 mrg return new TypeInfoStaticArrayDeclaration(tinfo);
2120 1.1 mrg }
2121 1.1 mrg
2122 1.1 mrg override void accept(Visitor v)
2123 1.1 mrg {
2124 1.1 mrg v.visit(this);
2125 1.1 mrg }
2126 1.1 mrg }
2127 1.1 mrg
2128 1.1 mrg /***********************************************************
2129 1.1 mrg */
2130 1.1 mrg extern (C++) final class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
2131 1.1 mrg {
2132 1.1 mrg extern (D) this(Type tinfo)
2133 1.1 mrg {
2134 1.1 mrg super(tinfo);
2135 1.1 mrg if (!Type.typeinfoassociativearray)
2136 1.1 mrg {
2137 1.1 mrg ObjectNotFound(Id.TypeInfo_AssociativeArray);
2138 1.1 mrg }
2139 1.1 mrg type = Type.typeinfoassociativearray.type;
2140 1.1 mrg }
2141 1.1 mrg
2142 1.1 mrg static TypeInfoAssociativeArrayDeclaration create(Type tinfo)
2143 1.1 mrg {
2144 1.1 mrg return new TypeInfoAssociativeArrayDeclaration(tinfo);
2145 1.1 mrg }
2146 1.1 mrg
2147 1.1 mrg override void accept(Visitor v)
2148 1.1 mrg {
2149 1.1 mrg v.visit(this);
2150 1.1 mrg }
2151 1.1 mrg }
2152 1.1 mrg
2153 1.1 mrg /***********************************************************
2154 1.1 mrg */
2155 1.1 mrg extern (C++) final class TypeInfoEnumDeclaration : TypeInfoDeclaration
2156 1.1 mrg {
2157 1.1 mrg extern (D) this(Type tinfo)
2158 1.1 mrg {
2159 1.1 mrg super(tinfo);
2160 1.1 mrg if (!Type.typeinfoenum)
2161 1.1 mrg {
2162 1.1 mrg ObjectNotFound(Id.TypeInfo_Enum);
2163 1.1 mrg }
2164 1.1 mrg type = Type.typeinfoenum.type;
2165 1.1 mrg }
2166 1.1 mrg
2167 1.1 mrg static TypeInfoEnumDeclaration create(Type tinfo)
2168 1.1 mrg {
2169 1.1 mrg return new TypeInfoEnumDeclaration(tinfo);
2170 1.1 mrg }
2171 1.1 mrg
2172 1.1 mrg override void accept(Visitor v)
2173 1.1 mrg {
2174 1.1 mrg v.visit(this);
2175 1.1 mrg }
2176 1.1 mrg }
2177 1.1 mrg
2178 1.1 mrg /***********************************************************
2179 1.1 mrg */
2180 1.1 mrg extern (C++) final class TypeInfoFunctionDeclaration : TypeInfoDeclaration
2181 1.1 mrg {
2182 1.1 mrg extern (D) this(Type tinfo)
2183 1.1 mrg {
2184 1.1 mrg super(tinfo);
2185 1.1 mrg if (!Type.typeinfofunction)
2186 1.1 mrg {
2187 1.1 mrg ObjectNotFound(Id.TypeInfo_Function);
2188 1.1 mrg }
2189 1.1 mrg type = Type.typeinfofunction.type;
2190 1.1 mrg }
2191 1.1 mrg
2192 1.1 mrg static TypeInfoFunctionDeclaration create(Type tinfo)
2193 1.1 mrg {
2194 1.1 mrg return new TypeInfoFunctionDeclaration(tinfo);
2195 1.1 mrg }
2196 1.1 mrg
2197 1.1 mrg override void accept(Visitor v)
2198 1.1 mrg {
2199 1.1 mrg v.visit(this);
2200 1.1 mrg }
2201 1.1 mrg }
2202 1.1 mrg
2203 1.1 mrg /***********************************************************
2204 1.1 mrg */
2205 1.1 mrg extern (C++) final class TypeInfoDelegateDeclaration : TypeInfoDeclaration
2206 1.1 mrg {
2207 1.1 mrg extern (D) this(Type tinfo)
2208 1.1 mrg {
2209 1.1 mrg super(tinfo);
2210 1.1 mrg if (!Type.typeinfodelegate)
2211 1.1 mrg {
2212 1.1 mrg ObjectNotFound(Id.TypeInfo_Delegate);
2213 1.1 mrg }
2214 1.1 mrg type = Type.typeinfodelegate.type;
2215 1.1 mrg }
2216 1.1 mrg
2217 1.1 mrg static TypeInfoDelegateDeclaration create(Type tinfo)
2218 1.1 mrg {
2219 1.1 mrg return new TypeInfoDelegateDeclaration(tinfo);
2220 1.1 mrg }
2221 1.1 mrg
2222 1.1 mrg override void accept(Visitor v)
2223 1.1 mrg {
2224 1.1 mrg v.visit(this);
2225 1.1 mrg }
2226 1.1 mrg }
2227 1.1 mrg
2228 1.1 mrg /***********************************************************
2229 1.1 mrg */
2230 1.1 mrg extern (C++) final class TypeInfoTupleDeclaration : TypeInfoDeclaration
2231 1.1 mrg {
2232 1.1 mrg extern (D) this(Type tinfo)
2233 1.1 mrg {
2234 1.1 mrg super(tinfo);
2235 1.1 mrg if (!Type.typeinfotypelist)
2236 1.1 mrg {
2237 1.1 mrg ObjectNotFound(Id.TypeInfo_Tuple);
2238 1.1 mrg }
2239 1.1 mrg type = Type.typeinfotypelist.type;
2240 1.1 mrg }
2241 1.1 mrg
2242 1.1 mrg static TypeInfoTupleDeclaration create(Type tinfo)
2243 1.1 mrg {
2244 1.1 mrg return new TypeInfoTupleDeclaration(tinfo);
2245 1.1 mrg }
2246 1.1 mrg
2247 1.1 mrg override void accept(Visitor v)
2248 1.1 mrg {
2249 1.1 mrg v.visit(this);
2250 1.1 mrg }
2251 1.1 mrg }
2252 1.1 mrg
2253 1.1 mrg /***********************************************************
2254 1.1 mrg */
2255 1.1 mrg extern (C++) final class TypeInfoConstDeclaration : TypeInfoDeclaration
2256 1.1 mrg {
2257 1.1 mrg extern (D) this(Type tinfo)
2258 1.1 mrg {
2259 1.1 mrg super(tinfo);
2260 1.1 mrg if (!Type.typeinfoconst)
2261 1.1 mrg {
2262 1.1 mrg ObjectNotFound(Id.TypeInfo_Const);
2263 1.1 mrg }
2264 1.1 mrg type = Type.typeinfoconst.type;
2265 1.1 mrg }
2266 1.1 mrg
2267 1.1 mrg static TypeInfoConstDeclaration create(Type tinfo)
2268 1.1 mrg {
2269 1.1 mrg return new TypeInfoConstDeclaration(tinfo);
2270 1.1 mrg }
2271 1.1 mrg
2272 1.1 mrg override void accept(Visitor v)
2273 1.1 mrg {
2274 1.1 mrg v.visit(this);
2275 1.1 mrg }
2276 1.1 mrg }
2277 1.1 mrg
2278 1.1 mrg /***********************************************************
2279 1.1 mrg */
2280 1.1 mrg extern (C++) final class TypeInfoInvariantDeclaration : TypeInfoDeclaration
2281 1.1 mrg {
2282 1.1 mrg extern (D) this(Type tinfo)
2283 1.1 mrg {
2284 1.1 mrg super(tinfo);
2285 1.1 mrg if (!Type.typeinfoinvariant)
2286 1.1 mrg {
2287 1.1 mrg ObjectNotFound(Id.TypeInfo_Invariant);
2288 1.1 mrg }
2289 1.1 mrg type = Type.typeinfoinvariant.type;
2290 1.1 mrg }
2291 1.1 mrg
2292 1.1 mrg static TypeInfoInvariantDeclaration create(Type tinfo)
2293 1.1 mrg {
2294 1.1 mrg return new TypeInfoInvariantDeclaration(tinfo);
2295 1.1 mrg }
2296 1.1 mrg
2297 1.1 mrg override void accept(Visitor v)
2298 1.1 mrg {
2299 1.1 mrg v.visit(this);
2300 1.1 mrg }
2301 1.1 mrg }
2302 1.1 mrg
2303 1.1 mrg /***********************************************************
2304 1.1 mrg */
2305 1.1 mrg extern (C++) final class TypeInfoSharedDeclaration : TypeInfoDeclaration
2306 1.1 mrg {
2307 1.1 mrg extern (D) this(Type tinfo)
2308 1.1 mrg {
2309 1.1 mrg super(tinfo);
2310 1.1 mrg if (!Type.typeinfoshared)
2311 1.1 mrg {
2312 1.1 mrg ObjectNotFound(Id.TypeInfo_Shared);
2313 1.1 mrg }
2314 1.1 mrg type = Type.typeinfoshared.type;
2315 1.1 mrg }
2316 1.1 mrg
2317 1.1 mrg static TypeInfoSharedDeclaration create(Type tinfo)
2318 1.1 mrg {
2319 1.1 mrg return new TypeInfoSharedDeclaration(tinfo);
2320 1.1 mrg }
2321 1.1 mrg
2322 1.1 mrg override void accept(Visitor v)
2323 1.1 mrg {
2324 1.1 mrg v.visit(this);
2325 1.1 mrg }
2326 1.1 mrg }
2327 1.1 mrg
2328 1.1 mrg /***********************************************************
2329 1.1 mrg */
2330 1.1 mrg extern (C++) final class TypeInfoWildDeclaration : TypeInfoDeclaration
2331 1.1 mrg {
2332 1.1 mrg extern (D) this(Type tinfo)
2333 1.1 mrg {
2334 1.1 mrg super(tinfo);
2335 1.1 mrg if (!Type.typeinfowild)
2336 1.1 mrg {
2337 1.1 mrg ObjectNotFound(Id.TypeInfo_Wild);
2338 1.1 mrg }
2339 1.1 mrg type = Type.typeinfowild.type;
2340 1.1 mrg }
2341 1.1 mrg
2342 1.1 mrg static TypeInfoWildDeclaration create(Type tinfo)
2343 1.1 mrg {
2344 1.1 mrg return new TypeInfoWildDeclaration(tinfo);
2345 1.1 mrg }
2346 1.1 mrg
2347 1.1 mrg override void accept(Visitor v)
2348 1.1 mrg {
2349 1.1 mrg v.visit(this);
2350 1.1 mrg }
2351 1.1 mrg }
2352 1.1 mrg
2353 1.1 mrg /***********************************************************
2354 1.1 mrg */
2355 1.1 mrg extern (C++) final class TypeInfoVectorDeclaration : TypeInfoDeclaration
2356 1.1 mrg {
2357 1.1 mrg extern (D) this(Type tinfo)
2358 1.1 mrg {
2359 1.1 mrg super(tinfo);
2360 1.1 mrg if (!Type.typeinfovector)
2361 1.1 mrg {
2362 1.1 mrg ObjectNotFound(Id.TypeInfo_Vector);
2363 1.1 mrg }
2364 1.1 mrg type = Type.typeinfovector.type;
2365 1.1 mrg }
2366 1.1 mrg
2367 1.1 mrg static TypeInfoVectorDeclaration create(Type tinfo)
2368 1.1 mrg {
2369 1.1 mrg return new TypeInfoVectorDeclaration(tinfo);
2370 1.1 mrg }
2371 1.1 mrg
2372 1.1 mrg override void accept(Visitor v)
2373 1.1 mrg {
2374 1.1 mrg v.visit(this);
2375 1.1 mrg }
2376 1.1 mrg }
2377 1.1 mrg
2378 1.1 mrg /***********************************************************
2379 1.1 mrg * For the "this" parameter to member functions
2380 1.1 mrg */
2381 1.1 mrg extern (C++) final class ThisDeclaration : VarDeclaration
2382 1.1 mrg {
2383 1.1 mrg extern (D) this(const ref Loc loc, Type t)
2384 1.1 mrg {
2385 1.1 mrg super(loc, t, Id.This, null);
2386 1.1 mrg storage_class |= STC.nodtor;
2387 1.1 mrg }
2388 1.1 mrg
2389 1.1 mrg override ThisDeclaration syntaxCopy(Dsymbol s)
2390 1.1 mrg {
2391 1.1 mrg assert(0); // should never be produced by syntax
2392 1.1 mrg }
2393 1.1 mrg
2394 1.1 mrg override inout(ThisDeclaration) isThisDeclaration() inout
2395 1.1 mrg {
2396 1.1 mrg return this;
2397 1.1 mrg }
2398 1.1 mrg
2399 1.1 mrg override void accept(Visitor v)
2400 1.1 mrg {
2401 1.1 mrg v.visit(this);
2402 1.1 mrg }
2403 1.1 mrg }
2404