Commit 3cc48399 by Per Bothner Committed by Per Bothner

java-tree.h (CONSTANT_VALUE_P): New macro.


	* java-tree.h (CONSTANT_VALUE_P):  New macro.
	* jcf-write.c (generate_classfile):  Use CONSTANT_VALUE_P.
	* parse.y (maybe_build_class_init_for_field):  New static function.
	(resolve_expression_name, resolve_field_access):  Use
	maybe_build_class_init_for_field instead of build_class_init
	This does not do the init if the field is compile-time-constant.
	(resolve_field_access):  Simplify.

	* parse.y (fold_constant_for_init):  Merge test into switch.

From-SVN: r41094
parent 8e184d9c
2001-04-04 Per Bothner <per@bothner.com>
* java-tree.h (CONSTANT_VALUE_P): New macro.
* jcf-write.c (generate_classfile): Use CONSTANT_VALUE_P.
* parse.y (maybe_build_class_init_for_field): New static function.
(resolve_expression_name, resolve_field_access): Use
maybe_build_class_init_for_field instead of build_class_init
This does not do the init if the field is compile-time-constant.
(resolve_field_access): Simplify.
* parse.y (fold_constant_for_init): Merge test into switch.
2001-04-03 Zack Weinberg <zackw@stanford.edu> 2001-04-03 Zack Weinberg <zackw@stanford.edu>
* Make-lang.in (buffer.o, check-init.o, class.o): Don't depend * Make-lang.in (buffer.o, check-init.o, class.o): Don't depend
......
...@@ -829,6 +829,13 @@ struct lang_identifier ...@@ -829,6 +829,13 @@ struct lang_identifier
ggc_alloc_cleared (sizeof (struct lang_decl_var))); \ ggc_alloc_cleared (sizeof (struct lang_decl_var))); \
} }
/* A ConstantExpression, after folding and name resolution. */
#define CONSTANT_VALUE_P(NODE) \
(TREE_CODE (NODE) == STRING_CST \
|| (TREE_CODE (NODE) == INTEGER_CST \
&& TREE_CODE (TREE_TYPE (NODE)) != POINTER_TYPE) \
|| TREE_CODE (NODE) == REAL_CST)
/* For a local VAR_DECL, holds the index into a words bitstring that /* For a local VAR_DECL, holds the index into a words bitstring that
specifies if this decl is definitively assigned. specifies if this decl is definitively assigned.
A DECL_BIT_INDEX of -1 means we no longer care. */ A DECL_BIT_INDEX of -1 means we no longer care. */
......
...@@ -2885,11 +2885,7 @@ generate_classfile (clas, state) ...@@ -2885,11 +2885,7 @@ generate_classfile (clas, state)
build_java_signature (TREE_TYPE (part))); build_java_signature (TREE_TYPE (part)));
PUT2(i); PUT2(i);
have_value = DECL_INITIAL (part) != NULL_TREE have_value = DECL_INITIAL (part) != NULL_TREE
&& FIELD_STATIC (part) && FIELD_STATIC (part) && CONSTANT_VALUE_P (DECL_INITIAL (part));
&& (TREE_CODE (DECL_INITIAL (part)) == STRING_CST
|| (TREE_CODE (DECL_INITIAL (part)) == INTEGER_CST
&& TREE_CODE (TREE_TYPE (DECL_INITIAL (part))) != POINTER_TYPE)
|| TREE_CODE (DECL_INITIAL (part)) == REAL_CST);
if (have_value) if (have_value)
attr_count++; attr_count++;
......
...@@ -329,6 +329,7 @@ static tree build_dot_class_method PARAMS ((tree)); ...@@ -329,6 +329,7 @@ static tree build_dot_class_method PARAMS ((tree));
static tree build_dot_class_method_invocation PARAMS ((tree)); static tree build_dot_class_method_invocation PARAMS ((tree));
static void create_new_parser_context PARAMS ((int)); static void create_new_parser_context PARAMS ((int));
static void mark_parser_ctxt PARAMS ((void *)); static void mark_parser_ctxt PARAMS ((void *));
static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
/* Number of error found so far. */ /* Number of error found so far. */
int java_error_count; int java_error_count;
...@@ -8855,8 +8856,8 @@ resolve_expression_name (id, orig) ...@@ -8855,8 +8856,8 @@ resolve_expression_name (id, orig)
/* Otherwise build what it takes to access the field */ /* Otherwise build what it takes to access the field */
access = build_field_ref ((fs ? NULL_TREE : current_this), access = build_field_ref ((fs ? NULL_TREE : current_this),
DECL_CONTEXT (decl), name); DECL_CONTEXT (decl), name);
if (fs && !flag_emit_class_files && !flag_emit_xref) if (fs)
access = build_class_init (DECL_CONTEXT (access), access); access = maybe_build_class_init_for_field (decl, access);
/* We may be asked to save the real field access node */ /* We may be asked to save the real field access node */
if (orig) if (orig)
*orig = access; *orig = access;
...@@ -8939,29 +8940,16 @@ resolve_field_access (qual_wfl, field_decl, field_type) ...@@ -8939,29 +8940,16 @@ resolve_field_access (qual_wfl, field_decl, field_type)
field_ref = decl; field_ref = decl;
else if (JDECL_P (decl)) else if (JDECL_P (decl))
{ {
int static_final_found = 0;
if (!type_found) if (!type_found)
type_found = DECL_CONTEXT (decl); type_found = DECL_CONTEXT (decl);
is_static = JDECL_P (decl) && FIELD_STATIC (decl); is_static = FIELD_STATIC (decl);
if (CLASS_FINAL_VARIABLE_P (decl) field_ref = build_field_ref ((is_static && !flag_emit_xref?
&& JPRIMITIVE_TYPE_P (TREE_TYPE (decl)) NULL_TREE : where_found),
&& DECL_INITIAL (decl)) type_found, DECL_NAME (decl));
{
/* When called on a FIELD_DECL of the right (primitive)
type, java_complete_tree will try to substitue the decl
for it's initial value. */
field_ref = java_complete_tree (decl);
static_final_found = 1;
}
else
field_ref = build_field_ref ((is_static && !flag_emit_xref?
NULL_TREE : where_found),
type_found, DECL_NAME (decl));
if (field_ref == error_mark_node) if (field_ref == error_mark_node)
return error_mark_node; return error_mark_node;
if (is_static && !static_final_found if (is_static)
&& !flag_emit_class_files && !flag_emit_xref) field_ref = maybe_build_class_init_for_field (decl, field_ref);
field_ref = build_class_init (DECL_CONTEXT (decl), field_ref);
} }
else else
field_ref = decl; field_ref = decl;
...@@ -15489,6 +15477,29 @@ patch_conditional_expr (node, wfl_cond, wfl_op1) ...@@ -15489,6 +15477,29 @@ patch_conditional_expr (node, wfl_cond, wfl_op1)
return node; return node;
} }
/* Wrap EXPR with code to initialize DECL's class, if appropriate. */
static tree
maybe_build_class_init_for_field (decl, expr)
tree decl, expr;
{
tree clas = DECL_CONTEXT (decl);
if (flag_emit_class_files || flag_emit_xref)
return expr;
if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)
&& FIELD_FINAL (decl))
{
tree init = DECL_INITIAL (decl);
if (init != NULL_TREE)
init = fold_constant_for_init (init, decl);
if (init != NULL_TREE && CONSTANT_VALUE_P (init))
return expr;
}
return build_class_init (clas, expr);
}
/* Try to constant fold NODE. /* Try to constant fold NODE.
If NODE is not a constant expression, return NULL_EXPR. If NODE is not a constant expression, return NULL_EXPR.
CONTEXT is a static final VAR_DECL whose initializer we are folding. */ CONTEXT is a static final VAR_DECL whose initializer we are folding. */
...@@ -15501,11 +15512,13 @@ fold_constant_for_init (node, context) ...@@ -15501,11 +15512,13 @@ fold_constant_for_init (node, context)
tree op0, op1, val; tree op0, op1, val;
enum tree_code code = TREE_CODE (node); enum tree_code code = TREE_CODE (node);
if (code == STRING_CST || code == INTEGER_CST || code == REAL_CST)
return node;
switch (code) switch (code)
{ {
case STRING_CST:
case INTEGER_CST:
case REAL_CST:
return node;
case PLUS_EXPR: case PLUS_EXPR:
case MINUS_EXPR: case MINUS_EXPR:
case MULT_EXPR: case MULT_EXPR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment