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