2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 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
13 #include "root/root.h"
14 #include "root/stringtable.h"
17 #include "arraytypes.h"
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
;
49 class AttribDeclaration
;
58 class ForwardingScopeDsymbol
;
59 class TemplateDeclaration
;
60 class TemplateInstance
;
62 class ForwardingAttribDeclaration
;
65 class WithScopeSymbol
;
66 class ArrayScopeSymbol
;
67 class SymbolDeclaration
;
69 class DeleteDeclaration
;
73 typedef union tree_node Symbol
;
82 Ungag(unsigned old
) : oldgag(old
) {}
83 ~Ungag() { global
.gag
= oldgag
; }
89 PROTnone
, // no access
105 bool isMoreRestrictiveThan(const Prot other
) const;
106 bool operator==(const Prot
& other
) const;
107 bool isSubsetOf(const Prot
& other
) const;
111 void protectionToBuffer(OutBuffer
*buf
, Prot prot
);
112 const char *protectionToChars(PROTKIND kind
);
114 /* State of symbol in winding its way through the passes of the compiler
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
130 /* Flags for symbol search
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
144 IgnoreSymbolVisibility
= 0x80 // also find private and package protected symbols
147 typedef int (*Dsymbol_apply_ft_t
)(Dsymbol
*, void *);
149 class Dsymbol
: public RootObject
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()
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)
167 Dsymbol(Identifier
*);
168 static Dsymbol
*create(Identifier
*);
169 const char *toChars();
170 virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments
172 const char *locToChars();
173 bool equals(RootObject
*o
);
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
);
181 Module
*getAccessModule();
182 Dsymbol
*pastMixin();
184 Dsymbol
*toParent2();
185 TemplateInstance
*isInstantiated();
186 TemplateInstance
*isSpeculative();
187 Ungag
ungagSpeculative();
189 // kludge for template.isSymbol()
190 int dyncast() const { return DYNCAST_DSYMBOL
; }
192 static Dsymbols
*arraySyntaxCopy(Dsymbols
*a
);
194 virtual Identifier
*getIdent();
195 virtual const char *toPrettyChars(bool QualifyTypes
= false);
196 virtual const char *kind();
197 virtual Dsymbol
*toAlias(); // resolve real symbol
198 virtual Dsymbol
*toAlias2();
199 virtual int apply(Dsymbol_apply_ft_t fp
, void *param
);
200 virtual void addMember(Scope
*sc
, ScopeDsymbol
*sds
);
201 virtual void setScope(Scope
*sc
);
202 virtual void importAll(Scope
*sc
);
203 virtual void semantic(Scope
*sc
);
204 virtual void semantic2(Scope
*sc
);
205 virtual void semantic3(Scope
*sc
);
206 virtual Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= IgnoreNone
);
207 Dsymbol
*search_correct(Identifier
*id
);
208 Dsymbol
*searchX(Loc loc
, Scope
*sc
, RootObject
*id
);
209 virtual bool overloadInsert(Dsymbol
*s
);
210 virtual d_uns64
size(Loc loc
);
211 virtual bool isforwardRef();
212 virtual AggregateDeclaration
*isThis(); // is a 'this' required to access the member
213 virtual bool isExport() const; // is Dsymbol exported?
214 virtual bool isImportedSymbol() const; // is Dsymbol imported?
215 virtual bool isDeprecated(); // is Dsymbol deprecated?
216 virtual bool isOverloadable();
217 virtual LabelDsymbol
*isLabel(); // is this a LabelDsymbol?
218 AggregateDeclaration
*isMember(); // is this a member of an AggregateDeclaration?
219 AggregateDeclaration
*isMember2(); // is this a member of an AggregateDeclaration?
220 ClassDeclaration
*isClassMember(); // is this a member of a ClassDeclaration?
221 virtual Type
*getType(); // is this a type?
222 virtual bool needThis(); // need a 'this' pointer?
224 virtual Dsymbol
*syntaxCopy(Dsymbol
*s
); // copy only syntax trees
225 virtual bool oneMember(Dsymbol
**ps
, Identifier
*ident
);
226 static bool oneMembers(Dsymbols
*members
, Dsymbol
**ps
, Identifier
*ident
);
227 virtual void setFieldOffset(AggregateDeclaration
*ad
, unsigned *poffset
, bool isunion
);
228 virtual bool hasPointers();
229 virtual bool hasStaticCtorOrDtor();
230 virtual void addLocalClass(ClassDeclarations
*) { }
231 virtual void checkCtorConstInit() { }
233 virtual void addComment(const utf8_t
*comment
);
237 // Eliminate need for dynamic_cast
238 virtual Package
*isPackage() { return NULL
; }
239 virtual Module
*isModule() { return NULL
; }
240 virtual EnumMember
*isEnumMember() { return NULL
; }
241 virtual TemplateDeclaration
*isTemplateDeclaration() { return NULL
; }
242 virtual TemplateInstance
*isTemplateInstance() { return NULL
; }
243 virtual TemplateMixin
*isTemplateMixin() { return NULL
; }
244 virtual ForwardingAttribDeclaration
*isForwardingAttribDeclaration() { return NULL
; }
245 virtual Nspace
*isNspace() { return NULL
; }
246 virtual Declaration
*isDeclaration() { return NULL
; }
247 virtual StorageClassDeclaration
*isStorageClassDeclaration(){ return NULL
; }
248 virtual ThisDeclaration
*isThisDeclaration() { return NULL
; }
249 virtual TypeInfoDeclaration
*isTypeInfoDeclaration() { return NULL
; }
250 virtual TupleDeclaration
*isTupleDeclaration() { return NULL
; }
251 virtual AliasDeclaration
*isAliasDeclaration() { return NULL
; }
252 virtual AggregateDeclaration
*isAggregateDeclaration() { return NULL
; }
253 virtual FuncDeclaration
*isFuncDeclaration() { return NULL
; }
254 virtual FuncAliasDeclaration
*isFuncAliasDeclaration() { return NULL
; }
255 virtual OverDeclaration
*isOverDeclaration() { return NULL
; }
256 virtual FuncLiteralDeclaration
*isFuncLiteralDeclaration() { return NULL
; }
257 virtual CtorDeclaration
*isCtorDeclaration() { return NULL
; }
258 virtual PostBlitDeclaration
*isPostBlitDeclaration() { return NULL
; }
259 virtual DtorDeclaration
*isDtorDeclaration() { return NULL
; }
260 virtual StaticCtorDeclaration
*isStaticCtorDeclaration() { return NULL
; }
261 virtual StaticDtorDeclaration
*isStaticDtorDeclaration() { return NULL
; }
262 virtual SharedStaticCtorDeclaration
*isSharedStaticCtorDeclaration() { return NULL
; }
263 virtual SharedStaticDtorDeclaration
*isSharedStaticDtorDeclaration() { return NULL
; }
264 virtual InvariantDeclaration
*isInvariantDeclaration() { return NULL
; }
265 virtual UnitTestDeclaration
*isUnitTestDeclaration() { return NULL
; }
266 virtual NewDeclaration
*isNewDeclaration() { return NULL
; }
267 virtual VarDeclaration
*isVarDeclaration() { return NULL
; }
268 virtual ClassDeclaration
*isClassDeclaration() { return NULL
; }
269 virtual StructDeclaration
*isStructDeclaration() { return NULL
; }
270 virtual UnionDeclaration
*isUnionDeclaration() { return NULL
; }
271 virtual InterfaceDeclaration
*isInterfaceDeclaration() { return NULL
; }
272 virtual ScopeDsymbol
*isScopeDsymbol() { return NULL
; }
273 virtual ForwardingScopeDsymbol
*isForwardingScopeDsymbol() { return NULL
; }
274 virtual WithScopeSymbol
*isWithScopeSymbol() { return NULL
; }
275 virtual ArrayScopeSymbol
*isArrayScopeSymbol() { return NULL
; }
276 virtual Import
*isImport() { return NULL
; }
277 virtual EnumDeclaration
*isEnumDeclaration() { return NULL
; }
278 virtual DeleteDeclaration
*isDeleteDeclaration() { return NULL
; }
279 virtual SymbolDeclaration
*isSymbolDeclaration() { return NULL
; }
280 virtual AttribDeclaration
*isAttribDeclaration() { return NULL
; }
281 virtual AnonDeclaration
*isAnonDeclaration() { return NULL
; }
282 virtual OverloadSet
*isOverloadSet() { return NULL
; }
283 virtual void accept(Visitor
*v
) { v
->visit(this); }
286 // Dsymbol that generates a scope
288 class ScopeDsymbol
: public Dsymbol
291 Dsymbols
*members
; // all Dsymbol's in this scope
292 DsymbolTable
*symtab
; // members[] sorted into table
293 unsigned endlinnum
; // the linnumber of the statement after the scope (0 if unknown)
296 Dsymbols
*importedScopes
; // imported Dsymbol's
297 PROTKIND
*prots
; // array of PROTKIND, one for each import
299 BitArray accessiblePackages
, privateAccessiblePackages
;
303 ScopeDsymbol(Identifier
*id
);
304 Dsymbol
*syntaxCopy(Dsymbol
*s
);
305 Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= SearchLocalsOnly
);
306 OverloadSet
*mergeOverloadSet(Identifier
*ident
, OverloadSet
*os
, Dsymbol
*s
);
307 virtual void importScope(Dsymbol
*s
, Prot protection
);
308 void addAccessiblePackage(Package
*p
, Prot protection
);
309 virtual bool isPackageAccessible(Package
*p
, Prot protection
, int flags
= 0);
311 static void multiplyDefined(Loc loc
, Dsymbol
*s1
, Dsymbol
*s2
);
313 FuncDeclaration
*findGetMembers();
314 virtual Dsymbol
*symtabInsert(Dsymbol
*s
);
315 virtual Dsymbol
*symtabLookup(Dsymbol
*s
, Identifier
*id
);
316 bool hasStaticCtorOrDtor();
318 static size_t dim(Dsymbols
*members
);
319 static Dsymbol
*getNth(Dsymbols
*members
, size_t nth
, size_t *pn
= NULL
);
321 ScopeDsymbol
*isScopeDsymbol() { return this; }
322 void semantic(Scope
*sc
);
323 void accept(Visitor
*v
) { v
->visit(this); }
326 // With statement scope
328 class WithScopeSymbol
: public ScopeDsymbol
331 WithStatement
*withstate
;
333 WithScopeSymbol(WithStatement
*withstate
);
334 Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= SearchLocalsOnly
);
336 WithScopeSymbol
*isWithScopeSymbol() { return this; }
337 void accept(Visitor
*v
) { v
->visit(this); }
340 // Array Index/Slice scope
342 class ArrayScopeSymbol
: public ScopeDsymbol
345 Expression
*exp
; // IndexExp or SliceExp
346 TypeTuple
*type
; // for tuple[length]
347 TupleDeclaration
*td
; // for tuples of objects
350 ArrayScopeSymbol(Scope
*sc
, Expression
*e
);
351 ArrayScopeSymbol(Scope
*sc
, TypeTuple
*t
);
352 ArrayScopeSymbol(Scope
*sc
, TupleDeclaration
*td
);
353 Dsymbol
*search(const Loc
&loc
, Identifier
*ident
, int flags
= IgnoreNone
);
355 ArrayScopeSymbol
*isArrayScopeSymbol() { return this; }
356 void accept(Visitor
*v
) { v
->visit(this); }
361 class OverloadSet
: public Dsymbol
364 Dsymbols a
; // array of Dsymbols
366 OverloadSet(Identifier
*ident
, OverloadSet
*os
= NULL
);
367 void push(Dsymbol
*s
);
368 OverloadSet
*isOverloadSet() { return this; }
370 void accept(Visitor
*v
) { v
->visit(this); }
373 // Forwarding ScopeDsymbol
375 class ForwardingScopeDsymbol
: public ScopeDsymbol
377 ScopeDsymbol
*forward
;
379 Dsymbol
*symtabInsert(Dsymbol
*s
);
380 Dsymbol
*symtabLookup(Dsymbol
*s
, Identifier
*id
);
381 void importScope(Dsymbol
*s
, Prot protection
);
382 void semantic(Scope
*sc
);
385 ForwardingScopeDsymbol
*isForwardingScopeDsymbol() { return this; }
388 // Table of Dsymbol's
390 class DsymbolTable
: public RootObject
397 // Look up Identifier. Return Dsymbol if found, NULL if not.
398 Dsymbol
*lookup(Identifier
const * const ident
);
400 // Insert Dsymbol in table. Return NULL if already there.
401 Dsymbol
*insert(Dsymbol
*s
);
403 // Look for Dsymbol in table. If there, return it. If not, insert s and return that.
404 Dsymbol
*update(Dsymbol
*s
);
405 Dsymbol
*insert(Identifier
const * const ident
, Dsymbol
*s
); // when ident and s are not the same