1 /// Author: Aziz Köksal 2 /// License: GPL3 3 /// $(Maturity high) 4 module dil.ast.Declarations; 5 6 public import dil.ast.Declaration; 7 import dil.ast.Node, 8 dil.ast.Expression, 9 dil.ast.Types, 10 dil.ast.Statements, 11 dil.ast.Parameters, 12 dil.ast.NodeCopier, 13 dil.ast.Meta; 14 import dil.lexer.IdTable; 15 import dil.semantic.Symbols; 16 import dil.Enums; 17 import common; 18 19 class CompoundDecl : Declaration 20 { 21 this() 22 { 23 mixin(set_kind); 24 } 25 26 this(Declaration[] decls) 27 { 28 this(); 29 this.decls = decls; 30 } 31 32 void opCatAssign(Declaration d) 33 { 34 addChild(d); 35 } 36 37 void opCatAssign(CompoundDecl ds) 38 { 39 addChildren(ds.children); 40 } 41 42 Declaration[] decls() @property 43 { 44 return cast(Declaration[])this.children; 45 } 46 47 void decls(Declaration[] decls) @property 48 { 49 this.children = cast(Node[])decls; 50 } 51 52 mixin(memberInfo("decls")); 53 54 mixin methods; 55 } 56 57 /// $(BNF ColonBlockDecl := ":" CompoundDecl) 58 class ColonBlockDecl : Declaration 59 { 60 CompoundDecl decls; 61 mixin(memberInfo("decls")); 62 this(CompoundDecl decls) 63 { 64 mixin(set_kind); 65 addChild(decls); 66 this.decls = decls; 67 } 68 mixin methods; 69 } 70 71 /// Single semicolon. 72 class EmptyDecl : Declaration 73 { 74 mixin(memberInfo()); 75 this() 76 { 77 mixin(set_kind); 78 } 79 mixin methods; 80 } 81 82 /// Illegal declarations encompass all tokens that don't 83 /// start a DeclarationDefinition. 84 /// See_Also: dil.lexer.Token.isDeclDefStartToken() 85 class IllegalDecl : Declaration 86 { 87 mixin(memberInfo()); 88 this() 89 { 90 mixin(set_kind); 91 } 92 mixin methods; 93 } 94 95 /// FQN means "fully qualified name". 96 /// $(BNF ModuleFQN := Identifier ("." Identifier)*) 97 alias ModuleFQN = Token*[]; 98 99 class ModuleDecl : Declaration 100 { 101 Token* type; /// safe | system 102 Token* name; /// E.g.: Declarations 103 Token*[] packages; /// E.g.: [dil, ast] 104 Token*[] fqn; /// E.g.: [dil, ast, Declarations] 105 mixin(memberInfo("type", "fqn")); 106 107 this(Token* type, ModuleFQN fqn) 108 { 109 mixin(set_kind); 110 assert(fqn.length != 0); 111 this.type = type; 112 this.fqn = fqn; 113 this.name = fqn[$-1]; 114 this.packages = fqn[0..$-1]; 115 } 116 117 /// Returns the fully qualified name. E.g.: "dil.ast.Declarations" 118 cstring getFQN() 119 { 120 auto fqn = getPackageName('.'); 121 if (fqn.length) 122 fqn ~= '.'; 123 fqn ~= getName(); 124 return fqn; 125 } 126 127 /// Returns the name of this module. E.ǵ.: "Declarations" 128 cstring getName() 129 { 130 return name ? name.ident.str : ""; 131 } 132 133 /// Returns the packages of this module. E.g.: "dil.ast" 134 char[] getPackageName(char separator) 135 { 136 char[] pname; 137 foreach (pckg; packages) 138 if (pckg) 139 pname ~= pckg.ident.str ~ separator; 140 if (pname.length) 141 pname = pname[0..$-1]; // Remove last separator 142 return pname; 143 } 144 145 mixin methods; 146 } 147 148 class ImportDecl : Declaration 149 { 150 private alias Ids = Token*[]; 151 ModuleFQN[] moduleFQNs; 152 Ids moduleAliases; 153 Ids bindNames; 154 Ids bindAliases; 155 mixin(memberInfo("moduleFQNs", "moduleAliases", "bindNames", "bindAliases", 156 "isStatic")); 157 158 this(ModuleFQN[] moduleFQNs, Ids moduleAliases, Ids bindNames, 159 Ids bindAliases, bool isStatic) 160 { 161 mixin(set_kind); 162 this.moduleFQNs = moduleFQNs; 163 this.moduleAliases = moduleAliases; 164 this.bindNames = bindNames; 165 this.bindAliases = bindAliases; 166 if (isStatic) 167 this.stcs |= StorageClass.Static; 168 } 169 170 cstring[] getModuleFQNs(char separator) 171 { 172 cstring[] FQNs; 173 foreach (moduleFQN; moduleFQNs) 174 { 175 char[] FQN; 176 foreach (ident; moduleFQN) 177 if (ident) 178 FQN ~= ident.ident.str ~ separator; 179 FQNs ~= FQN[0..$-1]; // Remove last separator 180 } 181 return FQNs; 182 } 183 184 mixin methods; 185 } 186 187 class AliasDecl : Declaration 188 { 189 Declaration decl; 190 /// Shortcut that skips any attributes inbetween. 191 /// Eg.: alias extern(C) void function() C_funcptr; 192 /// decl^ vardecl^ 193 Declaration vardecl; 194 mixin(memberInfo("decl")); 195 this(Declaration decl) 196 { 197 mixin(set_kind); 198 addChild(decl); 199 this.decl = decl; 200 } 201 AliasSymbol[] symbols; 202 mixin methods; 203 } 204 205 class AliasesDecl : Declaration 206 { 207 Token*[] idents; 208 TypeNode[] types; 209 mixin(memberInfo("idents", "types")); 210 this(Token*[] idents, TypeNode[] types) 211 { 212 mixin(set_kind); 213 addChildren(types); 214 this.idents = idents; 215 this.types = types; 216 } 217 AliasSymbol[] symbols; 218 mixin methods; 219 } 220 221 class AliasThisDecl : Declaration 222 { 223 Token* name; 224 AliasSymbol symbol; /// Semantic symbol. 225 mixin(memberInfo("name")); 226 this(Token* name) 227 { 228 mixin(set_kind); 229 this.name = name; 230 } 231 mixin methods; 232 } 233 234 class TypedefDecl : Declaration 235 { 236 Declaration decl; 237 Declaration vardecl; 238 TypedefSymbol[] symbols; /// Semantic symbols. 239 mixin(memberInfo("decl")); 240 this(Declaration decl) 241 { 242 mixin(set_kind); 243 addChild(decl); 244 this.decl = decl; 245 } 246 mixin methods; 247 } 248 249 class EnumDecl : Declaration 250 { 251 Token* name; 252 TypeNode baseType; 253 EnumMemberDecl[] members; 254 EnumSymbol symbol; /// Semantic symbol. 255 mixin(memberInfo("name", "baseType?", "members")); 256 257 this(Token* name, TypeNode baseType, EnumMemberDecl[] members) 258 { 259 mixin(set_kind); 260 addOptChild(baseType); 261 addOptChildren(members); 262 263 this.name = name; 264 this.baseType = baseType; 265 this.members = members; 266 } 267 268 /// Returns the Identifier of this enum, or null if anonymous. 269 Identifier* nameId() 270 { 271 return name ? name.ident : null; 272 } 273 274 mixin methods; 275 } 276 277 class EnumMemberDecl : Declaration 278 { 279 TypeNode type; // D 2.0 280 Token* name; 281 Expression value; 282 EnumMemberSymbol symbol; /// Semantic symbol. 283 mixin(memberInfo("type?", "name", "value?")); 284 285 private this(Token* name, Expression value) 286 { 287 mixin(set_kind); 288 addOptChild(value); 289 290 this.name = name; 291 this.value = value; 292 } 293 294 // D 2.0 295 this(TypeNode type, Token* name, Expression value) 296 { 297 addOptChild(type); 298 this.type = type; 299 this(name, value); 300 } 301 302 mixin methods; 303 } 304 305 class TemplateDecl : Declaration 306 { 307 Token* name; 308 TemplateParameters tparams; 309 Expression constraint; /// If-constraint in D2. 310 CompoundDecl decls; 311 bool isMixin; /// Is this a mixin template? (D2 feature.) 312 bool isWrapper; /// Is this wrapping a func/class/struct/etc. declaration? 313 TemplateSymbol symbol; /// Semantic symbol. 314 mixin(memberInfo("name", "tparams", "constraint?", "decls")); 315 316 this(Token* name, TemplateParameters tparams, Expression constraint, 317 CompoundDecl decls) 318 { 319 mixin(set_kind); 320 addChild(tparams); 321 addOptChild(constraint); 322 addChild(decls); 323 324 this.name = name; 325 this.tparams = tparams; 326 this.constraint = constraint; 327 this.decls = decls; 328 329 auto list = decls.decls; 330 alias NK = NodeKind; 331 if (list.length == 1 && list[0].kind.In(NK.FunctionDecl, NK.ClassDecl, 332 NK.InterfaceDecl, NK.StructDecl, NK.UnionDecl, NK.ConstructorDecl)) 333 this.isWrapper = true; 334 } 335 336 /// Returns the Identifier of this template. 337 Identifier* nameId() 338 { 339 return name.ident; 340 } 341 342 mixin methods; 343 } 344 345 abstract class AggregateDecl : Declaration 346 { 347 Token* name; 348 CompoundDecl decls; 349 this(Token* name, CompoundDecl decls) 350 { 351 this.name = name; 352 this.decls = decls; 353 } 354 355 /// Returns the Identifier of this declaration, or null if anonymous. 356 Identifier* nameId() 357 { 358 return name ? name.ident : null; 359 } 360 } 361 362 class ClassDecl : AggregateDecl 363 { 364 BaseClassType[] bases; 365 ClassSymbol symbol; /// Semantic symbol. 366 mixin(memberInfo("name", "bases", "decls?")); 367 this(Token* name, BaseClassType[] bases, CompoundDecl decls) 368 { 369 super(name, decls); 370 mixin(set_kind); 371 addOptChildren(bases); 372 addOptChild(decls); 373 374 this.bases = bases; 375 } 376 mixin methods; 377 } 378 379 class InterfaceDecl : AggregateDecl 380 { 381 BaseClassType[] bases; 382 InterfaceSymbol symbol; /// Semantic symbol. 383 mixin(memberInfo("name", "bases", "decls?")); 384 this(Token* name, BaseClassType[] bases, CompoundDecl decls) 385 { 386 super(name, decls); 387 mixin(set_kind); 388 addOptChildren(bases); 389 addOptChild(decls); 390 391 this.bases = bases; 392 } 393 mixin methods; 394 } 395 396 class StructDecl : AggregateDecl 397 { 398 uint alignSize; 399 StructSymbol symbol; /// Semantic type. 400 mixin(memberInfo("name?", "decls?", "alignSize")); 401 this(Token* name, CompoundDecl decls) 402 { 403 super(name, decls); 404 mixin(set_kind); 405 addOptChild(decls); 406 } 407 408 /// For ASTSerializer. 409 this(Token* name, CompoundDecl decls, uint alignSize) 410 { 411 this(name, decls); 412 setAlignSize(alignSize); 413 } 414 415 void setAlignSize(uint alignSize) 416 { 417 this.alignSize = alignSize; 418 } 419 420 mixin methods; 421 } 422 423 class UnionDecl : AggregateDecl 424 { 425 UnionSymbol symbol; /// Semantic symbol. 426 mixin(memberInfo("name?", "decls?")); 427 this(Token* name, CompoundDecl decls) 428 { 429 super(name, decls); 430 mixin(set_kind); 431 addOptChild(decls); 432 } 433 mixin methods; 434 } 435 436 class ConstructorDecl : Declaration 437 { 438 Parameters params; 439 FuncBodyStmt funcBody; 440 mixin(memberInfo("params", "funcBody")); 441 this(Parameters params, FuncBodyStmt funcBody) 442 { 443 mixin(set_kind); 444 addChild(params); 445 addChild(funcBody); 446 447 this.params = params; 448 this.funcBody = funcBody; 449 } 450 mixin methods; 451 } 452 453 class StaticCtorDecl : Declaration 454 { 455 FuncBodyStmt funcBody; 456 mixin(memberInfo("funcBody")); 457 this(FuncBodyStmt funcBody) 458 { 459 mixin(set_kind); 460 addChild(funcBody); 461 462 this.funcBody = funcBody; 463 } 464 mixin methods; 465 } 466 467 class DestructorDecl : Declaration 468 { 469 FuncBodyStmt funcBody; 470 mixin(memberInfo("funcBody")); 471 this(FuncBodyStmt funcBody) 472 { 473 mixin(set_kind); 474 addChild(funcBody); 475 476 this.funcBody = funcBody; 477 } 478 mixin methods; 479 } 480 481 class StaticDtorDecl : Declaration 482 { 483 FuncBodyStmt funcBody; 484 mixin(memberInfo("funcBody")); 485 this(FuncBodyStmt funcBody) 486 { 487 mixin(set_kind); 488 addChild(funcBody); 489 490 this.funcBody = funcBody; 491 } 492 mixin methods; 493 } 494 495 class FunctionDecl : Declaration 496 { 497 TypeNode returnType; 498 Token* name; 499 Parameters params; 500 FuncBodyStmt funcBody; 501 LinkageType lnkg; 502 bool cantInterpret = false; 503 504 mixin(memberInfo("returnType?", "name", "params", "funcBody", "lnkg")); 505 this(TypeNode returnType, Token* name, 506 Parameters params, FuncBodyStmt funcBody, 507 LinkageType lnkg = LinkageType.None) 508 { 509 mixin(set_kind); 510 addOptChild(returnType); 511 addChild(params); 512 addChild(funcBody); 513 514 this.returnType = returnType; 515 this.name = name; 516 this.params = params; 517 this.funcBody = funcBody; 518 this.lnkg = lnkg; 519 } 520 521 bool isTemplatized() 522 { // E.g.: void func(T)(T t) 523 // ^ params.begin.prevNWS 524 return params.begin.prevNWS.kind == TOK.RParen; 525 } 526 527 mixin methods; 528 } 529 530 /// $(BNF VariablesDecl := 531 /// Type? Identifier ("=" Init)? ("," Identifier ("=" Init)?)* ";") 532 class VariablesDecl : Declaration 533 { 534 TypeNode type; /// The type of the variables. 535 Token*[] names; /// Variable names. 536 Expression[] inits; /// Respective initial values. 537 LinkageType lnkg; /// They linkage type. 538 mixin(memberInfo("type?", "names", "inits?", "lnkg")); 539 540 this(TypeNode type, Token*[] names, Expression[] inits, 541 LinkageType lnkg = LinkageType.None) 542 { 543 // No empty arrays allowed. Both arrays must be of same size. 544 assert(names.length != 0 && names.length == inits.length); 545 // If no type (in case of AutoDecl), first value mustn't be null. 546 assert(type || inits[0] !is null); 547 mixin(set_kind); 548 addOptChild(type); 549 foreach (init; inits) 550 addOptChild(init); 551 552 this.type = type; 553 this.names = names; 554 this.inits = inits; 555 this.lnkg = lnkg; 556 } 557 558 /// Returns the first non-null init expression, or null if there is none. 559 Expression firstInit() 560 { 561 foreach (init; inits) 562 if (init !is null) 563 return init; 564 return null; 565 } 566 567 VariableSymbol[] variables; 568 569 mixin methods; 570 } 571 572 class InvariantDecl : Declaration 573 { 574 FuncBodyStmt funcBody; 575 mixin(memberInfo("funcBody")); 576 this(FuncBodyStmt funcBody) 577 { 578 mixin(set_kind); 579 addChild(funcBody); 580 581 this.funcBody = funcBody; 582 } 583 mixin methods; 584 } 585 586 class UnittestDecl : Declaration 587 { 588 FuncBodyStmt funcBody; 589 mixin(memberInfo("funcBody")); 590 this(FuncBodyStmt funcBody) 591 { 592 mixin(set_kind); 593 addChild(funcBody); 594 595 this.funcBody = funcBody; 596 } 597 mixin methods; 598 } 599 600 abstract class ConditionalCompilationDecl : Declaration 601 { 602 Token* spec; 603 Token* cond; 604 Declaration decls, elseDecls; 605 606 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) 607 { 608 addOptChild(decls); 609 addOptChild(elseDecls); 610 611 this.spec = spec; 612 this.cond = cond; 613 this.decls = decls; 614 this.elseDecls = elseDecls; 615 } 616 617 bool isSpecification() 618 { 619 return decls is null; 620 } 621 622 bool isCondition() 623 { 624 return decls !is null; 625 } 626 627 /// The branch to be compiled in. 628 Declaration compiledDecls; 629 } 630 631 class DebugDecl : ConditionalCompilationDecl 632 { 633 mixin(memberInfo("spec?", "cond?", "decls?", "elseDecls?")); 634 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) 635 { 636 super(spec, cond, decls, elseDecls); 637 mixin(set_kind); 638 } 639 mixin methods; 640 } 641 642 class VersionDecl : ConditionalCompilationDecl 643 { 644 mixin(memberInfo("spec?", "cond?", "decls?", "elseDecls?")); 645 this(Token* spec, Token* cond, Declaration decls, Declaration elseDecls) 646 { 647 super(spec, cond, decls, elseDecls); 648 mixin(set_kind); 649 } 650 mixin methods; 651 } 652 653 class StaticIfDecl : Declaration 654 { 655 Expression condition; 656 Declaration ifDecls, elseDecls; 657 mixin(memberInfo("condition", "ifDecls", "elseDecls?")); 658 this(Expression condition, Declaration ifDecls, Declaration elseDecls) 659 { 660 mixin(set_kind); 661 addChild(condition); 662 addChild(ifDecls); 663 addOptChild(elseDecls); 664 665 this.condition = condition; 666 this.ifDecls = ifDecls; 667 this.elseDecls = elseDecls; 668 } 669 mixin methods; 670 } 671 672 class StaticAssertDecl : Declaration 673 { 674 Expression condition, message; 675 mixin(memberInfo("condition", "message?")); 676 this(Expression condition, Expression message) 677 { 678 mixin(set_kind); 679 addChild(condition); 680 addOptChild(message); 681 682 this.condition = condition; 683 this.message = message; 684 } 685 mixin methods; 686 } 687 688 class NewDecl : Declaration 689 { 690 Parameters params; 691 FuncBodyStmt funcBody; 692 mixin(memberInfo("params", "funcBody")); 693 this(Parameters params, FuncBodyStmt funcBody) 694 { 695 mixin(set_kind); 696 addChild(params); 697 addChild(funcBody); 698 699 this.params = params; 700 this.funcBody = funcBody; 701 } 702 mixin methods; 703 } 704 705 class DeleteDecl : Declaration 706 { 707 Parameters params; 708 FuncBodyStmt funcBody; 709 mixin(memberInfo("params", "funcBody")); 710 this(Parameters params, FuncBodyStmt funcBody) 711 { 712 mixin(set_kind); 713 addChild(params); 714 addChild(funcBody); 715 716 this.params = params; 717 this.funcBody = funcBody; 718 } 719 mixin methods; 720 } 721 722 abstract class AttributeDecl : Declaration 723 { 724 Declaration decls; 725 this(Declaration decls) 726 { 727 addChild(decls); 728 this.decls = decls; 729 } 730 731 void setDecls(Declaration decls) 732 { 733 this.decls = decls; 734 if (children.length) 735 children[0] = decls; 736 else 737 addChild(decls); 738 } 739 } 740 741 class ProtectionDecl : AttributeDecl 742 { 743 Protection prot; 744 mixin(memberInfo("prot", "decls")); 745 this(Protection prot, Declaration decls) 746 { 747 super(decls); 748 mixin(set_kind); 749 this.prot = prot; 750 } 751 mixin methods; 752 } 753 754 class StorageClassDecl : AttributeDecl 755 { 756 StorageClass stc; 757 mixin(memberInfo("stc", "decls")); 758 this(StorageClass stc, Declaration decls) 759 { 760 super(decls); 761 mixin(set_kind); 762 763 this.stc = stc; 764 } 765 mixin methods; 766 } 767 768 class LinkageDecl : AttributeDecl 769 { 770 LinkageType linkageType; 771 mixin(memberInfo("linkageType", "decls")); 772 this(LinkageType linkageType, Declaration decls) 773 { 774 super(decls); 775 mixin(set_kind); 776 777 this.linkageType = linkageType; 778 } 779 mixin methods; 780 } 781 782 class AlignDecl : AttributeDecl 783 { 784 int size; 785 Token* sizetok; 786 mixin(memberInfo("sizetok", "decls")); 787 this(Token* sizetok, Declaration decls) 788 { 789 super(decls); 790 mixin(set_kind); 791 this.size = sizetok ? sizetok.int_ : -1; 792 this.sizetok = sizetok; 793 } 794 mixin methods; 795 } 796 797 class PragmaDecl : AttributeDecl 798 { 799 Token* name; 800 Expression[] args; 801 mixin(memberInfo("name", "args", "decls")); 802 this(Token* name, Expression[] args, Declaration decls) 803 { 804 addOptChildren(args); // Add args before calling super(). 805 super(decls); 806 mixin(set_kind); 807 808 this.name = name; 809 this.args = args; 810 } 811 812 mixin methods; 813 } 814 815 class MixinDecl : Declaration 816 { 817 /// IdExpr := IdentifierExpr | TmplInstanceExpr 818 /// MixinTemplate := IdExpr ("." IdExpr)* 819 Expression templateExpr; 820 Token* mixinIdent; /// Optional mixin identifier. 821 Expression argument; /// "mixin" "(" AssignExpr ")" 822 823 mixin(memberInfo("templateExpr?", "mixinIdent?", "argument?")); 824 this(Expression templateExpr, Token* mixinIdent) 825 { 826 mixin(set_kind); 827 addChild(templateExpr); 828 829 this.templateExpr = templateExpr; 830 this.mixinIdent = mixinIdent; 831 } 832 833 this(Expression argument) 834 { 835 mixin(set_kind); 836 addChild(argument); 837 838 this.argument = argument; 839 } 840 841 /// Constructor for the deserializer. 842 this(Expression templateExpr, Token* mixinIdent, Expression argument) 843 { 844 if (argument) 845 this(argument); 846 else 847 this(templateExpr, mixinIdent); 848 } 849 850 bool isMixinExpr() 851 { 852 return argument !is null; 853 } 854 855 Declaration decls; /// Initialized in the semantic phase. 856 857 mixin methods; 858 }