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