diff options
author | Per Bothner <bothner@gcc.gnu.org> | 1998-08-20 09:43:58 -0700 |
---|---|---|
committer | Per Bothner <bothner@gcc.gnu.org> | 1998-08-20 09:43:58 -0700 |
commit | 743f140d46759b39745c55bd081b1e92b6335ffc (patch) | |
tree | 3e43247679622880e247c3fa4cc949fd1bc5729e /gcc | |
parent | d35897f502c40ab304aca5159831bd9db62e0cff (diff) | |
download | gcc-743f140d46759b39745c55bd081b1e92b6335ffc.zip gcc-743f140d46759b39745c55bd081b1e92b6335ffc.tar.gz gcc-743f140d46759b39745c55bd081b1e92b6335ffc.tar.bz2 |
Handle new'ing of Java classes.
d
Handle new'ing of Java classes.
* init.c (build_class_classref): New function.
(build_new_1): If type is TYPE_FOR_JAVA: Call _Jv_AllocObject;
constructor does not return this; don't need to exception-protect.
* pt.c (lookup_template_class): Copy TYPE_FOR_JAVA flag.
* decl2.c (acceptable_java_type): Handle template-derived types.
From-SVN: r21879
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/init.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 2711322..ce61077 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2145,6 +2145,47 @@ build_new (placement, decl, init, use_global_new) return rval; } +/* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ + +static tree jclass_node = NULL_TREE; + +/* Given a Java class, return a decl for the corresponding java.lang.Class. */ + +tree +build_java_class_ref (type) + tree type; +{ + tree name, class_decl; + static tree CL_prefix = NULL_TREE; + static tree alloc_decl = NULL_TREE; + if (CL_prefix == NULL_TREE) + CL_prefix = get_identifier("_CL_"); + if (jclass_node == NULL_TREE) + { + jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier("jclass")); + if (jclass_node == NULL_TREE) + fatal("call to Java constructor, while `jclass' undefined"); + jclass_node = TREE_TYPE (jclass_node); + } + name = build_overload_with_type (CL_prefix, type); + class_decl = IDENTIFIER_GLOBAL_VALUE (name); + if (class_decl == NULL_TREE) + { + push_obstacks_nochange (); + end_temporary_allocation (); + class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node)); + TREE_STATIC (class_decl) = 1; + DECL_EXTERNAL (class_decl) = 1; + TREE_PUBLIC (class_decl) = 1; + DECL_ARTIFICIAL (class_decl) = 1; + DECL_IGNORED_P (class_decl) = 1; + pushdecl_top_level (class_decl); + make_decl_rtl (class_decl, NULL_PTR, 1); + pop_obstacks (); + } + return class_decl; +} + /* Called from cplus_expand_expr when expanding a NEW_EXPR. The return value is immediately handed to expand_expr. */ @@ -2160,6 +2201,7 @@ build_new_1 (exp) enum tree_code code = NEW_EXPR; int use_cookie, nothrow, check_new; int use_global_new; + int use_java_new = 0; placement = TREE_OPERAND (exp, 0); type = TREE_OPERAND (exp, 1); @@ -2257,6 +2299,23 @@ build_new_1 (exp) return error_mark_node; } } + else if (! placement && TYPE_FOR_JAVA (true_type)) + { + tree name, class_addr, alloc_decl; + tree class_decl = build_java_class_ref (true_type); + tree class_size = size_in_bytes (true_type); + static char alloc_name[] = "_Jv_AllocObject"; + use_java_new = 1; + alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name)); + if (alloc_decl == NULL_TREE) + fatal("call to Java constructor, while `%s' undefined", alloc_name); + class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); + rval = build_function_call (alloc_decl, + tree_cons (NULL_TREE, class_addr, + build_tree_list (NULL_TREE, + class_size))); + rval = cp_convert (build_pointer_type (true_type), rval); + } else { int susp; @@ -2297,7 +2356,7 @@ build_new_1 (exp) if (t && TREE_VALUE (t) == NULL_TREE) nothrow = 1; } - check_new = flag_check_new || nothrow; + check_new = (flag_check_new || nothrow) && ! use_java_new; if ((check_new || flag_exceptions) && rval) { @@ -2383,6 +2442,8 @@ build_new_1 (exp) flags |= LOOKUP_HAS_IN_CHARGE; } + if (use_java_new) + rval = save_expr (rval); newrval = rval; if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE) @@ -2394,6 +2455,10 @@ build_new_1 (exp) if (newrval == NULL_TREE || newrval == error_mark_node) return error_mark_node; + /* Java constructors compiled by jc1 do not return this. */ + if (use_java_new) + newrval = build (COMPOUND_EXPR, TREE_TYPE (newrval), + newrval, rval); rval = newrval; TREE_HAS_CONSTRUCTOR (rval) = 1; } @@ -2405,7 +2470,7 @@ build_new_1 (exp) an exception and the new-expression does not contain a new-placement, then the deallocation function is called to free the memory in which the object was being constructed. */ - if (flag_exceptions && alloc_expr) + if (flag_exceptions && alloc_expr && ! use_java_new) { enum tree_code dcode = has_array ? VEC_DELETE_EXPR : DELETE_EXPR; tree cleanup, fn = NULL_TREE; |