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