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 UngagUngag86 Ungag(unsigned old) : oldgag(old) {} ~UngagUngag87 ~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() dyncast()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(); addLocalClass(ClassDeclarations *)247 virtual void addLocalClass(ClassDeclarations *) { } addObjcSymbols(ClassDeclarations *,ClassDeclarations *)248 virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { } checkCtorConstInit()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 isPackage()260 virtual Package *isPackage() { return NULL; } isModule()261 virtual Module *isModule() { return NULL; } isEnumMember()262 virtual EnumMember *isEnumMember() { return NULL; } isTemplateDeclaration()263 virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; } isTemplateInstance()264 virtual TemplateInstance *isTemplateInstance() { return NULL; } isTemplateMixin()265 virtual TemplateMixin *isTemplateMixin() { return NULL; } isForwardingAttribDeclaration()266 virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; } isNspace()267 virtual Nspace *isNspace() { return NULL; } isDeclaration()268 virtual Declaration *isDeclaration() { return NULL; } isStorageClassDeclaration()269 virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; } isExpressionDsymbol()270 virtual ExpressionDsymbol *isExpressionDsymbol() { return NULL; } isAliasAssign()271 virtual AliasAssign *isAliasAssign() { return NULL; } isThisDeclaration()272 virtual ThisDeclaration *isThisDeclaration() { return NULL; } isBitFieldDeclaration()273 virtual BitFieldDeclaration *isBitFieldDeclaration() { return NULL; } isTypeInfoDeclaration()274 virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; } isTupleDeclaration()275 virtual TupleDeclaration *isTupleDeclaration() { return NULL; } isAliasDeclaration()276 virtual AliasDeclaration *isAliasDeclaration() { return NULL; } isAggregateDeclaration()277 virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; } isFuncDeclaration()278 virtual FuncDeclaration *isFuncDeclaration() { return NULL; } isFuncAliasDeclaration()279 virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; } isOverDeclaration()280 virtual OverDeclaration *isOverDeclaration() { return NULL; } isFuncLiteralDeclaration()281 virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } isCtorDeclaration()282 virtual CtorDeclaration *isCtorDeclaration() { return NULL; } isPostBlitDeclaration()283 virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } isDtorDeclaration()284 virtual DtorDeclaration *isDtorDeclaration() { return NULL; } isStaticCtorDeclaration()285 virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } isStaticDtorDeclaration()286 virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; } isSharedStaticCtorDeclaration()287 virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; } isSharedStaticDtorDeclaration()288 virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; } isInvariantDeclaration()289 virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; } isUnitTestDeclaration()290 virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; } isNewDeclaration()291 virtual NewDeclaration *isNewDeclaration() { return NULL; } isVarDeclaration()292 virtual VarDeclaration *isVarDeclaration() { return NULL; } isVersionSymbol()293 virtual VersionSymbol *isVersionSymbol() { return NULL; } isDebugSymbol()294 virtual DebugSymbol *isDebugSymbol() { return NULL; } isClassDeclaration()295 virtual ClassDeclaration *isClassDeclaration() { return NULL; } isStructDeclaration()296 virtual StructDeclaration *isStructDeclaration() { return NULL; } isUnionDeclaration()297 virtual UnionDeclaration *isUnionDeclaration() { return NULL; } isInterfaceDeclaration()298 virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; } isScopeDsymbol()299 virtual ScopeDsymbol *isScopeDsymbol() { return NULL; } isForwardingScopeDsymbol()300 virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; } isWithScopeSymbol()301 virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; } isArrayScopeSymbol()302 virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } isImport()303 virtual Import *isImport() { return NULL; } isEnumDeclaration()304 virtual EnumDeclaration *isEnumDeclaration() { return NULL; } isSymbolDeclaration()305 virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } isAttribDeclaration()306 virtual AttribDeclaration *isAttribDeclaration() { return NULL; } isAnonDeclaration()307 virtual AnonDeclaration *isAnonDeclaration() { return NULL; } isCPPNamespaceDeclaration()308 virtual CPPNamespaceDeclaration *isCPPNamespaceDeclaration() { return NULL; } isVisibilityDeclaration()309 virtual VisibilityDeclaration *isVisibilityDeclaration() { return NULL; } isOverloadSet()310 virtual OverloadSet *isOverloadSet() { return NULL; } isCompileDeclaration()311 virtual CompileDeclaration *isCompileDeclaration() { return NULL; } isStaticAssert()312 virtual StaticAssert *isStaticAssert() { return NULL; } accept(Visitor * v)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 isScopeDsymbol()344 ScopeDsymbol *isScopeDsymbol() { return this; } accept(Visitor * v)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 isWithScopeSymbol()357 WithScopeSymbol *isWithScopeSymbol() { return this; } accept(Visitor * v)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 isArrayScopeSymbol()372 ArrayScopeSymbol *isArrayScopeSymbol() { return this; } accept(Visitor * v)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); isOverloadSet()384 OverloadSet *isOverloadSet() { return this; } 385 const char *kind() const; accept(Visitor * v)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 isForwardingScopeDsymbol()401 ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; } 402 }; 403 404 class ExpressionDsymbol : public Dsymbol 405 { 406 public: 407 Expression *exp; 408 isExpressionDsymbol()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