+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>
* Make-lang.in (buffer.o, check-init.o, class.o): Don't depend
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
specifies if this decl is definitively assigned.
A DECL_BIT_INDEX of -1 means we no longer care. */
static tree build_dot_class_method_invocation PARAMS ((tree));
static void create_new_parser_context PARAMS ((int));
static void mark_parser_ctxt PARAMS ((void *));
+static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
/* Number of error found so far. */
int java_error_count;
/* Otherwise build what it takes to access the field */
access = build_field_ref ((fs ? NULL_TREE : current_this),
DECL_CONTEXT (decl), name);
- if (fs && !flag_emit_class_files && !flag_emit_xref)
- access = build_class_init (DECL_CONTEXT (access), access);
+ if (fs)
+ access = maybe_build_class_init_for_field (decl, access);
/* We may be asked to save the real field access node */
if (orig)
*orig = access;
field_ref = decl;
else if (JDECL_P (decl))
{
- int static_final_found = 0;
if (!type_found)
type_found = DECL_CONTEXT (decl);
- is_static = JDECL_P (decl) && FIELD_STATIC (decl);
- if (CLASS_FINAL_VARIABLE_P (decl)
- && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
- && DECL_INITIAL (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));
+ is_static = FIELD_STATIC (decl);
+ 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)
return error_mark_node;
- if (is_static && !static_final_found
- && !flag_emit_class_files && !flag_emit_xref)
- field_ref = build_class_init (DECL_CONTEXT (decl), field_ref);
+ if (is_static)
+ field_ref = maybe_build_class_init_for_field (decl, field_ref);
}
else
field_ref = decl;
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.
If NODE is not a constant expression, return NULL_EXPR.
CONTEXT is a static final VAR_DECL whose initializer we are folding. */
tree op0, op1, val;
enum tree_code code = TREE_CODE (node);
- if (code == STRING_CST || code == INTEGER_CST || code == REAL_CST)
- return node;
-
switch (code)
{
+ case STRING_CST:
+ case INTEGER_CST:
+ case REAL_CST:
+ return node;
+
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR: