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/dlang/dmd/blob/master/src/dmd/dsymbol.h 9 */ 10 11 #pragma once 12 13 #include "root/root.h" 14 #include "root/stringtable.h" 15 16 #include "globals.h" 17 #include "arraytypes.h" 18 #include "visitor.h" 19 20 class Identifier; 21 struct Scope; 22 class DsymbolTable; 23 class Declaration; 24 class ThisDeclaration; 25 class TypeInfoDeclaration; 26 class TupleDeclaration; 27 class AliasDeclaration; 28 class AggregateDeclaration; 29 class EnumDeclaration; 30 class ClassDeclaration; 31 class InterfaceDeclaration; 32 class StructDeclaration; 33 class UnionDeclaration; 34 class FuncDeclaration; 35 class FuncAliasDeclaration; 36 class OverDeclaration; 37 class FuncLiteralDeclaration; 38 class CtorDeclaration; 39 class PostBlitDeclaration; 40 class DtorDeclaration; 41 class StaticCtorDeclaration; 42 class StaticDtorDeclaration; 43 class SharedStaticCtorDeclaration; 44 class SharedStaticDtorDeclaration; 45 class InvariantDeclaration; 46 class UnitTestDeclaration; 47 class NewDeclaration; 48 class VarDeclaration; 49 class AttribDeclaration; 50 class Package; 51 class Module; 52 class Import; 53 class Type; 54 class TypeTuple; 55 class WithStatement; 56 class LabelDsymbol; 57 class ScopeDsymbol; 58 class ForwardingScopeDsymbol; 59 class TemplateDeclaration; 60 class TemplateInstance; 61 class TemplateMixin; 62 class ForwardingAttribDeclaration; 63 class Nspace; 64 class EnumMember; 65 class WithScopeSymbol; 66 class ArrayScopeSymbol; 67 class SymbolDeclaration; 68 class Expression; 69 class DeleteDeclaration; 70 class OverloadSet; 71 struct AA; 72 #ifdef IN_GCC 73 typedef union tree_node Symbol; 74 #else 75 struct Symbol; 76 #endif 77 78 struct Ungag 79 { 80 unsigned oldgag; 81 UngagUngag82 Ungag(unsigned old) : oldgag(old) {} ~UngagUngag83 ~Ungag() { global.gag = oldgag; } 84 }; 85 86 enum PROTKIND 87 { 88 PROTundefined, 89 PROTnone, // no access 90 PROTprivate, 91 PROTpackage, 92 PROTprotected, 93 PROTpublic, 94 PROTexport 95 }; 96 97 struct Prot 98 { 99 PROTKIND kind; 100 Package *pkg; 101 102 Prot(); 103 Prot(PROTKIND kind); 104 105 bool isMoreRestrictiveThan(const Prot other) const; 106 bool operator==(const Prot& other) const; 107 bool isSubsetOf(const Prot& other) const; 108 }; 109 110 // in hdrgen.c 111 void protectionToBuffer(OutBuffer *buf, Prot prot); 112 const char *protectionToChars(PROTKIND kind); 113 114 /* State of symbol in winding its way through the passes of the compiler 115 */ 116 enum PASS 117 { 118 PASSinit, // initial state 119 PASSsemantic, // semantic() started 120 PASSsemanticdone, // semantic() done 121 PASSsemantic2, // semantic2() started 122 PASSsemantic2done, // semantic2() done 123 PASSsemantic3, // semantic3() started 124 PASSsemantic3done, // semantic3() done 125 PASSinline, // inline started 126 PASSinlinedone, // inline done 127 PASSobj // toObjFile() run 128 }; 129 130 /* Flags for symbol search 131 */ 132 enum 133 { 134 IgnoreNone = 0x00, // default 135 IgnorePrivateImports = 0x01, // don't search private imports 136 IgnoreErrors = 0x02, // don't give error messages 137 IgnoreAmbiguous = 0x04, // return NULL if ambiguous 138 SearchLocalsOnly = 0x08, // only look at locals (don't search imports) 139 SearchImportsOnly = 0x10, // only look in imports 140 SearchUnqualifiedModule = 0x20, // the module scope search is unqualified, 141 // meaning don't search imports in that scope, 142 // because qualified module searches search 143 // their imports 144 IgnoreSymbolVisibility = 0x80 // also find private and package protected symbols 145 }; 146 147 typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *); 148 149 class Dsymbol : public RootObject 150 { 151 public: 152 Identifier *ident; 153 Dsymbol *parent; 154 Symbol *csym; // symbol for code generator 155 Symbol *isym; // import version of csym 156 const utf8_t *comment; // documentation comment for this Dsymbol 157 Loc loc; // where defined 158 Scope *_scope; // !=NULL means context to use for semantic() 159 const utf8_t *prettystring; 160 bool errors; // this symbol failed to pass semantic() 161 PASS semanticRun; 162 DeprecatedDeclaration *depdecl; // customized deprecation message 163 UserAttributeDeclaration *userAttribDecl; // user defined attributes 164 UnitTestDeclaration *ddocUnittest; // !=NULL means there's a ddoc unittest associated with this symbol (only use this with ddoc) 165 166 Dsymbol(); 167 Dsymbol(Identifier *); 168 static Dsymbol *create(Identifier *); 169 const char *toChars(); 170 virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments 171 Loc& getLoc(); 172 const char *locToChars(); 173 bool equals(RootObject *o); 174 bool isAnonymous(); 175 void error(Loc loc, const char *format, ...); 176 void error(const char *format, ...); 177 void deprecation(Loc loc, const char *format, ...); 178 void deprecation(const char *format, ...); 179 void checkDeprecated(Loc loc, Scope *sc); 180 Module *getModule(); 181 Module *getAccessModule(); 182 Dsymbol *pastMixin(); 183 Dsymbol *pastMixinAndNspace(); 184 Dsymbol *toParent(); 185 Dsymbol *toParent2(); 186 Dsymbol *toParent3(); 187 TemplateInstance *isInstantiated(); 188 TemplateInstance *isSpeculative(); 189 Ungag ungagSpeculative(); 190 191 // kludge for template.isSymbol() dyncast()192 int dyncast() const { return DYNCAST_DSYMBOL; } 193 194 static Dsymbols *arraySyntaxCopy(Dsymbols *a); 195 196 virtual Identifier *getIdent(); 197 virtual const char *toPrettyChars(bool QualifyTypes = false); 198 virtual const char *kind() const; 199 virtual Dsymbol *toAlias(); // resolve real symbol 200 virtual Dsymbol *toAlias2(); 201 virtual int apply(Dsymbol_apply_ft_t fp, void *param); 202 virtual void addMember(Scope *sc, ScopeDsymbol *sds); 203 virtual void setScope(Scope *sc); 204 virtual void importAll(Scope *sc); 205 virtual void semantic(Scope *sc); 206 virtual void semantic2(Scope *sc); 207 virtual void semantic3(Scope *sc); 208 virtual Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone); 209 Dsymbol *search_correct(Identifier *id); 210 Dsymbol *searchX(Loc loc, Scope *sc, RootObject *id); 211 virtual bool overloadInsert(Dsymbol *s); 212 virtual d_uns64 size(Loc loc); 213 virtual bool isforwardRef(); 214 virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member 215 virtual bool isExport() const; // is Dsymbol exported? 216 virtual bool isImportedSymbol() const; // is Dsymbol imported? 217 virtual bool isDeprecated(); // is Dsymbol deprecated? 218 virtual bool isOverloadable(); 219 virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol? 220 AggregateDeclaration *isMember(); // is this a member of an AggregateDeclaration? 221 AggregateDeclaration *isMember2(); // is this a member of an AggregateDeclaration? 222 ClassDeclaration *isClassMember(); // is this a member of a ClassDeclaration? 223 virtual Type *getType(); // is this a type? 224 virtual bool needThis(); // need a 'this' pointer? 225 virtual Prot prot(); 226 virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees 227 virtual bool oneMember(Dsymbol **ps, Identifier *ident); 228 static bool oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident); 229 virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); 230 virtual bool hasPointers(); 231 virtual bool hasStaticCtorOrDtor(); addLocalClass(ClassDeclarations *)232 virtual void addLocalClass(ClassDeclarations *) { } checkCtorConstInit()233 virtual void checkCtorConstInit() { } 234 235 virtual void addComment(const utf8_t *comment); 236 237 bool inNonRoot(); 238 239 // Eliminate need for dynamic_cast isPackage()240 virtual Package *isPackage() { return NULL; } isModule()241 virtual Module *isModule() { return NULL; } isEnumMember()242 virtual EnumMember *isEnumMember() { return NULL; } isTemplateDeclaration()243 virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; } isTemplateInstance()244 virtual TemplateInstance *isTemplateInstance() { return NULL; } isTemplateMixin()245 virtual TemplateMixin *isTemplateMixin() { return NULL; } isForwardingAttribDeclaration()246 virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; } isNspace()247 virtual Nspace *isNspace() { return NULL; } isDeclaration()248 virtual Declaration *isDeclaration() { return NULL; } isStorageClassDeclaration()249 virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; } isThisDeclaration()250 virtual ThisDeclaration *isThisDeclaration() { return NULL; } isTypeInfoDeclaration()251 virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; } isTupleDeclaration()252 virtual TupleDeclaration *isTupleDeclaration() { return NULL; } isAliasDeclaration()253 virtual AliasDeclaration *isAliasDeclaration() { return NULL; } isAggregateDeclaration()254 virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; } isFuncDeclaration()255 virtual FuncDeclaration *isFuncDeclaration() { return NULL; } isFuncAliasDeclaration()256 virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; } isOverDeclaration()257 virtual OverDeclaration *isOverDeclaration() { return NULL; } isFuncLiteralDeclaration()258 virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; } isCtorDeclaration()259 virtual CtorDeclaration *isCtorDeclaration() { return NULL; } isPostBlitDeclaration()260 virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; } isDtorDeclaration()261 virtual DtorDeclaration *isDtorDeclaration() { return NULL; } isStaticCtorDeclaration()262 virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; } isStaticDtorDeclaration()263 virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; } isSharedStaticCtorDeclaration()264 virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; } isSharedStaticDtorDeclaration()265 virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; } isInvariantDeclaration()266 virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; } isUnitTestDeclaration()267 virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; } isNewDeclaration()268 virtual NewDeclaration *isNewDeclaration() { return NULL; } isVarDeclaration()269 virtual VarDeclaration *isVarDeclaration() { return NULL; } isClassDeclaration()270 virtual ClassDeclaration *isClassDeclaration() { return NULL; } isStructDeclaration()271 virtual StructDeclaration *isStructDeclaration() { return NULL; } isUnionDeclaration()272 virtual UnionDeclaration *isUnionDeclaration() { return NULL; } isInterfaceDeclaration()273 virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; } isScopeDsymbol()274 virtual ScopeDsymbol *isScopeDsymbol() { return NULL; } isForwardingScopeDsymbol()275 virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; } isWithScopeSymbol()276 virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; } isArrayScopeSymbol()277 virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; } isImport()278 virtual Import *isImport() { return NULL; } isEnumDeclaration()279 virtual EnumDeclaration *isEnumDeclaration() { return NULL; } isDeleteDeclaration()280 virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } isSymbolDeclaration()281 virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } isAttribDeclaration()282 virtual AttribDeclaration *isAttribDeclaration() { return NULL; } isAnonDeclaration()283 virtual AnonDeclaration *isAnonDeclaration() { return NULL; } isOverloadSet()284 virtual OverloadSet *isOverloadSet() { return NULL; } accept(Visitor * v)285 virtual void accept(Visitor *v) { v->visit(this); } 286 }; 287 288 // Dsymbol that generates a scope 289 290 class ScopeDsymbol : public Dsymbol 291 { 292 public: 293 Dsymbols *members; // all Dsymbol's in this scope 294 DsymbolTable *symtab; // members[] sorted into table 295 unsigned endlinnum; // the linnumber of the statement after the scope (0 if unknown) 296 297 private: 298 Dsymbols *importedScopes; // imported Dsymbol's 299 PROTKIND *prots; // array of PROTKIND, one for each import 300 301 BitArray accessiblePackages, privateAccessiblePackages; 302 303 public: 304 ScopeDsymbol(); 305 ScopeDsymbol(Identifier *id); 306 Dsymbol *syntaxCopy(Dsymbol *s); 307 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 308 OverloadSet *mergeOverloadSet(Identifier *ident, OverloadSet *os, Dsymbol *s); 309 virtual void importScope(Dsymbol *s, Prot protection); 310 void addAccessiblePackage(Package *p, Prot protection); 311 virtual bool isPackageAccessible(Package *p, Prot protection, int flags = 0); 312 bool isforwardRef(); 313 static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2); 314 const char *kind() const; 315 FuncDeclaration *findGetMembers(); 316 virtual Dsymbol *symtabInsert(Dsymbol *s); 317 virtual Dsymbol *symtabLookup(Dsymbol *s, Identifier *id); 318 bool hasStaticCtorOrDtor(); 319 320 static size_t dim(Dsymbols *members); 321 static Dsymbol *getNth(Dsymbols *members, size_t nth, size_t *pn = NULL); 322 isScopeDsymbol()323 ScopeDsymbol *isScopeDsymbol() { return this; } 324 void semantic(Scope *sc); accept(Visitor * v)325 void accept(Visitor *v) { v->visit(this); } 326 }; 327 328 // With statement scope 329 330 class WithScopeSymbol : public ScopeDsymbol 331 { 332 public: 333 WithStatement *withstate; 334 335 WithScopeSymbol(WithStatement *withstate); 336 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 337 isWithScopeSymbol()338 WithScopeSymbol *isWithScopeSymbol() { return this; } accept(Visitor * v)339 void accept(Visitor *v) { v->visit(this); } 340 }; 341 342 // Array Index/Slice scope 343 344 class ArrayScopeSymbol : public ScopeDsymbol 345 { 346 public: 347 Expression *exp; // IndexExp or SliceExp 348 TypeTuple *type; // for tuple[length] 349 TupleDeclaration *td; // for tuples of objects 350 Scope *sc; 351 352 ArrayScopeSymbol(Scope *sc, Expression *e); 353 ArrayScopeSymbol(Scope *sc, TypeTuple *t); 354 ArrayScopeSymbol(Scope *sc, TupleDeclaration *td); 355 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = IgnoreNone); 356 isArrayScopeSymbol()357 ArrayScopeSymbol *isArrayScopeSymbol() { return this; } accept(Visitor * v)358 void accept(Visitor *v) { v->visit(this); } 359 }; 360 361 // Overload Sets 362 363 class OverloadSet : public Dsymbol 364 { 365 public: 366 Dsymbols a; // array of Dsymbols 367 368 OverloadSet(Identifier *ident, OverloadSet *os = NULL); 369 void push(Dsymbol *s); isOverloadSet()370 OverloadSet *isOverloadSet() { return this; } 371 const char *kind() const; accept(Visitor * v)372 void accept(Visitor *v) { v->visit(this); } 373 }; 374 375 // Forwarding ScopeDsymbol 376 377 class ForwardingScopeDsymbol : public ScopeDsymbol 378 { 379 public: 380 ScopeDsymbol *forward; 381 382 ForwardingScopeDsymbol(ScopeDsymbol *forward); 383 Dsymbol *symtabInsert(Dsymbol *s); 384 Dsymbol *symtabLookup(Dsymbol *s, Identifier *id); 385 void importScope(Dsymbol *s, Prot protection); 386 void semantic(Scope *sc); 387 const char *kind() const; 388 isForwardingScopeDsymbol()389 ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; } 390 }; 391 392 // Table of Dsymbol's 393 394 class DsymbolTable : public RootObject 395 { 396 public: 397 AA *tab; 398 399 DsymbolTable(); 400 401 // Look up Identifier. Return Dsymbol if found, NULL if not. 402 Dsymbol *lookup(Identifier const * const ident); 403 404 // Insert Dsymbol in table. Return NULL if already there. 405 Dsymbol *insert(Dsymbol *s); 406 407 // Look for Dsymbol in table. If there, return it. If not, insert s and return that. 408 Dsymbol *update(Dsymbol *s); 409 Dsymbol *insert(Identifier const * const ident, Dsymbol *s); // when ident and s are not the same 410 }; 411