Home | History | Annotate | Line # | Download | only in dmd
      1 
      2 /* Compiler implementation of the D programming language
      3  * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
      4  * written by Walter Bright
      5  * https://www.digitalmars.com
      6  * Distributed under the Boost Software License, Version 1.0.
      7  * https://www.boost.org/LICENSE_1_0.txt
      8  * https://github.com/dlang/dmd/blob/master/src/dmd/dsymbol.h
      9  */
     10 
     11 #pragma once
     12 
     13 #include "root/port.h"
     14 #include "ast_node.h"
     15 #include "globals.h"
     16 #include "arraytypes.h"
     17 #include "visitor.h"
     18 
     19 class CPPNamespaceDeclaration;
     20 class Identifier;
     21 struct Scope;
     22 class DsymbolTable;
     23 class Declaration;
     24 class ThisDeclaration;
     25 class BitFieldDeclaration;
     26 class TypeInfoDeclaration;
     27 class TupleDeclaration;
     28 class AliasDeclaration;
     29 class AggregateDeclaration;
     30 class EnumDeclaration;
     31 class ClassDeclaration;
     32 class InterfaceDeclaration;
     33 class StructDeclaration;
     34 class UnionDeclaration;
     35 class FuncDeclaration;
     36 class FuncAliasDeclaration;
     37 class OverDeclaration;
     38 class FuncLiteralDeclaration;
     39 class CtorDeclaration;
     40 class PostBlitDeclaration;
     41 class DtorDeclaration;
     42 class StaticCtorDeclaration;
     43 class StaticDtorDeclaration;
     44 class SharedStaticCtorDeclaration;
     45 class SharedStaticDtorDeclaration;
     46 class InvariantDeclaration;
     47 class UnitTestDeclaration;
     48 class NewDeclaration;
     49 class VarDeclaration;
     50 class AttribDeclaration;
     51 class VisibilityDeclaration;
     52 class Package;
     53 class Module;
     54 class Import;
     55 class Type;
     56 class TypeTuple;
     57 class WithStatement;
     58 class LabelDsymbol;
     59 class ScopeDsymbol;
     60 class ForwardingScopeDsymbol;
     61 class TemplateDeclaration;
     62 class TemplateInstance;
     63 class TemplateMixin;
     64 class ForwardingAttribDeclaration;
     65 class Nspace;
     66 class EnumMember;
     67 class WithScopeSymbol;
     68 class ArrayScopeSymbol;
     69 class SymbolDeclaration;
     70 class Expression;
     71 class ExpressionDsymbol;
     72 class AliasAssign;
     73 class OverloadSet;
     74 class StaticAssert;
     75 struct AA;
     76 #ifdef IN_GCC
     77 typedef union tree_node Symbol;
     78 #else
     79 struct Symbol;
     80 #endif
     81 
     82 struct Ungag
     83 {
     84     unsigned oldgag;
     85 
     86     Ungag(unsigned old) : oldgag(old) {}
     87     ~Ungag() { global.gag = oldgag; }
     88 };
     89 
     90 void dsymbolSemantic(Dsymbol *dsym, Scope *sc);
     91 void semantic2(Dsymbol *dsym, Scope *sc);
     92 void semantic3(Dsymbol *dsym, Scope* sc);
     93 
     94 struct Visibility
     95 {
     96     enum Kind
     97     {
     98         undefined,
     99         none,           // no access
    100         private_,
    101         package_,
    102         protected_,
    103         public_,
    104         export_
    105     };
    106     Kind kind;
    107     Package *pkg;
    108 };
    109 
    110 /* State of symbol in winding its way through the passes of the compiler
    111  */
    112 enum class PASS : uint8_t
    113 {
    114     initial,        // initial state
    115     semantic,       // semantic() started
    116     semanticdone,   // semantic() done
    117     semantic2,      // semantic2() started
    118     semantic2done,  // semantic2() done
    119     semantic3,      // semantic3() started
    120     semantic3done,  // semantic3() done
    121     inline_,         // inline started
    122     inlinedone,     // inline done
    123     obj             // toObjFile() run
    124 };
    125 
    126 enum
    127 {
    128     PASSinit,           // initial state
    129     PASSsemantic,       // semantic() started
    130     PASSsemanticdone,   // semantic() done
    131     PASSsemantic2,      // semantic2() started
    132     PASSsemantic2done,  // semantic2() done
    133     PASSsemantic3,      // semantic3() started
    134     PASSsemantic3done,  // semantic3() done
    135     PASSinline,         // inline started
    136     PASSinlinedone,     // inline done
    137     PASSobj             // toObjFile() run
    138 };
    139 
    140 /* Flags for symbol search
    141  */
    142 enum
    143 {
    144     IgnoreNone              = 0x00, // default
    145     IgnorePrivateImports    = 0x01, // don't search private imports
    146     IgnoreErrors            = 0x02, // don't give error messages
    147     IgnoreAmbiguous         = 0x04, // return NULL if ambiguous
    148     SearchLocalsOnly        = 0x08, // only look at locals (don't search imports)
    149     SearchImportsOnly       = 0x10, // only look in imports
    150     SearchUnqualifiedModule = 0x20, // the module scope search is unqualified,
    151                                     // meaning don't search imports in that scope,
    152                                     // because qualified module searches search
    153                                     // their imports
    154     IgnoreSymbolVisibility  = 0x80,  // also find private and package protected symbols
    155     TagNameSpace            = 0x100, // search ImportC tag symbol table
    156 };
    157 
    158 struct FieldState
    159 {
    160     unsigned offset;
    161 
    162     unsigned fieldOffset;
    163     unsigned fieldSize;
    164     unsigned fieldAlign;
    165     unsigned bitOffset;
    166 
    167     bool inFlight;
    168 };
    169 
    170 class Dsymbol : public ASTNode
    171 {
    172 public:
    173     Identifier *ident;
    174     Dsymbol *parent;
    175     /// C++ namespace this symbol belongs to
    176     CPPNamespaceDeclaration *namespace_;
    177     Symbol *csym;               // symbol for code generator
    178     Loc loc;                    // where defined
    179     Scope *_scope;               // !=NULL means context to use for semantic()
    180     const utf8_t *prettystring;
    181     bool errors;                // this symbol failed to pass semantic()
    182     PASS semanticRun;
    183     unsigned short localNum;        // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab
    184     DeprecatedDeclaration *depdecl; // customized deprecation message
    185     UserAttributeDeclaration *userAttribDecl;   // user defined attributes
    186 
    187     static Dsymbol *create(Identifier *);
    188     const char *toChars() const;
    189     virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments
    190     Loc getLoc();
    191     const char *locToChars();
    192     bool equals(const RootObject *o) const;
    193     bool isAnonymous() const;
    194     void error(const Loc &loc, const char *format, ...);
    195     void error(const char *format, ...);
    196     void deprecation(const Loc &loc, const char *format, ...);
    197     void deprecation(const char *format, ...);
    198     bool checkDeprecated(const Loc &loc, Scope *sc);
    199     Module *getModule();
    200     bool isCsymbol();
    201     Module *getAccessModule();
    202     Dsymbol *pastMixin();
    203     Dsymbol *toParent();
    204     Dsymbol *toParent2();
    205     Dsymbol *toParentDecl();
    206     Dsymbol *toParentLocal();
    207     Dsymbol *toParentP(Dsymbol *p1, Dsymbol *p2 = NULL);
    208     TemplateInstance *isInstantiated();
    209     bool followInstantiationContext(Dsymbol *p1, Dsymbol *p2 = NULL);
    210     TemplateInstance *isSpeculative();
    211     Ungag ungagSpeculative();
    212 
    213     // kludge for template.isSymbol()
    214     DYNCAST dyncast() const { return DYNCAST_DSYMBOL; }
    215 
    216     virtual Identifier *getIdent();
    217     virtual const char *toPrettyChars(bool QualifyTypes = false);
    218     virtual const char *kind() const;
    219     virtual Dsymbol *toAlias();                 // resolve real symbol
    220     virtual Dsymbol *toAlias2();
    221     virtual void addMember(Scope *sc, ScopeDsymbol *sds);
    222     virtual void setScope(Scope *sc);
    223     virtual void importAll(Scope *sc);
    224     virtual Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);
    225     virtual bool overloadInsert(Dsymbol *s);
    226     virtual uinteger_t size(const Loc &loc);
    227     virtual bool isforwardRef();
    228     virtual AggregateDeclaration *isThis();     // is a 'this' required to access the member
    229     virtual bool isExport() const;              // is Dsymbol exported?
    230     virtual bool isImportedSymbol() const;      // is Dsymbol imported?
    231     virtual bool isDeprecated() const;                // is Dsymbol deprecated?
    232     virtual bool isOverloadable() const;
    233     virtual LabelDsymbol *isLabel();            // is this a LabelDsymbol?
    234     AggregateDeclaration *isMember();           // is toParent() an AggregateDeclaration?
    235     AggregateDeclaration *isMember2();          // is toParent2() an AggregateDeclaration?
    236     AggregateDeclaration *isMemberDecl();       // is toParentDecl() an AggregateDeclaration?
    237     AggregateDeclaration *isMemberLocal();      // is toParentLocal() an AggregateDeclaration?
    238     ClassDeclaration *isClassMember();          // isMember() is a ClassDeclaration?
    239     virtual Type *getType();                    // is this a type?
    240     virtual bool needThis();                    // need a 'this' pointer?
    241     virtual Visibility visible();
    242     virtual Dsymbol *syntaxCopy(Dsymbol *s);    // copy only syntax trees
    243     virtual bool oneMember(Dsymbol **ps, Identifier *ident);
    244     virtual void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
    245     virtual bool hasPointers();
    246     virtual bool hasStaticCtorOrDtor();
    247     virtual void addLocalClass(ClassDeclarations *) { }
    248     virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { }
    249     virtual void checkCtorConstInit() { }
    250 
    251     virtual void addComment(const utf8_t *comment);
    252     const utf8_t *comment();                      // current value of comment
    253 
    254     UnitTestDeclaration *ddocUnittest();
    255     void ddocUnittest(UnitTestDeclaration *);
    256 
    257     bool inNonRoot();
    258 
    259     // Eliminate need for dynamic_cast
    260     virtual Package *isPackage() { return NULL; }
    261     virtual Module *isModule() { return NULL; }
    262     virtual EnumMember *isEnumMember() { return NULL; }
    263     virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
    264     virtual TemplateInstance *isTemplateInstance() { return NULL; }
    265     virtual TemplateMixin *isTemplateMixin() { return NULL; }
    266     virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; }
    267     virtual Nspace *isNspace() { return NULL; }
    268     virtual Declaration *isDeclaration() { return NULL; }
    269     virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; }
    270     virtual ExpressionDsymbol *isExpressionDsymbol() { return NULL; }
    271     virtual AliasAssign *isAliasAssign() { return NULL; }
    272     virtual ThisDeclaration *isThisDeclaration() { return NULL; }
    273     virtual BitFieldDeclaration *isBitFieldDeclaration() { return NULL; }
    274     virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; }
    275     virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
    276     virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
    277     virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
    278     virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
    279     virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
    280     virtual OverDeclaration *isOverDeclaration() { return NULL; }
    281     virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
    282     virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
    283     virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }
    284     virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
    285     virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
    286     virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
    287     virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
    288     virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
    289     virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
    290     virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
    291     virtual NewDeclaration *isNewDeclaration() { return NULL; }
    292     virtual VarDeclaration *isVarDeclaration() { return NULL; }
    293     virtual VersionSymbol *isVersionSymbol() { return NULL; }
    294     virtual DebugSymbol *isDebugSymbol() { return NULL; }
    295     virtual ClassDeclaration *isClassDeclaration() { return NULL; }
    296     virtual StructDeclaration *isStructDeclaration() { return NULL; }
    297     virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
    298     virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
    299     virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
    300     virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; }
    301     virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
    302     virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
    303     virtual Import *isImport() { return NULL; }
    304     virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
    305     virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
    306     virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
    307     virtual AnonDeclaration *isAnonDeclaration() { return NULL; }
    308     virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return NULL; }
    309     virtual VisibilityDeclaration *isVisibilityDeclaration() { return NULL; }
    310     virtual OverloadSet *isOverloadSet() { return NULL; }
    311     virtual CompileDeclaration *isCompileDeclaration() { return NULL; }
    312     virtual StaticAssert *isStaticAssert() { return NULL; }
    313     void accept(Visitor *v) { v->visit(this); }
    314 };
    315 
    316 // Dsymbol that generates a scope
    317 
    318 class ScopeDsymbol : public Dsymbol
    319 {
    320 public:
    321     Dsymbols *members;          // all Dsymbol's in this scope
    322     DsymbolTable *symtab;       // members[] sorted into table
    323     unsigned endlinnum;         // the linnumber of the statement after the scope (0 if unknown)
    324 
    325 private:
    326     Dsymbols *importedScopes;   // imported Dsymbol's
    327     Visibility::Kind *visibilities;   // array of `Visibility.Kind`, one for each import
    328 
    329     BitArray accessiblePackages, privateAccessiblePackages;
    330 
    331 public:
    332     ScopeDsymbol *syntaxCopy(Dsymbol *s);
    333     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
    334     virtual void importScope(Dsymbol *s, Visibility visibility);
    335     virtual bool isPackageAccessible(Package *p, Visibility visibility, int flags = 0);
    336     bool isforwardRef();
    337     static void multiplyDefined(const Loc &loc, Dsymbol *s1, Dsymbol *s2);
    338     const char *kind() const;
    339     FuncDeclaration *findGetMembers();
    340     virtual Dsymbol *symtabInsert(Dsymbol *s);
    341     virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
    342     bool hasStaticCtorOrDtor();
    343 
    344     ScopeDsymbol *isScopeDsymbol() { return this; }
    345     void accept(Visitor *v) { v->visit(this); }
    346 };
    347 
    348 // With statement scope
    349 
    350 class WithScopeSymbol : public ScopeDsymbol
    351 {
    352 public:
    353     WithStatement *withstate;
    354 
    355     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
    356 
    357     WithScopeSymbol *isWithScopeSymbol() { return this; }
    358     void accept(Visitor *v) { v->visit(this); }
    359 };
    360 
    361 // Array Index/Slice scope
    362 
    363 class ArrayScopeSymbol : public ScopeDsymbol
    364 {
    365 private:
    366     RootObject *arrayContent;
    367 public:
    368     Scope *sc;
    369 
    370     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone);
    371 
    372     ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
    373     void accept(Visitor *v) { v->visit(this); }
    374 };
    375 
    376 // Overload Sets
    377 
    378 class OverloadSet : public Dsymbol
    379 {
    380 public:
    381     Dsymbols a;         // array of Dsymbols
    382 
    383     void push(Dsymbol *s);
    384     OverloadSet *isOverloadSet() { return this; }
    385     const char *kind() const;
    386     void accept(Visitor *v) { v->visit(this); }
    387 };
    388 
    389 // Forwarding ScopeDsymbol
    390 
    391 class ForwardingScopeDsymbol : public ScopeDsymbol
    392 {
    393 public:
    394     ScopeDsymbol *forward;
    395 
    396     Dsymbol *symtabInsert(Dsymbol *s);
    397     Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
    398     void importScope(Dsymbol *s, Visibility visibility);
    399     const char *kind() const;
    400 
    401     ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; }
    402 };
    403 
    404 class ExpressionDsymbol : public Dsymbol
    405 {
    406 public:
    407     Expression *exp;
    408 
    409     ExpressionDsymbol *isExpressionDsymbol() { return this; }
    410 };
    411 
    412 // Table of Dsymbol's
    413 
    414 class DsymbolTable : public RootObject
    415 {
    416 public:
    417     AA *tab;
    418 
    419     // Look up Identifier. Return Dsymbol if found, NULL if not.
    420     Dsymbol *lookup(Identifier const * const ident);
    421 
    422     // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
    423     void update(Dsymbol *s);
    424 
    425     // Insert Dsymbol in table. Return NULL if already there.
    426     Dsymbol *insert(Dsymbol *s);
    427     Dsymbol *insert(Identifier const * const ident, Dsymbol *s);     // when ident and s are not the same
    428 
    429     // Number of symbols in symbol table
    430     size_t length() const;
    431 };
    432