From: Benjamin Kosnik Date: Thu, 9 Apr 1998 20:36:47 +0000 (+0000) Subject: cp-tree.h (start_decl): Update prototype. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a177473334c4f427428326747b97656a0af049fa;p=gcc.git cp-tree.h (start_decl): Update prototype. d Thu Apr 9 22:16:57 1998 Per Bothner * 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 * 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 --- diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d0013311410..1c50b7eed4c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -382,11 +382,12 @@ build_scoped_method_call (exp, basetype, name, parms) and template parms. */ 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')", exp, basetype, type); 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'", basetype, name); return cp_convert (void_type_node, exp); @@ -630,7 +631,7 @@ build_method_call (instance, name, parms, basetype_path, flags) basetype = TREE_TYPE (instance); if (TREE_CODE (basetype) == REFERENCE_TYPE) basetype = TREE_TYPE (basetype); - if (! (name == basetype + if (! (name == TYPE_MAIN_VARIANT (basetype) || (IS_AGGR_TYPE (basetype) && name == constructor_name (basetype)) || basetype == get_type_value (name))) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index c2d6b0530b2..5c4be24268a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -131,7 +131,7 @@ tree *current_lang_base, *current_lang_stack; int current_lang_stacksize; /* 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; /* When layout out an aggregate type, the size of the @@ -4886,7 +4886,7 @@ push_lang_context (name) current_lang_stacksize += 10; } - if (name == lang_name_cplusplus) + if (name == lang_name_cplusplus || name == lang_name_java) { strict_prototype = strict_prototypes_lang_cplusplus; current_lang_name = name; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 32009a98f57..a71a768ceda 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3286,22 +3286,25 @@ pushdecl (x) else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE) return push_overloaded_decl (x, 0); - /* If declaring a type as a typedef, and the type has no known - typedef name, install this TYPE_DECL as its typedef name. */ + /* If declaring a type as a typedef, copy the type (unless we're + 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) { tree type = TREE_TYPE (x); - tree name = (type != error_mark_node) ? TYPE_NAME (type) : x; - - if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL) - { - /* If these are different names, and we're at the global - binding level, make two equivalent definitions. */ - name = x; - if (global_bindings_p ()) - TYPE_NAME (type) = x; - } - my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140); + if (DECL_SOURCE_LINE (x) == 0) + { + if (TYPE_NAME (type) == 0) + TYPE_NAME (type) = x; + } + 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 && TYPE_NAME (type) @@ -4615,7 +4618,7 @@ lookup_name_real (name, prefer_type, nonclass) type = complete_type (type); - if (type == void_type_node) + if (TREE_CODE (type) == VOID_TYPE) val = IDENTIFIER_GLOBAL_VALUE (name); else if (TREE_CODE (type) == NAMESPACE_DECL) { @@ -4954,6 +4957,7 @@ init_decl_processing () /* Have to make these distinct before we try using them. */ lang_name_cplusplus = get_identifier ("C++"); lang_name_c = get_identifier ("C"); + lang_name_java = get_identifier ("Java"); /* enter the global namespace */ my_friendly_assert (global_namespace == NULL_TREE, 375); @@ -5862,9 +5866,10 @@ groktypename (typename) int debug_temp_inits = 1; tree -start_decl (declarator, declspecs, initialized) +start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) tree declarator, declspecs; int initialized; + tree attributes, prefix_attributes; { register tree decl; register tree type, tem; @@ -5887,7 +5892,7 @@ start_decl (declarator, declspecs, initialized) decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, NULL_TREE); - if (decl == NULL_TREE || decl == void_type_node) + if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) return NULL_TREE; type = TREE_TYPE (decl); @@ -6029,6 +6034,9 @@ start_decl (declarator, declspecs, initialized) 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 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. */ @@ -7825,7 +7833,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) *next = TREE_OPERAND (decl, 0); 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 */ if (TREE_USED (TREE_TYPE (decl))) TREE_USED (decl) = 1; @@ -8387,7 +8395,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type); volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type); - type = TYPE_MAIN_VARIANT (type); + type = build_type_variant (type, 0, 0); staticp = 0; inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); @@ -8642,7 +8650,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* 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); type = error_mark_node; @@ -9081,7 +9089,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } else { - if (TYPE_MAIN_VARIANT (type) == void_type_node) + if (TREE_CODE (type) == VOID_TYPE) error ("invalid type: `void &'"); else type = build_reference_type (type); @@ -9354,6 +9362,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (IS_SIGNATURE (current_class_type) && opaque_typedef) 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 decl = build_decl (TYPE_DECL, declarator, type); @@ -9495,7 +9505,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) We don't complain about parms either, but that is because 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) error ("unnamed variable or field declared void"); @@ -9537,7 +9547,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = build_pointer_type (type); else if (TREE_CODE (type) == OFFSET_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); return NULL_TREE; @@ -10116,7 +10126,7 @@ grokparms (first_parm, funcdef_flag) } else if (first_parm != NULL_TREE && 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); else { @@ -10138,7 +10148,8 @@ grokparms (first_parm, funcdef_flag) chain = TREE_CHAIN (parm); /* @@ 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. */ if (TREE_CODE (decl) == STRING_CST) @@ -10148,7 +10159,7 @@ grokparms (first_parm, funcdef_flag) continue; } - if (decl != void_type_node) + if (TREE_CODE (decl) != VOID_TYPE) { decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl), @@ -10157,7 +10168,7 @@ grokparms (first_parm, funcdef_flag) if (! decl) continue; type = TREE_TYPE (decl); - if (TYPE_MAIN_VARIANT (type) == void_type_node) + if (TREE_CODE (type) == VOID_TYPE) decl = void_type_node; else if (TREE_CODE (type) == METHOD_TYPE) { @@ -10197,7 +10208,7 @@ grokparms (first_parm, funcdef_flag) } } - if (decl == void_type_node) + if (TREE_CODE (decl) == VOID_TYPE) { if (result == NULL_TREE) { @@ -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); 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); if (TREE_CODE (arg) == REFERENCE_TYPE) @@ -11364,7 +11375,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) int doing_friend = 0; /* 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); /* Assume, until we see it does. */ @@ -11539,7 +11550,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) /* Effective C++ rule 15. See also c_expand_return. */ if (warn_ecpp && 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'"); /* Make the init_value nonzero so pushdecl knows this is not tentative. @@ -11797,7 +11808,7 @@ store_parm_decls () { 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); else { @@ -12250,8 +12261,7 @@ finish_function (lineno, call_poplevel, nested) } c_expand_return (current_class_ptr); } - else if (TYPE_MAIN_VARIANT (TREE_TYPE ( - DECL_RESULT (current_function_decl))) != void_type_node + else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE && return_label != NULL_RTX) no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); @@ -12490,7 +12500,7 @@ finish_function (lineno, call_poplevel, nested) cp_warning ("`noreturn' function `%D' does return", fndecl); else if ((warn_return_type || pedantic) && 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, complain. */ @@ -12582,7 +12592,7 @@ start_method (declspecs, declarator) return NULL_TREE; /* Pass friends other than inline friend functions back. */ - if (TYPE_MAIN_VARIANT (fndecl) == void_type_node) + if (fndecl == void_type_node) return fndecl; if (TREE_CODE (fndecl) != FUNCTION_DECL) @@ -12673,7 +12683,7 @@ finish_method (decl) register tree link; - if (TYPE_MAIN_VARIANT (decl) == void_type_node) + if (decl == void_type_node) return decl; old_initial = DECL_INITIAL (fndecl); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 60333008db4..74f05191f76 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -4373,6 +4373,8 @@ build_lang_decl (code, name, type) DECL_LANGUAGE (t) = lang_cplusplus; else if (current_lang_name == lang_name_c) DECL_LANGUAGE (t) = lang_c; + else if (current_lang_name == lang_name_java) + DECL_LANGUAGE (t) = lang_java; else my_friendly_abort (64); SET_DECL_NAMESPACE (t, current_namespace); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index e8ed718d165..6e20848102e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1044,7 +1044,8 @@ build_mangled_name (parmtypes, begin, end) /* Every argument gets counted. */ typevec[maxtype++] = parmtype; - if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]) + if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2] + && ! is_java_type (parmtype)) { Nrepeats++; continue; @@ -1067,9 +1068,10 @@ build_mangled_name (parmtypes, begin, end) } /* Only cache types which take more than one character. */ - if (parmtype != TYPE_MAIN_VARIANT (parmtype) - || (TREE_CODE (parmtype) != INTEGER_TYPE - && TREE_CODE (parmtype) != REAL_TYPE)) + if ((parmtype != TYPE_MAIN_VARIANT (parmtype) + || (TREE_CODE (parmtype) != INTEGER_TYPE + && TREE_CODE (parmtype) != REAL_TYPE)) + && ! is_java_type (parmtype)) TREE_USED (parmtype) = 1; } if (TYPE_PTRMEMFUNC_P (parmtype)) @@ -1113,14 +1115,34 @@ process_modifiers (parmtype) if (TREE_READONLY (parmtype)) OB_PUTC ('C'); - if (TREE_CODE (parmtype) == INTEGER_TYPE && - TYPE_MAIN_VARIANT (parmtype) == - unsigned_type (TYPE_MAIN_VARIANT (parmtype))) - OB_PUTC ('U'); + if (TREE_CODE (parmtype) == INTEGER_TYPE + && (TYPE_MAIN_VARIANT (parmtype) + == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) + && ! is_java_type (parmtype)) + { + OB_PUTC ('U'); + } if (TYPE_VOLATILE (parmtype)) 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 if not, add it. Otherwise emit the code and return TRUE */ static int @@ -1292,6 +1314,30 @@ process_overload_item (parmtype, extra_Gcode) } 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); if (parmtype == integer_type_node || parmtype == unsigned_type_node) diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index a471c82565b..7e79685eb76 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -318,8 +318,8 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl) used_extern_spec = 1; } sm = suspend_momentary (); - *decl = start_decl (declarator, current_declspecs, initialized); - cplus_decl_attributes (*decl, attributes, prefix_attributes); + *decl = start_decl (declarator, current_declspecs, initialized, + attributes, prefix_attributes); return sm; } %} @@ -942,9 +942,8 @@ condition: } current_declspecs = $1.t; $5 = suspend_momentary (); - $$ = start_decl ($2, current_declspecs, 1); - cplus_decl_attributes ($$, $4, - /*prefix_attributes*/ NULL_TREE); + $$ = start_decl ($2, current_declspecs, 1, + $4, /*prefix_attributes*/ NULL_TREE); } init { @@ -1769,14 +1768,14 @@ maybeasm: initdcl: declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1); - cplus_decl_attributes ($$, $3, prefix_attributes); } + { $$ = start_decl ($1, current_declspecs, 1, + $3, prefix_attributes); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { cp_finish_decl ($5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } | declarator maybeasm maybe_attribute - { $$ = start_decl ($1, current_declspecs, 0); - cplus_decl_attributes ($$, $3, prefix_attributes); + { $$ = start_decl ($1, current_declspecs, 0, + $3, prefix_attributes); cp_finish_decl ($$, NULL_TREE, $2, 1, 0); } ; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1c632f73547..4a7512ed844 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5014,7 +5014,7 @@ tsubst_expr (t, args, in_decl) dcl = start_decl (tsubst (TREE_OPERAND (t, 0), 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); cp_finish_decl (dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);