comparison trunk/src/dil/ast/Declarations.d @ 585:05c375fb2d5c

Moved dil.Declarations to dil.ast.Declarations.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 05 Jan 2008 23:01:42 +0100
parents trunk/src/dil/Declarations.d@556bfb18dff8
children e25345656d10
comparison
equal deleted inserted replaced
584:556bfb18dff8 585:05c375fb2d5c
1 /++
2 Author: Aziz Köksal
3 License: GPL3
4 +/
5 module dil.ast.Declarations;
6
7 import dil.ast.Node;
8 import dil.Expressions;
9 import dil.Types;
10 import dil.Statements;
11 import dil.Token;
12 import dil.Enums;
13 import dil.Scope;
14 import dil.IdTable;
15 import dil.semantic.Analysis;
16 import dil.Symbols;
17 import dil.semantic.Types;
18 import dil.Messages;
19 import common;
20
21 abstract class Declaration : Node
22 {
23 bool hasBody;
24 this()
25 {
26 super(NodeCategory.Declaration);
27 }
28
29 // Members relevant to semantic phase.
30 StorageClass stc; /// The storage class of this declaration.
31 Protection prot; /// The protection attribute of this declaration.
32
33 void semantic(Scope sc)
34 {
35 foreach (node; this.children)
36 {
37 assert(node !is null);
38 if (node.category == NodeCategory.Declaration)
39 (cast(Declaration)cast(void*)node).semantic(sc);
40 }
41 }
42
43 final bool isStatic()
44 {
45 return !!(stc & StorageClass.Static);
46 }
47
48 final bool isPublic()
49 {
50 return !!(prot & Protection.Public);
51 }
52
53 final void setStorageClass(StorageClass stc)
54 {
55 this.stc = stc;
56 }
57
58 final void setProtection(Protection prot)
59 {
60 this.prot = prot;
61 }
62
63 }
64
65 class Declarations : Declaration
66 {
67 this()
68 {
69 hasBody = true;
70 mixin(set_kind);
71 }
72
73 void opCatAssign(Declaration d)
74 {
75 addChild(d);
76 }
77
78 void opCatAssign(Declarations ds)
79 {
80 addChildren(ds.children);
81 }
82
83 override void semantic(Scope scop)
84 {
85 foreach (node; this.children)
86 {
87 assert(node.category == NodeCategory.Declaration);
88 (cast(Declaration)cast(void*)node).semantic(scop);
89 }
90 }
91 }
92
93 /// Single semicolon.
94 class EmptyDeclaration : Declaration
95 {
96 this()
97 {
98 mixin(set_kind);
99 }
100
101 override void semantic(Scope)
102 {}
103 }
104
105 /++
106 Illegal declarations encompass all tokens that don't
107 start a DeclarationDefinition.
108 See_Also: dil.Token.isDeclDefStartToken()
109 +/
110 class IllegalDeclaration : Declaration
111 {
112 this()
113 {
114 mixin(set_kind);
115 }
116
117 override void semantic(Scope)
118 {}
119 }
120
121 /// FQN = fully qualified name
122 alias Identifier*[] ModuleFQN; // Identifier(.Identifier)*
123
124 class ModuleDeclaration : Declaration
125 {
126 Identifier* moduleName;
127 Identifier*[] packages;
128 this(ModuleFQN moduleFQN)
129 {
130 mixin(set_kind);
131 assert(moduleFQN.length != 0);
132 this.moduleName = moduleFQN[$-1];
133 this.packages = moduleFQN[0..$-1];
134 }
135
136 char[] getFQN()
137 {
138 auto pname = getPackageName('.');
139 if (pname.length)
140 return pname ~ "." ~ getName();
141 else
142 return getName();
143 }
144
145 char[] getName()
146 {
147 if (moduleName)
148 return moduleName.str;
149 return null;
150 }
151
152 char[] getPackageName(char separator)
153 {
154 char[] pname;
155 foreach (pckg; packages)
156 if (pckg)
157 pname ~= pckg.str ~ separator;
158 if (pname.length)
159 pname = pname[0..$-1]; // Remove last separator
160 return pname;
161 }
162 }
163
164 class ImportDeclaration : Declaration
165 {
166 private alias Identifier*[] Ids;
167 ModuleFQN[] moduleFQNs;
168 Ids moduleAliases;
169 Ids bindNames;
170 Ids bindAliases;
171
172 this(ModuleFQN[] moduleFQNs, Ids moduleAliases, Ids bindNames, Ids bindAliases, bool isStatic)
173 {
174 mixin(set_kind);
175 this.moduleFQNs = moduleFQNs;
176 this.moduleAliases = moduleAliases;
177 this.bindNames = bindNames;
178 this.bindAliases = bindAliases;
179 if (isStatic)
180 this.stc |= StorageClass.Static;
181 }
182
183 char[][] getModuleFQNs(char separator)
184 {
185 char[][] FQNs;
186 foreach (moduleFQN; moduleFQNs)
187 {
188 char[] FQN;
189 foreach (ident; moduleFQN)
190 if (ident)
191 FQN ~= ident.str ~ separator;
192 FQNs ~= FQN[0..$-1]; // Remove last separator
193 }
194 return FQNs;
195 }
196 }
197
198 class AliasDeclaration : Declaration
199 {
200 Declaration decl;
201 this(Declaration decl)
202 {
203 mixin(set_kind);
204 addChild(decl);
205 this.decl = decl;
206 }
207 }
208
209 class TypedefDeclaration : Declaration
210 {
211 Declaration decl;
212 this(Declaration decl)
213 {
214 mixin(set_kind);
215 addChild(decl);
216 this.decl = decl;
217 }
218 }
219
220 class EnumDeclaration : Declaration
221 {
222 Identifier* name;
223 TypeNode baseType;
224 EnumMember[] members;
225 this(Identifier* name, TypeNode baseType, EnumMember[] members, bool hasBody)
226 {
227 super.hasBody = hasBody;
228 mixin(set_kind);
229 addOptChild(baseType);
230 addOptChildren(members);
231
232 this.name = name;
233 this.baseType = baseType;
234 this.members = members;
235 }
236 }
237
238 class EnumMember : Node
239 {
240 Identifier* name;
241 Expression value;
242 this(Identifier* name, Expression value)
243 {
244 super(NodeCategory.Other);
245 mixin(set_kind);
246 addOptChild(value);
247
248 this.name = name;
249 this.value = value;
250 }
251 }
252
253 abstract class AggregateDeclaration : Declaration
254 {
255 Identifier* name;
256 TemplateParameters tparams;
257 Declarations decls;
258 this(Identifier* name, TemplateParameters tparams, Declarations decls)
259 {
260 super.hasBody = decls !is null;
261 this.name = name;
262 this.tparams = tparams;
263 this.decls = decls;
264 }
265 }
266
267 class ClassDeclaration : AggregateDeclaration
268 {
269 BaseClass[] bases;
270 this(Identifier* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls)
271 {
272 super(name, tparams, decls);
273 mixin(set_kind);
274 addOptChild(tparams);
275 addOptChildren(bases);
276 addOptChild(decls);
277
278 this.bases = bases;
279 }
280
281 Class class_; /// The class symbol for this declaration.
282
283 override void semantic(Scope scop)
284 {
285 if (class_)
286 return;
287 class_ = new Class(name, this);
288 // Create a new scope.
289 scop = scop.push(class_);
290 // Continue semantic analysis.
291 decls && decls.semantic(scop);
292 scop.pop();
293 }
294 }
295
296 class InterfaceDeclaration : AggregateDeclaration
297 {
298 BaseClass[] bases;
299 this(Identifier* name, TemplateParameters tparams, BaseClass[] bases, Declarations decls)
300 {
301 super(name, tparams, decls);
302 mixin(set_kind);
303 addOptChild(tparams);
304 addOptChildren(bases);
305 addOptChild(decls);
306
307 this.bases = bases;
308 }
309
310 alias dil.Symbols.Interface InterfaceSymbol;
311
312 InterfaceSymbol interface_; /// The interface symbol for this declaration.
313
314 override void semantic(Scope scop)
315 {
316 if (interface_)
317 return;
318 interface_ = new InterfaceSymbol(name, this);
319 // Create a new scope.
320 scop = scop.push(interface_);
321 // Continue semantic analysis.
322 decls && decls.semantic(scop);
323 scop.pop();
324 }
325 }
326
327 class StructDeclaration : AggregateDeclaration
328 {
329 uint alignSize;
330 this(Identifier* name, TemplateParameters tparams, Declarations decls)
331 {
332 super(name, tparams, decls);
333 mixin(set_kind);
334 addOptChild(tparams);
335 addOptChild(decls);
336 }
337
338 void setAlignSize(uint alignSize)
339 {
340 this.alignSize = alignSize;
341 }
342
343 Struct struct_; /// The struct symbol for this declaration.
344
345 override void semantic(Scope scop)
346 {
347 if (struct_)
348 return;
349 struct_ = new Struct(name, this);
350 // Create a new scope.
351 scop = scop.push(struct_);
352 // Continue semantic analysis.
353 decls && decls.semantic(scop);
354 scop.pop();
355 }
356 }
357
358 class UnionDeclaration : AggregateDeclaration
359 {
360 this(Identifier* name, TemplateParameters tparams, Declarations decls)
361 {
362 super(name, tparams, decls);
363 mixin(set_kind);
364 addOptChild(tparams);
365 addOptChild(decls);
366 }
367
368 Union union_; /// The union symbol for this declaration.
369
370 override void semantic(Scope scop)
371 {
372 if (union_)
373 return;
374 union_ = new Union(name, this);
375 // Create a new scope.
376 scop = scop.push(union_);
377 // Continue semantic analysis.
378 decls && decls.semantic(scop);
379 scop.pop();
380 }
381 }
382
383 class ConstructorDeclaration : Declaration
384 {
385 Parameters parameters;
386 FunctionBody funcBody;
387 this(Parameters parameters, FunctionBody funcBody)
388 {
389 super.hasBody = true;
390 mixin(set_kind);
391 addChild(parameters);
392 addChild(funcBody);
393
394 this.parameters = parameters;
395 this.funcBody = funcBody;
396 }
397 }
398
399 class StaticConstructorDeclaration : Declaration
400 {
401 FunctionBody funcBody;
402 this(FunctionBody funcBody)
403 {
404 super.hasBody = true;
405 mixin(set_kind);
406 addChild(funcBody);
407
408 this.funcBody = funcBody;
409 }
410 }
411
412 class DestructorDeclaration : Declaration
413 {
414 FunctionBody funcBody;
415 this(FunctionBody funcBody)
416 {
417 super.hasBody = true;
418 mixin(set_kind);
419 addChild(funcBody);
420
421 this.funcBody = funcBody;
422 }
423 }
424
425 class StaticDestructorDeclaration : Declaration
426 {
427 FunctionBody funcBody;
428 this(FunctionBody funcBody)
429 {
430 super.hasBody = true;
431 mixin(set_kind);
432 addChild(funcBody);
433
434 this.funcBody = funcBody;
435 }
436 }
437
438 class FunctionDeclaration : Declaration
439 {
440 TypeNode returnType;
441 Identifier* funcName;
442 TemplateParameters tparams;
443 Parameters params;
444 FunctionBody funcBody;
445 LinkageType linkageType;
446 this(TypeNode returnType, Identifier* funcName, TemplateParameters tparams,
447 Parameters params, FunctionBody funcBody)
448 {
449 super.hasBody = funcBody.funcBody !is null;
450 mixin(set_kind);
451 addChild(returnType);
452 addOptChild(tparams);
453 addChild(params);
454 addChild(funcBody);
455
456 this.returnType = returnType;
457 this.funcName = funcName;
458 this.tparams = tparams;
459 this.params = params;
460 this.funcBody = funcBody;
461 }
462
463 void setLinkageType(LinkageType linkageType)
464 {
465 this.linkageType = linkageType;
466 }
467 }
468
469 class VariableDeclaration : Declaration
470 {
471 TypeNode typeNode;
472 Identifier*[] idents;
473 Expression[] values;
474 LinkageType linkageType;
475 this(TypeNode typeNode, Identifier*[] idents, Expression[] values)
476 {
477 // No empty arrays allowed. Both arrays must be of same size.
478 assert(idents.length != 0 && idents.length == values.length);
479 // If no type (in case of AutoDeclaration), first value mustn't be null.
480 assert(typeNode ? 1 : values[0] !is null);
481 mixin(set_kind);
482 addOptChild(typeNode);
483 foreach(value; values)
484 addOptChild(value);
485
486 this.typeNode = typeNode;
487 this.idents = idents;
488 this.values = values;
489 }
490
491 void setLinkageType(LinkageType linkageType)
492 {
493 this.linkageType = linkageType;
494 }
495
496 Variable[] variables;
497
498 override void semantic(Scope scop)
499 {
500 Type type;
501
502 if (typeNode)
503 // Get type from typeNode.
504 type = typeNode.semantic(scop);
505 else
506 { // Infer type from first initializer.
507 auto firstValue = values[0];
508 firstValue = firstValue.semantic(scop);
509 type = firstValue.type;
510 }
511 assert(type !is null);
512
513 // Check for interface.
514 if (scop.isInterface)
515 return scop.error(begin, MSG.InterfaceCantHaveVariables);
516
517 // Iterate over variable identifiers in this declaration.
518 foreach (i, ident; idents)
519 {
520 // Perform semantic analysis on value.
521 if (values[i])
522 values[i] = values[i].semantic(scop);
523 // Create a new variable symbol.
524 auto variable = new Variable(stc, linkageType, type, ident, this);
525 variables ~= variable;
526 // Add to scope.
527 scop.insert(variable);
528 }
529 }
530 }
531
532 class InvariantDeclaration : Declaration
533 {
534 FunctionBody funcBody;
535 this(FunctionBody funcBody)
536 {
537 super.hasBody = true;
538 mixin(set_kind);
539 addChild(funcBody);
540
541 this.funcBody = funcBody;
542 }
543 }
544
545 class UnittestDeclaration : Declaration
546 {
547 FunctionBody funcBody;
548 this(FunctionBody funcBody)
549 {
550 super.hasBody = true;
551 mixin(set_kind);
552 addChild(funcBody);
553
554 this.funcBody = funcBody;
555 }
556 }
557
558 abstract class ConditionalCompilationDeclaration : Declaration
559 {
560 Token* spec;
561 Token* cond;
562 Declaration decls, elseDecls;
563
564 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
565 {
566 super.hasBody = decls !is null;
567 addOptChild(decls);
568 addOptChild(elseDecls);
569
570 this.spec = spec;
571 this.cond = cond;
572 this.decls = decls;
573 this.elseDecls = elseDecls;
574 }
575 }
576
577 class DebugDeclaration : ConditionalCompilationDeclaration
578 {
579 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
580 {
581 super(spec, cond, decls, elseDecls);
582 mixin(set_kind);
583 }
584 }
585
586 class VersionDeclaration : ConditionalCompilationDeclaration
587 {
588 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls)
589 {
590 super(spec, cond, decls, elseDecls);
591 mixin(set_kind);
592 }
593 }
594
595 class StaticIfDeclaration : Declaration
596 {
597 Expression condition;
598 Declaration ifDecls, elseDecls;
599 this(Expression condition, Declaration ifDecls, Declaration elseDecls)
600 {
601 super.hasBody = true;
602 mixin(set_kind);
603 addChild(condition);
604 addOptChild(ifDecls);
605 addOptChild(elseDecls);
606
607 this.condition = condition;
608 this.ifDecls = ifDecls;
609 this.elseDecls = elseDecls;
610 }
611 }
612
613 class StaticAssertDeclaration : Declaration
614 {
615 Expression condition, message;
616 this(Expression condition, Expression message)
617 {
618 super.hasBody = true;
619 mixin(set_kind);
620 addChild(condition);
621 addOptChild(message);
622
623 this.condition = condition;
624 this.message = message;
625 }
626 }
627
628 class TemplateDeclaration : Declaration
629 {
630 Identifier* name;
631 TemplateParameters tparams;
632 Declarations decls;
633 this(Identifier* name, TemplateParameters tparams, Declarations decls)
634 {
635 super.hasBody = true;
636 mixin(set_kind);
637 addOptChild(tparams);
638 addChild(decls);
639
640 this.name = name;
641 this.tparams = tparams;
642 this.decls = decls;
643 }
644 }
645
646 class NewDeclaration : Declaration
647 {
648 Parameters parameters;
649 FunctionBody funcBody;
650 this(Parameters parameters, FunctionBody funcBody)
651 {
652 super.hasBody = true;
653 mixin(set_kind);
654 addChild(parameters);
655 addChild(funcBody);
656
657 this.parameters = parameters;
658 this.funcBody = funcBody;
659 }
660 }
661
662 class DeleteDeclaration : Declaration
663 {
664 Parameters parameters;
665 FunctionBody funcBody;
666 this(Parameters parameters, FunctionBody funcBody)
667 {
668 super.hasBody = true;
669 mixin(set_kind);
670 addChild(parameters);
671 addChild(funcBody);
672
673 this.parameters = parameters;
674 this.funcBody = funcBody;
675 }
676 }
677
678 class AttributeDeclaration : Declaration
679 {
680 TOK attribute;
681 Declaration decls;
682 this(TOK attribute, Declaration decls)
683 {
684 super.hasBody = true;
685 mixin(set_kind);
686 addChild(decls);
687
688 this.attribute = attribute;
689 this.decls = decls;
690 }
691 }
692
693 class ProtectionDeclaration : AttributeDeclaration
694 {
695 Protection prot;
696 this(Protection prot, Declaration decls)
697 {
698 super(cast(TOK)0, decls);
699 mixin(set_kind);
700 this.prot = prot;
701 }
702 }
703
704 class StorageClassDeclaration : AttributeDeclaration
705 {
706 StorageClass storageClass;
707 this(StorageClass storageClass, TOK tok, Declaration decl)
708 {
709 super(tok, decl);
710 mixin(set_kind);
711
712 this.storageClass = storageClass;
713 }
714 }
715
716 class LinkageDeclaration : AttributeDeclaration
717 {
718 LinkageType linkageType;
719 this(LinkageType linkageType, Declaration decls)
720 {
721 super(TOK.Extern, decls);
722 mixin(set_kind);
723
724 this.linkageType = linkageType;
725 }
726 }
727
728 class AlignDeclaration : AttributeDeclaration
729 {
730 int size;
731 this(int size, Declaration decls)
732 {
733 super(TOK.Align, decls);
734 mixin(set_kind);
735 this.size = size;
736 }
737 }
738
739 class PragmaDeclaration : AttributeDeclaration
740 {
741 Identifier* ident;
742 Expression[] args;
743 this(Identifier* ident, Expression[] args, Declaration decls)
744 {
745 addOptChildren(args); // Add args before calling super().
746 super(TOK.Pragma, decls);
747 mixin(set_kind);
748
749 this.ident = ident;
750 this.args = args;
751 }
752
753 override void semantic(Scope scop)
754 {
755 pragmaSemantic(scop, begin, ident, args);
756 decls.semantic(scop);
757 }
758 }
759
760 class MixinDeclaration : Declaration
761 {
762 Expression[] templateIdents;
763 Identifier* mixinIdent;
764 Expression argument; // mixin ( AssignExpression )
765
766 this(Expression[] templateIdents, Identifier* mixinIdent)
767 {
768 mixin(set_kind);
769 addChildren(templateIdents);
770
771 this.templateIdents = templateIdents;
772 this.mixinIdent = mixinIdent;
773 }
774
775 this(Expression argument)
776 {
777 mixin(set_kind);
778 addChild(argument);
779
780 this.argument = argument;
781 }
782 }