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