1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://www.boost.org/LICENSE_1_0.txt 8 * https://github.com/D-Programming-Language/dmd/blob/master/src/module.c 9 */ 10 11 #include "root/dsystem.h" 12 #include "root/rmem.h" 13 14 #include "mars.h" 15 #include "module.h" 16 #include "parse.h" 17 #include "scope.h" 18 #include "identifier.h" 19 #include "id.h" 20 #include "import.h" 21 #include "dsymbol.h" 22 #include "expression.h" 23 #include "lexer.h" 24 #include "attrib.h" 25 26 AggregateDeclaration *Module::moduleinfo; 27 28 Module *Module::rootModule; 29 DsymbolTable *Module::modules; 30 Modules Module::amodules; 31 32 Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them 33 Dsymbols Module::deferred2; // deferred Dsymbol's needing semantic2() run on them 34 Dsymbols Module::deferred3; // deferred Dsymbol's needing semantic3() run on them 35 unsigned Module::dprogress; 36 37 const char *lookForSourceFile(const char **path, const char *filename); 38 StringExp *semanticString(Scope *sc, Expression *exp, const char *s); 39 40 void Module::_init() 41 { 42 modules = new DsymbolTable(); 43 } 44 45 Module::Module(const char *filename, Identifier *ident, int doDocComment, int doHdrGen) 46 : Package(ident) 47 { 48 const char *srcfilename; 49 50 // printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars()); 51 this->arg = filename; 52 md = NULL; 53 errors = 0; 54 numlines = 0; 55 members = NULL; 56 isDocFile = 0; 57 isPackageFile = false; 58 needmoduleinfo = 0; 59 selfimports = 0; 60 rootimports = 0; 61 insearch = 0; 62 searchCacheIdent = NULL; 63 searchCacheSymbol = NULL; 64 searchCacheFlags = 0; 65 decldefs = NULL; 66 sictor = NULL; 67 sctor = NULL; 68 sdtor = NULL; 69 ssharedctor = NULL; 70 sshareddtor = NULL; 71 stest = NULL; 72 sfilename = NULL; 73 importedFrom = NULL; 74 srcfile = NULL; 75 srcfilePath = NULL; 76 docfile = NULL; 77 78 debuglevel = 0; 79 debugids = NULL; 80 debugidsNot = NULL; 81 versionlevel = 0; 82 versionids = NULL; 83 versionidsNot = NULL; 84 85 macrotable = NULL; 86 escapetable = NULL; 87 doppelganger = 0; 88 cov = NULL; 89 covb = NULL; 90 91 nameoffset = 0; 92 namelen = 0; 93 94 srcfilename = FileName::defaultExt(filename, global.mars_ext); 95 96 if (global.run_noext && global.params.run && 97 !FileName::ext(filename) && 98 FileName::exists(srcfilename) == 0 && 99 FileName::exists(filename) == 1) 100 { 101 FileName::free(srcfilename); 102 srcfilename = FileName::removeExt(filename); // just does a mem.strdup(filename) 103 } 104 else if (!FileName::equalsExt(srcfilename, global.mars_ext) && 105 !FileName::equalsExt(srcfilename, global.hdr_ext) && 106 !FileName::equalsExt(srcfilename, "dd")) 107 { 108 error("source file name '%s' must have .%s extension", srcfilename, global.mars_ext); 109 fatal(); 110 } 111 srcfile = new File(srcfilename); 112 if (!FileName::absolute(srcfilename)) 113 srcfilePath = getcwd(NULL, 0); 114 115 objfile = setOutfile(global.params.objname, global.params.objdir, filename, global.obj_ext); 116 117 if (doDocComment) 118 setDocfile(); 119 120 if (doHdrGen) 121 hdrfile = setOutfile(global.params.hdrname, global.params.hdrdir, arg, global.hdr_ext); 122 123 //objfile = new File(objfilename); 124 } 125 126 Module *Module::create(const char *filename, Identifier *ident, int doDocComment, int doHdrGen) 127 { 128 return new Module(filename, ident, doDocComment, doHdrGen); 129 } 130 131 void Module::setDocfile() 132 { 133 docfile = setOutfile(global.params.docname, global.params.docdir, arg, global.doc_ext); 134 } 135 136 /********************************************* 137 * Combines things into output file name for .html and .di files. 138 * Input: 139 * name Command line name given for the file, NULL if none 140 * dir Command line directory given for the file, NULL if none 141 * arg Name of the source file 142 * ext File name extension to use if 'name' is NULL 143 * global.params.preservePaths get output path from arg 144 * srcfile Input file - output file name must not match input file 145 */ 146 147 File *Module::setOutfile(const char *name, const char *dir, const char *arg, const char *ext) 148 { 149 const char *docfilename; 150 151 if (name) 152 { 153 docfilename = name; 154 } 155 else 156 { 157 const char *argdoc; 158 if (global.params.preservePaths) 159 argdoc = arg; 160 else 161 argdoc = FileName::name(arg); 162 163 // If argdoc doesn't have an absolute path, make it relative to dir 164 if (!FileName::absolute(argdoc)) 165 { //FileName::ensurePathExists(dir); 166 argdoc = FileName::combine(dir, argdoc); 167 } 168 docfilename = FileName::forceExt(argdoc, ext); 169 } 170 171 if (FileName::equals(docfilename, srcfile->name->str)) 172 { 173 error("source file and output file have same name '%s'", srcfile->name->str); 174 fatal(); 175 } 176 177 return new File(docfilename); 178 } 179 180 void Module::deleteObjFile() 181 { 182 if (global.params.obj) 183 objfile->remove(); 184 if (docfile) 185 docfile->remove(); 186 } 187 188 const char *Module::kind() const 189 { 190 return "module"; 191 } 192 193 static void checkModFileAlias(OutBuffer *buf, OutBuffer *dotmods, 194 Array<const char *> *ms, size_t msdim, const char *p) 195 { 196 /* Check and replace the contents of buf[] with 197 * an alias string from global.params.modFileAliasStrings[] 198 */ 199 dotmods->writestring(p); 200 for (size_t j = msdim; j--;) 201 { 202 const char *m = (*ms)[j]; 203 const char *q = strchr(m, '='); 204 assert(q); 205 if (dotmods->offset == (size_t)(q - m) && memcmp(dotmods->peekString(), m, q - m) == 0) 206 { 207 buf->reset(); 208 size_t qlen = strlen(q + 1); 209 if (qlen && (q[qlen] == '/' || q[qlen] == '\\')) 210 --qlen; // remove trailing separator 211 buf->write(q + 1, qlen); 212 break; // last matching entry in ms[] wins 213 } 214 } 215 dotmods->writeByte('.'); 216 } 217 218 Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) 219 { 220 //printf("Module::load(ident = '%s')\n", ident->toChars()); 221 222 // Build module filename by turning: 223 // foo.bar.baz 224 // into: 225 // foo\bar\baz 226 const char *filename = ident->toChars(); 227 if (packages && packages->dim) 228 { 229 OutBuffer buf; 230 OutBuffer dotmods; 231 Array<const char *> *ms = global.params.modFileAliasStrings; 232 const size_t msdim = ms ? ms->dim : 0; 233 234 for (size_t i = 0; i < packages->dim; i++) 235 { 236 Identifier *pid = (*packages)[i]; 237 const char *p = pid->toChars(); 238 buf.writestring(p); 239 if (msdim) 240 checkModFileAlias(&buf, &dotmods, ms, msdim, p); 241 #if _WIN32 242 buf.writeByte('\\'); 243 #else 244 buf.writeByte('/'); 245 #endif 246 } 247 buf.writestring(filename); 248 if (msdim) 249 checkModFileAlias(&buf, &dotmods, ms, msdim, filename); 250 buf.writeByte(0); 251 filename = (char *)buf.extractData(); 252 } 253 254 Module *m = new Module(filename, ident, 0, 0); 255 m->loc = loc; 256 257 /* Look for the source file 258 */ 259 const char *path; 260 const char *result = lookForSourceFile(&path, filename); 261 if (result) 262 { 263 m->srcfile = new File(result); 264 if (path) 265 m->srcfilePath = path; 266 else if (!FileName::absolute(result)) 267 m->srcfilePath = getcwd(NULL, 0); 268 } 269 270 if (!m->read(loc)) 271 return NULL; 272 273 if (global.params.verbose) 274 { 275 OutBuffer buf; 276 if (packages) 277 { 278 for (size_t i = 0; i < packages->dim; i++) 279 { 280 Identifier *pid = (*packages)[i]; 281 buf.writestring(pid->toChars()); 282 buf.writeByte('.'); 283 } 284 } 285 buf.printf("%s\t(%s)", ident->toChars(), m->srcfile->toChars()); 286 message("import %s", buf.peekString()); 287 } 288 289 m = m->parse(); 290 291 Compiler::loadModule(m); 292 293 return m; 294 } 295 296 bool Module::read(Loc loc) 297 { 298 //printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars()); 299 if (srcfile->read()) 300 { 301 if (!strcmp(srcfile->toChars(), "object.d")) 302 { 303 ::error(loc, "cannot find source code for runtime library file 'object.d'"); 304 errorSupplemental(loc, "dmd might not be correctly installed. Run 'dmd -man' for installation instructions."); 305 const char *dmdConfFile = global.inifilename ? FileName::canonicalName(global.inifilename) : NULL; 306 errorSupplemental(loc, "config file: %s", dmdConfFile ? dmdConfFile : "not found"); 307 } 308 else 309 { 310 // if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module 311 bool isPackageMod = (strcmp(toChars(), "package") != 0) && 312 (strcmp(srcfile->name->name(), "package.d") == 0 || (strcmp(srcfile->name->name(), "package.di") == 0)); 313 314 if (isPackageMod) 315 ::error(loc, "importing package '%s' requires a 'package.d' file which cannot be found in '%s'", 316 toChars(), srcfile->toChars()); 317 else 318 error(loc, "is in file '%s' which cannot be read", srcfile->toChars()); 319 } 320 321 if (!global.gag) 322 { 323 /* Print path 324 */ 325 if (global.path) 326 { 327 for (size_t i = 0; i < global.path->dim; i++) 328 { 329 const char *p = (*global.path)[i]; 330 fprintf(stderr, "import path[%llu] = %s\n", (ulonglong)i, p); 331 } 332 } 333 else 334 fprintf(stderr, "Specify path to file '%s' with -I switch\n", srcfile->toChars()); 335 fatal(); 336 } 337 return false; 338 } 339 return true; 340 } 341 342 Module *Module::parse() 343 { 344 //printf("Module::parse(srcfile='%s') this=%p\n", srcfile->name->toChars(), this); 345 346 const char *srcname = srcfile->name->toChars(); 347 //printf("Module::parse(srcname = '%s')\n", srcname); 348 349 isPackageFile = (strcmp(srcfile->name->name(), "package.d") == 0 || 350 strcmp(srcfile->name->name(), "package.di") == 0); 351 352 utf8_t *buf = (utf8_t *)srcfile->buffer; 353 size_t buflen = srcfile->len; 354 355 if (buflen >= 2) 356 { 357 /* Convert all non-UTF-8 formats to UTF-8. 358 * BOM : http://www.unicode.org/faq/utf_bom.html 359 * 00 00 FE FF UTF-32BE, big-endian 360 * FF FE 00 00 UTF-32LE, little-endian 361 * FE FF UTF-16BE, big-endian 362 * FF FE UTF-16LE, little-endian 363 * EF BB BF UTF-8 364 */ 365 366 unsigned le; 367 unsigned bom = 1; // assume there's a BOM 368 if (buf[0] == 0xFF && buf[1] == 0xFE) 369 { 370 if (buflen >= 4 && buf[2] == 0 && buf[3] == 0) 371 { // UTF-32LE 372 le = 1; 373 374 Lutf32: 375 OutBuffer dbuf; 376 unsigned *pu = (unsigned *)(buf); 377 unsigned *pumax = &pu[buflen / 4]; 378 379 if (buflen & 3) 380 { error("odd length of UTF-32 char source %u", buflen); 381 fatal(); 382 } 383 384 dbuf.reserve(buflen / 4); 385 for (pu += bom; pu < pumax; pu++) 386 { unsigned u; 387 388 u = le ? Port::readlongLE(pu) : Port::readlongBE(pu); 389 if (u & ~0x7F) 390 { 391 if (u > 0x10FFFF) 392 { error("UTF-32 value %08x greater than 0x10FFFF", u); 393 fatal(); 394 } 395 dbuf.writeUTF8(u); 396 } 397 else 398 dbuf.writeByte(u); 399 } 400 dbuf.writeByte(0); // add 0 as sentinel for scanner 401 buflen = dbuf.offset - 1; // don't include sentinel in count 402 buf = (utf8_t *) dbuf.extractData(); 403 } 404 else 405 { // UTF-16LE (X86) 406 // Convert it to UTF-8 407 le = 1; 408 409 Lutf16: 410 OutBuffer dbuf; 411 unsigned short *pu = (unsigned short *)(buf); 412 unsigned short *pumax = &pu[buflen / 2]; 413 414 if (buflen & 1) 415 { error("odd length of UTF-16 char source %u", buflen); 416 fatal(); 417 } 418 419 dbuf.reserve(buflen / 2); 420 for (pu += bom; pu < pumax; pu++) 421 { unsigned u; 422 423 u = le ? Port::readwordLE(pu) : Port::readwordBE(pu); 424 if (u & ~0x7F) 425 { if (u >= 0xD800 && u <= 0xDBFF) 426 { unsigned u2; 427 428 if (++pu > pumax) 429 { error("surrogate UTF-16 high value %04x at EOF", u); 430 fatal(); 431 } 432 u2 = le ? Port::readwordLE(pu) : Port::readwordBE(pu); 433 if (u2 < 0xDC00 || u2 > 0xDFFF) 434 { error("surrogate UTF-16 low value %04x out of range", u2); 435 fatal(); 436 } 437 u = (u - 0xD7C0) << 10; 438 u |= (u2 - 0xDC00); 439 } 440 else if (u >= 0xDC00 && u <= 0xDFFF) 441 { error("unpaired surrogate UTF-16 value %04x", u); 442 fatal(); 443 } 444 else if (u == 0xFFFE || u == 0xFFFF) 445 { error("illegal UTF-16 value %04x", u); 446 fatal(); 447 } 448 dbuf.writeUTF8(u); 449 } 450 else 451 dbuf.writeByte(u); 452 } 453 dbuf.writeByte(0); // add 0 as sentinel for scanner 454 buflen = dbuf.offset - 1; // don't include sentinel in count 455 buf = (utf8_t *) dbuf.extractData(); 456 } 457 } 458 else if (buf[0] == 0xFE && buf[1] == 0xFF) 459 { // UTF-16BE 460 le = 0; 461 goto Lutf16; 462 } 463 else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF) 464 { // UTF-32BE 465 le = 0; 466 goto Lutf32; 467 } 468 else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF) 469 { // UTF-8 470 471 buf += 3; 472 buflen -= 3; 473 } 474 else 475 { 476 /* There is no BOM. Make use of Arcane Jill's insight that 477 * the first char of D source must be ASCII to 478 * figure out the encoding. 479 */ 480 481 bom = 0; 482 if (buflen >= 4) 483 { if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0) 484 { // UTF-32LE 485 le = 1; 486 goto Lutf32; 487 } 488 else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) 489 { // UTF-32BE 490 le = 0; 491 goto Lutf32; 492 } 493 } 494 if (buflen >= 2) 495 { 496 if (buf[1] == 0) 497 { // UTF-16LE 498 le = 1; 499 goto Lutf16; 500 } 501 else if (buf[0] == 0) 502 { // UTF-16BE 503 le = 0; 504 goto Lutf16; 505 } 506 } 507 508 // It's UTF-8 509 if (buf[0] >= 0x80) 510 { error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]); 511 fatal(); 512 } 513 } 514 } 515 516 /* If it starts with the string "Ddoc", then it's a documentation 517 * source file. 518 */ 519 if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0) 520 { 521 comment = buf + 4; 522 isDocFile = 1; 523 if (!docfile) 524 setDocfile(); 525 return this; 526 } 527 { 528 Parser p(this, buf, buflen, docfile != NULL); 529 p.nextToken(); 530 members = p.parseModule(); 531 md = p.md; 532 numlines = p.scanloc.linnum; 533 if (p.errors) 534 ++global.errors; 535 } 536 537 if (srcfile->ref == 0) 538 ::free(srcfile->buffer); 539 srcfile->buffer = NULL; 540 srcfile->len = 0; 541 542 /* The symbol table into which the module is to be inserted. 543 */ 544 DsymbolTable *dst; 545 546 if (md) 547 { 548 /* A ModuleDeclaration, md, was provided. 549 * The ModuleDeclaration sets the packages this module appears in, and 550 * the name of this module. 551 */ 552 this->ident = md->id; 553 Package *ppack = NULL; 554 dst = Package::resolve(md->packages, &this->parent, &ppack); 555 assert(dst); 556 557 Module *m = ppack ? ppack->isModule() : NULL; 558 if (m && (strcmp(m->srcfile->name->name(), "package.d") != 0 && 559 strcmp(m->srcfile->name->name(), "package.di") != 0)) 560 { 561 ::error(md->loc, "package name '%s' conflicts with usage as a module name in file %s", 562 ppack->toPrettyChars(), m->srcfile->toChars()); 563 } 564 } 565 else 566 { 567 /* The name of the module is set to the source file name. 568 * There are no packages. 569 */ 570 dst = modules; // and so this module goes into global module symbol table 571 572 /* Check to see if module name is a valid identifier 573 */ 574 if (!Identifier::isValidIdentifier(this->ident->toChars())) 575 error("has non-identifier characters in filename, use module declaration instead"); 576 } 577 578 // Insert module into the symbol table 579 Dsymbol *s = this; 580 if (isPackageFile) 581 { 582 /* If the source tree is as follows: 583 * pkg/ 584 * +- package.d 585 * +- common.d 586 * the 'pkg' will be incorporated to the internal package tree in two ways: 587 * import pkg; 588 * and: 589 * import pkg.common; 590 * 591 * If both are used in one compilation, 'pkg' as a module (== pkg/package.d) 592 * and a package name 'pkg' will conflict each other. 593 * 594 * To avoid the conflict: 595 * 1. If preceding package name insertion had occurred by Package::resolve, 596 * later package.d loading will change Package::isPkgMod to PKGmodule and set Package::mod. 597 * 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here. 598 */ 599 Package *p = new Package(ident); 600 p->parent = this->parent; 601 p->isPkgMod = PKGmodule; 602 p->mod = this; 603 p->tag = this->tag; // reuse the same package tag 604 p->symtab = new DsymbolTable(); 605 s = p; 606 } 607 if (!dst->insert(s)) 608 { 609 /* It conflicts with a name that is already in the symbol table. 610 * Figure out what went wrong, and issue error message. 611 */ 612 Dsymbol *prev = dst->lookup(ident); 613 assert(prev); 614 if (Module *mprev = prev->isModule()) 615 { 616 if (FileName::compare(srcname, mprev->srcfile->toChars()) != 0) 617 error(loc, "from file %s conflicts with another module %s from file %s", 618 srcname, mprev->toChars(), mprev->srcfile->toChars()); 619 else if (isRoot() && mprev->isRoot()) 620 error(loc, "from file %s is specified twice on the command line", 621 srcname); 622 else 623 error(loc, "from file %s must be imported with 'import %s;'", 624 srcname, toPrettyChars()); 625 626 // Bugzilla 14446: Return previously parsed module to avoid AST duplication ICE. 627 return mprev; 628 } 629 else if (Package *pkg = prev->isPackage()) 630 { 631 if (pkg->isPkgMod == PKGunknown && isPackageFile) 632 { 633 /* If the previous inserted Package is not yet determined as package.d, 634 * link it to the actual module. 635 */ 636 pkg->isPkgMod = PKGmodule; 637 pkg->mod = this; 638 pkg->tag = this->tag; // reuse the same package tag 639 } 640 else 641 error(md ? md->loc : loc, "from file %s conflicts with package name %s", 642 srcname, pkg->toChars()); 643 } 644 else 645 assert(global.errors); 646 } 647 else 648 { 649 // Add to global array of all modules 650 amodules.push(this); 651 } 652 return this; 653 } 654 655 void Module::importAll(Scope *) 656 { 657 //printf("+Module::importAll(this = %p, '%s'): parent = %p\n", this, toChars(), parent); 658 659 if (_scope) 660 return; // already done 661 662 if (isDocFile) 663 { 664 error("is a Ddoc file, cannot import it"); 665 return; 666 } 667 668 /* Note that modules get their own scope, from scratch. 669 * This is so regardless of where in the syntax a module 670 * gets imported, it is unaffected by context. 671 * Ignore prevsc. 672 */ 673 Scope *sc = Scope::createGlobal(this); // create root scope 674 675 if (md && md->msg) 676 md->msg = semanticString(sc, md->msg, "deprecation message"); 677 678 // Add import of "object", even for the "object" module. 679 // If it isn't there, some compiler rewrites, like 680 // classinst == classinst -> .object.opEquals(classinst, classinst) 681 // would fail inside object.d. 682 if (members->dim == 0 || ((*members)[0])->ident != Id::object || 683 (*members)[0]->isImport() == NULL) 684 { 685 Import *im = new Import(Loc(), NULL, Id::object, NULL, 0); 686 members->shift(im); 687 } 688 689 if (!symtab) 690 { 691 // Add all symbols into module's symbol table 692 symtab = new DsymbolTable(); 693 for (size_t i = 0; i < members->dim; i++) 694 { 695 Dsymbol *s = (*members)[i]; 696 s->addMember(sc, sc->scopesym); 697 } 698 } 699 // anything else should be run after addMember, so version/debug symbols are defined 700 701 /* Set scope for the symbols so that if we forward reference 702 * a symbol, it can possibly be resolved on the spot. 703 * If this works out well, it can be extended to all modules 704 * before any semantic() on any of them. 705 */ 706 setScope(sc); // remember module scope for semantic 707 for (size_t i = 0; i < members->dim; i++) 708 { 709 Dsymbol *s = (*members)[i]; 710 s->setScope(sc); 711 } 712 713 for (size_t i = 0; i < members->dim; i++) 714 { 715 Dsymbol *s = (*members)[i]; 716 s->importAll(sc); 717 } 718 719 sc = sc->pop(); 720 sc->pop(); // 2 pops because Scope::createGlobal() created 2 721 } 722 723 void Module::semantic(Scope *) 724 { 725 if (semanticRun != PASSinit) 726 return; 727 728 //printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); 729 semanticRun = PASSsemantic; 730 731 // Note that modules get their own scope, from scratch. 732 // This is so regardless of where in the syntax a module 733 // gets imported, it is unaffected by context. 734 Scope *sc = _scope; // see if already got one from importAll() 735 if (!sc) 736 { 737 Scope::createGlobal(this); // create root scope 738 } 739 740 //printf("Module = %p, linkage = %d\n", sc->scopesym, sc->linkage); 741 742 // Pass 1 semantic routines: do public side of the definition 743 for (size_t i = 0; i < members->dim; i++) 744 { 745 Dsymbol *s = (*members)[i]; 746 747 //printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars()); 748 s->semantic(sc); 749 runDeferredSemantic(); 750 } 751 752 if (userAttribDecl) 753 { 754 userAttribDecl->semantic(sc); 755 } 756 757 if (!_scope) 758 { 759 sc = sc->pop(); 760 sc->pop(); // 2 pops because Scope::createGlobal() created 2 761 } 762 semanticRun = PASSsemanticdone; 763 //printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent); 764 } 765 766 void Module::semantic2(Scope*) 767 { 768 //printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent); 769 if (semanticRun != PASSsemanticdone) // semantic() not completed yet - could be recursive call 770 return; 771 semanticRun = PASSsemantic2; 772 773 // Note that modules get their own scope, from scratch. 774 // This is so regardless of where in the syntax a module 775 // gets imported, it is unaffected by context. 776 Scope *sc = Scope::createGlobal(this); // create root scope 777 //printf("Module = %p\n", sc.scopesym); 778 779 // Pass 2 semantic routines: do initializers and function bodies 780 for (size_t i = 0; i < members->dim; i++) 781 { 782 Dsymbol *s = (*members)[i]; 783 s->semantic2(sc); 784 } 785 786 if (userAttribDecl) 787 { 788 userAttribDecl->semantic2(sc); 789 } 790 791 sc = sc->pop(); 792 sc->pop(); 793 semanticRun = PASSsemantic2done; 794 //printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent); 795 } 796 797 void Module::semantic3(Scope*) 798 { 799 //printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent); 800 if (semanticRun != PASSsemantic2done) 801 return; 802 semanticRun = PASSsemantic3; 803 804 // Note that modules get their own scope, from scratch. 805 // This is so regardless of where in the syntax a module 806 // gets imported, it is unaffected by context. 807 Scope *sc = Scope::createGlobal(this); // create root scope 808 //printf("Module = %p\n", sc.scopesym); 809 810 // Pass 3 semantic routines: do initializers and function bodies 811 for (size_t i = 0; i < members->dim; i++) 812 { 813 Dsymbol *s = (*members)[i]; 814 //printf("Module %s: %s.semantic3()\n", toChars(), s->toChars()); 815 s->semantic3(sc); 816 817 runDeferredSemantic2(); 818 } 819 820 if (userAttribDecl) 821 { 822 userAttribDecl->semantic3(sc); 823 } 824 825 sc = sc->pop(); 826 sc->pop(); 827 semanticRun = PASSsemantic3done; 828 } 829 830 /********************************** 831 * Determine if we need to generate an instance of ModuleInfo 832 * for this Module. 833 */ 834 835 int Module::needModuleInfo() 836 { 837 //printf("needModuleInfo() %s, %d, %d\n", toChars(), needmoduleinfo, global.params.cov); 838 return needmoduleinfo || global.params.cov; 839 } 840 841 Dsymbol *Module::search(const Loc &loc, Identifier *ident, int flags) 842 { 843 /* Since modules can be circularly referenced, 844 * need to stop infinite recursive searches. 845 * This is done with the cache. 846 */ 847 848 //printf("%s Module::search('%s', flags = x%x) insearch = %d\n", toChars(), ident->toChars(), flags, insearch); 849 if (insearch) 850 return NULL; 851 852 /* Qualified module searches always search their imports, 853 * even if SearchLocalsOnly 854 */ 855 if (!(flags & SearchUnqualifiedModule)) 856 flags &= ~(SearchUnqualifiedModule | SearchLocalsOnly); 857 858 if (searchCacheIdent == ident && searchCacheFlags == flags) 859 { 860 //printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", 861 // toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null"); 862 return searchCacheSymbol; 863 } 864 865 unsigned int errors = global.errors; 866 867 insearch = 1; 868 Dsymbol *s = ScopeDsymbol::search(loc, ident, flags); 869 insearch = 0; 870 871 if (errors == global.errors) 872 { 873 // Bugzilla 10752: We can cache the result only when it does not cause 874 // access error so the side-effect should be reproduced in later search. 875 searchCacheIdent = ident; 876 searchCacheSymbol = s; 877 searchCacheFlags = flags; 878 } 879 return s; 880 } 881 882 bool Module::isPackageAccessible(Package *p, Prot protection, int flags) 883 { 884 if (insearch) // don't follow import cycles 885 return false; 886 if (flags & IgnorePrivateImports) 887 protection = Prot(PROTpublic); // only consider public imports 888 insearch = true; 889 bool r = ScopeDsymbol::isPackageAccessible(p, protection); 890 insearch = false; 891 return r; 892 } 893 894 Dsymbol *Module::symtabInsert(Dsymbol *s) 895 { 896 searchCacheIdent = NULL; // symbol is inserted, so invalidate cache 897 return Package::symtabInsert(s); 898 } 899 900 void Module::clearCache() 901 { 902 for (size_t i = 0; i < amodules.dim; i++) 903 { 904 Module *m = amodules[i]; 905 m->searchCacheIdent = NULL; 906 } 907 } 908 909 /******************************************* 910 * Can't run semantic on s now, try again later. 911 */ 912 913 void Module::addDeferredSemantic(Dsymbol *s) 914 { 915 // Don't add it if it is already there 916 for (size_t i = 0; i < deferred.dim; i++) 917 { 918 Dsymbol *sd = deferred[i]; 919 920 if (sd == s) 921 return; 922 } 923 924 //printf("Module::addDeferredSemantic('%s')\n", s->toChars()); 925 deferred.push(s); 926 } 927 928 void Module::addDeferredSemantic2(Dsymbol *s) 929 { 930 //printf("Module::addDeferredSemantic2('%s')\n", s->toChars()); 931 deferred2.push(s); 932 } 933 934 void Module::addDeferredSemantic3(Dsymbol *s) 935 { 936 //printf("Module::addDeferredSemantic3('%s')\n", s->toChars()); 937 deferred3.push(s); 938 } 939 940 /****************************************** 941 * Run semantic() on deferred symbols. 942 */ 943 944 void Module::runDeferredSemantic() 945 { 946 if (dprogress == 0) 947 return; 948 949 static int nested; 950 if (nested) 951 return; 952 //if (deferred.dim) printf("+Module::runDeferredSemantic(), len = %d\n", deferred.dim); 953 nested++; 954 955 size_t len; 956 do 957 { 958 dprogress = 0; 959 len = deferred.dim; 960 if (!len) 961 break; 962 963 Dsymbol **todo; 964 Dsymbol **todoalloc = NULL; 965 Dsymbol *tmp; 966 if (len == 1) 967 { 968 todo = &tmp; 969 } 970 else 971 { 972 todo = (Dsymbol **)mem.xmalloc(len * sizeof(Dsymbol *)); 973 todoalloc = todo; 974 } 975 memcpy(todo, deferred.tdata(), len * sizeof(Dsymbol *)); 976 deferred.setDim(0); 977 978 for (size_t i = 0; i < len; i++) 979 { 980 Dsymbol *s = todo[i]; 981 982 s->semantic(NULL); 983 //printf("deferred: %s, parent = %s\n", s->toChars(), s->parent->toChars()); 984 } 985 //printf("\tdeferred.dim = %d, len = %d, dprogress = %d\n", deferred.dim, len, dprogress); 986 if (todoalloc) 987 free(todoalloc); 988 } while (deferred.dim < len || dprogress); // while making progress 989 nested--; 990 //printf("-Module::runDeferredSemantic(), len = %d\n", deferred.dim); 991 } 992 993 void Module::runDeferredSemantic2() 994 { 995 Module::runDeferredSemantic(); 996 997 Dsymbols *a = &Module::deferred2; 998 for (size_t i = 0; i < a->dim; i++) 999 { 1000 Dsymbol *s = (*a)[i]; 1001 //printf("[%d] %s semantic2a\n", i, s->toPrettyChars()); 1002 s->semantic2(NULL); 1003 1004 if (global.errors) 1005 break; 1006 } 1007 a->setDim(0); 1008 } 1009 1010 void Module::runDeferredSemantic3() 1011 { 1012 Module::runDeferredSemantic2(); 1013 1014 Dsymbols *a = &Module::deferred3; 1015 for (size_t i = 0; i < a->dim; i++) 1016 { 1017 Dsymbol *s = (*a)[i]; 1018 //printf("[%d] %s semantic3a\n", i, s->toPrettyChars()); 1019 1020 s->semantic3(NULL); 1021 1022 if (global.errors) 1023 break; 1024 } 1025 a->setDim(0); 1026 } 1027 1028 /************************************ 1029 * Recursively look at every module this module imports, 1030 * return true if it imports m. 1031 * Can be used to detect circular imports. 1032 */ 1033 1034 int Module::imports(Module *m) 1035 { 1036 //printf("%s Module::imports(%s)\n", toChars(), m->toChars()); 1037 for (size_t i = 0; i < aimports.dim; i++) 1038 { 1039 Module *mi = aimports[i]; 1040 if (mi == m) 1041 return true; 1042 if (!mi->insearch) 1043 { 1044 mi->insearch = 1; 1045 int r = mi->imports(m); 1046 if (r) 1047 return r; 1048 } 1049 } 1050 return false; 1051 } 1052 1053 /************************************* 1054 * Return true if module imports itself. 1055 */ 1056 1057 bool Module::selfImports() 1058 { 1059 //printf("Module::selfImports() %s\n", toChars()); 1060 if (selfimports == 0) 1061 { 1062 for (size_t i = 0; i < amodules.dim; i++) 1063 amodules[i]->insearch = 0; 1064 1065 selfimports = imports(this) + 1; 1066 1067 for (size_t i = 0; i < amodules.dim; i++) 1068 amodules[i]->insearch = 0; 1069 } 1070 return selfimports == 2; 1071 } 1072 1073 /************************************* 1074 * Return true if module imports root module. 1075 */ 1076 1077 bool Module::rootImports() 1078 { 1079 //printf("Module::rootImports() %s\n", toChars()); 1080 if (rootimports == 0) 1081 { 1082 for (size_t i = 0; i < amodules.dim; i++) 1083 amodules[i]->insearch = 0; 1084 1085 rootimports = 1; 1086 for (size_t i = 0; i < amodules.dim; ++i) 1087 { 1088 Module *m = amodules[i]; 1089 if (m->isRoot() && imports(m)) 1090 { 1091 rootimports = 2; 1092 break; 1093 } 1094 } 1095 1096 for (size_t i = 0; i < amodules.dim; i++) 1097 amodules[i]->insearch = 0; 1098 } 1099 return rootimports == 2; 1100 } 1101 1102 bool Module::isCoreModule(Identifier *ident) 1103 { 1104 return this->ident == ident && parent && parent->ident == Id::core && !parent->parent; 1105 } 1106 1107 /* =========================== ModuleDeclaration ===================== */ 1108 1109 ModuleDeclaration::ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id) 1110 { 1111 this->loc = loc; 1112 this->packages = packages; 1113 this->id = id; 1114 this->isdeprecated = false; 1115 this->msg = NULL; 1116 } 1117 1118 const char *ModuleDeclaration::toChars() 1119 { 1120 OutBuffer buf; 1121 1122 if (packages && packages->dim) 1123 { 1124 for (size_t i = 0; i < packages->dim; i++) 1125 { 1126 Identifier *pid = (*packages)[i]; 1127 buf.writestring(pid->toChars()); 1128 buf.writeByte('.'); 1129 } 1130 } 1131 buf.writestring(id->toChars()); 1132 return buf.extractString(); 1133 } 1134 1135 /* =========================== Package ===================== */ 1136 1137 Package::Package(Identifier *ident) 1138 : ScopeDsymbol(ident) 1139 { 1140 this->isPkgMod = PKGunknown; 1141 this->mod = NULL; 1142 static unsigned packageTag = 0; 1143 this->tag = packageTag++; 1144 } 1145 1146 1147 const char *Package::kind() const 1148 { 1149 return "package"; 1150 } 1151 1152 Module *Package::isPackageMod() 1153 { 1154 if (isPkgMod == PKGmodule) 1155 { 1156 return mod; 1157 } 1158 return NULL; 1159 } 1160 1161 /** 1162 * Checks if pkg is a sub-package of this 1163 * 1164 * For example, if this qualifies to 'a1.a2' and pkg - to 'a1.a2.a3', 1165 * this function returns 'true'. If it is other way around or qualified 1166 * package paths conflict function returns 'false'. 1167 * 1168 * Params: 1169 * pkg = possible subpackage 1170 * 1171 * Returns: 1172 * see description 1173 */ 1174 bool Package::isAncestorPackageOf(const Package * const pkg) const 1175 { 1176 if (this == pkg) 1177 return true; 1178 if (!pkg || !pkg->parent) 1179 return false; 1180 return isAncestorPackageOf(pkg->parent->isPackage()); 1181 } 1182 1183 void Package::semantic(Scope *) 1184 { 1185 if (semanticRun < PASSsemanticdone) 1186 semanticRun = PASSsemanticdone; 1187 } 1188 1189 /**************************************************** 1190 * Input: 1191 * packages[] the pkg1.pkg2 of pkg1.pkg2.mod 1192 * Returns: 1193 * the symbol table that mod should be inserted into 1194 * Output: 1195 * *pparent the rightmost package, i.e. pkg2, or NULL if no packages 1196 * *ppkg the leftmost package, i.e. pkg1, or NULL if no packages 1197 */ 1198 1199 DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg) 1200 { 1201 DsymbolTable *dst = Module::modules; 1202 Dsymbol *parent = NULL; 1203 1204 //printf("Package::resolve()\n"); 1205 if (ppkg) 1206 *ppkg = NULL; 1207 1208 if (packages) 1209 { 1210 for (size_t i = 0; i < packages->dim; i++) 1211 { 1212 Identifier *pid = (*packages)[i]; 1213 Package *pkg; 1214 Dsymbol *p = dst->lookup(pid); 1215 if (!p) 1216 { 1217 pkg = new Package(pid); 1218 dst->insert(pkg); 1219 pkg->parent = parent; 1220 pkg->symtab = new DsymbolTable(); 1221 } 1222 else 1223 { 1224 pkg = p->isPackage(); 1225 assert(pkg); 1226 // It might already be a module, not a package, but that needs 1227 // to be checked at a higher level, where a nice error message 1228 // can be generated. 1229 // dot net needs modules and packages with same name 1230 1231 // But we still need a symbol table for it 1232 if (!pkg->symtab) 1233 pkg->symtab = new DsymbolTable(); 1234 } 1235 parent = pkg; 1236 dst = pkg->symtab; 1237 if (ppkg && !*ppkg) 1238 *ppkg = pkg; 1239 if (pkg->isModule()) 1240 { 1241 // Return the module so that a nice error message can be generated 1242 if (ppkg) 1243 *ppkg = (Package *)p; 1244 break; 1245 } 1246 } 1247 } 1248 if (pparent) 1249 *pparent = parent; 1250 return dst; 1251 } 1252 1253 Dsymbol *Package::search(const Loc &loc, Identifier *ident, int flags) 1254 { 1255 //printf("%s Package::search('%s', flags = x%x)\n", toChars(), ident->toChars(), flags); 1256 flags &= ~SearchLocalsOnly; // searching an import is always transitive 1257 if (!isModule() && mod) 1258 { 1259 // Prefer full package name. 1260 Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; 1261 if (s) 1262 return s; 1263 //printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars()); 1264 return mod->search(loc, ident, flags); 1265 } 1266 1267 return ScopeDsymbol::search(loc, ident, flags); 1268 } 1269 1270 /* =========================== ===================== */ 1271 1272 /******************************************** 1273 * Look for the source file if it's different from filename. 1274 * Look for .di, .d, directory, and along global.path. 1275 * Does not open the file. 1276 * Output: 1277 * path the path where the file was found if it was not the current directory 1278 * Input: 1279 * filename as supplied by the user 1280 * global.path 1281 * Returns: 1282 * NULL if it's not different from filename. 1283 */ 1284 1285 const char *lookForSourceFile(const char **path, const char *filename) 1286 { 1287 /* Search along global.path for .di file, then .d file. 1288 */ 1289 *path = NULL; 1290 1291 const char *sdi = FileName::forceExt(filename, global.hdr_ext); 1292 if (FileName::exists(sdi) == 1) 1293 return sdi; 1294 1295 const char *sd = FileName::forceExt(filename, global.mars_ext); 1296 if (FileName::exists(sd) == 1) 1297 return sd; 1298 1299 if (FileName::exists(filename) == 2) 1300 { 1301 /* The filename exists and it's a directory. 1302 * Therefore, the result should be: filename/package.d 1303 * iff filename/package.d is a file 1304 */ 1305 const char *ni = FileName::combine(filename, "package.di"); 1306 if (FileName::exists(ni) == 1) 1307 return ni; 1308 FileName::free(ni); 1309 const char *n = FileName::combine(filename, "package.d"); 1310 if (FileName::exists(n) == 1) 1311 return n; 1312 FileName::free(n); 1313 } 1314 1315 if (FileName::absolute(filename)) 1316 return NULL; 1317 1318 if (!global.path) 1319 return NULL; 1320 1321 for (size_t i = 0; i < global.path->dim; i++) 1322 { 1323 const char *p = (*global.path)[i]; 1324 1325 const char *n = FileName::combine(p, sdi); 1326 if (FileName::exists(n) == 1) 1327 { 1328 *path = p; 1329 return n; 1330 } 1331 FileName::free(n); 1332 1333 n = FileName::combine(p, sd); 1334 if (FileName::exists(n) == 1) 1335 { 1336 *path = p; 1337 return n; 1338 } 1339 FileName::free(n); 1340 1341 const char *b = FileName::removeExt(filename); 1342 n = FileName::combine(p, b); 1343 FileName::free(b); 1344 if (FileName::exists(n) == 2) 1345 { 1346 const char *n2i = FileName::combine(n, "package.di"); 1347 if (FileName::exists(n2i) == 1) 1348 return n2i; 1349 FileName::free(n2i); 1350 const char *n2 = FileName::combine(n, "package.d"); 1351 if (FileName::exists(n2) == 1) 1352 { 1353 *path = p; 1354 return n2; 1355 } 1356 FileName::free(n2); 1357 } 1358 FileName::free(n); 1359 } 1360 return NULL; 1361 } 1362