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