diff options
Diffstat (limited to 'gcc/java/parse.y')
| -rw-r--r-- | gcc/java/parse.y | 97 | 
1 files changed, 94 insertions, 3 deletions
| diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 864984b9122..907ca285808 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -220,6 +220,7 @@ static tree build_string_concatenation PARAMS ((tree, tree));  static tree patch_string_cst PARAMS ((tree));  static tree patch_string PARAMS ((tree));  static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree)); +static tree build_assertion PARAMS ((int, tree, tree));  static tree build_try_statement PARAMS ((int, tree, tree));  static tree build_try_finally_statement PARAMS ((int, tree, tree));  static tree patch_try_statement PARAMS ((tree)); @@ -505,6 +506,7 @@ static GTY(()) tree src_parse_roots[1];  %token   SWITCH_TK       CONST_TK           TRY_TK  %token   FOR_TK          NEW_TK             CONTINUE_TK  %token   GOTO_TK         PACKAGE_TK         THIS_TK +%token   ASSERT_TK  %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK  %token   CHAR_TK         INTEGRAL_TK @@ -571,12 +573,13 @@ static GTY(()) tree src_parse_roots[1];  			left_hand_side assignment for_header for_begin  			constant_expression do_statement_begin empty_statement  			switch_statement synchronized_statement throw_statement -			try_statement switch_expression switch_block +			try_statement assert_statement +			switch_expression switch_block  			catches catch_clause catch_clause_parameter finally  			anonymous_class_creation trap_overflow_corner_case  %type    <node>         return_statement break_statement continue_statement -%type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK +%type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK    %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK  %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK  %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK @@ -588,7 +591,7 @@ static GTY(()) tree src_parse_roots[1];  %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK  %type    <operator>	THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK  %type	 <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK -%type	 <operator>     NEW_TK +%type	 <operator>     NEW_TK ASSERT_TK  %type	 <node>		method_body @@ -1460,6 +1463,7 @@ statement_without_trailing_substatement:  |	synchronized_statement  |	throw_statement  |	try_statement +|	assert_statement  ;  empty_statement: @@ -1845,6 +1849,21 @@ throw_statement:  		{yyerror ("';' expected"); RECOVER;}  ; +assert_statement: +	ASSERT_TK expression REL_CL_TK expression SC_TK +		{ +		  $$ = build_assertion ($1.location, $2, $4); +		} +|	ASSERT_TK expression SC_TK +		{ +		  $$ = build_assertion ($1.location, $2, NULL_TREE); +		} +|	ASSERT_TK error +		{yyerror ("Missing term"); RECOVER;} +|	ASSERT_TK expression error +		{yyerror ("';' expected"); RECOVER;} +; +  synchronized_statement:  	synchronized OP_TK expression CP_TK block  		{ @@ -15292,6 +15311,78 @@ patch_switch_statement (node)    return node;  } +/* Assertions.  */ + +/* Build an assertion expression for `assert CONDITION : VALUE'; VALUE +   might be NULL_TREE.  */ +static tree +build_assertion (location, condition, value) +     int location; +     tree condition, value; +{ +  tree node; +  tree klass = GET_CPC (); + +  if (! CLASS_USES_ASSERTIONS (klass)) +    { +      tree field, classdollar, id, call; +      tree class_type = TREE_TYPE (klass); + +      field = add_field (class_type, +			 get_identifier ("$assertionsDisabled"), +			 boolean_type_node, +			 ACC_PRIVATE | ACC_STATIC | ACC_FINAL); +      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field); +      FIELD_SYNTHETIC (field) = 1; + +      if (!TYPE_DOT_CLASS (class_type)) +	build_dot_class_method (class_type); +      classdollar = build_dot_class_method_invocation (class_type); + +      /* Call CLASS.desiredAssertionStatus().  */ +      id = build_wfl_node (get_identifier ("desiredAssertionStatus")); +      call = build (CALL_EXPR, NULL_TREE, id, NULL_TREE, NULL_TREE); +      call = make_qualified_primary (classdollar, call, location); +      TREE_SIDE_EFFECTS (call) = 1; +      DECL_INITIAL (field) = call; + +      /* Record the initializer in the initializer statement list.  */ +      call = build (MODIFY_EXPR, NULL_TREE, field, call); +      TREE_CHAIN (call) = CPC_STATIC_INITIALIZER_STMT (ctxp); +      SET_CPC_STATIC_INITIALIZER_STMT (ctxp, call); +      MODIFY_EXPR_FROM_INITIALIZATION_P (call) = 1; + +      CLASS_USES_ASSERTIONS (klass) = 1; +    } + +  if (value != NULL_TREE) +    value = tree_cons (NULL_TREE, value, NULL_TREE); + +  node = build_wfl_node (get_identifier ("java")); +  node = make_qualified_name (node, build_wfl_node (get_identifier ("lang")), +			      location); +  node = make_qualified_name (node, build_wfl_node (get_identifier ("AssertionError")), +			      location); + +  node = build (NEW_CLASS_EXPR, NULL_TREE, node, value, NULL_TREE); +  TREE_SIDE_EFFECTS (node) = 1; +  /* It is too early to use BUILD_THROW.  */ +  node = build1 (THROW_EXPR, NULL_TREE, node); +  TREE_SIDE_EFFECTS (node) = 1; + +  /* We invert the condition; if we just put NODE as the `else' part +     then we generate weird-looking bytecode.  */ +  condition = build1 (TRUTH_NOT_EXPR, NULL_TREE, condition); +  /* Check $assertionsDisabled.  */ +  condition +    = build (TRUTH_ANDIF_EXPR, NULL_TREE, +	     build1 (TRUTH_NOT_EXPR, NULL_TREE, +		     build_wfl_node (get_identifier ("$assertionsDisabled"))), +	     condition); +  node = build_if_else_statement (location, condition, node, NULL_TREE); +  return node; +} +  /* 14.18 The try/catch statements */  /* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause | 

