Mercurial > projects > ldc
comparison dmd/parse.c @ 1195:e961851fb8be
Merged DMD 1.042.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Fri, 03 Apr 2009 17:59:34 +0200 |
parents | 226c07c71967 |
children | dda95755f63d |
comparison
equal
deleted
inserted
replaced
1194:1853dcd9b944 | 1195:e961851fb8be |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2008 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
30 #include "declaration.h" | 30 #include "declaration.h" |
31 #include "aggregate.h" | 31 #include "aggregate.h" |
32 #include "enum.h" | 32 #include "enum.h" |
33 #include "id.h" | 33 #include "id.h" |
34 #include "version.h" | 34 #include "version.h" |
35 #if DMDV2 | |
36 #include "aliasthis.h" | |
37 #endif | |
35 | 38 |
36 // How multiple declarations are parsed. | 39 // How multiple declarations are parsed. |
37 // If 1, treat as C. | 40 // If 1, treat as C. |
38 // If 0, treat: | 41 // If 0, treat: |
39 // int *p, i; | 42 // int *p, i; |
73 if (token.value == TOKmodule) | 76 if (token.value == TOKmodule) |
74 { | 77 { |
75 unsigned char *comment = token.blockComment; | 78 unsigned char *comment = token.blockComment; |
76 | 79 |
77 nextToken(); | 80 nextToken(); |
81 #if DMDV2 | |
82 if (token.value == TOKlparen) | |
83 { | |
84 nextToken(); | |
85 if (token.value != TOKidentifier) | |
86 { error("module (system) identifier expected"); | |
87 goto Lerr; | |
88 } | |
89 Identifier *id = token.ident; | |
90 | |
91 if (id == Id::system) | |
92 safe = TRUE; | |
93 else | |
94 error("(safe) expected, not %s", id->toChars()); | |
95 nextToken(); | |
96 check(TOKrparen); | |
97 } | |
98 #endif | |
99 | |
78 if (token.value != TOKidentifier) | 100 if (token.value != TOKidentifier) |
79 { error("Identifier expected following module"); | 101 { error("Identifier expected following module"); |
80 goto Lerr; | 102 goto Lerr; |
81 } | 103 } |
82 else | 104 else |
257 case TOKscope: stc = STCscope; goto Lstc; | 279 case TOKscope: stc = STCscope; goto Lstc; |
258 case TOKoverride: stc = STCoverride; goto Lstc; | 280 case TOKoverride: stc = STCoverride; goto Lstc; |
259 case TOKabstract: stc = STCabstract; goto Lstc; | 281 case TOKabstract: stc = STCabstract; goto Lstc; |
260 case TOKsynchronized: stc = STCsynchronized; goto Lstc; | 282 case TOKsynchronized: stc = STCsynchronized; goto Lstc; |
261 case TOKdeprecated: stc = STCdeprecated; goto Lstc; | 283 case TOKdeprecated: stc = STCdeprecated; goto Lstc; |
284 #if DMDV2 | |
285 case TOKnothrow: stc = STCnothrow; goto Lstc; | |
286 case TOKpure: stc = STCpure; goto Lstc; | |
287 case TOKref: stc = STCref; goto Lstc; | |
288 case TOKtls: stc = STCtls; goto Lstc; | |
289 //case TOKmanifest: stc = STCmanifest; goto Lstc; | |
290 #endif | |
262 | 291 |
263 Lstc: | 292 Lstc: |
264 nextToken(); | 293 nextToken(); |
265 Lstc2: | 294 Lstc2: |
266 switch (token.value) | 295 switch (token.value) |
340 case TOKpublic: prot = PROTpublic; goto Lprot; | 369 case TOKpublic: prot = PROTpublic; goto Lprot; |
341 case TOKexport: prot = PROTexport; goto Lprot; | 370 case TOKexport: prot = PROTexport; goto Lprot; |
342 | 371 |
343 Lprot: | 372 Lprot: |
344 nextToken(); | 373 nextToken(); |
374 switch (token.value) | |
375 { | |
376 case TOKprivate: | |
377 case TOKpackage: | |
378 case TOKprotected: | |
379 case TOKpublic: | |
380 case TOKexport: | |
381 error("redundant protection attribute"); | |
382 break; | |
383 } | |
345 a = parseBlock(); | 384 a = parseBlock(); |
346 s = new ProtDeclaration(prot, a); | 385 s = new ProtDeclaration(prot, a); |
347 break; | 386 break; |
348 | 387 |
349 case TOKalign: | 388 case TOKalign: |
800 return f; | 839 return f; |
801 } | 840 } |
802 | 841 |
803 /***************************************** | 842 /***************************************** |
804 * Parse an invariant definition: | 843 * Parse an invariant definition: |
805 * invariant { body } | 844 * invariant() { body } |
806 * Current token is 'invariant'. | 845 * Current token is 'invariant'. |
807 */ | 846 */ |
808 | 847 |
809 InvariantDeclaration *Parser::parseInvariant() | 848 InvariantDeclaration *Parser::parseInvariant() |
810 { | 849 { |
985 */ | 1024 */ |
986 | 1025 |
987 EnumDeclaration *Parser::parseEnum() | 1026 EnumDeclaration *Parser::parseEnum() |
988 { EnumDeclaration *e; | 1027 { EnumDeclaration *e; |
989 Identifier *id; | 1028 Identifier *id; |
990 Type *t; | 1029 Type *memtype; |
991 Loc loc = this->loc; | 1030 Loc loc = this->loc; |
992 | 1031 |
993 //printf("Parser::parseEnum()\n"); | 1032 //printf("Parser::parseEnum()\n"); |
994 nextToken(); | 1033 nextToken(); |
995 if (token.value == TOKidentifier) | 1034 if (token.value == TOKidentifier) |
1000 id = NULL; | 1039 id = NULL; |
1001 | 1040 |
1002 if (token.value == TOKcolon) | 1041 if (token.value == TOKcolon) |
1003 { | 1042 { |
1004 nextToken(); | 1043 nextToken(); |
1005 t = parseBasicType(); | 1044 memtype = parseBasicType(); |
1006 } | 1045 } |
1007 else | 1046 else |
1008 t = NULL; | 1047 memtype = NULL; |
1009 | 1048 |
1010 e = new EnumDeclaration(loc, id, t); | 1049 e = new EnumDeclaration(loc, id, memtype); |
1011 if (token.value == TOKsemicolon && id) | 1050 if (token.value == TOKsemicolon && id) |
1012 nextToken(); | 1051 nextToken(); |
1013 else if (token.value == TOKlcurly) | 1052 else if (token.value == TOKlcurly) |
1014 { | 1053 { |
1015 //printf("enum definition\n"); | 1054 //printf("enum definition\n"); |
1055 error("enum declaration is invalid"); | 1094 error("enum declaration is invalid"); |
1056 | 1095 |
1057 //printf("-parseEnum() %s\n", e->toChars()); | 1096 //printf("-parseEnum() %s\n", e->toChars()); |
1058 return e; | 1097 return e; |
1059 } | 1098 } |
1099 | |
1100 /******************************** | |
1101 * Parse struct, union, interface, class. | |
1102 */ | |
1060 | 1103 |
1061 Dsymbol *Parser::parseAggregate() | 1104 Dsymbol *Parser::parseAggregate() |
1062 { AggregateDeclaration *a = NULL; | 1105 { AggregateDeclaration *a = NULL; |
1063 int anon = 0; | 1106 int anon = 0; |
1064 enum TOK tok; | 1107 enum TOK tok; |
1158 TemplateDeclaration *tempdecl; | 1201 TemplateDeclaration *tempdecl; |
1159 | 1202 |
1160 // Wrap a template around the aggregate declaration | 1203 // Wrap a template around the aggregate declaration |
1161 decldefs = new Array(); | 1204 decldefs = new Array(); |
1162 decldefs->push(a); | 1205 decldefs->push(a); |
1163 tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); | 1206 tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs); |
1164 return tempdecl; | 1207 return tempdecl; |
1165 } | 1208 } |
1166 | 1209 |
1167 return a; | 1210 return a; |
1168 } | 1211 } |
1263 goto Lerr; | 1306 goto Lerr; |
1264 } | 1307 } |
1265 nextToken(); | 1308 nextToken(); |
1266 } | 1309 } |
1267 | 1310 |
1268 tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); | 1311 tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs); |
1269 return tempdecl; | 1312 return tempdecl; |
1270 | 1313 |
1271 Lerr: | 1314 Lerr: |
1272 return NULL; | 1315 return NULL; |
1273 } | 1316 } |
1647 nextToken(); | 1690 nextToken(); |
1648 } | 1691 } |
1649 | 1692 |
1650 return NULL; | 1693 return NULL; |
1651 } | 1694 } |
1695 | |
1696 #if DMDV2 | |
1697 Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl) | |
1698 { Type *t; | |
1699 | |
1700 /* Take care of the storage class prefixes that | |
1701 * serve as type attributes: | |
1702 * const shared, shared const, const, invariant, shared | |
1703 */ | |
1704 if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen || | |
1705 token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen) | |
1706 { | |
1707 nextToken(); | |
1708 nextToken(); | |
1709 /* shared const type | |
1710 */ | |
1711 t = parseType(pident, tpl); | |
1712 t = t->makeSharedConst(); | |
1713 return t; | |
1714 } | |
1715 else if (token.value == TOKconst && peekNext() != TOKlparen) | |
1716 { | |
1717 nextToken(); | |
1718 /* const type | |
1719 */ | |
1720 t = parseType(pident, tpl); | |
1721 t = t->makeConst(); | |
1722 return t; | |
1723 } | |
1724 else if ((token.value == TOKinvariant || token.value == TOKimmutable) && | |
1725 peekNext() != TOKlparen) | |
1726 { | |
1727 nextToken(); | |
1728 /* invariant type | |
1729 */ | |
1730 t = parseType(pident, tpl); | |
1731 t = t->makeInvariant(); | |
1732 return t; | |
1733 } | |
1734 else if (token.value == TOKshared && peekNext() != TOKlparen) | |
1735 { | |
1736 nextToken(); | |
1737 /* shared type | |
1738 */ | |
1739 t = parseType(pident, tpl); | |
1740 t = t->makeShared(); | |
1741 return t; | |
1742 } | |
1743 else | |
1744 t = parseBasicType(); | |
1745 t = parseDeclarator(t, pident, tpl); | |
1746 return t; | |
1747 } | |
1748 #endif | |
1652 | 1749 |
1653 Type *Parser::parseBasicType() | 1750 Type *Parser::parseBasicType() |
1654 { Type *t; | 1751 { Type *t; |
1655 Identifier *id; | 1752 Identifier *id; |
1656 TypeQualified *tid; | 1753 TypeQualified *tid; |
1887 default: | 1984 default: |
1888 ts = t; | 1985 ts = t; |
1889 break; | 1986 break; |
1890 } | 1987 } |
1891 | 1988 |
1989 // parse DeclaratorSuffixes | |
1892 while (1) | 1990 while (1) |
1893 { | 1991 { |
1894 switch (token.value) | 1992 switch (token.value) |
1895 { | 1993 { |
1896 #if CARRAYDECL | 1994 #if CARRAYDECL |
1922 //printf("it's [expression]\n"); | 2020 //printf("it's [expression]\n"); |
1923 Expression *e = parseExpression(); // [ expression ] | 2021 Expression *e = parseExpression(); // [ expression ] |
1924 ta = new TypeSArray(t, e); | 2022 ta = new TypeSArray(t, e); |
1925 check(TOKrbracket); | 2023 check(TOKrbracket); |
1926 } | 2024 } |
2025 | |
1927 /* Insert ta into | 2026 /* Insert ta into |
1928 * ts -> ... -> t | 2027 * ts -> ... -> t |
1929 * so that | 2028 * so that |
1930 * ts -> ... -> ta -> t | 2029 * ts -> ... -> ta -> t |
1931 */ | 2030 */ |
1984 Type *ts; | 2083 Type *ts; |
1985 Type *t; | 2084 Type *t; |
1986 Type *tfirst; | 2085 Type *tfirst; |
1987 Identifier *ident; | 2086 Identifier *ident; |
1988 Array *a; | 2087 Array *a; |
1989 enum TOK tok; | 2088 enum TOK tok = TOKreserved; |
1990 unsigned char *comment = token.blockComment; | 2089 unsigned char *comment = token.blockComment; |
1991 enum LINK link = linkage; | 2090 enum LINK link = linkage; |
1992 | 2091 |
1993 //printf("parseDeclarations()\n"); | 2092 //printf("parseDeclarations()\n"); |
1994 switch (token.value) | 2093 switch (token.value) |
2016 case TOKscope: stc = STCscope; goto L1; | 2115 case TOKscope: stc = STCscope; goto L1; |
2017 case TOKoverride: stc = STCoverride; goto L1; | 2116 case TOKoverride: stc = STCoverride; goto L1; |
2018 case TOKabstract: stc = STCabstract; goto L1; | 2117 case TOKabstract: stc = STCabstract; goto L1; |
2019 case TOKsynchronized: stc = STCsynchronized; goto L1; | 2118 case TOKsynchronized: stc = STCsynchronized; goto L1; |
2020 case TOKdeprecated: stc = STCdeprecated; goto L1; | 2119 case TOKdeprecated: stc = STCdeprecated; goto L1; |
2120 #if DMDV2 | |
2121 case TOKnothrow: stc = STCnothrow; goto L1; | |
2122 case TOKpure: stc = STCpure; goto L1; | |
2123 case TOKref: stc = STCref; goto L1; | |
2124 case TOKtls: stc = STCtls; goto L1; | |
2125 case TOKenum: stc = STCmanifest; goto L1; | |
2126 #endif | |
2021 L1: | 2127 L1: |
2022 if (storage_class & stc) | 2128 if (storage_class & stc) |
2023 error("redundant storage class '%s'", token.toChars()); | 2129 error("redundant storage class '%s'", token.toChars()); |
2024 storage_class = (STC) (storage_class | stc); | 2130 storage_class = (STC) (storage_class | stc); |
2025 nextToken(); | 2131 nextToken(); |
2106 if (!ident) | 2212 if (!ident) |
2107 error("no identifier for declarator %s", t->toChars()); | 2213 error("no identifier for declarator %s", t->toChars()); |
2108 | 2214 |
2109 if (tok == TOKtypedef || tok == TOKalias) | 2215 if (tok == TOKtypedef || tok == TOKalias) |
2110 { Declaration *v; | 2216 { Declaration *v; |
2111 Initializer *init; | 2217 Initializer *init = NULL; |
2112 | 2218 |
2113 init = NULL; | |
2114 if (token.value == TOKassign) | 2219 if (token.value == TOKassign) |
2115 { | 2220 { |
2116 nextToken(); | 2221 nextToken(); |
2117 init = parseInitializer(); | 2222 init = parseInitializer(); |
2118 } | 2223 } |
2148 error("semicolon expected to close %s declaration", Token::toChars(tok)); | 2253 error("semicolon expected to close %s declaration", Token::toChars(tok)); |
2149 break; | 2254 break; |
2150 } | 2255 } |
2151 } | 2256 } |
2152 else if (t->ty == Tfunction) | 2257 else if (t->ty == Tfunction) |
2153 { FuncDeclaration *f; | 2258 { FuncDeclaration *f = |
2154 Dsymbol *s; | 2259 new FuncDeclaration(loc, 0, ident, storage_class, t); |
2155 | |
2156 f = new FuncDeclaration(loc, 0, ident, storage_class, t); | |
2157 addComment(f, comment); | 2260 addComment(f, comment); |
2158 parseContracts(f); | 2261 parseContracts(f); |
2159 addComment(f, NULL); | 2262 addComment(f, NULL); |
2263 Dsymbol *s; | |
2160 if (link == linkage) | 2264 if (link == linkage) |
2161 { | 2265 { |
2162 s = f; | 2266 s = f; |
2163 } | 2267 } |
2164 else | 2268 else |
2172 TemplateDeclaration *tempdecl; | 2276 TemplateDeclaration *tempdecl; |
2173 | 2277 |
2174 // Wrap a template around the aggregate declaration | 2278 // Wrap a template around the aggregate declaration |
2175 decldefs = new Array(); | 2279 decldefs = new Array(); |
2176 decldefs->push(s); | 2280 decldefs->push(s); |
2177 tempdecl = new TemplateDeclaration(loc, s->ident, tpl, decldefs); | 2281 tempdecl = new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs); |
2178 s = tempdecl; | 2282 s = tempdecl; |
2179 } | 2283 } |
2180 addComment(s, comment); | 2284 addComment(s, comment); |
2181 a->push(s); | 2285 a->push(s); |
2182 } | 2286 } |
2183 else | 2287 else |
2184 { VarDeclaration *v; | 2288 { |
2185 Initializer *init; | 2289 Initializer *init = NULL; |
2186 | |
2187 init = NULL; | |
2188 if (token.value == TOKassign) | 2290 if (token.value == TOKassign) |
2189 { | 2291 { |
2190 nextToken(); | 2292 nextToken(); |
2191 init = parseInitializer(); | 2293 init = parseInitializer(); |
2192 } | 2294 } |
2193 v = new VarDeclaration(loc, t, ident, init); | 2295 |
2296 VarDeclaration *v = new VarDeclaration(loc, t, ident, init); | |
2194 v->storage_class = storage_class; | 2297 v->storage_class = storage_class; |
2195 if (link == linkage) | 2298 if (link == linkage) |
2196 a->push(v); | 2299 a->push(v); |
2197 else | 2300 else |
2198 { | 2301 { |
2361 } | 2464 } |
2362 linkage = linksave; | 2465 linkage = linksave; |
2363 } | 2466 } |
2364 | 2467 |
2365 /***************************************** | 2468 /***************************************** |
2469 * Parse initializer for variable declaration. | |
2366 */ | 2470 */ |
2367 | 2471 |
2368 Initializer *Parser::parseInitializer() | 2472 Initializer *Parser::parseInitializer() |
2369 { | 2473 { |
2370 StructInitializer *is; | 2474 StructInitializer *is; |
2618 error("statement expected to be { }, not %s", token.toChars()); | 2722 error("statement expected to be { }, not %s", token.toChars()); |
2619 | 2723 |
2620 switch (token.value) | 2724 switch (token.value) |
2621 { | 2725 { |
2622 case TOKidentifier: | 2726 case TOKidentifier: |
2623 // Need to look ahead to see if it is a declaration, label, or expression | 2727 /* A leading identifier can be a declaration, label, or expression. |
2728 * The easiest case to check first is label: | |
2729 */ | |
2624 t = peek(&token); | 2730 t = peek(&token); |
2625 if (t->value == TOKcolon) | 2731 if (t->value == TOKcolon) |
2626 { // It's a label | 2732 { // It's a label |
2627 Identifier *ident; | 2733 |
2628 | 2734 Identifier *ident = token.ident; |
2629 ident = token.ident; | |
2630 nextToken(); | 2735 nextToken(); |
2631 nextToken(); | 2736 nextToken(); |
2632 s = parseStatement(PSsemi); | 2737 s = parseStatement(PSsemi); |
2633 s = new LabelStatement(loc, ident, s); | 2738 s = new LabelStatement(loc, ident, s); |
2634 break; | 2739 break; |
2716 case TOKconst: | 2821 case TOKconst: |
2717 case TOKauto: | 2822 case TOKauto: |
2718 case TOKextern: | 2823 case TOKextern: |
2719 case TOKfinal: | 2824 case TOKfinal: |
2720 case TOKinvariant: | 2825 case TOKinvariant: |
2826 #if DMDV2 | |
2827 case TOKimmutable: | |
2828 case TOKshared: | |
2829 #endif | |
2721 // case TOKtypeof: | 2830 // case TOKtypeof: |
2722 Ldeclaration: | 2831 Ldeclaration: |
2723 { Array *a; | 2832 { Array *a; |
2724 | 2833 |
2725 a = parseDeclarations(); | 2834 a = parseDeclarations(); |
2731 { | 2840 { |
2732 Dsymbol *d = (Dsymbol *)a->data[i]; | 2841 Dsymbol *d = (Dsymbol *)a->data[i]; |
2733 s = new DeclarationStatement(loc, d); | 2842 s = new DeclarationStatement(loc, d); |
2734 as->push(s); | 2843 as->push(s); |
2735 } | 2844 } |
2736 s = new CompoundStatement(loc, as); | 2845 s = new CompoundDeclarationStatement(loc, as); |
2737 } | 2846 } |
2738 else if (a->dim == 1) | 2847 else if (a->dim == 1) |
2739 { | 2848 { |
2740 Dsymbol *d = (Dsymbol *)a->data[0]; | 2849 Dsymbol *d = (Dsymbol *)a->data[0]; |
2741 s = new DeclarationStatement(loc, d); | 2850 s = new DeclarationStatement(loc, d); |
3441 if (token.value != value) | 3550 if (token.value != value) |
3442 error(loc, "found '%s' when expecting '%s'", token.toChars(), Token::toChars(value)); | 3551 error(loc, "found '%s' when expecting '%s'", token.toChars(), Token::toChars(value)); |
3443 nextToken(); | 3552 nextToken(); |
3444 } | 3553 } |
3445 | 3554 |
3446 void Parser::check(enum TOK value, char *string) | 3555 void Parser::check(enum TOK value, const char *string) |
3447 { | 3556 { |
3448 if (token.value != value) | 3557 if (token.value != value) |
3449 error("found '%s' when expecting '%s' following '%s'", | 3558 error("found '%s' when expecting '%s' following '%s'", |
3450 token.toChars(), Token::toChars(value), string); | 3559 token.toChars(), Token::toChars(value), string); |
3451 nextToken(); | 3560 nextToken(); |
3459 * 2 must have identifier | 3568 * 2 must have identifier |
3460 */ | 3569 */ |
3461 | 3570 |
3462 int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) | 3571 int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) |
3463 { | 3572 { |
3573 //printf("isDeclaration(needId = %d)\n", needId); | |
3464 int haveId = 0; | 3574 int haveId = 0; |
3465 | 3575 |
3466 #if DMDV2 | 3576 #if DMDV2 |
3467 if ((t->value == TOKconst || t->value == TOKinvariant) && | 3577 if ((t->value == TOKconst || t->value == TOKinvariant) && |
3468 peek(t)->value != TOKlparen) | 3578 peek(t)->value != TOKlparen) |
3549 | 3659 |
3550 default: | 3660 default: |
3551 goto Lfalse; | 3661 goto Lfalse; |
3552 } | 3662 } |
3553 *pt = t; | 3663 *pt = t; |
3664 //printf("is\n"); | |
3554 return TRUE; | 3665 return TRUE; |
3555 | 3666 |
3556 Lfalse: | 3667 Lfalse: |
3668 //printf("is not\n"); | |
3557 return FALSE; | 3669 return FALSE; |
3558 } | 3670 } |
3559 | 3671 |
3560 int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) | 3672 int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) |
3561 { // This code parallels parseDeclarator() | 3673 { // This code parallels parseDeclarator() |
3676 | 3788 |
3677 case TOKlparen: | 3789 case TOKlparen: |
3678 parens = FALSE; | 3790 parens = FALSE; |
3679 if (!isParameters(&t)) | 3791 if (!isParameters(&t)) |
3680 return FALSE; | 3792 return FALSE; |
3793 #if DMDV2 | |
3794 while (1) | |
3795 { | |
3796 switch (t->value) | |
3797 { | |
3798 case TOKconst: | |
3799 case TOKinvariant: | |
3800 case TOKimmutable: | |
3801 case TOKshared: | |
3802 case TOKpure: | |
3803 case TOKnothrow: | |
3804 t = peek(t); | |
3805 continue; | |
3806 default: | |
3807 break; | |
3808 } | |
3809 break; | |
3810 } | |
3811 #endif | |
3681 continue; | 3812 continue; |
3682 | 3813 |
3683 // Valid tokens that follow a declaration | 3814 // Valid tokens that follow a declaration |
3684 case TOKrparen: | 3815 case TOKrparen: |
3685 case TOKrbracket: | 3816 case TOKrbracket: |
4201 token.value == TOKunion || | 4332 token.value == TOKunion || |
4202 token.value == TOKclass || | 4333 token.value == TOKclass || |
4203 token.value == TOKsuper || | 4334 token.value == TOKsuper || |
4204 token.value == TOKenum || | 4335 token.value == TOKenum || |
4205 token.value == TOKinterface || | 4336 token.value == TOKinterface || |
4337 #if DMDV2 | |
4338 token.value == TOKconst && peek(&token)->value == TOKrparen || | |
4339 token.value == TOKinvariant && peek(&token)->value == TOKrparen || | |
4340 token.value == TOKimmutable && peek(&token)->value == TOKrparen || | |
4341 token.value == TOKshared && peek(&token)->value == TOKrparen || | |
4342 #endif | |
4206 token.value == TOKfunction || | 4343 token.value == TOKfunction || |
4207 token.value == TOKdelegate || | 4344 token.value == TOKdelegate || |
4208 token.value == TOKreturn)) | 4345 token.value == TOKreturn)) |
4209 { | 4346 { |
4210 tok2 = token.value; | 4347 tok2 = token.value; |