145
|
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
|
|
82 Ungag(unsigned old) : oldgag(old) {}
|
|
83 ~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()
|
|
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();
|
|
232 virtual void addLocalClass(ClassDeclarations *) { }
|
|
233 virtual void checkCtorConstInit() { }
|
|
234
|
|
235 virtual void addComment(const utf8_t *comment);
|
|
236
|
|
237 bool inNonRoot();
|
|
238
|
|
239 // Eliminate need for dynamic_cast
|
|
240 virtual Package *isPackage() { return NULL; }
|
|
241 virtual Module *isModule() { return NULL; }
|
|
242 virtual EnumMember *isEnumMember() { return NULL; }
|
|
243 virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
|
|
244 virtual TemplateInstance *isTemplateInstance() { return NULL; }
|
|
245 virtual TemplateMixin *isTemplateMixin() { return NULL; }
|
|
246 virtual ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return NULL; }
|
|
247 virtual Nspace *isNspace() { return NULL; }
|
|
248 virtual Declaration *isDeclaration() { return NULL; }
|
|
249 virtual StorageClassDeclaration *isStorageClassDeclaration(){ return NULL; }
|
|
250 virtual ThisDeclaration *isThisDeclaration() { return NULL; }
|
|
251 virtual TypeInfoDeclaration *isTypeInfoDeclaration() { return NULL; }
|
|
252 virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
|
|
253 virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
|
|
254 virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
|
|
255 virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
|
|
256 virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
|
|
257 virtual OverDeclaration *isOverDeclaration() { return NULL; }
|
|
258 virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
|
|
259 virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
|
|
260 virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }
|
|
261 virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
|
262 virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
|
263 virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
|
264 virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
|
|
265 virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
|
|
266 virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
|
267 virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
|
268 virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
|
269 virtual VarDeclaration *isVarDeclaration() { return NULL; }
|
|
270 virtual ClassDeclaration *isClassDeclaration() { return NULL; }
|
|
271 virtual StructDeclaration *isStructDeclaration() { return NULL; }
|
|
272 virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
|
|
273 virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
|
|
274 virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
|
|
275 virtual ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return NULL; }
|
|
276 virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
|
|
277 virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
|
|
278 virtual Import *isImport() { return NULL; }
|
|
279 virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
|
|
280 virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
|
|
281 virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; }
|
|
282 virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
|
|
283 virtual AnonDeclaration *isAnonDeclaration() { return NULL; }
|
|
284 virtual OverloadSet *isOverloadSet() { return NULL; }
|
|
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
|
|
323 ScopeDsymbol *isScopeDsymbol() { return this; }
|
|
324 void semantic(Scope *sc);
|
|
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
|
|
338 WithScopeSymbol *isWithScopeSymbol() { return this; }
|
|
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
|
|
357 ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
|
|
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);
|
|
370 OverloadSet *isOverloadSet() { return this; }
|
|
371 const char *kind() const;
|
|
372 void accept(Visitor *v) { v->visit(this); }
|
|
373 };
|
|
374
|
|
375 // Forwarding ScopeDsymbol
|
|
376
|
|
377 class ForwardingScopeDsymbol : public ScopeDsymbol
|
|
378 {
|
|
379 ScopeDsymbol *forward;
|
|
380
|
|
381 Dsymbol *symtabInsert(Dsymbol *s);
|
|
382 Dsymbol *symtabLookup(Dsymbol *s, Identifier *id);
|
|
383 void importScope(Dsymbol *s, Prot protection);
|
|
384 void semantic(Scope *sc);
|
|
385 const char *kind() const;
|
|
386
|
|
387 ForwardingScopeDsymbol *isForwardingScopeDsymbol() { return this; }
|
|
388 };
|
|
389
|
|
390 // Table of Dsymbol's
|
|
391
|
|
392 class DsymbolTable : public RootObject
|
|
393 {
|
|
394 public:
|
|
395 AA *tab;
|
|
396
|
|
397 DsymbolTable();
|
|
398
|
|
399 // Look up Identifier. Return Dsymbol if found, NULL if not.
|
|
400 Dsymbol *lookup(Identifier const * const ident);
|
|
401
|
|
402 // Insert Dsymbol in table. Return NULL if already there.
|
|
403 Dsymbol *insert(Dsymbol *s);
|
|
404
|
|
405 // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
|
406 Dsymbol *update(Dsymbol *s);
|
|
407 Dsymbol *insert(Identifier const * const ident, Dsymbol *s); // when ident and s are not the same
|
|
408 };
|