2000-08-07 Alexandre Petit-Bianco <apbianco@cygnus.com
* parse.y (build_dot_class_method_invocation): Changed parameter name to `type.' Build signature from `type' and convert it to a STRING_CST if it's an array. (patch_incomplete_class_ref): `build_dot_class_method_invocation' to use `ref_type' directly. 2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com> * parse.y (maybe_yank_clinit): When generating bytecode: non empty method bodies not to rule out discarding `<clinit>'; don't use <clinit> to initialize static fields with constant initializers. 2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com> * gjavah.c (print_method_info): Added `synth' parameter. Skip synthetic methods. (method_synthetic): New global. (HANDLE_METHOD): Recognize synthetic method and tell `print_method_info' about it. (HANDLE_END_METHOD): Do not issue an additional `;\n' if we're processing a synthetic method. * jcf-reader.c (skip_attribute): New function. ( skip_attribute): Likewise. 2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com> * parse.y (build_outer_field_access): Fixed comments. (fix_constructors): Emit the initialization of this$<n> before calling $finit$. (resolve_qualified_expression_name): Build an access to `decl' if necessary. 2000-07-31 Alexandre Petit-Bianco <apbianco@cygnus.com> * parse-scan.y (curent_class): Non longer const. (inner_qualifier, inner_qualifier_length): Deleted. (current_class_length): New global. (bracket_count): Fixed typo in leading comment. (anonymous_count): New global. (class_instance_creation_expression:): Handle anonymous classes. (anonymous_class_creation:): New rule. (push_class_context): Rewritten. (pop_class_context): Likewise. (INNER_QUALIFIER): Macro deleted. (report_class_declaration): call `push_class_context' when entering the function. `fprintf' format modified not to use INNER_QUALIFIER. (report_class_declaration): Assign `package_name' and `current_class' to NULL separatly. 2000-07-31 Alexandre Petit-Bianco <apbianco@cygnus.com> * expr.c (build_invokeinterface): Call layout_class_methods on target interface. (http://gcc.gnu.org/ml/gcc-patches/2000-08/msg00339.html) From-SVN: r35560
This commit is contained in:
parent
0da9afa6d6
commit
f0f3a77740
@ -1,3 +1,11 @@
|
||||
2000-08-07 Alexandre Petit-Bianco <apbianco@cygnus.com
|
||||
|
||||
* parse.y (build_dot_class_method_invocation): Changed parameter
|
||||
name to `type.' Build signature from `type' and convert it to a
|
||||
STRING_CST if it's an array.
|
||||
(patch_incomplete_class_ref): `build_dot_class_method_invocation'
|
||||
to use `ref_type' directly.
|
||||
|
||||
Sun Aug 6 00:47:24 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* lang-options.h: Added a comma after the last element to avoid
|
||||
@ -17,6 +25,55 @@ Sun Aug 6 00:47:24 2000 Ovidiu Predescu <ovidiu@cup.hp.com>
|
||||
|
||||
* class.c (build_dtable_decl): Initialize dummy.
|
||||
|
||||
2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
||||
* parse.y (maybe_yank_clinit): When generating bytecode: non empty
|
||||
method bodies not to rule out discarding `<clinit>'; don't use
|
||||
<clinit> to initialize static fields with constant initializers.
|
||||
|
||||
2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
||||
* gjavah.c (print_method_info): Added `synth' parameter. Skip
|
||||
synthetic methods.
|
||||
(method_synthetic): New global.
|
||||
(HANDLE_METHOD): Recognize synthetic method and tell
|
||||
`print_method_info' about it.
|
||||
(HANDLE_END_METHOD): Do not issue an additional `;\n' if we're
|
||||
processing a synthetic method.
|
||||
* jcf-reader.c (skip_attribute): New function.
|
||||
( skip_attribute): Likewise.
|
||||
|
||||
2000-08-01 Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
||||
* parse.y (build_outer_field_access): Fixed comments.
|
||||
(fix_constructors): Emit the initialization of this$<n> before
|
||||
calling $finit$.
|
||||
(resolve_qualified_expression_name): Build an access to `decl' if
|
||||
necessary.
|
||||
|
||||
2000-07-31 Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
||||
* parse-scan.y (curent_class): Non longer const.
|
||||
(inner_qualifier, inner_qualifier_length): Deleted.
|
||||
(current_class_length): New global.
|
||||
(bracket_count): Fixed typo in leading comment.
|
||||
(anonymous_count): New global.
|
||||
(class_instance_creation_expression:): Handle anonymous classes.
|
||||
(anonymous_class_creation:): New rule.
|
||||
(push_class_context): Rewritten.
|
||||
(pop_class_context): Likewise.
|
||||
(INNER_QUALIFIER): Macro deleted.
|
||||
(report_class_declaration): call `push_class_context' when
|
||||
entering the function. `fprintf' format modified not to use
|
||||
INNER_QUALIFIER.
|
||||
(report_class_declaration): Assign `package_name' and
|
||||
`current_class' to NULL separatly.
|
||||
|
||||
2000-07-31 Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
||||
* expr.c (build_invokeinterface): Call layout_class_methods on
|
||||
target interface.
|
||||
|
||||
2000-07-27 Tom Tromey <tromey@cygnus.com>
|
||||
Anthony Green <green@cygnus.com>
|
||||
Alexandre Petit-Bianco <apbianco@cygnus.com>
|
||||
|
@ -1783,6 +1783,7 @@ build_invokeinterface (dtable, method)
|
||||
lookup_field (&dtable_type, class_ident));
|
||||
|
||||
interface = DECL_CONTEXT (method);
|
||||
layout_class_methods (interface);
|
||||
|
||||
i = 1;
|
||||
for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
|
||||
|
@ -116,7 +116,7 @@ static struct method_name *method_name_list;
|
||||
static void print_field_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
|
||||
static void print_mangled_classname PARAMS ((FILE*, JCF*, const char*, int));
|
||||
static int print_cxx_classname PARAMS ((FILE*, const char*, JCF*, int));
|
||||
static void print_method_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
|
||||
static void print_method_info PARAMS ((FILE*, JCF*, int, int, JCF_u2, int));
|
||||
static void print_c_decl PARAMS ((FILE*, JCF*, int, int, int, const char *,
|
||||
int));
|
||||
static void print_stub_or_jni PARAMS ((FILE*, JCF*, int, int, int,
|
||||
@ -182,26 +182,45 @@ static int method_pass;
|
||||
static int method_declared = 0;
|
||||
static int method_access = 0;
|
||||
static int method_printed = 0;
|
||||
#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
|
||||
if (method_pass) \
|
||||
{ \
|
||||
decompiled = 0; method_printed = 0; \
|
||||
if (out) \
|
||||
print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
print_method_info (NULL, jcf, NAME, SIGNATURE, ACCESS_FLAGS); \
|
||||
if (! stubs && ! flag_jni) \
|
||||
add_class_decl (out, jcf, SIGNATURE); \
|
||||
}
|
||||
static int method_synthetic = 0;
|
||||
#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
|
||||
{ \
|
||||
method_synthetic = 0; \
|
||||
if (ATTRIBUTE_COUNT) \
|
||||
method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
|
||||
(const char *)"Synthetic", 9); \
|
||||
/* If a synthetic methods have been declared, its attribute aren't \
|
||||
worth reading (and triggering side-effects). We skip them an \
|
||||
set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
|
||||
jcf_parse_one_method. */ \
|
||||
if (method_synthetic) \
|
||||
{ \
|
||||
skip_attribute (jcf, ATTRIBUTE_COUNT); \
|
||||
ATTRIBUTE_COUNT = 0; \
|
||||
} \
|
||||
if (method_pass && !method_synthetic) \
|
||||
{ \
|
||||
decompiled = 0; method_printed = 0; \
|
||||
if (out) \
|
||||
print_method_info (out, jcf, NAME, SIGNATURE, \
|
||||
ACCESS_FLAGS, method_synthetic); \
|
||||
} \
|
||||
else if (!method_synthetic) \
|
||||
{ \
|
||||
print_method_info (NULL, jcf, NAME, SIGNATURE, \
|
||||
ACCESS_FLAGS, method_synthetic); \
|
||||
if (! stubs && ! flag_jni) \
|
||||
add_class_decl (out, jcf, SIGNATURE); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
|
||||
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
|
||||
if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
|
||||
|
||||
static int decompiled = 0;
|
||||
#define HANDLE_END_METHOD() \
|
||||
if (out && method_printed) fputs (decompiled || stubs ? "\n" : ";\n", out);
|
||||
#define HANDLE_END_METHOD() \
|
||||
if (out && method_printed && !method_synthetic) \
|
||||
fputs (decompiled || stubs ? "\n" : ";\n", out);
|
||||
|
||||
#include "jcf-reader.c"
|
||||
|
||||
@ -670,9 +689,9 @@ DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
|
||||
|
||||
|
||||
static void
|
||||
DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags, synth),
|
||||
FILE *stream AND JCF* jcf
|
||||
AND int name_index AND int sig_index AND JCF_u2 flags)
|
||||
AND int name_index AND int sig_index AND JCF_u2 flags AND int synth)
|
||||
{
|
||||
const unsigned char *str;
|
||||
int length, is_init = 0;
|
||||
@ -684,10 +703,15 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
|
||||
fprintf (stream, "<not a UTF8 constant>");
|
||||
str = JPOOL_UTF_DATA (jcf, name_index);
|
||||
length = JPOOL_UTF_LENGTH (jcf, name_index);
|
||||
if (str[0] == '<' || str[0] == '$')
|
||||
|
||||
/* Ignore synthetic methods. */
|
||||
if (synth)
|
||||
return;
|
||||
|
||||
if (str[0] == '<')
|
||||
{
|
||||
/* Ignore internally generated methods like <clinit> and
|
||||
$finit$. However, treat <init> as a constructor. */
|
||||
/* Ignore the internally generated method <clinit>. However,
|
||||
treat <init> as a constructor. */
|
||||
if (! utf8_cmp (str, length, "<init>"))
|
||||
is_init = 1;
|
||||
else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
|
||||
|
@ -27,6 +27,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
||||
#include "zipfile.h"
|
||||
|
||||
static int get_attribute PARAMS ((JCF *));
|
||||
static int peek_attribute PARAMS ((JCF *, int, const char *, int));
|
||||
static void skip_attribute PARAMS ((JCF *, int));
|
||||
static int jcf_parse_preamble PARAMS ((JCF *));
|
||||
static int jcf_parse_constant_pool PARAMS ((JCF *));
|
||||
static void jcf_parse_class PARAMS ((JCF *));
|
||||
@ -35,6 +37,64 @@ static int jcf_parse_one_method PARAMS ((JCF *));
|
||||
static int jcf_parse_methods PARAMS ((JCF *));
|
||||
static int jcf_parse_final_attributes PARAMS ((JCF *));
|
||||
|
||||
/* Go through all available attribute (ATTRIBUTE_NUMER) and try to
|
||||
identify PEEKED_NAME. Return 1 if PEEKED_NAME was found, 0
|
||||
otherwise. JCF is restored to its initial position before
|
||||
returning. */
|
||||
|
||||
static int
|
||||
peek_attribute (jcf, attribute_number, peeked_name, peeked_name_length)
|
||||
JCF *jcf;
|
||||
int attribute_number;
|
||||
const char *peeked_name;
|
||||
int peeked_name_length;
|
||||
{
|
||||
int to_return = 0;
|
||||
long absolute_offset = (long)JCF_TELL (jcf);
|
||||
int i;
|
||||
|
||||
for (i = 0; !to_return && i < attribute_number; i++)
|
||||
{
|
||||
uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
|
||||
uint32 attribute_length = JCF_readu4 (jcf);
|
||||
int name_length;
|
||||
const unsigned char *name_data;
|
||||
|
||||
JCF_FILL (jcf, (long) attribute_length);
|
||||
if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf)
|
||||
|| JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
|
||||
continue;
|
||||
|
||||
name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
|
||||
name_data = JPOOL_UTF_DATA (jcf, attribute_name);
|
||||
|
||||
if (name_length == peeked_name_length
|
||||
&& ! memcmp (name_data, peeked_name, peeked_name_length))
|
||||
{
|
||||
to_return = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
JCF_SKIP (jcf, attribute_length);
|
||||
}
|
||||
|
||||
JCF_SEEK (jcf, absolute_offset);
|
||||
return to_return;
|
||||
}
|
||||
|
||||
static void
|
||||
skip_attribute (jcf, number_of_attribute)
|
||||
JCF *jcf;
|
||||
int number_of_attribute;
|
||||
{
|
||||
while (number_of_attribute--)
|
||||
{
|
||||
JCF_FILL (jcf, 6);
|
||||
(void) JCF_readu2 (jcf);
|
||||
JCF_SKIP (jcf, JCF_readu4 (jcf));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
DEFUN(get_attribute, (jcf),
|
||||
JCF *jcf)
|
||||
|
@ -63,12 +63,11 @@ static int absorber;
|
||||
#define USE_ABSORBER absorber = 0
|
||||
|
||||
/* Keep track of the current class name and package name. */
|
||||
static const char *current_class;
|
||||
static char *current_class;
|
||||
static const char *package_name;
|
||||
|
||||
/* Keep track of the current inner class qualifier. */
|
||||
static char *inner_qualifier;
|
||||
static int inner_qualifier_length;
|
||||
static int current_class_length;
|
||||
|
||||
/* Keep track of whether things have be listed before. */
|
||||
static int previous_output;
|
||||
@ -76,10 +75,13 @@ static int previous_output;
|
||||
/* Record modifier uses */
|
||||
static int modifier_value;
|
||||
|
||||
/* Keep track of number of bracket pairs after a variable declarator
|
||||
/* Keeps track of number of bracket pairs after a variable declarator
|
||||
id. */
|
||||
static int bracket_count;
|
||||
|
||||
/* Numbers anonymous classes */
|
||||
static int anonymous_count;
|
||||
|
||||
/* Record a method declaration */
|
||||
struct method_declarator {
|
||||
const char *method_name;
|
||||
@ -897,20 +899,22 @@ primary_no_new_array:
|
||||
class_instance_creation_expression:
|
||||
NEW_TK class_type OP_TK argument_list CP_TK
|
||||
| NEW_TK class_type OP_TK CP_TK
|
||||
/* Added, JDK1.1 inner classes but modified to use
|
||||
'class_type' instead of 'TypeName' (type_name) mentionned
|
||||
in the documentation but doesn't exist. */
|
||||
| NEW_TK class_type OP_TK argument_list CP_TK class_body
|
||||
| NEW_TK class_type OP_TK CP_TK class_body
|
||||
/* Added, JDK1.1 inner classes, modified to use name or
|
||||
primary instead of primary solely which couldn't work in
|
||||
all situations. */
|
||||
| anonymous_class_creation
|
||||
| something_dot_new identifier OP_TK CP_TK
|
||||
| something_dot_new identifier OP_TK CP_TK class_body
|
||||
| something_dot_new identifier OP_TK argument_list CP_TK
|
||||
| something_dot_new identifier OP_TK argument_list CP_TK class_body
|
||||
;
|
||||
|
||||
anonymous_class_creation:
|
||||
NEW_TK class_type OP_TK CP_TK
|
||||
{ report_class_declaration (NULL); }
|
||||
class_body
|
||||
| NEW_TK class_type OP_TK argument_list CP_TK
|
||||
{ report_class_declaration (NULL); }
|
||||
class_body
|
||||
;
|
||||
|
||||
something_dot_new: /* Added, not part of the specs. */
|
||||
name DOT_TK NEW_TK
|
||||
{ USE_ABSORBER; }
|
||||
@ -1128,29 +1132,61 @@ static void
|
||||
push_class_context (name)
|
||||
const char *name;
|
||||
{
|
||||
size_t name_length = strlen (name);
|
||||
inner_qualifier = xrealloc (inner_qualifier,
|
||||
inner_qualifier_length + name_length+2);
|
||||
memcpy (inner_qualifier+inner_qualifier_length, name, name_length);
|
||||
inner_qualifier_length += name_length;
|
||||
inner_qualifier [inner_qualifier_length] = '$';
|
||||
inner_qualifier [++inner_qualifier_length] = '\0';
|
||||
/* If we already have CURRENT_CLASS set, we're in an inter
|
||||
class. Mangle its name. */
|
||||
if (current_class)
|
||||
{
|
||||
const char *p;
|
||||
char anonymous [3];
|
||||
int additional_length;
|
||||
|
||||
/* NAME set to NULL indicates an anonymous class, which are named by
|
||||
numbering them. */
|
||||
if (!name)
|
||||
{
|
||||
sprintf (anonymous, "%d", ++anonymous_count);
|
||||
p = anonymous;
|
||||
}
|
||||
else
|
||||
p = name;
|
||||
|
||||
additional_length = strlen (p)+1; /* +1 for `$' */
|
||||
current_class = xrealloc (current_class,
|
||||
current_class_length + additional_length + 1);
|
||||
current_class [current_class_length] = '$';
|
||||
strcpy (¤t_class [current_class_length+1], p);
|
||||
current_class_length += additional_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!name)
|
||||
return;
|
||||
current_class_length = strlen (name);
|
||||
current_class = xmalloc (current_class_length+1);
|
||||
strcpy (current_class, name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pop_class_context ()
|
||||
{
|
||||
while (--inner_qualifier_length > 0
|
||||
&& inner_qualifier [inner_qualifier_length-1] != '$')
|
||||
/* Go back to the last `$' and cut. */
|
||||
while (--current_class_length > 0
|
||||
&& current_class [current_class_length] != '$')
|
||||
;
|
||||
inner_qualifier = xrealloc (inner_qualifier, inner_qualifier_length+1);
|
||||
if (inner_qualifier_length == -1)
|
||||
inner_qualifier_length = 0;
|
||||
inner_qualifier [inner_qualifier_length] = '\0';
|
||||
if (current_class_length)
|
||||
{
|
||||
current_class = xrealloc (current_class, current_class_length+1);
|
||||
current_class [current_class_length] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
current_class = NULL;
|
||||
anonymous_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Actions defined here */
|
||||
#define INNER_QUALIFIER (inner_qualifier ? inner_qualifier : "")
|
||||
|
||||
static void
|
||||
report_class_declaration (name)
|
||||
@ -1158,6 +1194,7 @@ report_class_declaration (name)
|
||||
{
|
||||
extern int flag_dump_class, flag_list_filename;
|
||||
|
||||
push_class_context (name);
|
||||
if (flag_dump_class)
|
||||
{
|
||||
if (!previous_output)
|
||||
@ -1168,13 +1205,10 @@ report_class_declaration (name)
|
||||
}
|
||||
|
||||
if (package_name)
|
||||
fprintf (out, "%s.%s%s ", package_name, INNER_QUALIFIER, name);
|
||||
fprintf (out, "%s.%s ", package_name, current_class);
|
||||
else
|
||||
fprintf (out, "%s%s ", INNER_QUALIFIER, name);
|
||||
fprintf (out, "%s ", current_class);
|
||||
}
|
||||
|
||||
push_class_context (name);
|
||||
current_class = name;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1208,7 +1242,8 @@ report_main_declaration (declarator)
|
||||
void reset_report ()
|
||||
{
|
||||
previous_output = 0;
|
||||
current_class = package_name = NULL;
|
||||
package_name = NULL;
|
||||
current_class = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7523,12 +7523,14 @@ maybe_yank_clinit (mdecl)
|
||||
|
||||
if (!DECL_CLINIT_P (mdecl))
|
||||
return 0;
|
||||
|
||||
/* If the body isn't empty, then we keep <clinit> */
|
||||
|
||||
/* If the body isn't empty, then we keep <clinit>. Note that if
|
||||
we're emitting classfiles, this isn't enough not to rule it
|
||||
out. */
|
||||
fbody = DECL_FUNCTION_BODY (mdecl);
|
||||
if ((bbody = BLOCK_EXPR_BODY (fbody)))
|
||||
bbody = BLOCK_EXPR_BODY (bbody);
|
||||
if (bbody && bbody != empty_stmt_node)
|
||||
if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
|
||||
return 0;
|
||||
|
||||
type = DECL_CONTEXT (mdecl);
|
||||
@ -7536,9 +7538,34 @@ maybe_yank_clinit (mdecl)
|
||||
|
||||
for (current = (current ? TREE_CHAIN (current) : current);
|
||||
current; current = TREE_CHAIN (current))
|
||||
if (!(FIELD_STATIC (current) && FIELD_FINAL (current)
|
||||
&& DECL_INITIAL (current) && TREE_CONSTANT (DECL_INITIAL (current))))
|
||||
break;
|
||||
{
|
||||
tree f_init;
|
||||
|
||||
/* We're not interested in non static field */
|
||||
if (!FIELD_STATIC (current))
|
||||
continue;
|
||||
|
||||
/* Anything that isn't String or a basic type is ruled out -- or
|
||||
if we now how to deal with it (when doing things natively) we
|
||||
should generated an empty <clinit> so that SUID are computed
|
||||
correctly. */
|
||||
if (! JSTRING_TYPE_P (TREE_TYPE (current))
|
||||
&& ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
|
||||
break;
|
||||
|
||||
f_init = DECL_INITIAL (current);
|
||||
/* If we're emitting native code, we want static final fields to
|
||||
have constant initializers. If we don't meet these
|
||||
conditions, we keep <clinit> */
|
||||
if (!flag_emit_class_files
|
||||
&& !(FIELD_FINAL (current) && f_init && TREE_CONSTANT (f_init)))
|
||||
break;
|
||||
/* If we're emitting bytecode, we want static fields to have
|
||||
constant initializers or no initializer. If we don't meet
|
||||
these conditions, we keep <clinit> */
|
||||
if (flag_emit_class_files && f_init && !TREE_CONSTANT (f_init))
|
||||
break;
|
||||
}
|
||||
|
||||
if (current)
|
||||
return 0;
|
||||
@ -7661,7 +7688,7 @@ build_outer_field_access (id, decl)
|
||||
tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
|
||||
|
||||
/* If decl's class is the direct outer class of the current_class,
|
||||
build the access as `this$<n>.<field>'. Not that we will break
|
||||
build the access as `this$<n>.<field>'. Note that we will break
|
||||
the `private' barrier if we're not emitting bytecodes. */
|
||||
if (ctx == DECL_CONTEXT (decl)
|
||||
&& (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
|
||||
@ -7677,7 +7704,7 @@ build_outer_field_access (id, decl)
|
||||
int lc = EXPR_WFL_LINECOL (id);
|
||||
|
||||
/* Now we chain the required number of calls to the access$0 to
|
||||
get a hold to the enclosing instance we need, and the we
|
||||
get a hold to the enclosing instance we need, and then we
|
||||
build the field access. */
|
||||
access = build_access_to_thisn (ctx, DECL_CONTEXT (decl), lc);
|
||||
|
||||
@ -8269,14 +8296,21 @@ build_dot_class_method (class)
|
||||
}
|
||||
|
||||
static tree
|
||||
build_dot_class_method_invocation (name)
|
||||
tree name;
|
||||
build_dot_class_method_invocation (type)
|
||||
tree type;
|
||||
{
|
||||
tree s = make_node (STRING_CST);
|
||||
TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (name);
|
||||
tree sig_id, s;
|
||||
|
||||
if (TYPE_ARRAY_P (type))
|
||||
sig_id = build_java_signature (type);
|
||||
else
|
||||
sig_id = DECL_NAME (TYPE_NAME (type));
|
||||
|
||||
s = make_node (STRING_CST);
|
||||
TREE_STRING_LENGTH (s) = IDENTIFIER_LENGTH (sig_id);
|
||||
TREE_STRING_POINTER (s) = obstack_alloc (expression_obstack,
|
||||
TREE_STRING_LENGTH (s)+1);
|
||||
strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (name));
|
||||
strcpy (TREE_STRING_POINTER (s), IDENTIFIER_POINTER (sig_id));
|
||||
return build_method_invocation (build_wfl_node (get_identifier ("class$")),
|
||||
build_tree_list (NULL_TREE, s));
|
||||
}
|
||||
@ -8318,6 +8352,11 @@ fix_constructors (mdecl)
|
||||
CLASSNAME() constructor */
|
||||
start_artificial_method_body (mdecl);
|
||||
|
||||
/* Insert an assignment to the this$<n> hidden field, if
|
||||
necessary */
|
||||
if ((thisn_assign = build_thisn_assign ()))
|
||||
java_method_add_stmt (mdecl, thisn_assign);
|
||||
|
||||
/* We don't generate a super constructor invocation if we're
|
||||
compiling java.lang.Object. build_super_invocation takes care
|
||||
of that. */
|
||||
@ -8327,11 +8366,6 @@ fix_constructors (mdecl)
|
||||
super invocation. */
|
||||
add_instance_initializer (mdecl);
|
||||
|
||||
/* Insert an assignment to the this$<n> hidden field, if
|
||||
necessary */
|
||||
if ((thisn_assign = build_thisn_assign ()))
|
||||
java_method_add_stmt (mdecl, thisn_assign);
|
||||
|
||||
end_artificial_method_body (mdecl);
|
||||
}
|
||||
/* Search for an explicit constructor invocation */
|
||||
@ -8363,14 +8397,14 @@ fix_constructors (mdecl)
|
||||
compound = add_stmt_to_compound (compound, NULL_TREE,
|
||||
build_super_invocation (mdecl));
|
||||
|
||||
/* Insert the instance initializer block right here, after the
|
||||
super invocation. */
|
||||
add_instance_initializer (mdecl);
|
||||
|
||||
/* Generate the assignment to this$<n>, if necessary */
|
||||
if ((thisn_assign = build_thisn_assign ()))
|
||||
compound = add_stmt_to_compound (compound, NULL_TREE, thisn_assign);
|
||||
|
||||
/* Insert the instance initializer block right here, after the
|
||||
super invocation. */
|
||||
add_instance_initializer (mdecl);
|
||||
|
||||
/* Fix the constructor main block if we're adding extra stmts */
|
||||
if (compound)
|
||||
{
|
||||
@ -9170,6 +9204,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
|
||||
current_class);
|
||||
return 1;
|
||||
}
|
||||
if (outer_field_access_p (current_class, decl))
|
||||
decl = build_outer_field_access (qual_wfl, decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -13114,8 +13150,7 @@ patch_incomplete_class_ref (node)
|
||||
synthetic static method `class$'. */
|
||||
if (!TYPE_DOT_CLASS (current_class))
|
||||
build_dot_class_method (current_class);
|
||||
ref_type =
|
||||
build_dot_class_method_invocation (DECL_NAME (TYPE_NAME (ref_type)));
|
||||
ref_type = build_dot_class_method_invocation (ref_type);
|
||||
return java_complete_tree (ref_type);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user