Commit a1774733 by Benjamin Kosnik

cp-tree.h (start_decl): Update prototype.

d
Thu Apr  9 22:16:57 1998  Per Bothner  <bothner@cygnus.com>
        * cp-tree.h (start_decl):  Update prototype.
        * decl.c (start_decl):  Like the C version, new parameters
        for the attributes.  Call cplus_decl_attributes here,
        (pushdecl):  Like C version, do build_type_copy if TYPE_DECL,
        (grokdeclarator):  Pass NULL for new start_decl arguments.
        * pt.c (tsubst_expr):  Likewise.
        * parse.y:  Merge cplus_decl_attribute calls into start_decl calls.
	* typeck.c (common_type): Check TYPE_MAIN_VARIANT.
	* lex.c (build_lang_decl): Add lang_name_java.
	* class.c (push_lang_context): Add lang_name_java.
	* method.c (build_mangled_name): Check for is_java_type.
Thu Apr  9 22:16:57 1998  Benjamin Kosnik  <bkoz@loony.cygnus.com>
	* decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT.
	* call.c (build_scoped_method_call): Check for TREE_CODE for
	VOID_TYPE instead of type ==  void_type_node.
	(build_method_call): Ditto.
	* decl.c (lookup_name_real): Ditto.
	(grokdeclarator): Ditto.
	(start_decl): Ditto.
	(grokparms): Ditto.
	(start_function): Ditto.
	(finish_function): Ditto.
	(start_method): Ditto.
also fixes g++/15415

From-SVN: r19071
parent 2e076ddf
...@@ -382,11 +382,12 @@ build_scoped_method_call (exp, basetype, name, parms) ...@@ -382,11 +382,12 @@ build_scoped_method_call (exp, basetype, name, parms)
and template parms. */ and template parms. */
if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype)) if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
{ {
if (type != basetype) if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')", cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type); exp, basetype, type);
name = TREE_OPERAND (name, 0); name = TREE_OPERAND (name, 0);
if (basetype != name && basetype != get_type_value (name)) if (TYPE_MAIN_VARIANT (basetype) != name
&& basetype != get_type_value (name))
cp_error ("qualified type `%T' does not match destructor name `~%T'", cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, name); basetype, name);
return cp_convert (void_type_node, exp); return cp_convert (void_type_node, exp);
...@@ -630,7 +631,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -630,7 +631,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype = TREE_TYPE (instance); basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE) if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype); basetype = TREE_TYPE (basetype);
if (! (name == basetype if (! (name == TYPE_MAIN_VARIANT (basetype)
|| (IS_AGGR_TYPE (basetype) || (IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype)) && name == constructor_name (basetype))
|| basetype == get_type_value (name))) || basetype == get_type_value (name)))
......
...@@ -131,7 +131,7 @@ tree *current_lang_base, *current_lang_stack; ...@@ -131,7 +131,7 @@ tree *current_lang_base, *current_lang_stack;
int current_lang_stacksize; int current_lang_stacksize;
/* Names of languages we recognize. */ /* Names of languages we recognize. */
tree lang_name_c, lang_name_cplusplus; tree lang_name_c, lang_name_cplusplus, lang_name_java;
tree current_lang_name; tree current_lang_name;
/* When layout out an aggregate type, the size of the /* When layout out an aggregate type, the size of the
...@@ -4886,7 +4886,7 @@ push_lang_context (name) ...@@ -4886,7 +4886,7 @@ push_lang_context (name)
current_lang_stacksize += 10; current_lang_stacksize += 10;
} }
if (name == lang_name_cplusplus) if (name == lang_name_cplusplus || name == lang_name_java)
{ {
strict_prototype = strict_prototypes_lang_cplusplus; strict_prototype = strict_prototypes_lang_cplusplus;
current_lang_name = name; current_lang_name = name;
......
...@@ -3286,22 +3286,25 @@ pushdecl (x) ...@@ -3286,22 +3286,25 @@ pushdecl (x)
else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE) else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE)
return push_overloaded_decl (x, 0); return push_overloaded_decl (x, 0);
/* If declaring a type as a typedef, and the type has no known /* If declaring a type as a typedef, copy the type (unless we're
typedef name, install this TYPE_DECL as its typedef name. */ at line 0), and install this TYPE_DECL as the new type's typedef
name. See the extensive comment in ../c-decl.c (pushdecl). */
if (TREE_CODE (x) == TYPE_DECL) if (TREE_CODE (x) == TYPE_DECL)
{ {
tree type = TREE_TYPE (x); tree type = TREE_TYPE (x);
tree name = (type != error_mark_node) ? TYPE_NAME (type) : x; if (DECL_SOURCE_LINE (x) == 0)
if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL)
{ {
/* If these are different names, and we're at the global if (TYPE_NAME (type) == 0)
binding level, make two equivalent definitions. */
name = x;
if (global_bindings_p ())
TYPE_NAME (type) = x; TYPE_NAME (type) = x;
} }
my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); else if (type != error_mark_node && TYPE_NAME (type) != x)
{
DECL_ORIGINAL_TYPE (x) = type;
type = build_type_copy (type);
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
TYPE_NAME (type) = x;
TREE_TYPE (x) = type;
}
if (type != error_mark_node if (type != error_mark_node
&& TYPE_NAME (type) && TYPE_NAME (type)
...@@ -4615,7 +4618,7 @@ lookup_name_real (name, prefer_type, nonclass) ...@@ -4615,7 +4618,7 @@ lookup_name_real (name, prefer_type, nonclass)
type = complete_type (type); type = complete_type (type);
if (type == void_type_node) if (TREE_CODE (type) == VOID_TYPE)
val = IDENTIFIER_GLOBAL_VALUE (name); val = IDENTIFIER_GLOBAL_VALUE (name);
else if (TREE_CODE (type) == NAMESPACE_DECL) else if (TREE_CODE (type) == NAMESPACE_DECL)
{ {
...@@ -4954,6 +4957,7 @@ init_decl_processing () ...@@ -4954,6 +4957,7 @@ init_decl_processing ()
/* Have to make these distinct before we try using them. */ /* Have to make these distinct before we try using them. */
lang_name_cplusplus = get_identifier ("C++"); lang_name_cplusplus = get_identifier ("C++");
lang_name_c = get_identifier ("C"); lang_name_c = get_identifier ("C");
lang_name_java = get_identifier ("Java");
/* enter the global namespace */ /* enter the global namespace */
my_friendly_assert (global_namespace == NULL_TREE, 375); my_friendly_assert (global_namespace == NULL_TREE, 375);
...@@ -5862,9 +5866,10 @@ groktypename (typename) ...@@ -5862,9 +5866,10 @@ groktypename (typename)
int debug_temp_inits = 1; int debug_temp_inits = 1;
tree tree
start_decl (declarator, declspecs, initialized) start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
tree declarator, declspecs; tree declarator, declspecs;
int initialized; int initialized;
tree attributes, prefix_attributes;
{ {
register tree decl; register tree decl;
register tree type, tem; register tree type, tem;
...@@ -5887,7 +5892,7 @@ start_decl (declarator, declspecs, initialized) ...@@ -5887,7 +5892,7 @@ start_decl (declarator, declspecs, initialized)
decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
NULL_TREE); NULL_TREE);
if (decl == NULL_TREE || decl == void_type_node) if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
return NULL_TREE; return NULL_TREE;
type = TREE_TYPE (decl); type = TREE_TYPE (decl);
...@@ -6029,6 +6034,9 @@ start_decl (declarator, declspecs, initialized) ...@@ -6029,6 +6034,9 @@ start_decl (declarator, declspecs, initialized)
pushclass (context, 2); pushclass (context, 2);
} }
/* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (decl, attributes, prefix_attributes);
/* Add this decl to the current binding level, but not if it /* Add this decl to the current binding level, but not if it
comes from another scope, e.g. a static member variable. comes from another scope, e.g. a static member variable.
TEM may equal DECL or it may be a previous decl of the same name. */ TEM may equal DECL or it may be a previous decl of the same name. */
...@@ -7825,7 +7833,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -7825,7 +7833,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
*next = TREE_OPERAND (decl, 0); *next = TREE_OPERAND (decl, 0);
init = TREE_OPERAND (decl, 1); init = TREE_OPERAND (decl, 1);
decl = start_decl (declarator, declspecs, 1); decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
/* Look for __unused__ attribute */ /* Look for __unused__ attribute */
if (TREE_USED (TREE_TYPE (decl))) if (TREE_USED (TREE_TYPE (decl)))
TREE_USED (decl) = 1; TREE_USED (decl) = 1;
...@@ -8387,7 +8395,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -8387,7 +8395,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type); constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type); volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
type = TYPE_MAIN_VARIANT (type); type = build_type_variant (type, 0, 0);
staticp = 0; staticp = 0;
inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
...@@ -8642,7 +8650,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -8642,7 +8650,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Check for some types that there cannot be arrays of. */ /* Check for some types that there cannot be arrays of. */
if (TYPE_MAIN_VARIANT (type) == void_type_node) if (TREE_CODE (type) == VOID_TYPE)
{ {
cp_error ("declaration of `%D' as array of voids", dname); cp_error ("declaration of `%D' as array of voids", dname);
type = error_mark_node; type = error_mark_node;
...@@ -9081,7 +9089,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9081,7 +9089,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
} }
else else
{ {
if (TYPE_MAIN_VARIANT (type) == void_type_node) if (TREE_CODE (type) == VOID_TYPE)
error ("invalid type: `void &'"); error ("invalid type: `void &'");
else else
type = build_reference_type (type); type = build_reference_type (type);
...@@ -9354,6 +9362,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9354,6 +9362,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (IS_SIGNATURE (current_class_type) && opaque_typedef) if (IS_SIGNATURE (current_class_type) && opaque_typedef)
SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1; SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
} }
else if (current_lang_name == lang_name_java)
decl = build_lang_decl (TYPE_DECL, declarator, type);
else else
decl = build_decl (TYPE_DECL, declarator, type); decl = build_decl (TYPE_DECL, declarator, type);
...@@ -9495,7 +9505,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9495,7 +9505,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
We don't complain about parms either, but that is because We don't complain about parms either, but that is because
a better error message can be made later. */ a better error message can be made later. */
if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM) if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
{ {
if (! declarator) if (! declarator)
error ("unnamed variable or field declared void"); error ("unnamed variable or field declared void");
...@@ -9537,7 +9547,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ...@@ -9537,7 +9547,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = build_pointer_type (type); type = build_pointer_type (type);
else if (TREE_CODE (type) == OFFSET_TYPE) else if (TREE_CODE (type) == OFFSET_TYPE)
type = build_pointer_type (type); type = build_pointer_type (type);
else if (type == void_type_node && declarator) else if (TREE_CODE (type) == VOID_TYPE && declarator)
{ {
error ("declaration of `%s' as void", name); error ("declaration of `%s' as void", name);
return NULL_TREE; return NULL_TREE;
...@@ -10116,7 +10126,7 @@ grokparms (first_parm, funcdef_flag) ...@@ -10116,7 +10126,7 @@ grokparms (first_parm, funcdef_flag)
} }
else if (first_parm != NULL_TREE else if (first_parm != NULL_TREE
&& TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
&& TREE_VALUE (first_parm) != void_type_node) && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
my_friendly_abort (145); my_friendly_abort (145);
else else
{ {
...@@ -10138,7 +10148,8 @@ grokparms (first_parm, funcdef_flag) ...@@ -10138,7 +10148,8 @@ grokparms (first_parm, funcdef_flag)
chain = TREE_CHAIN (parm); chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */ /* @@ weak defense against parse errors. */
if (decl != void_type_node && TREE_CODE (decl) != TREE_LIST) if (TREE_CODE (decl) != VOID_TYPE
&& TREE_CODE (decl) != TREE_LIST)
{ {
/* Give various messages as the need arises. */ /* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST) if (TREE_CODE (decl) == STRING_CST)
...@@ -10148,7 +10159,7 @@ grokparms (first_parm, funcdef_flag) ...@@ -10148,7 +10159,7 @@ grokparms (first_parm, funcdef_flag)
continue; continue;
} }
if (decl != void_type_node) if (TREE_CODE (decl) != VOID_TYPE)
{ {
decl = grokdeclarator (TREE_VALUE (decl), decl = grokdeclarator (TREE_VALUE (decl),
TREE_PURPOSE (decl), TREE_PURPOSE (decl),
...@@ -10157,7 +10168,7 @@ grokparms (first_parm, funcdef_flag) ...@@ -10157,7 +10168,7 @@ grokparms (first_parm, funcdef_flag)
if (! decl) if (! decl)
continue; continue;
type = TREE_TYPE (decl); type = TREE_TYPE (decl);
if (TYPE_MAIN_VARIANT (type) == void_type_node) if (TREE_CODE (type) == VOID_TYPE)
decl = void_type_node; decl = void_type_node;
else if (TREE_CODE (type) == METHOD_TYPE) else if (TREE_CODE (type) == METHOD_TYPE)
{ {
...@@ -10197,7 +10208,7 @@ grokparms (first_parm, funcdef_flag) ...@@ -10197,7 +10208,7 @@ grokparms (first_parm, funcdef_flag)
} }
} }
if (decl == void_type_node) if (TREE_CODE (decl) == VOID_TYPE)
{ {
if (result == NULL_TREE) if (result == NULL_TREE)
{ {
...@@ -10516,7 +10527,7 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10516,7 +10527,7 @@ grok_op_properties (decl, virtualp, friendp)
cp_error ("`%D' must be either a non-static member function or a non-member function", decl); cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
if (p) if (p)
for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p)) for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
{ {
tree arg = TREE_VALUE (p); tree arg = TREE_VALUE (p);
if (TREE_CODE (arg) == REFERENCE_TYPE) if (TREE_CODE (arg) == REFERENCE_TYPE)
...@@ -11364,7 +11375,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -11364,7 +11375,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
int doing_friend = 0; int doing_friend = 0;
/* Sanity check. */ /* Sanity check. */
my_friendly_assert (TREE_VALUE (void_list_node) == void_type_node, 160); my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);
/* Assume, until we see it does. */ /* Assume, until we see it does. */
...@@ -11539,7 +11550,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -11539,7 +11550,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
/* Effective C++ rule 15. See also c_expand_return. */ /* Effective C++ rule 15. See also c_expand_return. */
if (warn_ecpp if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR] && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
&& TREE_TYPE (fntype) == void_type_node) && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
cp_warning ("`operator=' should return a reference to `*this'"); cp_warning ("`operator=' should return a reference to `*this'");
/* Make the init_value nonzero so pushdecl knows this is not tentative. /* Make the init_value nonzero so pushdecl knows this is not tentative.
...@@ -11797,7 +11808,7 @@ store_parm_decls () ...@@ -11797,7 +11808,7 @@ store_parm_decls ()
{ {
pushdecl (parm); pushdecl (parm);
} }
else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node) else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE)
cp_error ("parameter `%D' declared void", parm); cp_error ("parameter `%D' declared void", parm);
else else
{ {
...@@ -12250,8 +12261,7 @@ finish_function (lineno, call_poplevel, nested) ...@@ -12250,8 +12261,7 @@ finish_function (lineno, call_poplevel, nested)
} }
c_expand_return (current_class_ptr); c_expand_return (current_class_ptr);
} }
else if (TYPE_MAIN_VARIANT (TREE_TYPE ( else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE
DECL_RESULT (current_function_decl))) != void_type_node
&& return_label != NULL_RTX) && return_label != NULL_RTX)
no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
...@@ -12490,7 +12500,7 @@ finish_function (lineno, call_poplevel, nested) ...@@ -12490,7 +12500,7 @@ finish_function (lineno, call_poplevel, nested)
cp_warning ("`noreturn' function `%D' does return", fndecl); cp_warning ("`noreturn' function `%D' does return", fndecl);
else if ((warn_return_type || pedantic) else if ((warn_return_type || pedantic)
&& current_function_returns_null && current_function_returns_null
&& TYPE_MAIN_VARIANT (TREE_TYPE (fntype)) != void_type_node) && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE)
{ {
/* If this function returns non-void and control can drop through, /* If this function returns non-void and control can drop through,
complain. */ complain. */
...@@ -12582,7 +12592,7 @@ start_method (declspecs, declarator) ...@@ -12582,7 +12592,7 @@ start_method (declspecs, declarator)
return NULL_TREE; return NULL_TREE;
/* Pass friends other than inline friend functions back. */ /* Pass friends other than inline friend functions back. */
if (TYPE_MAIN_VARIANT (fndecl) == void_type_node) if (fndecl == void_type_node)
return fndecl; return fndecl;
if (TREE_CODE (fndecl) != FUNCTION_DECL) if (TREE_CODE (fndecl) != FUNCTION_DECL)
...@@ -12673,7 +12683,7 @@ finish_method (decl) ...@@ -12673,7 +12683,7 @@ finish_method (decl)
register tree link; register tree link;
if (TYPE_MAIN_VARIANT (decl) == void_type_node) if (decl == void_type_node)
return decl; return decl;
old_initial = DECL_INITIAL (fndecl); old_initial = DECL_INITIAL (fndecl);
......
...@@ -4373,6 +4373,8 @@ build_lang_decl (code, name, type) ...@@ -4373,6 +4373,8 @@ build_lang_decl (code, name, type)
DECL_LANGUAGE (t) = lang_cplusplus; DECL_LANGUAGE (t) = lang_cplusplus;
else if (current_lang_name == lang_name_c) else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c; DECL_LANGUAGE (t) = lang_c;
else if (current_lang_name == lang_name_java)
DECL_LANGUAGE (t) = lang_java;
else my_friendly_abort (64); else my_friendly_abort (64);
SET_DECL_NAMESPACE (t, current_namespace); SET_DECL_NAMESPACE (t, current_namespace);
......
...@@ -1044,7 +1044,8 @@ build_mangled_name (parmtypes, begin, end) ...@@ -1044,7 +1044,8 @@ build_mangled_name (parmtypes, begin, end)
/* Every argument gets counted. */ /* Every argument gets counted. */
typevec[maxtype++] = parmtype; typevec[maxtype++] = parmtype;
if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]) if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]
&& ! is_java_type (parmtype))
{ {
Nrepeats++; Nrepeats++;
continue; continue;
...@@ -1067,9 +1068,10 @@ build_mangled_name (parmtypes, begin, end) ...@@ -1067,9 +1068,10 @@ build_mangled_name (parmtypes, begin, end)
} }
/* Only cache types which take more than one character. */ /* Only cache types which take more than one character. */
if (parmtype != TYPE_MAIN_VARIANT (parmtype) if ((parmtype != TYPE_MAIN_VARIANT (parmtype)
|| (TREE_CODE (parmtype) != INTEGER_TYPE || (TREE_CODE (parmtype) != INTEGER_TYPE
&& TREE_CODE (parmtype) != REAL_TYPE)) && TREE_CODE (parmtype) != REAL_TYPE))
&& ! is_java_type (parmtype))
TREE_USED (parmtype) = 1; TREE_USED (parmtype) = 1;
} }
if (TYPE_PTRMEMFUNC_P (parmtype)) if (TYPE_PTRMEMFUNC_P (parmtype))
...@@ -1113,14 +1115,34 @@ process_modifiers (parmtype) ...@@ -1113,14 +1115,34 @@ process_modifiers (parmtype)
if (TREE_READONLY (parmtype)) if (TREE_READONLY (parmtype))
OB_PUTC ('C'); OB_PUTC ('C');
if (TREE_CODE (parmtype) == INTEGER_TYPE && if (TREE_CODE (parmtype) == INTEGER_TYPE
TYPE_MAIN_VARIANT (parmtype) == && (TYPE_MAIN_VARIANT (parmtype)
unsigned_type (TYPE_MAIN_VARIANT (parmtype))) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
&& ! is_java_type (parmtype))
{
OB_PUTC ('U'); OB_PUTC ('U');
}
if (TYPE_VOLATILE (parmtype)) if (TYPE_VOLATILE (parmtype))
OB_PUTC ('V'); OB_PUTC ('V');
} }
/* True iff TYPE was declared as a "Java" type (inside extern "Java"). */
int
is_java_type (type)
tree type;
{
if (TYPE_NAME (type) != NULL_TREE)
{
tree decl = TYPE_NAME (type);
if (TREE_CODE (decl) == TYPE_DECL
&& DECL_LANG_SPECIFIC (decl) != NULL
&& DECL_LANGUAGE (decl) == lang_java)
return 1;
}
return 0;
}
/* Check to see if a tree node has been entered into the Bcode typelist /* Check to see if a tree node has been entered into the Bcode typelist
if not, add it. Otherwise emit the code and return TRUE */ if not, add it. Otherwise emit the code and return TRUE */
static int static int
...@@ -1292,6 +1314,30 @@ process_overload_item (parmtype, extra_Gcode) ...@@ -1292,6 +1314,30 @@ process_overload_item (parmtype, extra_Gcode)
} }
case INTEGER_TYPE: case INTEGER_TYPE:
/* "Java" integer types should mangle the same on all platforms,
and only depend on precision, not target 'int' size. */
if (is_java_type (parmtype))
{
if (TREE_UNSIGNED (parmtype))
{
switch (TYPE_PRECISION (parmtype))
{
case 8: OB_PUTC ('b'); return;
case 16: OB_PUTC ('w'); return;
}
}
else
{
switch (TYPE_PRECISION (parmtype))
{
case 8: OB_PUTC ('c'); return;
case 16: OB_PUTC ('s'); return;
case 32: OB_PUTC ('i'); return;
case 64: OB_PUTC ('x'); return;
}
}
}
parmtype = TYPE_MAIN_VARIANT (parmtype); parmtype = TYPE_MAIN_VARIANT (parmtype);
if (parmtype == integer_type_node if (parmtype == integer_type_node
|| parmtype == unsigned_type_node) || parmtype == unsigned_type_node)
......
...@@ -318,8 +318,8 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl) ...@@ -318,8 +318,8 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl)
used_extern_spec = 1; used_extern_spec = 1;
} }
sm = suspend_momentary (); sm = suspend_momentary ();
*decl = start_decl (declarator, current_declspecs, initialized); *decl = start_decl (declarator, current_declspecs, initialized,
cplus_decl_attributes (*decl, attributes, prefix_attributes); attributes, prefix_attributes);
return sm; return sm;
} }
%} %}
...@@ -942,9 +942,8 @@ condition: ...@@ -942,9 +942,8 @@ condition:
} }
current_declspecs = $1.t; current_declspecs = $1.t;
$<itype>5 = suspend_momentary (); $<itype>5 = suspend_momentary ();
$<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1); $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1,
cplus_decl_attributes ($<ttype>$, $4, $4, /*prefix_attributes*/ NULL_TREE);
/*prefix_attributes*/ NULL_TREE);
} }
init init
{ {
...@@ -1769,14 +1768,14 @@ maybeasm: ...@@ -1769,14 +1768,14 @@ maybeasm:
initdcl: initdcl:
declarator maybeasm maybe_attribute '=' declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1); { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1,
cplus_decl_attributes ($<ttype>$, $3, prefix_attributes); } $3, prefix_attributes); }
init init
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } { cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); }
| declarator maybeasm maybe_attribute | declarator maybeasm maybe_attribute
{ $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0); { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0,
cplus_decl_attributes ($<ttype>$, $3, prefix_attributes); $3, prefix_attributes);
cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); } cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); }
; ;
......
...@@ -5014,7 +5014,7 @@ tsubst_expr (t, args, in_decl) ...@@ -5014,7 +5014,7 @@ tsubst_expr (t, args, in_decl)
dcl = start_decl dcl = start_decl
(tsubst (TREE_OPERAND (t, 0), args, in_decl), (tsubst (TREE_OPERAND (t, 0), args, in_decl),
tsubst (TREE_OPERAND (t, 1), args, in_decl), tsubst (TREE_OPERAND (t, 1), args, in_decl),
TREE_OPERAND (t, 2) != 0); TREE_OPERAND (t, 2) != 0, NULL_TREE, NULL_TREE);
init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl); init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl);
cp_finish_decl cp_finish_decl
(dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0); (dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);
......
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