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