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/attrib.h
9  */
10 
11 #pragma once
12 
13 #include "dsymbol.h"
14 
15 class Expression;
16 class Statement;
17 class LabelDsymbol;
18 class Initializer;
19 class Module;
20 class Condition;
21 class StaticForeach;
22 
23 /**************************************************************/
24 
25 class AttribDeclaration : public Dsymbol
26 {
27 public:
28     Dsymbols *decl;     // array of Dsymbol's
29 
30     AttribDeclaration(Dsymbols *decl);
31     virtual Dsymbols *include(Scope *sc, ScopeDsymbol *sds);
32     int apply(Dsymbol_apply_ft_t fp, void *param);
33     static Scope *createNewScope(Scope *sc,
34         StorageClass newstc, LINK linkage, CPPMANGLE cppmangle, Prot protection,
35         int explicitProtection, AlignDeclaration *aligndecl, PINLINE inlining);
36     virtual Scope *newScope(Scope *sc);
37     void addMember(Scope *sc, ScopeDsymbol *sds);
38     void setScope(Scope *sc);
39     void importAll(Scope *sc);
40     void semantic(Scope *sc);
41     void semantic2(Scope *sc);
42     void semantic3(Scope *sc);
43     void addComment(const utf8_t *comment);
44     const char *kind() const;
45     bool oneMember(Dsymbol **ps, Identifier *ident);
46     void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
47     bool hasPointers();
48     bool hasStaticCtorOrDtor();
49     void checkCtorConstInit();
50     void addLocalClass(ClassDeclarations *);
isAttribDeclaration()51     AttribDeclaration *isAttribDeclaration() { return this; }
52 
accept(Visitor * v)53     void accept(Visitor *v) { v->visit(this); }
54 };
55 
56 class StorageClassDeclaration : public AttribDeclaration
57 {
58 public:
59     StorageClass stc;
60 
61     StorageClassDeclaration(StorageClass stc, Dsymbols *decl);
62     Dsymbol *syntaxCopy(Dsymbol *s);
63     Scope *newScope(Scope *sc);
64     bool oneMember(Dsymbol **ps, Identifier *ident);
65     void addMember(Scope *sc, ScopeDsymbol *sds);
isStorageClassDeclaration()66     StorageClassDeclaration *isStorageClassDeclaration() { return this; }
67 
accept(Visitor * v)68     void accept(Visitor *v) { v->visit(this); }
69 };
70 
71 class DeprecatedDeclaration : public StorageClassDeclaration
72 {
73 public:
74     Expression *msg;
75     const char *msgstr;
76 
77     DeprecatedDeclaration(Expression *msg, Dsymbols *decl);
78     Dsymbol *syntaxCopy(Dsymbol *s);
79     Scope *newScope(Scope *sc);
80     void setScope(Scope *sc);
81     void semantic2(Scope *sc);
82     const char *getMessage();
accept(Visitor * v)83     void accept(Visitor *v) { v->visit(this); }
84 };
85 
86 class LinkDeclaration : public AttribDeclaration
87 {
88 public:
89     LINK linkage;
90 
91     LinkDeclaration(LINK p, Dsymbols *decl);
92     static LinkDeclaration *create(LINK p, Dsymbols *decl);
93     Dsymbol *syntaxCopy(Dsymbol *s);
94     Scope *newScope(Scope *sc);
95     const char *toChars();
accept(Visitor * v)96     void accept(Visitor *v) { v->visit(this); }
97 };
98 
99 class CPPMangleDeclaration : public AttribDeclaration
100 {
101 public:
102     CPPMANGLE cppmangle;
103 
104     CPPMangleDeclaration(CPPMANGLE p, Dsymbols *decl);
105     Dsymbol *syntaxCopy(Dsymbol *s);
106     Scope *newScope(Scope *sc);
107     const char *toChars();
accept(Visitor * v)108     void accept(Visitor *v) { v->visit(this); }
109 };
110 
111 class ProtDeclaration : public AttribDeclaration
112 {
113 public:
114     Prot protection;
115     Identifiers* pkg_identifiers;
116 
117     ProtDeclaration(Loc loc, Prot p, Dsymbols *decl);
118     ProtDeclaration(Loc loc, Identifiers* pkg_identifiers, Dsymbols *decl);
119 
120     Dsymbol *syntaxCopy(Dsymbol *s);
121     Scope *newScope(Scope *sc);
122     void addMember(Scope *sc, ScopeDsymbol *sds);
123     const char *kind() const;
124     const char *toPrettyChars(bool unused);
accept(Visitor * v)125     void accept(Visitor *v) { v->visit(this); }
126 };
127 
128 class AlignDeclaration : public AttribDeclaration
129 {
130 public:
131     Expression *ealign;
132     structalign_t salign;
133 
134     AlignDeclaration(Loc loc, Expression *ealign, Dsymbols *decl);
135     Dsymbol *syntaxCopy(Dsymbol *s);
136     Scope *newScope(Scope *sc);
137     void semantic2(Scope *sc);
138     structalign_t getAlignment(Scope *sc);
accept(Visitor * v)139     void accept(Visitor *v) { v->visit(this); }
140 };
141 
142 class AnonDeclaration : public AttribDeclaration
143 {
144 public:
145     bool isunion;
146     int sem;                    // 1 if successful semantic()
147     unsigned anonoffset;        // offset of anonymous struct
148     unsigned anonstructsize;    // size of anonymous struct
149     unsigned anonalignsize;     // size of anonymous struct for alignment purposes
150 
151     AnonDeclaration(Loc loc, bool isunion, Dsymbols *decl);
152     Dsymbol *syntaxCopy(Dsymbol *s);
153     void setScope(Scope *sc);
154     void semantic(Scope *sc);
155     void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
156     const char *kind() const;
isAnonDeclaration()157     AnonDeclaration *isAnonDeclaration() { return this; }
accept(Visitor * v)158     void accept(Visitor *v) { v->visit(this); }
159 };
160 
161 class PragmaDeclaration : public AttribDeclaration
162 {
163 public:
164     Expressions *args;          // array of Expression's
165 
166     PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl);
167     Dsymbol *syntaxCopy(Dsymbol *s);
168     Scope *newScope(Scope *sc);
169     void semantic(Scope *sc);
170     const char *kind() const;
accept(Visitor * v)171     void accept(Visitor *v) { v->visit(this); }
172 };
173 
174 class ConditionalDeclaration : public AttribDeclaration
175 {
176 public:
177     Condition *condition;
178     Dsymbols *elsedecl; // array of Dsymbol's for else block
179 
180     ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
181     Dsymbol *syntaxCopy(Dsymbol *s);
182     bool oneMember(Dsymbol **ps, Identifier *ident);
183     Dsymbols *include(Scope *sc, ScopeDsymbol *sds);
184     void addComment(const utf8_t *comment);
185     void setScope(Scope *sc);
accept(Visitor * v)186     void accept(Visitor *v) { v->visit(this); }
187 };
188 
189 class StaticIfDeclaration : public ConditionalDeclaration
190 {
191 public:
192     ScopeDsymbol *scopesym;
193     bool addisdone;
194     bool onStack;
195 
196     StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
197     Dsymbol *syntaxCopy(Dsymbol *s);
198     Dsymbols *include(Scope *sc, ScopeDsymbol *sds);
199     void addMember(Scope *sc, ScopeDsymbol *sds);
200     void setScope(Scope *sc);
201     void importAll(Scope *sc);
202     void semantic(Scope *sc);
203     const char *kind() const;
accept(Visitor * v)204     void accept(Visitor *v) { v->visit(this); }
205 };
206 
207 class StaticForeachDeclaration : public AttribDeclaration
208 {
209 public:
210     StaticForeach *sfe;
211     ScopeDsymbol *scopesym;
212     bool onStack;
213     bool cached;
214     Dsymbols *cache;
215 
216     StaticForeachDeclaration(StaticForeach *sfe, Dsymbols *decl);
217     Dsymbol *syntaxCopy(Dsymbol *s);
218     bool oneMember(Dsymbol **ps, Identifier *ident);
219     Dsymbols *include(Scope *sc, ScopeDsymbol *sds);
220     void addMember(Scope *sc, ScopeDsymbol *sds);
221     void addComment(const utf8_t *comment);
222     void setScope(Scope *sc);
223     void importAll(Scope *sc);
224     void semantic(Scope *sc);
225     const char *kind() const;
accept(Visitor * v)226     void accept(Visitor *v) { v->visit(this); }
227 };
228 
229 class ForwardingAttribDeclaration : public AttribDeclaration
230 {
231 public:
232     ForwardingScopeDsymbol *sym;
233 
234     ForwardingAttribDeclaration(Dsymbols *decl);
235     Scope *newScope(Scope *sc);
236     void addMember(Scope *sc, ScopeDsymbol *sds);
isForwardingAttribDeclaration()237     ForwardingAttribDeclaration *isForwardingAttribDeclaration() { return this; }
accept(Visitor * v)238     void accept(Visitor *v) { v->visit(this); }
239 };
240 
241 // Mixin declarations
242 
243 class CompileDeclaration : public AttribDeclaration
244 {
245 public:
246     Expression *exp;
247 
248     ScopeDsymbol *scopesym;
249     bool compiled;
250 
251     CompileDeclaration(Loc loc, Expression *exp);
252     Dsymbol *syntaxCopy(Dsymbol *s);
253     void addMember(Scope *sc, ScopeDsymbol *sds);
254     void setScope(Scope *sc);
255     void compileIt(Scope *sc);
256     void semantic(Scope *sc);
257     const char *kind() const;
accept(Visitor * v)258     void accept(Visitor *v) { v->visit(this); }
259 };
260 
261 /**
262  * User defined attributes look like:
263  *      @(args, ...)
264  */
265 class UserAttributeDeclaration : public AttribDeclaration
266 {
267 public:
268     Expressions *atts;
269 
270     UserAttributeDeclaration(Expressions *atts, Dsymbols *decl);
271     Dsymbol *syntaxCopy(Dsymbol *s);
272     Scope *newScope(Scope *sc);
273     void setScope(Scope *sc);
274     void semantic(Scope *sc);
275     void semantic2(Scope *sc);
276     static Expressions *concat(Expressions *udas1, Expressions *udas2);
277     Expressions *getAttributes();
278     const char *kind() const;
accept(Visitor * v)279     void accept(Visitor *v) { v->visit(this); }
280 };
281