comparison trunk/src/dil/Parser.d @ 495:b60450804b6e

Attributes are evaluated during the parsing phase now. Renamed parseDeclarationDefinitionsBlock to parseDeclarationDefinitionsBody. Renamed parseDeclaration to parseVariableOrFunction. Removed class Linkage, renamed parseLinkage to parseLinkageType and modified it so that it returns a value from enum LinkageType. Fix in parseStorageAttribute(): class invariants are recognized now. Modified parseAlignAttribute() so that returns an uint - the alignment size. Removed classes AttributeStatement and ExternStatement. Using Declarations instead in parseAttributeStatement(). Added LinkageType to module Enums. Added StorageClassDeclaration and renamed ExternDeclaration to LinkageDeclaration.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sat, 08 Dec 2007 22:20:34 +0100
parents 9a7ca8c56e59
children 5a607597dc22
comparison
equal deleted inserted replaced
494:9a7ca8c56e59 495:b60450804b6e
11 import dil.Declarations; 11 import dil.Declarations;
12 import dil.Statements; 12 import dil.Statements;
13 import dil.Expressions; 13 import dil.Expressions;
14 import dil.Types; 14 import dil.Types;
15 import dil.Enums; 15 import dil.Enums;
16 import dil.CompilerInfo;
16 import common; 17 import common;
17 18
18 private alias TOK T; 19 private alias TOK T;
19 20
20 /++ 21 /++
27 Token* token; /// Current non-whitespace token. 28 Token* token; /// Current non-whitespace token.
28 Token* prevToken; /// Previous non-whitespace token. 29 Token* prevToken; /// Previous non-whitespace token.
29 30
30 Information[] errors; 31 Information[] errors;
31 32
32 ImportDeclaration[] imports; 33 ImportDeclaration[] imports; /// ImportDeclarations in the source text.
34
35 LinkageType linkageType;
36 Protection protection;
37 StorageClass storageClass;
38 uint alignSize = DEFAULT_ALIGN_SIZE;
33 39
34 this(char[] srcText, string filePath, InformationManager infoMan = null) 40 this(char[] srcText, string filePath, InformationManager infoMan = null)
35 { 41 {
36 lx = new Lexer(srcText, filePath); 42 lx = new Lexer(srcText, filePath);
37 } 43 }
158 require(T.Semicolon); 164 require(T.Semicolon);
159 return set(new ModuleDeclaration(moduleFQN), begin); 165 return set(new ModuleDeclaration(moduleFQN), begin);
160 } 166 }
161 167
162 /++ 168 /++
169 Parse DeclarationDefinitions until the end of file is hit.
163 DeclDefs: 170 DeclDefs:
164 DeclDef 171 DeclDef
165 DeclDefs 172 DeclDefs
166 +/ 173 +/
167 Declaration[] parseDeclarationDefinitions() 174 Declaration[] parseDeclarationDefinitions()
171 decls ~= parseDeclarationDefinition(); 178 decls ~= parseDeclarationDefinition();
172 return decls; 179 return decls;
173 } 180 }
174 181
175 /++ 182 /++
183 Parse the body of a template, class, interface, struct or union.
176 DeclDefsBlock: 184 DeclDefsBlock:
177 { } 185 { }
178 { DeclDefs } 186 { DeclDefs }
179 +/ 187 +/
180 Declarations parseDeclarationDefinitionsBlock() 188 Declarations parseDeclarationDefinitionsBody()
181 { 189 {
190 // Save attributes.
191 auto linkageType = this.linkageType;
192 auto protection = this.protection;
193 auto storageClass = this.storageClass;
194 // Clear attributes.
195 this.linkageType = LinkageType.None;
196 this.protection = Protection.None;
197 this.storageClass = StorageClass.None;
198
199 // Parse body.
182 auto begin = token; 200 auto begin = token;
183 auto decls = new Declarations; 201 auto decls = new Declarations;
184 require(T.LBrace); 202 require(T.LBrace);
185 while (token.type != T.RBrace && token.type != T.EOF) 203 while (token.type != T.RBrace && token.type != T.EOF)
186 decls ~= parseDeclarationDefinition(); 204 decls ~= parseDeclarationDefinition();
187 require(T.RBrace); 205 require(T.RBrace);
188 return set(decls, begin); 206 set(decls, begin);
207
208 // Restore original values.
209 this.linkageType = linkageType;
210 this.protection = protection;
211 this.storageClass = storageClass;
212
213 return decls;
189 } 214 }
190 215
191 Declaration parseDeclarationDefinition() 216 Declaration parseDeclarationDefinition()
217 out(decl)
218 { assert(isNodeSet(decl)); }
219 body
192 { 220 {
193 auto begin = token; 221 auto begin = token;
194 Declaration decl; 222 Declaration decl;
195 switch (token.type) 223 switch (token.type)
196 { 224 {
216 //T.Invariant, // D 2.0 244 //T.Invariant, // D 2.0
217 T.Auto, 245 T.Auto,
218 T.Scope: 246 T.Scope:
219 case_StaticAttribute: 247 case_StaticAttribute:
220 case_InvariantAttribute: // D 2.0 248 case_InvariantAttribute: // D 2.0
221 decl = parseStorageAttribute(); 249 return parseStorageAttribute();
222 break;
223 case T.Alias: 250 case T.Alias:
224 nT(); 251 nT();
225 // TODO: parse StorageClasses? 252 // TODO: parse StorageClasses?
226 decl = new AliasDeclaration(parseDeclaration()); 253 decl = new AliasDeclaration(parseVariableOrFunction());
227 break; 254 break;
228 case T.Typedef: 255 case T.Typedef:
229 nT(); 256 nT();
230 // TODO: parse StorageClasses? 257 // TODO: parse StorageClasses?
231 decl = new TypedefDeclaration(parseDeclaration()); 258 decl = new TypedefDeclaration(parseVariableOrFunction());
232 break; 259 break;
233 case T.Static: 260 case T.Static:
234 switch (peekNext()) 261 switch (peekNext())
235 { 262 {
236 case T.Import: 263 case T.Import:
252 } 279 }
253 break; 280 break;
254 case T.Import: 281 case T.Import:
255 case_Import: 282 case_Import:
256 decl = parseImportDeclaration(); 283 decl = parseImportDeclaration();
257 assert(decl && decl.kind == NodeKind.ImportDeclaration); 284 imports ~= CastTo!(ImportDeclaration)(decl);
258 imports ~= cast(ImportDeclaration)cast(void*)decl; 285 // Handle specially. StorageClass mustn't be set.
259 break; 286 decl.setProtection(this.protection);
287 return set(decl, begin);
260 case T.Enum: 288 case T.Enum:
261 decl = parseEnumDeclaration(); 289 decl = parseEnumDeclaration();
262 break; 290 break;
263 case T.Class: 291 case T.Class:
264 decl = parseClassDeclaration(); 292 decl = parseClassDeclaration();
322 T.Int, T.Uint, T.Long, T.Ulong, 350 T.Int, T.Uint, T.Long, T.Ulong,
323 T.Float, T.Double, T.Real, 351 T.Float, T.Double, T.Real,
324 T.Ifloat, T.Idouble, T.Ireal, 352 T.Ifloat, T.Idouble, T.Ireal,
325 T.Cfloat, T.Cdouble, T.Creal, T.Void: 353 T.Cfloat, T.Cdouble, T.Creal, T.Void:
326 case_Declaration: 354 case_Declaration:
327 return parseDeclaration(); 355 return parseVariableOrFunction(this.storageClass, this.protection, this.linkageType);
328 /+case T.Module: 356 /+case T.Module:
329 // TODO: Error: module is optional and can appear only once at the top of the source file. 357 // TODO: Error: module is optional and can appear only once at the top of the source file.
330 break;+/ 358 break;+/
331 default: 359 default:
332 error(MID.ExpectedButFound, "Declaration", token.srcText); 360 error(MID.ExpectedButFound, "Declaration", token.srcText);
333 decl = new IllegalDeclaration(token); 361 decl = new IllegalDeclaration(token);
334 nT(); 362 nT();
335 } 363 }
364 decl.setProtection(this.protection);
365 decl.setStorageClass(this.storageClass);
366 assert(!isNodeSet(decl));
336 set(decl, begin); 367 set(decl, begin);
337 return decl; 368 return decl;
338 } 369 }
339 370
340 /* 371 /++
341 DeclarationsBlock: 372 DeclarationsBlock:
342 : DeclDefs 373 : DeclDefs
343 { } 374 { }
344 { DeclDefs } 375 { DeclDefs }
345 DeclDef 376 DeclDef
346 */ 377 +/
347 Declaration parseDeclarationsBlock(bool noColon = false) 378 Declaration parseDeclarationsBlock(bool noColon = false)
348 { 379 {
349 Declaration d; 380 Declaration d;
350 switch (token.type) 381 switch (token.type)
351 { 382 {
352 case T.LBrace: 383 case T.LBrace:
353 d = parseDeclarationDefinitionsBlock(); 384 nT();
385 auto begin = token;
386 auto decls = new Declarations;
387 while (token.type != T.RBrace && token.type != T.EOF)
388 decls ~= parseDeclarationDefinition();
389 require(T.RBrace);
390 d = set(decls, begin);
354 break; 391 break;
355 case T.Colon: 392 case T.Colon:
356 if (noColon == true) 393 if (noColon == true)
357 goto default; 394 goto default;
358 nT(); 395 nT();
378 Parses either a VariableDeclaration or a FunctionDeclaration. 415 Parses either a VariableDeclaration or a FunctionDeclaration.
379 Params: 416 Params:
380 stc = the previously parsed storage classes 417 stc = the previously parsed storage classes
381 optionalParameterList = a hint for how to parse C-style function pointers 418 optionalParameterList = a hint for how to parse C-style function pointers
382 +/ 419 +/
383 Declaration parseDeclaration(StorageClass stc = StorageClass.None, bool optionalParameterList = true) 420 Declaration parseVariableOrFunction(StorageClass stc = StorageClass.None,
421 Protection protection = Protection.None,
422 LinkageType linkType = LinkageType.None,
423 bool optionalParameterList = true)
384 { 424 {
385 auto begin = token; 425 auto begin = token;
386 Type type; 426 Type type;
387 Token* ident; 427 Token* ident;
388 428
389 // Check for AutoDeclaration 429 // Check for AutoDeclaration: StorageClasses Identifier =
390 if (stc != StorageClass.None && 430 if (stc != StorageClass.None &&
391 token.type == T.Identifier && 431 token.type == T.Identifier &&
392 peekNext() == T.Assign) 432 peekNext() == T.Assign)
393 { 433 {
394 ident = token; 434 ident = token;
442 default: 482 default:
443 } 483 }
444 } 484 }
445 // ReturnType FunctionName ( ParameterList ) 485 // ReturnType FunctionName ( ParameterList )
446 auto funcBody = parseFunctionBody(); 486 auto funcBody = parseFunctionBody();
447 return set(new FunctionDeclaration(type, ident, tparams, params, funcBody, stc), begin); 487 auto d = new FunctionDeclaration(type, ident, tparams, params, funcBody);
488 d.setStorageClass(stc);
489 d.setLinkageType(linkType);
490 d.setProtection(protection);
491 return set(d, begin);
448 } 492 }
449 type = parseDeclaratorSuffix(type); 493 type = parseDeclaratorSuffix(type);
450 } 494 }
451 } 495 }
452 496
458 { 502 {
459 nT(); 503 nT();
460 idents ~= requireId(); 504 idents ~= requireId();
461 LenterLoop: 505 LenterLoop:
462 if (token.type == T.Assign) 506 if (token.type == T.Assign)
463 { 507 nT(), (values ~= parseInitializer());
464 nT();
465 values ~= parseInitializer();
466 }
467 else 508 else
468 values ~= null; 509 values ~= null;
469 } 510 }
470 require(T.Semicolon); 511 require(T.Semicolon);
471 return set(new VariableDeclaration(type, idents, values), begin); 512 auto d = new VariableDeclaration(type, idents, values);
513 d.setStorageClass(stc);
514 d.setLinkageType(linkType);
515 d.setProtection(protection);
516 return set(d, begin);
472 } 517 }
473 518
474 Expression parseInitializer() 519 Expression parseInitializer()
475 { 520 {
476 if (token.type == T.Void) 521 if (token.type == T.Void)
614 set(func, begin); 659 set(func, begin);
615 func.finishConstruction(); 660 func.finishConstruction();
616 return func; 661 return func;
617 } 662 }
618 663
619 Linkage parseLinkage() 664 LinkageType parseLinkageType()
620 { 665 {
666 LinkageType linkageType;
621 if (token.type != T.LParen) 667 if (token.type != T.LParen)
622 return null; 668 return linkageType;
623 669
624 nT(); // Skip ( 670 nT(); // Skip (
625 if (token.type == T.RParen) 671 if (token.type == T.RParen)
626 { 672 {
673 nT();
627 error(MID.MissingLinkageType); 674 error(MID.MissingLinkageType);
628 nT(); 675 return linkageType;
629 return null; 676 }
630 } 677
631
632 auto begin = token;
633 auto ident = requireId(); 678 auto ident = requireId();
634 679
635 Linkage.Type linktype;
636 switch (ident ? ident.identifier : null) 680 switch (ident ? ident.identifier : null)
637 { 681 {
638 case "C": 682 case "C":
639 if (token.type == T.PlusPlus) 683 if (token.type == T.PlusPlus)
640 { 684 {
641 nT(); 685 nT();
642 linktype = Linkage.Type.Cpp; 686 linkageType = LinkageType.Cpp;
643 break; 687 break;
644 } 688 }
645 linktype = Linkage.Type.C; 689 linkageType = LinkageType.C;
646 break; 690 break;
647 case "D": 691 case "D":
648 linktype = Linkage.Type.D; 692 linkageType = LinkageType.D;
649 break; 693 break;
650 case "Windows": 694 case "Windows":
651 linktype = Linkage.Type.Windows; 695 linkageType = LinkageType.Windows;
652 break; 696 break;
653 case "Pascal": 697 case "Pascal":
654 linktype = Linkage.Type.Pascal; 698 linkageType = LinkageType.Pascal;
655 break; 699 break;
656 case "System": 700 case "System":
657 linktype = Linkage.Type.System; 701 linkageType = LinkageType.System;
658 break; 702 break;
659 default: 703 default:
660 error(MID.UnrecognizedLinkageType, token.srcText); 704 error(MID.UnrecognizedLinkageType, token.srcText);
661 nT(); 705 nT();
662 } 706 }
663 auto linkage = new Linkage(linktype);
664 set(linkage, begin);
665 require(T.RParen); 707 require(T.RParen);
666 return linkage; 708 return linkageType;
709 }
710
711 void checkLinkageType(ref LinkageType prev_lt, LinkageType lt, char* tokStart)
712 {
713 if (prev_lt == LinkageType.None)
714 prev_lt = lt;
715 else
716 // TODO: create new msg RedundantLinkageType.
717 error(MID.RedundantStorageClass, tokStart[0 .. prevToken.end - tokStart]);
667 } 718 }
668 719
669 Declaration parseStorageAttribute() 720 Declaration parseStorageAttribute()
670 { 721 {
671 StorageClass stc, tmp; 722 StorageClass stc, stc_tmp;
672 Linkage.Category link_cat; 723 LinkageType prev_linkageType;
673 724
674 void addStorageClass() 725 auto saved_storageClass = this.storageClass; // Save.
675 { 726 // Nested function.
676 if (stc & tmp)
677 error(MID.RedundantStorageClass, token.srcText);
678 else
679 stc |= tmp;
680 }
681
682 Declaration parse() 727 Declaration parse()
683 { 728 {
684 Declaration decl; 729 Declaration decl;
685 auto begin = token; 730 auto begin = token;
686 switch (token.type) 731 switch (token.type)
687 { 732 {
688 case T.Extern: 733 case T.Extern:
689 stc |= StorageClass.Extern; 734 if (peekNext() != T.LParen)
690 nT();
691 Linkage linkage = parseLinkage();
692
693 // Check for redundancy.
694 Linkage.Category link_cat_tmp = Linkage.getCategory(linkage);
695 if (link_cat & link_cat_tmp)
696 { 735 {
697 char[] srcText = begin.srcText; 736 stc_tmp = StorageClass.Extern;
698 if (link_cat_tmp == Linkage.Category.MangleSymbol) 737 goto Lcommon;
699 srcText = begin.start[0 .. prevToken.end - begin.start];
700 error(MID.RedundantStorageClass, srcText);
701 } 738 }
702 else 739
703 link_cat |= link_cat_tmp; 740 nT();
704 741 auto linkageType = parseLinkageType();
705 decl = set(new ExternDeclaration(linkage, parse()), begin); 742 checkLinkageType(prev_linkageType, linkageType, begin.start);
743
744 auto saved = this.linkageType; // Save.
745 this.linkageType = linkageType; // Set.
746 decl = new LinkageDeclaration(linkageType, parse());
747 set(decl, begin);
748 this.linkageType = saved; // Restore.
706 break; 749 break;
707 case T.Override: 750 case T.Override:
708 tmp = StorageClass.Override; 751 stc_tmp = StorageClass.Override;
709 goto Lcommon; 752 goto Lcommon;
710 case T.Deprecated: 753 case T.Deprecated:
711 tmp = StorageClass.Deprecated; 754 stc_tmp = StorageClass.Deprecated;
712 goto Lcommon; 755 goto Lcommon;
713 case T.Abstract: 756 case T.Abstract:
714 tmp = StorageClass.Abstract; 757 stc_tmp = StorageClass.Abstract;
715 goto Lcommon; 758 goto Lcommon;
716 case T.Synchronized: 759 case T.Synchronized:
717 tmp = StorageClass.Synchronized; 760 stc_tmp = StorageClass.Synchronized;
718 goto Lcommon; 761 goto Lcommon;
719 case T.Static: 762 case T.Static:
720 tmp = StorageClass.Static; 763 stc_tmp = StorageClass.Static;
721 goto Lcommon; 764 goto Lcommon;
722 case T.Final: 765 case T.Final:
723 tmp = StorageClass.Final; 766 stc_tmp = StorageClass.Final;
724 goto Lcommon; 767 goto Lcommon;
725 case T.Const: 768 case T.Const:
726 version(D2) 769 version(D2)
727 { 770 {
728 if (peekNext() == T.LParen) 771 if (peekNext() == T.LParen)
729 goto case_Declaration; 772 goto case_Declaration;
730 } 773 }
731 tmp = StorageClass.Const; 774 stc_tmp = StorageClass.Const;
732 goto Lcommon; 775 goto Lcommon;
733 version(D2) 776 version(D2)
734 { 777 {
735 case T.Invariant: // D 2.0 778 case T.Invariant: // D 2.0
736 // TODO: could this be a class invariant? 779 auto next = token;
737 if (peekNext() == T.LParen) 780 if (peekAfter(next) == T.LParen)
738 goto case_Declaration; 781 {
739 tmp = StorageClass.Invariant; 782 if (peekAfter(next) != T.RParen)
783 goto case_Declaration; // invariant ( Type )
784 decl = parseDeclarationDefinition(); // invariant ( )
785 decl.setStorageClass(stc);
786 break;
787 }
788 // invariant as StorageClass.
789 stc_tmp = StorageClass.Invariant;
740 goto Lcommon; 790 goto Lcommon;
741 } 791 }
742 case T.Auto: 792 case T.Auto:
743 tmp = StorageClass.Auto; 793 stc_tmp = StorageClass.Auto;
744 goto Lcommon; 794 goto Lcommon;
745 case T.Scope: 795 case T.Scope:
746 tmp = StorageClass.Scope; 796 stc_tmp = StorageClass.Scope;
747 goto Lcommon; 797 goto Lcommon;
748 Lcommon: 798 Lcommon:
749 addStorageClass(); 799 // Issue error if redundant.
800 if (stc & stc_tmp)
801 error(MID.RedundantStorageClass, token.srcText);
802 else
803 stc |= stc_tmp;
804
750 auto tok = token.type; 805 auto tok = token.type;
751 nT(); 806 nT();
752 decl = set(new AttributeDeclaration(tok, parse()), begin); 807 decl = new StorageClassDeclaration(stc_tmp, tok, parse());
808 set(decl, begin);
753 break; 809 break;
754 case T.Identifier: 810 case T.Identifier:
755 case_Declaration: 811 case_Declaration:
756 // This could be a normal Declaration or an AutoDeclaration 812 // This could be a normal Declaration or an AutoDeclaration
757 decl = parseDeclaration(stc); 813 decl = parseVariableOrFunction(stc, this.protection, prev_linkageType);
758 break; 814 break;
759 default: 815 default:
816 this.storageClass = stc; // Set.
760 decl = parseDeclarationsBlock(); 817 decl = parseDeclarationsBlock();
761 } 818 this.storageClass = saved_storageClass; // Reset.
819 }
820 assert(isNodeSet(decl));
762 return decl; 821 return decl;
763 } 822 }
764 return parse(); 823 return parse();
765 } 824 }
766 825
767 Token* parseAlignAttribute() 826 uint parseAlignAttribute()
768 { 827 {
769 assert(token.type == T.Align); 828 assert(token.type == T.Align);
770 nT(); // Skip align keyword. 829 nT(); // Skip align keyword.
771 Token* tok; 830 uint size = DEFAULT_ALIGN_SIZE; // Global default.
772 if (token.type == T.LParen) 831 if (token.type == T.LParen)
773 { 832 {
774 nT(); 833 nT();
775 if (token.type == T.Int32) 834 if (token.type == T.Int32)
776 { 835 (size = token.int_), nT();
777 tok = token;
778 nT();
779 }
780 else 836 else
781 expected(T.Int32); 837 expected(T.Int32);
782 require(T.RParen); 838 require(T.RParen);
783 } 839 }
784 return tok; 840 return size;
785 } 841 }
786 842
787 Declaration parseAttributeSpecifier() 843 Declaration parseAttributeSpecifier()
788 { 844 {
789 Declaration decl; 845 Declaration decl;
790 846
791 switch (token.type) 847 switch (token.type)
792 { 848 {
793 case T.Align: 849 case T.Align:
794 int size = -1; 850 uint alignSize = parseAlignAttribute();
795 auto intTok = parseAlignAttribute(); 851 auto saved = this.alignSize; // Save.
796 if (intTok) 852 this.alignSize = alignSize; // Set.
797 size = intTok.int_; 853 decl = new AlignDeclaration(alignSize, parseDeclarationsBlock());
798 decl = new AlignDeclaration(size, parseDeclarationsBlock()); 854 this.alignSize = saved; // Restore.
799 break; 855 break;
800 case T.Pragma: 856 case T.Pragma:
801 // Pragma: 857 // Pragma:
802 // pragma ( Identifier ) 858 // pragma ( Identifier )
803 // pragma ( Identifier , ExpressionList ) 859 // pragma ( Identifier , ExpressionList )
844 prot = Protection.Export; break; 900 prot = Protection.Export; break;
845 default: 901 default:
846 assert(0); 902 assert(0);
847 } 903 }
848 nT(); 904 nT();
905 auto saved = this.protection; // Save.
906 this.protection = prot; // Set.
849 decl = new ProtectionDeclaration(prot, parseDeclarationsBlock()); 907 decl = new ProtectionDeclaration(prot, parseDeclarationsBlock());
908 this.protection = saved; // Restore.
850 } 909 }
851 return decl; 910 return decl;
852 } 911 }
853 912
854 Declaration parseImportDeclaration() 913 Declaration parseImportDeclaration()
1022 if (bases.length != 0) 1081 if (bases.length != 0)
1023 error(MID.BaseClassInForwardDeclaration); 1082 error(MID.BaseClassInForwardDeclaration);
1024 nT(); 1083 nT();
1025 } 1084 }
1026 else if (token.type == T.LBrace) 1085 else if (token.type == T.LBrace)
1027 decls = parseDeclarationDefinitionsBlock(); 1086 decls = parseDeclarationDefinitionsBody();
1028 else 1087 else
1029 expected(T.LBrace); // TODO: better error msg 1088 expected(T.LBrace); // TODO: better error msg
1030 1089
1031 return new ClassDeclaration(className, tparams, bases, decls); 1090 return new ClassDeclaration(className, tparams, bases, decls);
1032 } 1091 }
1092 if (bases.length != 0) 1151 if (bases.length != 0)
1093 error(MID.BaseClassInForwardDeclaration); 1152 error(MID.BaseClassInForwardDeclaration);
1094 nT(); 1153 nT();
1095 } 1154 }
1096 else if (token.type == T.LBrace) 1155 else if (token.type == T.LBrace)
1097 decls = parseDeclarationDefinitionsBlock(); 1156 decls = parseDeclarationDefinitionsBody();
1098 else 1157 else
1099 expected(T.LBrace); // TODO: better error msg 1158 expected(T.LBrace); // TODO: better error msg
1100 1159
1101 return new InterfaceDeclaration(name, tparams, bases, decls); 1160 return new InterfaceDeclaration(name, tparams, bases, decls);
1102 } 1161 }
1126 //if (name.length == 0) 1185 //if (name.length == 0)
1127 // TODO: error: forward declarations must have a name. 1186 // TODO: error: forward declarations must have a name.
1128 nT(); 1187 nT();
1129 } 1188 }
1130 else if (token.type == T.LBrace) 1189 else if (token.type == T.LBrace)
1131 decls = parseDeclarationDefinitionsBlock(); 1190 decls = parseDeclarationDefinitionsBody();
1132 else 1191 else
1133 expected(T.LBrace); // TODO: better error msg 1192 expected(T.LBrace); // TODO: better error msg
1134 1193
1135 if (tok == T.Struct) 1194 if (tok == T.Struct)
1136 return new StructDeclaration(name, tparams, decls); 1195 {
1196 auto d = new StructDeclaration(name, tparams, decls);
1197 d.setAlignSize(this.alignSize);
1198 return d;
1199 }
1137 else 1200 else
1138 return new UnionDeclaration(name, tparams, decls); 1201 return new UnionDeclaration(name, tparams, decls);
1139 } 1202 }
1140 1203
1141 Declaration parseConstructorDeclaration() 1204 Declaration parseConstructorDeclaration()
1367 { 1430 {
1368 assert(token.type == T.Template); 1431 assert(token.type == T.Template);
1369 nT(); // Skip template keyword. 1432 nT(); // Skip template keyword.
1370 auto templateName = requireId(); 1433 auto templateName = requireId();
1371 auto templateParams = parseTemplateParameterList(); 1434 auto templateParams = parseTemplateParameterList();
1372 auto decls = parseDeclarationDefinitionsBlock(); 1435 auto decls = parseDeclarationDefinitionsBody();
1373 return new TemplateDeclaration(templateName, templateParams, decls); 1436 return new TemplateDeclaration(templateName, templateParams, decls);
1374 } 1437 }
1375 1438
1376 Declaration parseNewDeclaration() 1439 Declaration parseNewDeclaration()
1377 { 1440 {
1623 Statement s; 1686 Statement s;
1624 Declaration d; 1687 Declaration d;
1625 switch (token.type) 1688 switch (token.type)
1626 { 1689 {
1627 case T.Align: 1690 case T.Align:
1628 int size = -1; 1691 uint size = parseAlignAttribute();
1629 auto intTok = parseAlignAttribute();
1630 if (intTok)
1631 size = intTok.int_;
1632 // Restrict align attribute to structs in parsing phase. 1692 // Restrict align attribute to structs in parsing phase.
1633 Declaration structDecl; 1693 StructDeclaration structDecl;
1634 if (token.type == T.Struct) 1694 if (token.type == T.Struct)
1635 structDecl = parseAggregateDeclaration(); 1695 {
1696 auto begin2 = token;
1697 structDecl = CastTo!(StructDeclaration)(parseAggregateDeclaration());
1698 structDecl.setAlignSize(size);
1699 set(structDecl, begin2);
1700 }
1636 else 1701 else
1637 expected(T.Struct); 1702 expected(T.Struct);
1638 d = new AlignDeclaration(size, structDecl ? structDecl : new Declarations); 1703
1704 d = new AlignDeclaration(size, structDecl ? cast(Declaration)structDecl : new Declarations);
1639 goto LreturnDeclarationStatement; 1705 goto LreturnDeclarationStatement;
1640 /+ Not applicable for statements. 1706 /+ Not applicable for statements.
1641 // T.Private, 1707 // T.Private,
1642 // T.Package, 1708 // T.Package,
1643 // T.Protected, 1709 // T.Protected,
1666 break; 1732 break;
1667 } 1733 }
1668 goto case T.Dot; 1734 goto case T.Dot;
1669 case T.Dot, T.Typeof: 1735 case T.Dot, T.Typeof:
1670 bool success; 1736 bool success;
1671 d = try_({return parseDeclaration(StorageClass.None, false);}, success); 1737 d = try_(delegate {
1738 return parseVariableOrFunction(StorageClass.None, Protection.None, LinkageType.None, false);
1739 }, success
1740 );
1672 if (success) 1741 if (success)
1673 goto LreturnDeclarationStatement; // Declaration 1742 goto LreturnDeclarationStatement; // Declaration
1674 else 1743 else
1675 goto case_parseExpressionStatement; // Expression 1744 goto case_parseExpressionStatement; // Expression
1676 // IntegralType 1745 // IntegralType
1679 T.Int, T.Uint, T.Long, T.Ulong, 1748 T.Int, T.Uint, T.Long, T.Ulong,
1680 T.Float, T.Double, T.Real, 1749 T.Float, T.Double, T.Real,
1681 T.Ifloat, T.Idouble, T.Ireal, 1750 T.Ifloat, T.Idouble, T.Ireal,
1682 T.Cfloat, T.Cdouble, T.Creal, T.Void: 1751 T.Cfloat, T.Cdouble, T.Creal, T.Void:
1683 case_parseDeclaration: 1752 case_parseDeclaration:
1684 d = parseDeclaration(); 1753 d = parseVariableOrFunction();
1685 goto LreturnDeclarationStatement; 1754 goto LreturnDeclarationStatement;
1686 case T.If: 1755 case T.If:
1687 s = parseIfStatement(); 1756 s = parseIfStatement();
1688 break; 1757 break;
1689 case T.While: 1758 case T.While:
1926 return parseNoScopeStatement(); 1995 return parseNoScopeStatement();
1927 } 1996 }
1928 1997
1929 Statement parseAttributeStatement() 1998 Statement parseAttributeStatement()
1930 { 1999 {
1931 StorageClass stc, tmp; 2000 StorageClass stc, stc_tmp;
1932 Linkage.Category link_cat; 2001 LinkageType prev_linkageType;
1933 2002
1934 void addStorageClass() 2003 // Nested function.
1935 { 2004 Declaration parse()
1936 if (stc & tmp)
1937 error(MID.RedundantStorageClass, token.srcText);
1938 else
1939 stc |= tmp;
1940 }
1941
1942 Statement parse()
1943 { 2005 {
1944 auto begin = token; 2006 auto begin = token;
1945 Statement s; 2007 Declaration d;
1946 switch (token.type) 2008 switch (token.type)
1947 { 2009 {
1948 case T.Extern: 2010 case T.Extern:
1949 stc |= StorageClass.Extern; 2011 if (peekNext() != T.LParen)
1950 nT();
1951 Linkage linkage = parseLinkage();
1952
1953 // Check for redundancy.
1954 Linkage.Category link_cat_tmp = Linkage.getCategory(linkage);
1955 if (link_cat & link_cat_tmp)
1956 { 2012 {
1957 char[] srcText = begin.srcText; 2013 stc_tmp = StorageClass.Extern;
1958 if (link_cat_tmp == Linkage.Category.MangleSymbol) 2014 goto Lcommon;
1959 srcText = begin.start[0 .. prevToken.end - begin.start];
1960 error(MID.RedundantStorageClass, srcText);
1961 } 2015 }
1962 else 2016
1963 link_cat |= link_cat_tmp; 2017 nT();
1964 2018 auto linkageType = parseLinkageType();
1965 s = new ExternStatement(linkage, parse()); 2019 checkLinkageType(prev_linkageType, linkageType, begin.start);
2020
2021 d = new LinkageDeclaration(linkageType, parse());
1966 break; 2022 break;
1967 case T.Static: 2023 case T.Static:
1968 tmp = StorageClass.Static; 2024 stc_tmp = StorageClass.Static;
1969 goto Lcommon; 2025 goto Lcommon;
1970 case T.Final: 2026 case T.Final:
1971 tmp = StorageClass.Final; 2027 stc_tmp = StorageClass.Final;
1972 goto Lcommon; 2028 goto Lcommon;
1973 case T.Const: 2029 case T.Const:
1974 version(D2) 2030 version(D2)
1975 { 2031 {
1976 if (peekNext() == T.LParen) 2032 if (peekNext() == T.LParen)
1977 goto case_Declaration; 2033 goto case_Declaration;
1978 } 2034 }
1979 tmp = StorageClass.Const; 2035 stc_tmp = StorageClass.Const;
1980 goto Lcommon; 2036 goto Lcommon;
1981 version(D2) 2037 version(D2)
1982 { 2038 {
1983 case T.Invariant: // D 2.0 2039 case T.Invariant: // D 2.0
1984 if (peekNext() == T.LParen) 2040 if (peekNext() == T.LParen)
1985 goto case_Declaration; 2041 goto case_Declaration;
1986 tmp = StorageClass.Invariant; 2042 stc_tmp = StorageClass.Invariant;
1987 goto Lcommon; 2043 goto Lcommon;
1988 } 2044 }
1989 case T.Auto: 2045 case T.Auto:
1990 tmp = StorageClass.Auto; 2046 stc_tmp = StorageClass.Auto;
1991 goto Lcommon; 2047 goto Lcommon;
1992 case T.Scope: 2048 case T.Scope:
1993 tmp = StorageClass.Scope; 2049 stc_tmp = StorageClass.Scope;
1994 goto Lcommon; 2050 goto Lcommon;
1995 Lcommon: 2051 Lcommon:
1996 addStorageClass(); 2052 // Issue error if redundant.
2053 if (stc & stc_tmp)
2054 error(MID.RedundantStorageClass, token.srcText);
2055 else
2056 stc |= stc_tmp;
2057
1997 auto tok = token.type; 2058 auto tok = token.type;
1998 nT(); 2059 nT();
1999 s = new AttributeStatement(tok, parse()); 2060 d = new StorageClassDeclaration(stc_tmp, tok, parse());
2000 break; 2061 break;
2001 // TODO: allow "scope class", "abstract scope class" in function bodies? 2062 // TODO: allow "scope class", "abstract scope class" in function bodies?
2002 //case T.Class: 2063 //case T.Class:
2003 default: 2064 default:
2004 case_Declaration: 2065 case_Declaration:
2005 s = new DeclarationStatement(parseDeclaration(stc)); 2066 return parseVariableOrFunction(stc, Protection.None, prev_linkageType);
2006 } 2067 }
2007 set(s, begin); 2068 return set(d, begin);
2008 return s; 2069 }
2009 } 2070 return new DeclarationStatement(parse());
2010 return parse();
2011 } 2071 }
2012 2072
2013 Statement parseIfStatement() 2073 Statement parseIfStatement()
2014 { 2074 {
2015 assert(token.type == T.If); 2075 assert(token.type == T.If);
2030 ident = requireId(); 2090 ident = requireId();
2031 require(T.Assign); 2091 require(T.Assign);
2032 auto init = parseExpression(); 2092 auto init = parseExpression();
2033 auto v = new VariableDeclaration(null, [ident], [init]); 2093 auto v = new VariableDeclaration(null, [ident], [init]);
2034 set(v, ident); 2094 set(v, ident);
2035 auto d = new DeclarationStatement(v); 2095 auto d = new StorageClassDeclaration(StorageClass.Auto, T.Auto, v);
2036 set(d, ident); 2096 set(d, begin);
2037 variable = new AttributeStatement(T.Auto, d); 2097 variable = new DeclarationStatement(d);
2038 set(variable, begin); 2098 set(variable, begin);
2039 } 2099 }
2040 else 2100 else
2041 { 2101 {
2042 // Declarator = Expression 2102 // Declarator = Expression
3745 if (token.type == T.LParen) 3805 if (token.type == T.LParen)
3746 ctorArguments = parseArguments(); 3806 ctorArguments = parseArguments();
3747 3807
3748 BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ; 3808 BaseClass[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ;
3749 3809
3750 auto decls = parseDeclarationDefinitionsBlock(); 3810 auto decls = parseDeclarationDefinitionsBody();
3751 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin); 3811 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin);
3752 } 3812 }
3753 3813
3754 // NewExpression: 3814 // NewExpression:
3755 // NewArguments Type [ AssignExpression ] 3815 // NewArguments Type [ AssignExpression ]