Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
cb0a70ca
Commit
cb0a70ca
authored
Dec 06, 2012
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
compiler: Correct test for whether go/defer arg is parenthesized.
From-SVN: r194240
parent
4d901dd7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
46 deletions
+87
-46
gcc/go/gofrontend/parse.cc
+82
-42
gcc/go/gofrontend/parse.h
+5
-4
No files found.
gcc/go/gofrontend/parse.cc
View file @
cb0a70ca
...
...
@@ -141,7 +141,7 @@ Parse::expression_list(Expression* first, bool may_be_sink,
while
(
true
)
{
ret
->
push_back
(
this
->
expression
(
PRECEDENCE_NORMAL
,
may_be_sink
,
may_be_composite_lit
,
NULL
));
may_be_composite_lit
,
NULL
,
NULL
));
const
Token
*
token
=
this
->
peek_token
();
if
(
!
token
->
is_op
(
OPERATOR_COMMA
))
...
...
@@ -394,7 +394,7 @@ Parse::array_type(bool may_use_ellipsis)
else
{
if
(
!
token
->
is_op
(
OPERATOR_ELLIPSIS
))
length
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
length
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
else
if
(
may_use_ellipsis
)
{
// An ellipsis is used in composite literals to represent a
...
...
@@ -2137,7 +2137,7 @@ Parse::simple_var_decl_or_assignment(const std::string& name,
bool
is_type_switch
=
false
;
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
may_be_composite_lit
,
&
is_type_switch
);
&
is_type_switch
,
NULL
);
if
(
is_type_switch
)
{
p_type_switch
->
found
=
true
;
...
...
@@ -2404,8 +2404,11 @@ Parse::receiver()
// If MAY_BE_SINK is true, this operand may be "_".
// If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
// if the entire expression is in parentheses.
Expression
*
Parse
::
operand
(
bool
may_be_sink
)
Parse
::
operand
(
bool
may_be_sink
,
bool
*
is_parenthesized
)
{
const
Token
*
token
=
this
->
peek_token
();
Expression
*
ret
;
...
...
@@ -2581,11 +2584,14 @@ Parse::operand(bool may_be_sink)
if
(
token
->
is_op
(
OPERATOR_LPAREN
))
{
this
->
advance_token
();
ret
=
this
->
expression
(
PRECEDENCE_NORMAL
,
may_be_sink
,
true
,
NULL
);
ret
=
this
->
expression
(
PRECEDENCE_NORMAL
,
may_be_sink
,
true
,
NULL
,
NULL
);
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_RPAREN
))
error_at
(
this
->
location
(),
"missing %<)%>"
);
else
this
->
advance_token
();
if
(
is_parenthesized
!=
NULL
)
*
is_parenthesized
=
true
;
return
ret
;
}
else
if
(
token
->
is_op
(
OPERATOR_LSQUARE
))
...
...
@@ -2708,11 +2714,12 @@ Parse::composite_lit(Type* type, int depth, Location location)
this
->
unget_token
(
Token
::
make_identifier_token
(
identifier
,
is_exported
,
location
));
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
}
}
else
if
(
!
token
->
is_op
(
OPERATOR_LCURLY
))
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
else
{
// This must be a composite literal inside another composite
...
...
@@ -2758,7 +2765,7 @@ Parse::composite_lit(Type* type, int depth, Location location)
vals
->
push_back
(
val
);
if
(
!
token
->
is_op
(
OPERATOR_LCURLY
))
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
else
{
// This must be a composite literal inside another
...
...
@@ -2931,19 +2938,25 @@ Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars,
// If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
// guard (var := expr.("type") using the literal keyword "type").
// If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
// if the entire expression is in parentheses.
Expression
*
Parse
::
primary_expr
(
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
)
bool
*
is_type_switch
,
bool
*
is_parenthesized
)
{
Location
start_loc
=
this
->
location
();
bool
is_parenthesized
=
this
->
peek_token
()
->
is_op
(
OPERATOR_LPAREN
);
bool
operand_is_parenthesized
=
false
;
bool
whole_is_parenthesized
=
false
;
Expression
*
ret
=
this
->
operand
(
may_be_sink
,
&
operand_is_parenthesized
);
Expression
*
ret
=
this
->
operand
(
may_be_sink
)
;
whole_is_parenthesized
=
operand_is_parenthesized
;
// An unknown name followed by a curly brace must be a composite
// literal, and the unknown name must be a type.
if
(
may_be_composite_lit
&&
!
is_parenthesized
&&
!
operand_
is_parenthesized
&&
ret
->
unknown_expression
()
!=
NULL
&&
this
->
peek_token
()
->
is_op
(
OPERATOR_LCURLY
))
{
...
...
@@ -2959,6 +2972,7 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
{
if
(
this
->
peek_token
()
->
is_op
(
OPERATOR_LCURLY
))
{
whole_is_parenthesized
=
false
;
if
(
!
may_be_composite_lit
)
{
Type
*
t
=
ret
->
type
();
...
...
@@ -2968,17 +2982,18 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
_
(
"parentheses required around this composite literal "
"to avoid parsing ambiguity"
));
}
else
if
(
is_parenthesized
)
else
if
(
operand_
is_parenthesized
)
error_at
(
start_loc
,
"cannot parenthesize type in composite literal"
);
ret
=
this
->
composite_lit
(
ret
->
type
(),
0
,
ret
->
location
());
}
else
if
(
this
->
peek_token
()
->
is_op
(
OPERATOR_LPAREN
))
{
whole_is_parenthesized
=
false
;
Location
loc
=
this
->
location
();
this
->
advance_token
();
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
NULL
,
NULL
);
if
(
this
->
peek_token
()
->
is_op
(
OPERATOR_COMMA
))
this
->
advance_token
();
if
(
this
->
peek_token
()
->
is_op
(
OPERATOR_ELLIPSIS
))
...
...
@@ -3014,19 +3029,29 @@ Parse::primary_expr(bool may_be_sink, bool may_be_composite_lit,
{
const
Token
*
token
=
this
->
peek_token
();
if
(
token
->
is_op
(
OPERATOR_LPAREN
))
ret
=
this
->
call
(
this
->
verify_not_sink
(
ret
));
{
whole_is_parenthesized
=
false
;
ret
=
this
->
call
(
this
->
verify_not_sink
(
ret
));
}
else
if
(
token
->
is_op
(
OPERATOR_DOT
))
{
whole_is_parenthesized
=
false
;
ret
=
this
->
selector
(
this
->
verify_not_sink
(
ret
),
is_type_switch
);
if
(
is_type_switch
!=
NULL
&&
*
is_type_switch
)
break
;
}
else
if
(
token
->
is_op
(
OPERATOR_LSQUARE
))
ret
=
this
->
index
(
this
->
verify_not_sink
(
ret
));
{
whole_is_parenthesized
=
false
;
ret
=
this
->
index
(
this
->
verify_not_sink
(
ret
));
}
else
break
;
}
if
(
whole_is_parenthesized
&&
is_parenthesized
!=
NULL
)
*
is_parenthesized
=
true
;
return
ret
;
}
...
...
@@ -3108,7 +3133,7 @@ Parse::index(Expression* expr)
Expression
*
start
;
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_COLON
))
start
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
start
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
else
{
mpz_t
zero
;
...
...
@@ -3124,7 +3149,7 @@ Parse::index(Expression* expr)
if
(
this
->
advance_token
()
->
is_op
(
OPERATOR_RSQUARE
))
end
=
Expression
::
make_nil
(
this
->
location
());
else
end
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
end
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
}
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_RSQUARE
))
error_at
(
this
->
location
(),
"missing %<]%>"
);
...
...
@@ -3233,12 +3258,16 @@ Parse::id_to_expression(const std::string& name, Location location)
// If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
// guard (var := expr.("type") using the literal keyword "type").
// If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
// if the entire expression is in parentheses.
Expression
*
Parse
::
expression
(
Precedence
precedence
,
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
)
bool
may_be_composite_lit
,
bool
*
is_type_switch
,
bool
*
is_parenthesized
)
{
Expression
*
left
=
this
->
unary_expr
(
may_be_sink
,
may_be_composite_lit
,
is_type_switch
);
is_type_switch
,
is_parenthesized
);
while
(
true
)
{
...
...
@@ -3295,6 +3324,9 @@ Parse::expression(Precedence precedence, bool may_be_sink,
return
left
;
}
if
(
is_parenthesized
!=
NULL
)
*
is_parenthesized
=
false
;
Operator
op
=
token
->
op
();
Location
binop_location
=
token
->
location
();
...
...
@@ -3310,7 +3342,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
left
=
this
->
verify_not_sink
(
left
);
Expression
*
right
=
this
->
expression
(
right_precedence
,
false
,
may_be_composite_lit
,
NULL
);
NULL
,
NULL
);
left
=
Expression
::
make_binary
(
op
,
left
,
right
,
binop_location
);
}
}
...
...
@@ -3376,9 +3408,12 @@ Parse::expression_may_start_here()
// If IS_TYPE_SWITCH is not NULL, this will recognize a type switch
// guard (var := expr.("type") using the literal keyword "type").
// If IS_PARENTHESIZED is not NULL, *IS_PARENTHESIZED is set to true
// if the entire expression is in parentheses.
Expression
*
Parse
::
unary_expr
(
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
)
bool
*
is_type_switch
,
bool
*
is_parenthesized
)
{
const
Token
*
token
=
this
->
peek_token
();
...
...
@@ -3395,7 +3430,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
if
(
this
->
advance_token
()
->
is_keyword
(
KEYWORD_CHAN
))
{
Expression
*
expr
=
this
->
primary_expr
(
false
,
may_be_composite_lit
,
NULL
);
NULL
,
NULL
);
if
(
expr
->
is_error_expression
())
return
expr
;
else
if
(
!
expr
->
is_type_expression
())
...
...
@@ -3448,7 +3483,8 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
Operator
op
=
token
->
op
();
this
->
advance_token
();
Expression
*
expr
=
this
->
unary_expr
(
false
,
may_be_composite_lit
,
NULL
);
Expression
*
expr
=
this
->
unary_expr
(
false
,
may_be_composite_lit
,
NULL
,
NULL
);
if
(
expr
->
is_error_expression
())
;
else
if
(
op
==
OPERATOR_MULT
&&
expr
->
is_type_expression
())
...
...
@@ -3464,7 +3500,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
}
else
return
this
->
primary_expr
(
may_be_sink
,
may_be_composite_lit
,
is_type_switch
);
is_type_switch
,
is_parenthesized
);
}
// This is called for the obscure case of
...
...
@@ -3747,7 +3783,8 @@ Parse::simple_stat(bool may_be_composite_lit, bool* return_exp,
may_be_composite_lit
,
(
p_type_switch
==
NULL
?
NULL
:
&
p_type_switch
->
found
));
:
&
p_type_switch
->
found
),
NULL
);
if
(
p_type_switch
!=
NULL
&&
p_type_switch
->
found
)
{
p_type_switch
->
name
.
clear
();
...
...
@@ -3857,7 +3894,8 @@ Parse::send_stmt(Expression* channel)
go_assert
(
this
->
peek_token
()
->
is_op
(
OPERATOR_CHANOP
));
Location
loc
=
this
->
location
();
this
->
advance_token
();
Expression
*
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
Expression
*
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
Statement
*
s
=
Statement
::
make_send_statement
(
channel
,
val
,
loc
);
this
->
gogo_
->
add_statement
(
s
);
}
...
...
@@ -4092,11 +4130,12 @@ Parse::go_or_defer_stat()
bool
is_go
=
this
->
peek_token
()
->
is_keyword
(
KEYWORD_GO
);
Location
stat_location
=
this
->
location
();
const
Token
*
token
=
this
->
advance_token
();
this
->
advance_token
();
Location
expr_location
=
this
->
location
();
bool
is_parenthesized
=
token
->
is_op
(
OPERATOR_LPAREN
);
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
bool
is_parenthesized
=
false
;
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
&
is_parenthesized
);
Call_expression
*
call_expr
=
expr
->
call_expression
();
if
(
is_parenthesized
||
call_expr
==
NULL
)
{
...
...
@@ -4198,7 +4237,7 @@ Parse::if_stat()
cond
=
Expression
::
make_error
(
this
->
location
());
}
if
(
cond
==
NULL
)
cond
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
);
cond
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
,
NULL
);
}
this
->
gogo_
->
start_block
(
this
->
location
());
...
...
@@ -4329,7 +4368,7 @@ Parse::switch_stat(Label* label)
if
(
switch_val
==
NULL
&&
!
type_switch
.
found
)
{
switch_val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
&
type_switch
.
found
);
&
type_switch
.
found
,
NULL
);
if
(
type_switch
.
found
)
{
type_switch
.
name
.
clear
();
...
...
@@ -4351,7 +4390,7 @@ Parse::switch_stat(Label* label)
error_at
(
token_loc
,
"invalid variable name"
);
this
->
advance_token
();
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
&
type_switch
.
found
);
&
type_switch
.
found
,
NULL
);
if
(
this
->
peek_token
()
->
is_op
(
OPERATOR_SEMICOLON
))
this
->
advance_token
();
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_LCURLY
))
...
...
@@ -4854,7 +4893,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
// case rv := <-c:
this
->
advance_token
();
Expression
*
e
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
);
NULL
,
NULL
);
Receive_expression
*
re
=
e
->
receive_expression
();
if
(
re
==
NULL
)
{
...
...
@@ -4889,7 +4928,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
// case rv, rc := <-c:
this
->
advance_token
();
Expression
*
e
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
);
false
,
NULL
,
NULL
);
Receive_expression
*
re
=
e
->
receive_expression
();
if
(
re
==
NULL
)
{
...
...
@@ -4937,13 +4976,13 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
Expression
*
e
;
if
(
saw_comma
||
!
this
->
peek_token
()
->
is_op
(
OPERATOR_CHANOP
))
e
=
this
->
expression
(
PRECEDENCE_NORMAL
,
true
,
true
,
NULL
);
e
=
this
->
expression
(
PRECEDENCE_NORMAL
,
true
,
true
,
NULL
,
NULL
);
else
{
// case <-c:
*
is_send
=
false
;
this
->
advance_token
();
*
channel
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
*
channel
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
// The next token should be ':'. If it is '<-', then we have
// case <-c <- v:
...
...
@@ -4963,7 +5002,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
}
*
is_send
=
false
;
this
->
advance_token
();
*
channel
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
*
channel
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
if
(
saw_comma
)
{
// case v, e = <-c:
...
...
@@ -4995,7 +5034,7 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val,
*
is_send
=
true
;
*
channel
=
this
->
verify_not_sink
(
e
);
this
->
advance_token
();
*
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
*
val
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
return
true
;
}
...
...
@@ -5142,7 +5181,7 @@ Parse::for_clause(Expression** cond, Block** post)
return
;
}
else
*
cond
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
);
*
cond
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
true
,
NULL
,
NULL
);
if
(
!
this
->
peek_token
()
->
is_op
(
OPERATOR_SEMICOLON
))
error_at
(
this
->
location
(),
"expected semicolon"
);
else
...
...
@@ -5176,7 +5215,8 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
error_at
(
this
->
location
(),
"too many variables for range clause"
);
this
->
advance_token
();
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
);
Expression
*
expr
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
,
NULL
);
p_range_clause
->
range
=
expr
;
bool
any_new
=
false
;
...
...
@@ -5223,7 +5263,7 @@ Parse::range_clause_expr(const Expression_list* vals,
this
->
advance_token
();
p_range_clause
->
range
=
this
->
expression
(
PRECEDENCE_NORMAL
,
false
,
false
,
NULL
);
NULL
,
NULL
);
p_range_clause
->
index
=
vals
->
front
();
if
(
vals
->
size
()
==
1
)
...
...
gcc/go/gofrontend/parse.h
View file @
cb0a70ca
...
...
@@ -216,7 +216,7 @@ class Parse
Range_clause
*
,
Type_switch
*
);
void
function_decl
(
bool
saw_nointerface
);
Typed_identifier
*
receiver
();
Expression
*
operand
(
bool
may_be_sink
);
Expression
*
operand
(
bool
may_be_sink
,
bool
*
is_parenthesized
);
Expression
*
enclosing_var_reference
(
Named_object
*
,
Named_object
*
,
Location
);
Expression
*
composite_lit
(
Type
*
,
int
depth
,
Location
);
...
...
@@ -224,15 +224,16 @@ class Parse
Expression
*
create_closure
(
Named_object
*
function
,
Enclosing_vars
*
,
Location
);
Expression
*
primary_expr
(
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
);
bool
*
is_type_switch
,
bool
*
is_parenthesized
);
Expression
*
selector
(
Expression
*
,
bool
*
is_type_switch
);
Expression
*
index
(
Expression
*
);
Expression
*
call
(
Expression
*
);
Expression
*
expression
(
Precedence
,
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
);
bool
may_be_composite_lit
,
bool
*
is_type_switch
,
bool
*
is_parenthesized
);
bool
expression_may_start_here
();
Expression
*
unary_expr
(
bool
may_be_sink
,
bool
may_be_composite_lit
,
bool
*
is_type_switch
);
bool
*
is_type_switch
,
bool
*
is_parenthesized
);
Type
*
reassociate_chan_direction
(
Channel_type
*
,
Location
);
Expression
*
qualified_expr
(
Expression
*
,
Location
);
Expression
*
id_to_expression
(
const
std
::
string
&
,
Location
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment