comparison dmd2/parse.c @ 1452:638d16625da2

LDC 2 compiles again.
author Robert Clipsham <robert@octarineparrot.com>
date Sat, 30 May 2009 17:23:32 +0100
parents 356e65836fb5
children 54b3c1394d62
comparison
equal deleted inserted replaced
1423:42bd767ec5a4 1452:638d16625da2
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.
11 // This is the D parser 11 // This is the D parser
12 12
13 #include <stdio.h> 13 #include <stdio.h>
14 #include <assert.h> 14 #include <assert.h>
15 15
16 #include "mem.h" 16 #include "rmem.h"
17 #include "lexer.h" 17 #include "lexer.h"
18 #include "parse.h" 18 #include "parse.h"
19 #include "init.h" 19 #include "init.h"
20 #include "attrib.h" 20 #include "attrib.h"
21 #include "cond.h" 21 #include "cond.h"
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 #include "aliasthis.h"
35 36
36 // How multiple declarations are parsed. 37 // How multiple declarations are parsed.
37 // If 1, treat as C. 38 // If 1, treat as C.
38 // If 0, treat: 39 // If 0, treat:
39 // int *p, i; 40 // int *p, i;
71 { 72 {
72 unsigned char *comment = token.blockComment; 73 unsigned char *comment = token.blockComment;
73 bool safe = FALSE; 74 bool safe = FALSE;
74 75
75 nextToken(); 76 nextToken();
77 #if DMDV2
76 if (token.value == TOKlparen) 78 if (token.value == TOKlparen)
77 { 79 {
78 nextToken(); 80 nextToken();
79 if (token.value != TOKidentifier) 81 if (token.value != TOKidentifier)
80 { error("module (safe) identifier expected"); 82 { error("module (system) identifier expected");
81 goto Lerr; 83 goto Lerr;
82 } 84 }
83 Identifier *id = token.ident; 85 Identifier *id = token.ident;
84 86
85 if (id == Id::system) 87 if (id == Id::system)
87 else 89 else
88 error("(safe) expected, not %s", id->toChars()); 90 error("(safe) expected, not %s", id->toChars());
89 nextToken(); 91 nextToken();
90 check(TOKrparen); 92 check(TOKrparen);
91 } 93 }
94 #endif
92 95
93 if (token.value != TOKidentifier) 96 if (token.value != TOKidentifier)
94 { error("Identifier expected following module"); 97 { error("Identifier expected following module");
95 goto Lerr; 98 goto Lerr;
96 } 99 }
220 223
221 case TOKthis: 224 case TOKthis:
222 s = parseCtor(); 225 s = parseCtor();
223 break; 226 break;
224 227
228 #if 0 // dead end, use this(this){} instead
225 case TOKassign: 229 case TOKassign:
226 s = parsePostBlit(); 230 s = parsePostBlit();
227 break; 231 break;
228 232 #endif
229 case TOKtilde: 233 case TOKtilde:
230 s = parseDtor(); 234 s = parseDtor();
231 break; 235 break;
232 236
233 case TOKinvariant: 237 case TOKinvariant:
242 // invariant(type) 246 // invariant(type)
243 goto Ldeclaration; 247 goto Ldeclaration;
244 } 248 }
245 else 249 else
246 { 250 {
247 stc = STCinvariant; 251 stc = STCimmutable;
248 goto Lstc; 252 goto Lstc;
249 } 253 }
250 break; 254 break;
251 } 255 }
252 256
302 goto Lstc; 306 goto Lstc;
303 307
304 case TOKimmutable: 308 case TOKimmutable:
305 if (peek(&token)->value == TOKlparen) 309 if (peek(&token)->value == TOKlparen)
306 goto Ldeclaration; 310 goto Ldeclaration;
307 stc = STCinvariant; 311 stc = STCimmutable;
312 goto Lstc;
313
314 case TOKshared:
315 if (peek(&token)->value == TOKlparen)
316 goto Ldeclaration;
317 stc = STCshared;
308 goto Lstc; 318 goto Lstc;
309 319
310 case TOKfinal: stc = STCfinal; goto Lstc; 320 case TOKfinal: stc = STCfinal; goto Lstc;
311 case TOKauto: stc = STCauto; goto Lstc; 321 case TOKauto: stc = STCauto; goto Lstc;
312 case TOKscope: stc = STCscope; goto Lstc; 322 case TOKscope: stc = STCscope; goto Lstc;
313 case TOKoverride: stc = STCoverride; goto Lstc; 323 case TOKoverride: stc = STCoverride; goto Lstc;
314 case TOKabstract: stc = STCabstract; goto Lstc; 324 case TOKabstract: stc = STCabstract; goto Lstc;
315 case TOKsynchronized: stc = STCsynchronized; goto Lstc; 325 case TOKsynchronized: stc = STCsynchronized; goto Lstc;
316 case TOKdeprecated: stc = STCdeprecated; goto Lstc; 326 case TOKdeprecated: stc = STCdeprecated; goto Lstc;
327 #if DMDV2
317 case TOKnothrow: stc = STCnothrow; goto Lstc; 328 case TOKnothrow: stc = STCnothrow; goto Lstc;
318 case TOKpure: stc = STCpure; goto Lstc; 329 case TOKpure: stc = STCpure; goto Lstc;
319 case TOKref: stc = STCref; goto Lstc; 330 case TOKref: stc = STCref; goto Lstc;
320 case TOKtls: stc = STCtls; goto Lstc; 331 case TOKtls: stc = STCtls; goto Lstc;
332 case TOKgshared: stc = STCgshared; goto Lstc;
321 //case TOKmanifest: stc = STCmanifest; goto Lstc; 333 //case TOKmanifest: stc = STCmanifest; goto Lstc;
334 #endif
322 335
323 Lstc: 336 Lstc:
324 if (storageClass & stc) 337 if (storageClass & stc)
325 error("redundant storage class %s", Token::toChars(token.value)); 338 error("redundant storage class %s", Token::toChars(token.value));
326 { 339 composeStorageClass(storageClass | stc);
327 unsigned u = storageClass | stc;
328 u &= STCconst | STCinvariant | STCmanifest;
329 if (u & (u - 1))
330 error("conflicting storage class %s", Token::toChars(token.value));
331 }
332 nextToken(); 340 nextToken();
333 Lstc2: 341 Lstc2:
334 storageClass |= stc; 342 storageClass |= stc;
335 switch (token.value) 343 switch (token.value)
336 { 344 {
337 case TOKconst: 345 case TOKconst:
338 case TOKinvariant: 346 case TOKinvariant:
339 case TOKimmutable: 347 case TOKimmutable:
348 case TOKshared:
340 // If followed by a (, it is not a storage class 349 // If followed by a (, it is not a storage class
341 if (peek(&token)->value == TOKlparen) 350 if (peek(&token)->value == TOKlparen)
342 break; 351 break;
343 if (token.value == TOKconst) 352 if (token.value == TOKconst)
344 stc = STCconst; 353 stc = STCconst;
354 else if (token.value == TOKshared)
355 stc = STCshared;
345 else 356 else
346 stc = STCinvariant; 357 stc = STCimmutable;
347 goto Lstc; 358 goto Lstc;
348 case TOKfinal: stc = STCfinal; goto Lstc; 359 case TOKfinal: stc = STCfinal; goto Lstc;
349 case TOKauto: stc = STCauto; goto Lstc; 360 case TOKauto: stc = STCauto; goto Lstc;
350 case TOKscope: stc = STCscope; goto Lstc; 361 case TOKscope: stc = STCscope; goto Lstc;
351 case TOKoverride: stc = STCoverride; goto Lstc; 362 case TOKoverride: stc = STCoverride; goto Lstc;
354 case TOKdeprecated: stc = STCdeprecated; goto Lstc; 365 case TOKdeprecated: stc = STCdeprecated; goto Lstc;
355 case TOKnothrow: stc = STCnothrow; goto Lstc; 366 case TOKnothrow: stc = STCnothrow; goto Lstc;
356 case TOKpure: stc = STCpure; goto Lstc; 367 case TOKpure: stc = STCpure; goto Lstc;
357 case TOKref: stc = STCref; goto Lstc; 368 case TOKref: stc = STCref; goto Lstc;
358 case TOKtls: stc = STCtls; goto Lstc; 369 case TOKtls: stc = STCtls; goto Lstc;
370 case TOKgshared: stc = STCgshared; goto Lstc;
359 //case TOKmanifest: stc = STCmanifest; goto Lstc; 371 //case TOKmanifest: stc = STCmanifest; goto Lstc;
360 default: 372 default:
361 break; 373 break;
362 } 374 }
363 375
376 */ 388 */
377 Token *tk; 389 Token *tk;
378 if (token.value == TOKidentifier && 390 if (token.value == TOKidentifier &&
379 (tk = peek(&token))->value == TOKlparen && 391 (tk = peek(&token))->value == TOKlparen &&
380 skipParens(tk, &tk) && 392 skipParens(tk, &tk) &&
381 peek(tk)->value == TOKlparen) 393 (peek(tk)->value == TOKlparen ||
394 peek(tk)->value == TOKlcurly)
395 )
382 { 396 {
383 a = parseDeclarations(storageClass); 397 a = parseDeclarations(storageClass);
384 decldefs->append(a); 398 decldefs->append(a);
385 continue; 399 continue;
386 } 400 }
550 } 564 }
551 } while (!once); 565 } while (!once);
552 return decldefs; 566 return decldefs;
553 } 567 }
554 568
569 /*********************************************
570 * Give error on conflicting storage classes.
571 */
572
573 void Parser::composeStorageClass(unsigned stc)
574 {
575 unsigned u = stc;
576 u &= STCconst | STCimmutable | STCmanifest;
577 if (u & (u - 1))
578 error("conflicting storage class %s", Token::toChars(token.value));
579 u = stc;
580 u &= STCgshared | STCshared | STCtls;
581 if (u & (u - 1))
582 error("conflicting storage class %s", Token::toChars(token.value));
583 }
555 584
556 /******************************************** 585 /********************************************
557 * Parse declarations after an align, protection, or extern decl. 586 * Parse declarations after an align, protection, or extern decl.
558 */ 587 */
559 588
566 switch (token.value) 595 switch (token.value)
567 { 596 {
568 case TOKsemicolon: 597 case TOKsemicolon:
569 error("declaration expected following attribute, not ';'"); 598 error("declaration expected following attribute, not ';'");
570 nextToken(); 599 nextToken();
600 break;
601
602 case TOKeof:
603 error("declaration expected following attribute, not EOF");
571 break; 604 break;
572 605
573 case TOKlcurly: 606 case TOKlcurly:
574 nextToken(); 607 nextToken();
575 a = parseDeclDefs(0); 608 a = parseDeclDefs(0);
795 } 828 }
796 829
797 830
798 /***************************************** 831 /*****************************************
799 * Parse a constructor definition: 832 * Parse a constructor definition:
800 * this(arguments) { body } 833 * this(parameters) { body }
801 * or postblit: 834 * or postblit:
802 * this(this) { body } 835 * this(this) { body }
836 * or constructor template:
837 * this(templateparameters)(parameters) { body }
803 * Current token is 'this'. 838 * Current token is 'this'.
804 */ 839 */
805 840
806 FuncDeclaration *Parser::parseCtor() 841 Dsymbol *Parser::parseCtor()
807 { 842 {
808 Loc loc = this->loc; 843 Loc loc = this->loc;
809 844
810 nextToken(); 845 nextToken();
811 if (token.value == TOKlparen && peek(&token)->value == TOKthis) 846 if (token.value == TOKlparen && peek(&token)->value == TOKthis)
815 check(TOKrparen); 850 check(TOKrparen);
816 PostBlitDeclaration *f = new PostBlitDeclaration(loc, 0); 851 PostBlitDeclaration *f = new PostBlitDeclaration(loc, 0);
817 parseContracts(f); 852 parseContracts(f);
818 return f; 853 return f;
819 } 854 }
855
856 /* Look ahead to see if:
857 * this(...)(...)
858 * which is a constructor template
859 */
860 TemplateParameters *tpl = NULL;
861 if (token.value == TOKlparen && peekPastParen(&token)->value == TOKlparen)
862 { tpl = parseTemplateParameterList();
863
864 int varargs;
865 Arguments *arguments = parseParameters(&varargs);
866
867 Expression *constraint = NULL;
868 if (tpl)
869 constraint = parseConstraint();
870
871 CtorDeclaration *f = new CtorDeclaration(loc, 0, arguments, varargs);
872 parseContracts(f);
873
874 // Wrap a template around it
875 Array *decldefs = new Array();
876 decldefs->push(f);
877 TemplateDeclaration *tempdecl =
878 new TemplateDeclaration(loc, f->ident, tpl, constraint, decldefs);
879 return tempdecl;
880 }
881
882 /* Just a regular constructor
883 */
820 int varargs; 884 int varargs;
821 Arguments *arguments = parseParameters(&varargs); 885 Arguments *arguments = parseParameters(&varargs);
822 CtorDeclaration *f = new CtorDeclaration(loc, 0, arguments, varargs); 886 CtorDeclaration *f = new CtorDeclaration(loc, 0, arguments, varargs);
823 parseContracts(f); 887 parseContracts(f);
824 return f; 888 return f;
1032 1096
1033 case TOKinvariant: 1097 case TOKinvariant:
1034 case TOKimmutable: 1098 case TOKimmutable:
1035 if (peek(&token)->value == TOKlparen) 1099 if (peek(&token)->value == TOKlparen)
1036 goto Ldefault; 1100 goto Ldefault;
1037 stc = STCinvariant; 1101 stc = STCimmutable;
1102 goto L2;
1103
1104 case TOKshared:
1105 if (peek(&token)->value == TOKlparen)
1106 goto Ldefault;
1107 stc = STCshared;
1038 goto L2; 1108 goto L2;
1039 1109
1040 case TOKin: stc = STCin; goto L2; 1110 case TOKin: stc = STCin; goto L2;
1041 case TOKout: stc = STCout; goto L2; 1111 case TOKout: stc = STCout; goto L2;
1042 case TOKinout: 1112 case TOKinout:
1049 (storageClass & STCin && stc & (STCconst | STCscope)) || 1119 (storageClass & STCin && stc & (STCconst | STCscope)) ||
1050 (stc & STCin && storageClass & (STCconst | STCscope)) 1120 (stc & STCin && storageClass & (STCconst | STCscope))
1051 ) 1121 )
1052 error("redundant storage class %s", Token::toChars(token.value)); 1122 error("redundant storage class %s", Token::toChars(token.value));
1053 storageClass |= stc; 1123 storageClass |= stc;
1054 { 1124 composeStorageClass(storageClass);
1055 unsigned u = storageClass & (STCconst | STCinvariant);
1056 if (u & (u - 1))
1057 error("conflicting storage class %s", Token::toChars(token.value));
1058 }
1059 continue; 1125 continue;
1060 1126
1061 #if 0 1127 #if 0
1062 case TOKstatic: stc = STCstatic; goto L2; 1128 case TOKstatic: stc = STCstatic; goto L2;
1063 case TOKauto: storageClass = STCauto; goto L4; 1129 case TOKauto: storageClass = STCauto; goto L4;
1090 stc = storageClass & (STCin | STCout | STCref | STClazy); 1156 stc = storageClass & (STCin | STCout | STCref | STClazy);
1091 if (stc & (stc - 1)) // if stc is not a power of 2 1157 if (stc & (stc - 1)) // if stc is not a power of 2
1092 error("incompatible parameter storage classes"); 1158 error("incompatible parameter storage classes");
1093 if ((storageClass & (STCconst | STCout)) == (STCconst | STCout)) 1159 if ((storageClass & (STCconst | STCout)) == (STCconst | STCout))
1094 error("out cannot be const"); 1160 error("out cannot be const");
1095 if ((storageClass & (STCinvariant | STCout)) == (STCinvariant | STCout)) 1161 if ((storageClass & (STCimmutable | STCout)) == (STCimmutable | STCout))
1096 error("out cannot be invariant"); 1162 error("out cannot be immutable");
1097 if ((storageClass & STCscope) && 1163 if ((storageClass & STCscope) &&
1098 (storageClass & (STCref | STCout))) 1164 (storageClass & (STCref | STCout)))
1099 error("scope cannot be ref or out"); 1165 error("scope cannot be ref or out");
1100 at = parseType(&ai); 1166 at = parseType(&ai);
1101 ae = NULL; 1167 ae = NULL;
1734 return parseTemplateArgumentList2(); 1800 return parseTemplateArgumentList2();
1735 } 1801 }
1736 1802
1737 Objects *Parser::parseTemplateArgumentList2() 1803 Objects *Parser::parseTemplateArgumentList2()
1738 { 1804 {
1805 //printf("Parser::parseTemplateArgumentList2()\n");
1739 Objects *tiargs = new Objects(); 1806 Objects *tiargs = new Objects();
1740 enum TOK endtok = TOKrparen; 1807 enum TOK endtok = TOKrparen;
1741 nextToken(); 1808 nextToken();
1742 1809
1743 // Get TemplateArgumentList 1810 // Get TemplateArgumentList
1752 tiargs->push(ta); 1819 tiargs->push(ta);
1753 } 1820 }
1754 else 1821 else
1755 { // Template argument is an expression 1822 { // Template argument is an expression
1756 Expression *ea = parseAssignExp(); 1823 Expression *ea = parseAssignExp();
1824
1825 if (ea->op == TOKfunction)
1826 { FuncLiteralDeclaration *fd = ((FuncExp *)ea)->fd;
1827 if (fd->type->ty == Tfunction)
1828 {
1829 TypeFunction *tf = (TypeFunction *)fd->type;
1830 /* If there are parameters that consist of only an identifier,
1831 * rather than assuming the identifier is a type, as we would
1832 * for regular function declarations, assume the identifier
1833 * is the parameter name, and we're building a template with
1834 * a deduced type.
1835 */
1836 TemplateParameters *tpl = NULL;
1837 for (int i = 0; i < tf->parameters->dim; i++)
1838 { Argument *param = (Argument *)tf->parameters->data[i];
1839 if (param->ident == NULL &&
1840 param->type &&
1841 param->type->ty == Tident &&
1842 ((TypeIdentifier *)param->type)->idents.dim == 0
1843 )
1844 {
1845 /* Switch parameter type to parameter identifier,
1846 * parameterize with template type parameter _T
1847 */
1848 TypeIdentifier *pt = (TypeIdentifier *)param->type;
1849 param->ident = pt->ident;
1850 Identifier *id = Lexer::uniqueId("__T");
1851 param->type = new TypeIdentifier(pt->loc, id);
1852 TemplateParameter *tp = new TemplateTypeParameter(fd->loc, id, NULL, NULL);
1853 if (!tpl)
1854 tpl = new TemplateParameters();
1855 tpl->push(tp);
1856 }
1857 }
1858
1859 if (tpl)
1860 { // Wrap a template around function fd
1861 Array *decldefs = new Array();
1862 decldefs->push(fd);
1863 TemplateDeclaration *tempdecl =
1864 new TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs);
1865 tempdecl->literal = 1; // it's a template 'literal'
1866 tiargs->push(tempdecl);
1867 goto L1;
1868 }
1869 }
1870 }
1871
1757 tiargs->push(ea); 1872 tiargs->push(ea);
1758 } 1873 }
1874 L1:
1759 if (token.value != TOKcomma) 1875 if (token.value != TOKcomma)
1760 break; 1876 break;
1761 nextToken(); 1877 nextToken();
1762 } 1878 }
1763 } 1879 }
1853 if (!a) 1969 if (!a)
1854 a = new Array(); 1970 a = new Array();
1855 a->push(id); 1971 a->push(id);
1856 nextToken(); 1972 nextToken();
1857 if (token.value != TOKidentifier) 1973 if (token.value != TOKidentifier)
1858 { error("Identifier expected following package"); 1974 { error("identifier expected following package");
1859 break; 1975 break;
1860 } 1976 }
1861 id = token.ident; 1977 id = token.ident;
1862 nextToken(); 1978 nextToken();
1863 } 1979 }
1864 1980
1865 s = new Import(loc, a, token.ident, aliasid, isstatic); 1981 s = new Import(loc, a, id, aliasid, isstatic);
1866 decldefs->push(s); 1982 decldefs->push(s);
1867 1983
1868 /* Look for 1984 /* Look for
1869 * : alias=name, alias=name; 1985 * : alias=name, alias=name;
1870 * syntax. 1986 * syntax.
1871 */ 1987 */
1872 if (token.value == TOKcolon) 1988 if (token.value == TOKcolon)
1873 { 1989 {
1874 do 1990 do
1875 { Identifier *name; 1991 { Identifier *name;
1876 Identifier *alias;
1877 1992
1878 nextToken(); 1993 nextToken();
1879 if (token.value != TOKidentifier) 1994 if (token.value != TOKidentifier)
1880 { error("Identifier expected following :"); 1995 { error("Identifier expected following :");
1881 break; 1996 break;
1882 } 1997 }
1883 alias = token.ident; 1998 Identifier *alias = token.ident;
1884 nextToken(); 1999 nextToken();
1885 if (token.value == TOKassign) 2000 if (token.value == TOKassign)
1886 { 2001 {
1887 nextToken(); 2002 nextToken();
1888 if (token.value != TOKidentifier) 2003 if (token.value != TOKidentifier)
1913 } 2028 }
1914 2029
1915 return NULL; 2030 return NULL;
1916 } 2031 }
1917 2032
2033 #if DMDV2
1918 Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl) 2034 Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl)
1919 { Type *t; 2035 { Type *t;
1920 2036
1921 if (token.value == TOKconst && peek(&token)->value != TOKlparen) 2037 /* Take care of the storage class prefixes that
2038 * serve as type attributes:
2039 * const shared, shared const, const, invariant, shared
2040 */
2041 if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen ||
2042 token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen)
2043 {
2044 nextToken();
2045 nextToken();
2046 /* shared const type
2047 */
2048 t = parseType(pident, tpl);
2049 t = t->makeSharedConst();
2050 return t;
2051 }
2052 else if (token.value == TOKconst && peekNext() != TOKlparen)
1922 { 2053 {
1923 nextToken(); 2054 nextToken();
1924 /* const type 2055 /* const type
1925 */ 2056 */
1926 t = parseType(pident, tpl); 2057 t = parseType(pident, tpl);
1927 t = t->makeConst(); 2058 t = t->makeConst();
1928 return t; 2059 return t;
1929 } 2060 }
1930 else if ((token.value == TOKinvariant || token.value == TOKimmutable) && 2061 else if ((token.value == TOKinvariant || token.value == TOKimmutable) &&
1931 peek(&token)->value != TOKlparen) 2062 peekNext() != TOKlparen)
1932 { 2063 {
1933 nextToken(); 2064 nextToken();
1934 /* invariant type 2065 /* invariant type
1935 */ 2066 */
1936 t = parseType(pident, tpl); 2067 t = parseType(pident, tpl);
1937 t = t->makeInvariant(); 2068 t = t->makeInvariant();
1938 return t; 2069 return t;
1939 } 2070 }
2071 else if (token.value == TOKshared && peekNext() != TOKlparen)
2072 {
2073 nextToken();
2074 /* shared type
2075 */
2076 t = parseType(pident, tpl);
2077 t = t->makeShared();
2078 return t;
2079 }
1940 else 2080 else
1941 t = parseBasicType(); 2081 t = parseBasicType();
1942 t = parseDeclarator(t, pident, tpl); 2082 t = parseDeclarator(t, pident, tpl);
1943 return t; 2083 return t;
1944 } 2084 }
2085 #endif
1945 2086
1946 Type *Parser::parseBasicType() 2087 Type *Parser::parseBasicType()
1947 { Type *t; 2088 { Type *t;
1948 Identifier *id; 2089 Identifier *id;
1949 TypeQualified *tid; 2090 TypeQualified *tid;
2014 // const(type) 2155 // const(type)
2015 nextToken(); 2156 nextToken();
2016 check(TOKlparen); 2157 check(TOKlparen);
2017 t = parseType(); 2158 t = parseType();
2018 check(TOKrparen); 2159 check(TOKrparen);
2019 t = t->makeConst(); 2160 if (t->isShared())
2161 t = t->makeSharedConst();
2162 else
2163 t = t->makeConst();
2020 break; 2164 break;
2021 2165
2022 case TOKinvariant: 2166 case TOKinvariant:
2023 case TOKimmutable: 2167 case TOKimmutable:
2024 // invariant(type) 2168 // invariant(type)
2025 nextToken(); 2169 nextToken();
2026 check(TOKlparen); 2170 check(TOKlparen);
2027 t = parseType(); 2171 t = parseType();
2028 check(TOKrparen); 2172 check(TOKrparen);
2029 t = t->makeInvariant(); 2173 t = t->makeInvariant();
2174 break;
2175
2176 case TOKshared:
2177 // shared(type)
2178 nextToken();
2179 check(TOKlparen);
2180 t = parseType();
2181 check(TOKrparen);
2182 if (t->isConst())
2183 t = t->makeSharedConst();
2184 else
2185 t = t->makeShared();
2030 break; 2186 break;
2031 2187
2032 default: 2188 default:
2033 error("basic type expected, not %s", token.toChars()); 2189 error("basic type expected, not %s", token.toChars());
2034 t = Type::tint32; 2190 t = Type::tint32;
2245 while (1) 2401 while (1)
2246 { 2402 {
2247 switch (token.value) 2403 switch (token.value)
2248 { 2404 {
2249 case TOKconst: 2405 case TOKconst:
2250 tf = tf->makeConst(); 2406 if (tf->isShared())
2407 tf = tf->makeSharedConst();
2408 else
2409 tf = tf->makeConst();
2251 nextToken(); 2410 nextToken();
2252 continue; 2411 continue;
2253 2412
2254 case TOKinvariant: 2413 case TOKinvariant:
2255 case TOKimmutable: 2414 case TOKimmutable:
2256 tf = tf->makeInvariant(); 2415 tf = tf->makeInvariant();
2416 nextToken();
2417 continue;
2418
2419 case TOKshared:
2420 if (tf->isConst())
2421 tf = tf->makeSharedConst();
2422 else
2423 tf = tf->makeShared();
2257 nextToken(); 2424 nextToken();
2258 continue; 2425 continue;
2259 2426
2260 case TOKnothrow: 2427 case TOKnothrow:
2261 ((TypeFunction *)tf)->isnothrow = 1; 2428 ((TypeFunction *)tf)->isnothrow = 1;
2314 goto L2; 2481 goto L2;
2315 } 2482 }
2316 2483
2317 switch (token.value) 2484 switch (token.value)
2318 { 2485 {
2486 case TOKalias:
2487 /* Look for:
2488 * alias identifier this;
2489 */
2490 tok = token.value;
2491 nextToken();
2492 if (token.value == TOKidentifier && peek(&token)->value == TOKthis)
2493 {
2494 AliasThis *s = new AliasThis(this->loc, token.ident);
2495 nextToken();
2496 check(TOKthis);
2497 check(TOKsemicolon);
2498 a = new Array();
2499 a->push(s);
2500 addComment(s, comment);
2501 return a;
2502 }
2503 break;
2319 case TOKtypedef: 2504 case TOKtypedef:
2320 case TOKalias:
2321 tok = token.value; 2505 tok = token.value;
2322 nextToken(); 2506 nextToken();
2323 break; 2507 break;
2324 } 2508 }
2325 2509
2336 2520
2337 case TOKinvariant: 2521 case TOKinvariant:
2338 case TOKimmutable: 2522 case TOKimmutable:
2339 if (peek(&token)->value == TOKlparen) 2523 if (peek(&token)->value == TOKlparen)
2340 break; 2524 break;
2341 stc = STCinvariant; 2525 stc = STCimmutable;
2342 goto L1; 2526 goto L1;
2343 2527
2344 case TOKshared: 2528 case TOKshared:
2345 if (peek(&token)->value == TOKlparen) 2529 if (peek(&token)->value == TOKlparen)
2346 break; 2530 break;
2353 case TOKscope: stc = STCscope; goto L1; 2537 case TOKscope: stc = STCscope; goto L1;
2354 case TOKoverride: stc = STCoverride; goto L1; 2538 case TOKoverride: stc = STCoverride; goto L1;
2355 case TOKabstract: stc = STCabstract; goto L1; 2539 case TOKabstract: stc = STCabstract; goto L1;
2356 case TOKsynchronized: stc = STCsynchronized; goto L1; 2540 case TOKsynchronized: stc = STCsynchronized; goto L1;
2357 case TOKdeprecated: stc = STCdeprecated; goto L1; 2541 case TOKdeprecated: stc = STCdeprecated; goto L1;
2542 #if DMDV2
2358 case TOKnothrow: stc = STCnothrow; goto L1; 2543 case TOKnothrow: stc = STCnothrow; goto L1;
2359 case TOKpure: stc = STCpure; goto L1; 2544 case TOKpure: stc = STCpure; goto L1;
2360 case TOKref: stc = STCref; goto L1; 2545 case TOKref: stc = STCref; goto L1;
2361 case TOKtls: stc = STCtls; goto L1; 2546 case TOKtls: stc = STCtls; goto L1;
2547 case TOKgshared: stc = STCgshared; goto L1;
2362 case TOKenum: stc = STCmanifest; goto L1; 2548 case TOKenum: stc = STCmanifest; goto L1;
2549 #endif
2363 L1: 2550 L1:
2364 if (storage_class & stc) 2551 if (storage_class & stc)
2365 error("redundant storage class '%s'", token.toChars()); 2552 error("redundant storage class '%s'", token.toChars());
2366 storage_class = (STC) (storage_class | stc); 2553 storage_class = (STC) (storage_class | stc);
2367 { 2554 composeStorageClass(storage_class);
2368 unsigned u = storage_class;
2369 u &= STCconst | STCinvariant | STCmanifest;
2370 if (u & (u - 1))
2371 error("conflicting storage class %s", Token::toChars(token.value));
2372 }
2373 nextToken(); 2555 nextToken();
2374 continue; 2556 continue;
2375 2557
2376 case TOKextern: 2558 case TOKextern:
2377 if (peek(&token)->value != TOKlparen) 2559 if (peek(&token)->value != TOKlparen)
3069 case TOKconst: 3251 case TOKconst:
3070 case TOKauto: 3252 case TOKauto:
3071 case TOKextern: 3253 case TOKextern:
3072 case TOKfinal: 3254 case TOKfinal:
3073 case TOKinvariant: 3255 case TOKinvariant:
3256 #if DMDV2
3074 case TOKimmutable: 3257 case TOKimmutable:
3258 case TOKshared:
3259 case TOKnothrow:
3260 case TOKpure:
3261 case TOKtls:
3262 case TOKgshared:
3263 #endif
3075 // case TOKtypeof: 3264 // case TOKtypeof:
3076 Ldeclaration: 3265 Ldeclaration:
3077 { Array *a; 3266 { Array *a;
3078 3267
3079 a = parseDeclarations(STCundefined); 3268 a = parseDeclarations(STCundefined);
3085 { 3274 {
3086 Dsymbol *d = (Dsymbol *)a->data[i]; 3275 Dsymbol *d = (Dsymbol *)a->data[i];
3087 s = new DeclarationStatement(loc, d); 3276 s = new DeclarationStatement(loc, d);
3088 as->push(s); 3277 as->push(s);
3089 } 3278 }
3090 s = new CompoundStatement(loc, as); 3279 s = new CompoundDeclarationStatement(loc, as);
3091 } 3280 }
3092 else if (a->dim == 1) 3281 else if (a->dim == 1)
3093 { 3282 {
3094 Dsymbol *d = (Dsymbol *)a->data[0]; 3283 Dsymbol *d = (Dsymbol *)a->data[0];
3095 s = new DeclarationStatement(loc, d); 3284 s = new DeclarationStatement(loc, d);
3841 { 4030 {
3842 //printf("isDeclaration(needId = %d)\n", needId); 4031 //printf("isDeclaration(needId = %d)\n", needId);
3843 int haveId = 0; 4032 int haveId = 0;
3844 4033
3845 #if DMDV2 4034 #if DMDV2
3846 if ((t->value == TOKconst || t->value == TOKinvariant || token.value == TOKimmutable) && 4035 if ((t->value == TOKconst ||
4036 t->value == TOKinvariant ||
4037 t->value == TOKimmutable ||
4038 t->value == TOKshared) &&
3847 peek(t)->value != TOKlparen) 4039 peek(t)->value != TOKlparen)
3848 { /* const type 4040 { /* const type
3849 * invariant type 4041 * immutable type
4042 * shared type
3850 */ 4043 */
3851 t = peek(t); 4044 t = peek(t);
3852 } 4045 }
3853 #endif 4046 #endif
3854 4047
3855 if (!isBasicType(&t)) 4048 if (!isBasicType(&t))
4049 {
3856 goto Lisnot; 4050 goto Lisnot;
4051 }
3857 if (!isDeclarator(&t, &haveId, endtok)) 4052 if (!isDeclarator(&t, &haveId, endtok))
3858 goto Lisnot; 4053 goto Lisnot;
3859 if ( needId == 1 || 4054 if ( needId == 1 ||
3860 (needId == 0 && !haveId) || 4055 (needId == 0 && !haveId) ||
3861 (needId == 2 && haveId)) 4056 (needId == 2 && haveId))
3968 goto L2; 4163 goto L2;
3969 4164
3970 case TOKconst: 4165 case TOKconst:
3971 case TOKinvariant: 4166 case TOKinvariant:
3972 case TOKimmutable: 4167 case TOKimmutable:
3973 // const(type) or invariant(type) 4168 case TOKshared:
4169 // const(type) or immutable(type) or shared(type)
3974 t = peek(t); 4170 t = peek(t);
3975 if (t->value != TOKlparen) 4171 if (t->value != TOKlparen)
3976 goto Lfalse; 4172 goto Lfalse;
3977 t = peek(t); 4173 t = peek(t);
3978 if (!isDeclaration(t, 0, TOKrparen, &t)) 4174 if (!isDeclaration(t, 0, TOKrparen, &t))
4175 {
3979 goto Lfalse; 4176 goto Lfalse;
4177 }
3980 t = peek(t); 4178 t = peek(t);
3981 break; 4179 break;
3982 4180
3983 default: 4181 default:
3984 goto Lfalse; 4182 goto Lfalse;
4006 { 4204 {
4007 parens = FALSE; 4205 parens = FALSE;
4008 switch (t->value) 4206 switch (t->value)
4009 { 4207 {
4010 case TOKmul: 4208 case TOKmul:
4011 // case TOKand: 4209 //case TOKand:
4012 t = peek(t); 4210 t = peek(t);
4013 continue; 4211 continue;
4014 4212
4015 case TOKlbracket: 4213 case TOKlbracket:
4016 t = peek(t); 4214 t = peek(t);
4111 4309
4112 case TOKlparen: 4310 case TOKlparen:
4113 parens = FALSE; 4311 parens = FALSE;
4114 if (!isParameters(&t)) 4312 if (!isParameters(&t))
4115 return FALSE; 4313 return FALSE;
4314 #if DMDV2
4116 while (1) 4315 while (1)
4117 { 4316 {
4118 switch (t->value) 4317 switch (t->value)
4119 { 4318 {
4120 case TOKconst: 4319 case TOKconst:
4121 case TOKinvariant: 4320 case TOKinvariant:
4122 case TOKimmutable: 4321 case TOKimmutable:
4322 case TOKshared:
4123 case TOKpure: 4323 case TOKpure:
4124 case TOKnothrow: 4324 case TOKnothrow:
4125 t = peek(t); 4325 t = peek(t);
4126 continue; 4326 continue;
4127 default: 4327 default:
4128 break; 4328 break;
4129 } 4329 }
4130 break; 4330 break;
4131 } 4331 }
4332 #endif
4132 continue; 4333 continue;
4133 4334
4134 // Valid tokens that follow a declaration 4335 // Valid tokens that follow a declaration
4135 case TOKrparen: 4336 case TOKrparen:
4136 case TOKrbracket: 4337 case TOKrbracket:
4180 case TOKref: 4381 case TOKref:
4181 case TOKlazy: 4382 case TOKlazy:
4182 case TOKconst: 4383 case TOKconst:
4183 case TOKinvariant: 4384 case TOKinvariant:
4184 case TOKimmutable: 4385 case TOKimmutable:
4386 case TOKshared:
4185 case TOKfinal: 4387 case TOKfinal:
4186 continue; 4388 continue;
4187 4389
4188 #if 0 4390 #if 0
4189 case TOKstatic: 4391 case TOKstatic:
4476 e = new SuperExp(loc); 4678 e = new SuperExp(loc);
4477 nextToken(); 4679 nextToken();
4478 break; 4680 break;
4479 4681
4480 case TOKint32v: 4682 case TOKint32v:
4481 e = new IntegerExp(loc, token.int32value, Type::tint32); 4683 e = new IntegerExp(loc, (d_int32)token.int64value, Type::tint32);
4482 nextToken(); 4684 nextToken();
4483 break; 4685 break;
4484 4686
4485 case TOKuns32v: 4687 case TOKuns32v:
4486 e = new IntegerExp(loc, token.uns32value, Type::tuns32); 4688 e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tuns32);
4487 nextToken(); 4689 nextToken();
4488 break; 4690 break;
4489 4691
4490 case TOKint64v: 4692 case TOKint64v:
4491 e = new IntegerExp(loc, token.int64value, Type::tint64); 4693 e = new IntegerExp(loc, token.int64value, Type::tint64);
4532 nextToken(); 4734 nextToken();
4533 break; 4735 break;
4534 4736
4535 #if DMDV2 4737 #if DMDV2
4536 case TOKfile: 4738 case TOKfile:
4537 { char *s = loc.filename ? loc.filename : mod->ident->toChars(); 4739 { const char *s = loc.filename ? loc.filename : mod->ident->toChars();
4538 e = new StringExp(loc, s, strlen(s), 0); 4740 e = new StringExp(loc, (char *)s, strlen(s), 0);
4539 nextToken(); 4741 nextToken();
4540 break; 4742 break;
4541 } 4743 }
4542 4744
4543 case TOKline: 4745 case TOKline:
4555 e = new IntegerExp(loc, 0, Type::tbool); 4757 e = new IntegerExp(loc, 0, Type::tbool);
4556 nextToken(); 4758 nextToken();
4557 break; 4759 break;
4558 4760
4559 case TOKcharv: 4761 case TOKcharv:
4560 e = new IntegerExp(loc, token.uns32value, Type::tchar); 4762 e = new IntegerExp(loc, (d_uns8)token.uns64value, Type::tchar);
4561 nextToken(); 4763 nextToken();
4562 break; 4764 break;
4563 4765
4564 case TOKwcharv: 4766 case TOKwcharv:
4565 e = new IntegerExp(loc, token.uns32value, Type::twchar); 4767 e = new IntegerExp(loc, (d_uns16)token.uns64value, Type::twchar);
4566 nextToken(); 4768 nextToken();
4567 break; 4769 break;
4568 4770
4569 case TOKdcharv: 4771 case TOKdcharv:
4570 e = new IntegerExp(loc, token.uns32value, Type::tdchar); 4772 e = new IntegerExp(loc, (d_uns32)token.uns64value, Type::tdchar);
4571 nextToken(); 4773 nextToken();
4572 break; 4774 break;
4573 4775
4574 case TOKstring: 4776 case TOKstring:
4575 { unsigned char *s; 4777 { unsigned char *s;
4615 check(TOKdot, t->toChars()); 4817 check(TOKdot, t->toChars());
4616 if (token.value != TOKidentifier) 4818 if (token.value != TOKidentifier)
4617 { error("found '%s' when expecting identifier following '%s.'", token.toChars(), t->toChars()); 4819 { error("found '%s' when expecting identifier following '%s.'", token.toChars(), t->toChars());
4618 goto Lerr; 4820 goto Lerr;
4619 } 4821 }
4620 e = new TypeDotIdExp(loc, t, token.ident); 4822 e = typeDotIdExp(loc, t, token.ident);
4621 nextToken(); 4823 nextToken();
4622 break; 4824 break;
4623 4825
4624 case TOKtypeof: 4826 case TOKtypeof:
4625 { 4827 {
4688 token.value == TOKunion || 4890 token.value == TOKunion ||
4689 token.value == TOKclass || 4891 token.value == TOKclass ||
4690 token.value == TOKsuper || 4892 token.value == TOKsuper ||
4691 token.value == TOKenum || 4893 token.value == TOKenum ||
4692 token.value == TOKinterface || 4894 token.value == TOKinterface ||
4895 #if DMDV2
4693 token.value == TOKconst && peek(&token)->value == TOKrparen || 4896 token.value == TOKconst && peek(&token)->value == TOKrparen ||
4694 token.value == TOKinvariant && peek(&token)->value == TOKrparen || 4897 token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
4695 token.value == TOKimmutable && peek(&token)->value == TOKrparen || 4898 token.value == TOKimmutable && peek(&token)->value == TOKrparen ||
4899 token.value == TOKshared && peek(&token)->value == TOKrparen ||
4900 #endif
4696 token.value == TOKfunction || 4901 token.value == TOKfunction ||
4697 token.value == TOKdelegate || 4902 token.value == TOKdelegate ||
4698 token.value == TOKreturn)) 4903 token.value == TOKreturn))
4699 { 4904 {
4700 tok2 = token.value; 4905 tok2 = token.value;
4863 else 5068 else
4864 break; 5069 break;
4865 nextToken(); 5070 nextToken();
4866 } 5071 }
4867 } 5072 }
5073
4868 TypeFunction *tf = new TypeFunction(arguments, t, varargs, linkage); 5074 TypeFunction *tf = new TypeFunction(arguments, t, varargs, linkage);
4869 tf->ispure = ispure; 5075 tf->ispure = ispure;
4870 tf->isnothrow = isnothrow; 5076 tf->isnothrow = isnothrow;
4871 fd = new FuncLiteralDeclaration(loc, 0, tf, save, NULL); 5077 fd = new FuncLiteralDeclaration(loc, 0, tf, save, NULL);
4872 parseContracts(fd); 5078 parseContracts(fd);
5056 case TOKnew: 5262 case TOKnew:
5057 e = parseNewExp(NULL); 5263 e = parseNewExp(NULL);
5058 break; 5264 break;
5059 5265
5060 case TOKcast: // cast(type) expression 5266 case TOKcast: // cast(type) expression
5061 { Type *t; 5267 {
5062
5063 nextToken(); 5268 nextToken();
5064 check(TOKlparen); 5269 check(TOKlparen);
5065 /* Look for cast(const) and cast(invariant) 5270 /* Look for cast(), cast(const), cast(immutable),
5271 * cast(shared), cast(shared const)
5066 */ 5272 */
5067 if ((token.value == TOKconst || token.value == TOKinvariant || token.value == TOKimmutable) && 5273 unsigned m;
5068 peek(&token)->value == TOKrparen) 5274 if (token.value == TOKrparen)
5069 { enum TOK tok = token.value; 5275 {
5070 nextToken(); 5276 m = 0;
5277 goto Lmod1;
5278 }
5279 else if (token.value == TOKconst && peekNext() == TOKrparen)
5280 {
5281 m = MODconst;
5282 goto Lmod2;
5283 }
5284 else if ((token.value == TOKimmutable || token.value == TOKinvariant) && peekNext() == TOKrparen)
5285 {
5286 m = MODinvariant;
5287 goto Lmod2;
5288 }
5289 else if (token.value == TOKshared && peekNext() == TOKrparen)
5290 {
5291 m = MODshared;
5292 goto Lmod2;
5293 }
5294 else if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() == TOKrparen ||
5295 token.value == TOKshared && peekNext() == TOKconst && peekNext2() == TOKrparen)
5296 {
5297 m = MODshared | MODconst;
5298 nextToken();
5299 Lmod2:
5300 nextToken();
5301 Lmod1:
5071 nextToken(); 5302 nextToken();
5072 e = parseUnaryExp(); 5303 e = parseUnaryExp();
5073 e = new CastExp(loc, e, tok); 5304 e = new CastExp(loc, e, m);
5074 } 5305 }
5075 else 5306 else
5076 { 5307 {
5077 t = parseType(); // ( type ) 5308 Type *t = parseType(); // ( type )
5078 check(TOKrparen); 5309 check(TOKrparen);
5079 e = parseUnaryExp(); 5310 e = parseUnaryExp();
5080 e = new CastExp(loc, e, t); 5311 e = new CastExp(loc, e, t);
5081 } 5312 }
5082 break; 5313 break;
5151 nextToken(); 5382 nextToken();
5152 if (token.value != TOKidentifier) 5383 if (token.value != TOKidentifier)
5153 { error("Identifier expected following (type)."); 5384 { error("Identifier expected following (type).");
5154 return NULL; 5385 return NULL;
5155 } 5386 }
5156 e = new TypeDotIdExp(loc, t, token.ident); 5387 e = typeDotIdExp(loc, t, token.ident);
5157 nextToken(); 5388 nextToken();
5158 e = parsePostExp(e); 5389 e = parsePostExp(e);
5159 } 5390 }
5160 else 5391 else
5161 { 5392 {