1 module d.ast.declaration;
2 
3 import d.ast.expression;
4 import d.ast.identifier;
5 import d.ast.type;
6 
7 import source.name;
8 import d.common.node;
9 
10 /**
11  * Any declaration.
12  */
13 class Declaration : Node {
14 	this(Location location) {
15 		super(location);
16 	}
17 }
18 
19 struct StorageClass {
20 	import std.bitmanip;
21 	mixin(bitfields!(
22 		// sdfmt off
23 		TypeQualifier, "qualifier", 3,
24 		Linkage, "linkage", 3,
25 		bool, "hasLinkage", 1,
26 		Visibility, "visibility", 3,
27 		bool, "hasVisibility", 1,
28 		bool, "hasQualifier", 1,
29 		bool, "isRef", 1,
30 		bool, "isStatic", 1,
31 		bool, "isEnum", 1,
32 		bool, "isFinal", 1,
33 		bool, "isAbstract", 1,
34 		bool, "isDeprecated", 1,
35 		bool, "isNoThrow", 1,
36 		bool, "isOverride", 1,
37 		bool, "isPure", 1,
38 		bool, "isSynchronized", 1,
39 		bool, "isGshared", 1,
40 		bool, "isProperty", 1,
41 		bool, "isNoGC", 1,
42 		uint, "", 7,
43 		// sdfmt on
44 	));
45 }
46 
47 @property
48 StorageClass defaultStorageClass() {
49 	StorageClass stcs;
50 	stcs.visibility = Visibility.Public;
51 
52 	return stcs;
53 }
54 
55 abstract class StorageClassDeclaration : Declaration {
56 	StorageClass storageClass = defaultStorageClass;
57 
58 	this(Location location, StorageClass storageClass) {
59 		super(location);
60 
61 		this.storageClass = storageClass;
62 	}
63 }
64 
65 class NamedDeclaration : StorageClassDeclaration {
66 	Name name;
67 
68 	this(Location location, StorageClass storageClass, Name name) {
69 		super(location, storageClass);
70 
71 		this.name = name;
72 	}
73 }
74 
75 /**
76  * Super class for all templates parameters
77  */
78 class AstTemplateParameter : Declaration {
79 	Name name;
80 
81 	this(Location location, Name name) {
82 		super(location);
83 
84 		this.name = name;
85 	}
86 }
87 
88 final:
89 /**
90  * A D module
91  */
92 class Module : Declaration {
93 	Name name;
94 	Name[] packages;
95 
96 	Declaration[] declarations;
97 
98 	this(Location location, Name name, Name[] packages,
99 	     Declaration[] declarations) {
100 		super(location);
101 
102 		this.name = name;
103 		this.packages = packages;
104 		this.declarations = declarations;
105 	}
106 }
107 
108 /**
109  * Identifier alias
110  */
111 class IdentifierAliasDeclaration : NamedDeclaration {
112 	Identifier identifier;
113 
114 	this(Location location, StorageClass storageClass, Name name,
115 	     Identifier identifier) {
116 		super(location, storageClass, name);
117 
118 		this.identifier = identifier;
119 	}
120 }
121 
122 /**
123  * Type alias
124  */
125 class TypeAliasDeclaration : NamedDeclaration {
126 	AstType type;
127 
128 	this(Location location, StorageClass storageClass, Name name,
129 	     AstType type) {
130 		super(location, storageClass, name);
131 
132 		this.type = type;
133 	}
134 }
135 
136 /**
137  * Value alias
138  */
139 class ValueAliasDeclaration : NamedDeclaration {
140 	AstExpression value;
141 
142 	this(Location location, StorageClass storageClass, Name name,
143 	     AstExpression value) {
144 		super(location, storageClass, name);
145 
146 		this.value = value;
147 	}
148 }
149 
150 /**
151  * Alias this
152  */
153 class AliasThisDeclaration : Declaration {
154 	Name name;
155 
156 	this(Location location, Name name) {
157 		super(location);
158 
159 		this.name = name;
160 	}
161 }
162 
163 /**
164  * Import declaration
165  */
166 class ImportDeclaration : Declaration {
167 	Name[][] modules;
168 
169 	this(Location location, Name[][] modules) {
170 		super(location);
171 
172 		this.modules = modules;
173 	}
174 }
175 
176 /**
177  * Group of delcarations.
178  */
179 class GroupDeclaration : StorageClassDeclaration {
180 	Declaration[] declarations;
181 
182 	this(Location location, StorageClass storageClass,
183 	     Declaration[] declarations) {
184 		super(location, storageClass);
185 
186 		this.declarations = declarations;
187 	}
188 }
189 
190 /**
191  * Variable declaration
192  */
193 class VariableDeclaration : NamedDeclaration {
194 	AstType type;
195 	AstExpression value;
196 
197 	this(Location location, StorageClass storageClass, AstType type, Name name,
198 	     AstExpression value) {
199 		super(location, storageClass, name);
200 
201 		this.type = type;
202 		this.value = value;
203 	}
204 }
205 
206 struct ParamDecl {
207 	Location location;
208 	ParamAstType type;
209 	Name name;
210 	AstExpression value;
211 
212 	this(Location location, ParamAstType type, Name name, AstExpression value) {
213 		this.location = location;
214 		this.type = type;
215 		this.name = name;
216 		this.value = value;
217 	}
218 }
219 
220 class FunctionDeclaration : NamedDeclaration {
221 	ParamDecl[] params;
222 
223 	ParamAstType returnType;
224 
225 	import d.ast.statement;
226 	BlockStatement fbody;
227 
228 	// XXX: Try to stick that in some pointer.
229 	bool isVariadic;
230 
231 	this(Location location, StorageClass storageClass, ParamAstType returnType,
232 	     Name name, ParamDecl[] params, bool isVariadic, BlockStatement fbody) {
233 		super(location, storageClass, name);
234 
235 		this.returnType = returnType;
236 		this.params = params;
237 		this.isVariadic = isVariadic;
238 		this.fbody = fbody;
239 	}
240 }
241 
242 /**
243  * A unittest block.
244  */
245 class UnittestDeclaration : NamedDeclaration {
246 	import d.ast.statement;
247 	BlockStatement fbody;
248 
249 	this(Location location, StorageClass storageClass, Name name,
250 	     BlockStatement fbody) {
251 		super(location, storageClass, name);
252 
253 		this.fbody = fbody;
254 	}
255 }
256 
257 /**
258  * Template declaration
259  */
260 class TemplateDeclaration : NamedDeclaration {
261 	AstTemplateParameter[] parameters;
262 	Declaration[] declarations;
263 
264 	this(Location location, StorageClass storageClass, Name name,
265 	     AstTemplateParameter[] parameters, Declaration[] declarations) {
266 		super(location, storageClass, name);
267 
268 		this.parameters = parameters;
269 		this.declarations = declarations;
270 	}
271 }
272 
273 /**
274  * Types templates parameters
275  */
276 class AstTypeTemplateParameter : AstTemplateParameter {
277 	AstType specialization;
278 	AstType defaultValue;
279 
280 	this(Location location, Name name, AstType specialization,
281 	     AstType defaultValue) {
282 		super(location, name);
283 
284 		this.specialization = specialization;
285 		this.defaultValue = defaultValue;
286 	}
287 }
288 
289 /**
290  * Value template parameters
291  */
292 class AstValueTemplateParameter : AstTemplateParameter {
293 	AstType type;
294 	AstExpression defaultValue;
295 
296 	this(Location location, Name name, AstType type,
297 	     AstExpression defaultValue) {
298 		super(location, name);
299 
300 		this.type = type;
301 		this.defaultValue = defaultValue;
302 	}
303 }
304 
305 /**
306  * Alias template parameter
307  */
308 class AstAliasTemplateParameter : AstTemplateParameter {
309 	this(Location location, Name name) {
310 		super(location, name);
311 	}
312 }
313 
314 /**
315  * Typed alias template parameter
316  */
317 class AstTypedAliasTemplateParameter : AstTemplateParameter {
318 	AstType type;
319 
320 	this(Location location, Name name, AstType type) {
321 		super(location, name);
322 
323 		this.type = type;
324 	}
325 }
326 
327 /**
328  * This templates parameters
329  */
330 class AstThisTemplateParameter : AstTemplateParameter {
331 	this(Location location, Name name) {
332 		super(location, name);
333 	}
334 }
335 
336 /**
337  * Tuple templates parameters
338  */
339 class AstTupleTemplateParameter : AstTemplateParameter {
340 	this(Location location, Name name) {
341 		super(location, name);
342 	}
343 }
344 
345 /**
346  * Struct Declaration
347  */
348 class StructDeclaration : NamedDeclaration {
349 	Declaration[] members;
350 
351 	this(Location location, StorageClass storageClass, Name name,
352 	     Declaration[] members) {
353 		super(location, storageClass, name);
354 
355 		this.members = members;
356 	}
357 }
358 
359 /**
360  * Union Declaration
361  */
362 class UnionDeclaration : NamedDeclaration {
363 	Declaration[] members;
364 
365 	this(Location location, StorageClass storageClass, Name name,
366 	     Declaration[] members) {
367 		super(location, storageClass, name);
368 
369 		this.members = members;
370 	}
371 }
372 
373 /**
374  * Class Declaration
375  */
376 class ClassDeclaration : NamedDeclaration {
377 	Identifier[] bases;
378 	Declaration[] members;
379 
380 	this(Location location, StorageClass storageClass, Name name,
381 	     Identifier[] bases, Declaration[] members) {
382 		super(location, storageClass, name);
383 
384 		this.bases = bases;
385 		this.members = members;
386 	}
387 }
388 
389 /**
390  * Interface Declaration
391  */
392 class InterfaceDeclaration : NamedDeclaration {
393 	Identifier[] bases;
394 	Declaration[] members;
395 
396 	this(Location location, StorageClass storageClass, Name name,
397 	     Identifier[] bases, Declaration[] members) {
398 		super(location, storageClass, name);
399 
400 		this.bases = bases;
401 		this.members = members;
402 	}
403 }
404 
405 /**
406  * Enum Declaration
407  */
408 class EnumDeclaration : NamedDeclaration {
409 	AstType type;
410 	VariableDeclaration[] entries;
411 
412 	this(Location location, StorageClass storageClass, Name name, AstType type,
413 	     VariableDeclaration[] entries) {
414 		super(location, storageClass, name);
415 
416 		this.type = type;
417 		this.entries = entries;
418 	}
419 }