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