/* Compiler implementation of the D programming language * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved * written by Walter Bright * https://www.digitalmars.com * Distributed under the Boost Software License, Version 1.0. * https://www.boost.org/LICENSE_1_0.txt * https://github.com/dlang/dmd/blob/master/src/dmd/module.h */ #pragma once #include "dsymbol.h" struct ModuleDeclaration; struct Escape; struct FileBuffer; struct MacroTable { void* internal; // PIMPL }; enum PKG { PKGunknown, // not yet determined whether it's a package.d or not PKGmodule, // already determined that's an actual package.d PKGpackage // already determined that's an actual package }; class Package : public ScopeDsymbol { public: PKG isPkgMod; unsigned tag; // auto incremented tag, used to mask package tree in scopes Module *mod; // != NULL if isPkgMod == PKGmodule const char *kind() const override; bool equals(const RootObject * const o) const override; Package *isPackage() override final { return this; } bool isAncestorPackageOf(const Package * const pkg) const; Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override; void accept(Visitor *v) override { v->visit(this); } Module *isPackageMod(); }; class Module final : public Package { public: static Module *rootModule; static DsymbolTable *modules; // symbol table of all modules static Modules amodules; // array of all modules static Dsymbols deferred; // deferred Dsymbol's needing semantic() run on them static Dsymbols deferred2; // deferred Dsymbol's needing semantic2() run on them static Dsymbols deferred3; // deferred Dsymbol's needing semantic3() run on them static void _init(); static AggregateDeclaration *moduleinfo; DString arg; // original argument name ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration FileName srcfile; // input source file FileName objfile; // output .obj file FileName hdrfile; // 'header' file FileName docfile; // output documentation file DArray src; // Raw content of the file unsigned errors; // if any errors in file unsigned numlines; // number of lines in source file FileType filetype; // source file type bool hasAlwaysInlines; // contains references to functions that must be inlined bool isPackageFile; // if it is a package.d Package *pkg; // if isPackageFile is true, the Package that contains this package.d Strings contentImportedFiles; // array of files whose content was imported int needmoduleinfo; int selfimports; // 0: don't know, 1: does not, 2: does void* tagSymTab; // ImportC: tag symbols that conflict with other symbols used as the index OutBuffer defines; // collect all the #define lines here bool selfImports(); // returns true if module imports itself int rootimports; // 0: don't know, 1: does not, 2: does bool rootImports(); // returns true if module imports root module int insearch; Identifier *searchCacheIdent; Dsymbol *searchCacheSymbol; // cached value of search int searchCacheFlags; // cached flags // module from command line we're imported from, // i.e. a module that will be taken all the // way to an object file Module *importedFrom; Dsymbols *decldefs; // top level declarations for this Module Modules aimports; // all imported modules unsigned debuglevel; // debug level Identifiers *debugids; // debug identifiers Identifiers *debugidsNot; // forward referenced debug identifiers unsigned versionlevel; // version level Identifiers *versionids; // version identifiers Identifiers *versionidsNot; // forward referenced version identifiers MacroTable macrotable; // document comment macros Escape *escapetable; // document comment escapes size_t nameoffset; // offset of module name from start of ModuleInfo size_t namelen; // length of module name in characters static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen); static const char *find(const char *filename); static Module *load(const Loc &loc, Identifiers *packages, Identifier *ident); const char *kind() const override; bool read(const Loc &loc); // read file, returns 'true' if succeed, 'false' otherwise. Module *parse(); // syntactic parse void importAll(Scope *sc) override; int needModuleInfo(); Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override; bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0) override; Dsymbol *symtabInsert(Dsymbol *s) override; void deleteObjFile(); static void runDeferredSemantic(); static void runDeferredSemantic2(); static void runDeferredSemantic3(); int imports(Module *m); bool isRoot() { return this->importedFrom == this; } // true if the module source file is directly // listed in command line. bool isCoreModule(Identifier *ident); // Back end int doppelganger; // sub-module Symbol *cov; // private uint[] __coverage; unsigned *covb; // bit array of valid code line numbers Symbol *sictor; // module order independent constructor Symbol *sctor; // module constructor Symbol *sdtor; // module destructor Symbol *ssharedctor; // module shared constructor Symbol *sshareddtor; // module shared destructor Symbol *stest; // module unit test Symbol *sfilename; // symbol for filename void *ctfe_cov; // stores coverage information from ctfe Module *isModule() override { return this; } void accept(Visitor *v) override { v->visit(this); } }; struct ModuleDeclaration { Loc loc; Identifier *id; DArray packages; // array of Identifier's representing packages bool isdeprecated; // if it is a deprecated module Expression *msg; const char *toChars() const; };