Merge 2.058beta

This commit is contained in:
Alexey Prokhin
2012-02-12 14:42:37 +04:00
parent f2ed2e96b0
commit e74e55df89
64 changed files with 5261 additions and 2974 deletions

View File

@@ -231,6 +231,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
case TOKsuper:
case TOKtypeof:
case TOKdot:
case TOKvector:
Ldeclaration:
a = parseDeclarations(STCundefined, NULL);
decldefs->append(a);
@@ -820,6 +821,23 @@ TypeQualified *Parser::parseTypeof()
}
#endif
/***********************************
* Parse __vector(type).
* Current token is on the '__vector'.
*/
#if DMDV2
Type *Parser::parseVector()
{
Loc loc = this->loc;
nextToken();
check(TOKlparen);
Type *tb = parseType();
check(TOKrparen);
return new TypeVector(loc, tb);
}
#endif
/***********************************
* Parse extern (linkage)
* The parser is on the 'extern' token.
@@ -1247,7 +1265,7 @@ DeleteDeclaration *Parser::parseDelete()
* Parse parameter list.
*/
Parameters *Parser::parseParameters(int *pvarargs)
Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
{
Parameters *arguments = new Parameters();
int varargs = 0;
@@ -1351,17 +1369,32 @@ Parameters *Parser::parseParameters(int *pvarargs)
default:
Ldefault:
stc = storageClass & (STCin | STCout | STCref | STClazy);
{ stc = storageClass & (STCin | STCout | STCref | STClazy);
if (stc & (stc - 1)) // if stc is not a power of 2
error("incompatible parameter storage classes");
if ((storageClass & (STCconst | STCout)) == (STCconst | STCout))
error("out cannot be const");
if ((storageClass & (STCimmutable | STCout)) == (STCimmutable | STCout))
error("out cannot be immutable");
if ((storageClass & STCscope) &&
(storageClass & (STCref | STCout)))
if ((storageClass & STCscope) && (storageClass & (STCref | STCout)))
error("scope cannot be ref or out");
at = parseType(&ai);
Token *t;
if (tpl && !stc && token.value == TOKidentifier &&
(t = peek(&token), (t->value == TOKcomma || t->value == TOKrparen)))
{ Identifier *id = Lexer::uniqueId("__T");
at = new TypeIdentifier(loc, id);
if (!*tpl)
*tpl = new TemplateParameters();
TemplateParameter *tp = new TemplateTypeParameter(loc, id, NULL, NULL);
(*tpl)->push(tp);
ai = token.ident;
nextToken();
}
else
at = parseType(&ai);
ae = NULL;
if (token.value == TOKassign) // = defaultArg
{ nextToken();
@@ -1394,6 +1427,7 @@ Parameters *Parser::parseParameters(int *pvarargs)
goto L1;
}
break;
}
}
break;
}
@@ -1494,6 +1528,11 @@ EnumDeclaration *Parser::parseEnum()
}
addComment(em, comment);
comment = token.blockComment;
if (token.value == TOKeof)
{ error("premature end of file");
break;
}
}
nextToken();
}
@@ -1627,26 +1666,33 @@ BaseClasses *Parser::parseBaseClasses()
for (; 1; nextToken())
{
bool prot = false;
enum PROT protection = PROTpublic;
switch (token.value)
{
case TOKprivate:
prot = true;
protection = PROTprivate;
nextToken();
break;
case TOKpackage:
prot = true;
protection = PROTpackage;
nextToken();
break;
case TOKprotected:
prot = true;
protection = PROTprotected;
nextToken();
break;
case TOKpublic:
prot = true;
protection = PROTpublic;
nextToken();
break;
}
if (prot && !global.params.useDeprecated)
error("use of base class protection is deprecated");
if (token.value == TOKidentifier)
{
BaseClass *b = new BaseClass(parseBasicType(), protection);
@@ -1920,6 +1966,11 @@ Dsymbol *Parser::parseMixin()
tqual = parseTypeof();
check(TOKdot);
}
else if (token.value == TOKvector)
{
tqual = parseVector();
check(TOKdot);
}
if (token.value != TOKidentifier)
{
error("identifier expected, not %s", token.toChars());
@@ -2018,56 +2069,11 @@ Objects *Parser::parseTemplateArgumentList2()
{ // Template argument is an expression
Expression *ea = parseAssignExp();
if (ea->op == TOKfunction)
{ FuncLiteralDeclaration *fd = ((FuncExp *)ea)->fd;
if (fd->type->ty == Tfunction)
{
TypeFunction *tf = (TypeFunction *)fd->type;
/* If there are parameters that consist of only an identifier,
* rather than assuming the identifier is a type, as we would
* for regular function declarations, assume the identifier
* is the parameter name, and we're building a template with
* a deduced type.
*/
TemplateParameters *tpl = NULL;
for (size_t i = 0; i < tf->parameters->dim; i++)
{ Parameter *param = tf->parameters->tdata()[i];
if (param->ident == NULL &&
param->type &&
param->type->ty == Tident &&
((TypeIdentifier *)param->type)->idents.dim == 0
)
{
/* Switch parameter type to parameter identifier,
* parameterize with template type parameter _T
*/
TypeIdentifier *pt = (TypeIdentifier *)param->type;
param->ident = pt->ident;
Identifier *id = Lexer::uniqueId("__T");
param->type = new TypeIdentifier(pt->loc, id);
TemplateParameter *tp = new TemplateTypeParameter(fd->loc, id, NULL, NULL);
if (!tpl)
tpl = new TemplateParameters();
tpl->push(tp);
}
}
if (tpl)
{ // Wrap a template around function fd
Dsymbols *decldefs = new Dsymbols();
decldefs->push(fd);
TemplateDeclaration *tempdecl =
new TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs, 0);
tempdecl->literal = 1; // it's a template 'literal'
tiargs->push(tempdecl);
goto L1;
}
}
}
tiargs->push(ea);
if (ea->op == TOKfunction && ((FuncExp *)ea)->td)
tiargs->push(((FuncExp *)ea)->td);
else
tiargs->push(ea);
}
L1:
if (token.value != TOKcomma)
break;
nextToken();
@@ -2094,6 +2100,10 @@ Objects *Parser::parseTemplateArgument()
ta = new TypeIdentifier(loc, token.ident);
goto LabelX;
case TOKvector:
ta = parseVector();
goto LabelX;
case BASIC_TYPES_X(ta):
tiargs->push(ta);
nextToken();
@@ -2369,6 +2379,10 @@ Type *Parser::parseBasicType()
tid = parseTypeof();
goto Lident2;
case TOKvector:
t = parseVector();
break;
case TOKconst:
// const(type)
nextToken();
@@ -2875,6 +2889,13 @@ L2:
{ Declaration *v;
Initializer *init = NULL;
/* Aliases can no longer have multiple declarators, storage classes,
* linkages, or auto declarations.
* These never made any sense, anyway.
* The code below needs to be fixed to reject them.
* The grammar has already been fixed to preclude them.
*/
if (token.value == TOKassign)
{
nextToken();
@@ -3434,13 +3455,14 @@ Statement *Parser::parseStatement(int flags)
Identifier *ident = token.ident;
nextToken();
nextToken();
s = parseStatement(PSsemi);
s = parseStatement(PSsemi_ok);
s = new LabelStatement(loc, ident, s);
break;
}
// fallthrough to TOKdot
case TOKdot:
case TOKtypeof:
case TOKvector:
if (isDeclaration(&token, 2, TOKreserved, NULL))
goto Ldeclaration;
else
@@ -3559,7 +3581,6 @@ Statement *Parser::parseStatement(int flags)
case TOKgshared:
case TOKat:
#endif
// case TOKtypeof:
Ldeclaration:
{ Dsymbols *a;
@@ -3680,8 +3701,15 @@ Statement *Parser::parseStatement(int flags)
}
case TOKsemicolon:
if (!(flags & PSsemi))
error("use '{ }' for an empty statement, not a ';'");
if (!(flags & PSsemi_ok))
{
if (flags & PSsemi)
{ if (global.params.warnings)
warning(loc, "use '{ }' for an empty statement, not a ';'");
}
else
error("use '{ }' for an empty statement, not a ';'");
}
nextToken();
s = new ExpStatement(loc, (Expression *)NULL);
break;
@@ -3865,13 +3893,13 @@ Statement *Parser::parseStatement(int flags)
else if (token.value == TOKidentifier)
{
Token *t = peek(&token);
if (t->value == TOKcomma || t->value == TOKsemicolon)
if (t->value == TOKsemicolon)
{
arg = new Parameter(0, NULL, token.ident, NULL);
nextToken();
nextToken();
if (1 || !global.params.useDeprecated)
error("if (v; e) is deprecated, use if (auto v = e)");
if (!global.params.useDeprecated)
error("if (v%s e) is deprecated, use if (auto v = e)", t->toChars());
}
}
@@ -4255,7 +4283,7 @@ Statement *Parser::parseStatement(int flags)
s = parseStatement(PSsemi | PScurlyscope);
#if DMDV2
if (!global.params.useDeprecated)
error("volatile statements deprecated; used synchronized statements instead");
error("volatile statements deprecated; use synchronized statements instead");
#endif
s = new VolatileStatement(loc, s);
break;
@@ -4531,6 +4559,7 @@ int Parser::isBasicType(Token **pt)
goto Ldot;
case TOKtypeof:
case TOKvector:
/* typeof(exp).identifier...
*/
t = peek(t);
@@ -4721,9 +4750,12 @@ int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok)
case TOKrbracket:
case TOKassign:
case TOKcomma:
case TOKdotdotdot:
case TOKsemicolon:
case TOKlcurly:
case TOKin:
case TOKout:
case TOKbody:
// The !parens is to disallow unnecessary parentheses
if (!parens && (endtok == TOKreserved || endtok == t->value))
{ *pt = t;
@@ -5092,6 +5124,9 @@ Expression *Parser::parsePrimaryExp()
switch (token.value)
{
case TOKidentifier:
if (peekNext() == TOKgoesto)
goto case_delegate;
id = token.ident;
nextToken();
if (token.value == TOKnot && (save = peekNext()) != TOKis && save != TOKin)
@@ -5284,6 +5319,13 @@ Expression *Parser::parsePrimaryExp()
break;
}
case TOKvector:
{
t = parseVector();
e = new TypeExp(loc, t);
break;
}
case TOKtypeid:
{
nextToken();
@@ -5433,9 +5475,14 @@ Expression *Parser::parsePrimaryExp()
}
case TOKlparen:
if (peekPastParen(&token)->value == TOKlcurly)
{ enum TOK past = peekPastParen(&token)->value;
if (past == TOKgoesto)
{ // (arguments) => expression
goto case_delegate;
}
else if (past == TOKlcurly)
{ // (arguments) { statements... }
save = TOKdelegate;
goto case_delegate;
}
// ( expression )
@@ -5444,6 +5491,7 @@ Expression *Parser::parsePrimaryExp()
e->parens = 1;
check(loc, TOKrparen);
break;
}
case TOKlbracket:
{ /* Parse array literals and associative array literals:
@@ -5484,53 +5532,102 @@ Expression *Parser::parsePrimaryExp()
}
case TOKlcurly:
// { statements... }
save = TOKdelegate;
goto case_delegate;
case TOKfunction:
case TOKdelegate:
save = token.value;
nextToken();
case_delegate:
{
/* function type(parameters) { body } pure nothrow
* delegate type(parameters) { body } pure nothrow
* (parameters) { body }
* { body }
*/
Parameters *arguments;
int varargs;
FuncLiteralDeclaration *fd;
Type *t;
TemplateParameters *tpl = NULL;
Parameters *parameters = NULL;
int varargs = 0;
Type *tret = NULL;
StorageClass stc = 0;
enum TOK save = TOKreserved;
Loc loc = this->loc;
if (token.value == TOKlcurly)
switch (token.value)
{
t = NULL;
varargs = 0;
arguments = new Parameters();
case TOKfunction:
case TOKdelegate:
save = token.value;
nextToken();
if (token.value != TOKlparen && token.value != TOKlcurly)
{ // function type (parameters) { statements... }
// delegate type (parameters) { statements... }
tret = parseBasicType();
tret = parseBasicType2(tret); // function return type
}
if (token.value == TOKlparen)
{ // function (parameters) { statements... }
// delegate (parameters) { statements... }
}
else
{ // function { statements... }
// delegate { statements... }
break;
}
/* fall through to TOKlparen */
case TOKlparen:
Lparen:
{ // (parameters) => expression
// (parameters) { statements... }
parameters = parseParameters(&varargs, &tpl);
stc = parsePostfix();
if (stc & (STCconst | STCimmutable | STCshared | STCwild))
error("const/immutable/shared/inout attributes are only valid for non-static member functions");
break;
}
case TOKlcurly:
// { statements... }
break;
case TOKidentifier:
{ // identifier => expression
parameters = new Parameters();
Identifier *id = Lexer::uniqueId("__T");
Type *t = new TypeIdentifier(loc, id);
parameters->push(new Parameter(0, t, token.ident, NULL));
tpl = new TemplateParameters();
TemplateParameter *tp = new TemplateTypeParameter(loc, id, NULL, NULL);
tpl->push(tp);
nextToken();
break;
}
default:
assert(0);
}
if (!parameters)
parameters = new Parameters();
TypeFunction *tf = new TypeFunction(parameters, tret, varargs, linkage, stc);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, save, NULL);
if (token.value == TOKgoesto)
{
check(TOKgoesto);
Loc loc = this->loc;
Expression *ae = parseAssignExp();
fd->fbody = new ReturnStatement(loc, ae);
fd->endloc = this->loc;
}
else
{
if (token.value == TOKlparen)
t = NULL;
else
{
t = parseBasicType();
t = parseBasicType2(t); // function return type
}
arguments = parseParameters(&varargs);
stc = parsePostfix();
if (stc & (STCconst | STCimmutable | STCshared | STCwild))
error("const/immutable/shared/inout attributes are only valid for non-static member functions");
parseContracts(fd);
}
TypeFunction *tf = new TypeFunction(arguments, t, varargs, linkage, stc);
TemplateDeclaration *td = NULL;
if (tpl)
{ // Wrap a template around function fd
Dsymbols *decldefs = new Dsymbols();
decldefs->push(fd);
td = new TemplateDeclaration(fd->loc, fd->ident, tpl, NULL, decldefs, 0);
td->literal = 1; // it's a template 'literal'
}
fd = new FuncLiteralDeclaration(loc, 0, tf, save, NULL);
parseContracts(fd);
e = new FuncExp(loc, fd);
e = new FuncExp(loc, fd, td);
break;
}
@@ -5853,6 +5950,7 @@ Expression *Parser::parseUnaryExp()
case TOKfunction:
case TOKdelegate:
case TOKtypeof:
case TOKvector:
#if DMDV2
case TOKfile:
case TOKline:
@@ -6336,7 +6434,7 @@ Expressions *Parser::parseArguments()
{
nextToken();
while (token.value != endtok)
while (token.value != endtok && token.value != TOKeof)
{
arg = parseAssignExp();
arguments->push(arg);
@@ -6528,6 +6626,7 @@ void initPrecedence()
precedence[TOKcast] = PREC_unary;
#if DMDV2
precedence[TOKvector] = PREC_unary;
precedence[TOKpow] = PREC_pow;
#endif