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