static void lto_input_ts_list_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { TREE_PURPOSE (expr) = stream_read_tree (ib, data_in); TREE_VALUE (expr) = stream_read_tree (ib, data_in); TREE_CHAIN (expr) = stream_read_tree (ib, data_in); }
bool cxx11_attribute_p (const_tree attr) { if (attr == NULL_TREE || TREE_CODE (attr) != TREE_LIST) return false; return (TREE_CODE (TREE_PURPOSE (attr)) == TREE_LIST); }
static void split_range (struct eh_range *range, int pc) { struct eh_range *ptr; struct eh_range **first_child, **second_child; struct eh_range *h; /* First, split all the sub-ranges. */ for (ptr = range->first_child; ptr; ptr = ptr->next_sibling) { if (pc > ptr->start_pc && pc < ptr->end_pc) { split_range (ptr, pc); } } /* Create a new range. */ h = XNEW (struct eh_range); h->start_pc = pc; h->end_pc = range->end_pc; h->next_sibling = range->next_sibling; range->next_sibling = h; range->end_pc = pc; h->handlers = build_tree_list (TREE_PURPOSE (range->handlers), TREE_VALUE (range->handlers)); h->next_sibling = NULL; h->expanded = 0; h->stmt = NULL; h->outer = range->outer; h->first_child = NULL; ptr = range->first_child; first_child = &range->first_child; second_child = &h->first_child; /* Distribute the sub-ranges between the two new ranges. */ for (ptr = range->first_child; ptr; ptr = ptr->next_sibling) { if (ptr->start_pc < pc) { *first_child = ptr; ptr->outer = range; first_child = &ptr->next_sibling; } else { *second_child = ptr; ptr->outer = h; second_child = &ptr->next_sibling; } } *first_child = NULL; *second_child = NULL; }
/* This emits all the meta-data string tables (and finalizes each var as it goes). */ void generate_strings (void) { tree chain, string_expr; tree string, decl; /* , type;*/ for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_var_decl (decl, string_expr); } for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_var_decl (decl, string_expr); } for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_var_decl (decl, string_expr); } for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain)) { string = TREE_VALUE (chain); decl = TREE_PURPOSE (chain); string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, IDENTIFIER_POINTER (string)); finish_var_decl (decl, string_expr); } }
tree expand_cond (tree t) { if (t && TREE_CODE (t) == TREE_LIST) { expand_stmt (TREE_PURPOSE (t)); return TREE_VALUE (t); } else return t; }
/* * Return a newly created TREE_LIST node whose * purpose and value fields are PARM and VALUE. */ tree build_tree_list (tree parm, tree value) { register tree t = make_node (TREE_LIST); TREE_PURPOSE (t) = parm; TREE_VALUE (t) = value; return (t); } /* end build_tree_list */
/* **************************************************************** * Create a OP_IDENTIFIER node * **************************************************************** */ tree build_op_identifier (tree op1, tree op2) { register tree t = make_node (OP_IDENTIFIER); TREE_PURPOSE (t) = op1; TREE_VALUE (t) = op2; return (t); } /* end build_op_identifier */
void oacc_replace_fn_attrib (tree fn, tree dims) { tree ident = get_identifier (OACC_FN_ATTRIB); tree attribs = DECL_ATTRIBUTES (fn); /* If we happen to be present as the first attrib, drop it. */ if (attribs && TREE_PURPOSE (attribs) == ident) attribs = TREE_CHAIN (attribs); DECL_ATTRIBUTES (fn) = tree_cons (ident, dims, attribs); }
/* * Return a newly created TREE_LIST node whose * purpose and value fields are PARM and VALUE * and whose TREE_CHAIN is CHAIN. */ tree tree_cons (tree purpose, tree value, tree chain) { register tree node = make_node (TREE_LIST); TREE_CHAIN (node) = chain; TREE_PURPOSE (node) = purpose; TREE_VALUE (node) = value; return (node); } /* end tree_cons */
/* If there are any handlers for this range, issue end of range, and then all handler blocks */ void expand_end_java_handler (struct eh_range *range) { tree handler = range->handlers; if (handler) { tree exc_obj = build_exception_object_var (); tree catches = make_node (STATEMENT_LIST); tree_stmt_iterator catches_i = tsi_last (catches); tree *body; for (; handler; handler = TREE_CHAIN (handler)) { tree type, eh_type, x; tree stmts = make_node (STATEMENT_LIST); tree_stmt_iterator stmts_i = tsi_last (stmts); type = TREE_PURPOSE (handler); if (type == NULL) type = throwable_type_node; eh_type = prepare_eh_table_type (type); x = build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER), 1, integer_zero_node); x = build2 (MODIFY_EXPR, void_type_node, exc_obj, x); tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING); x = build1 (GOTO_EXPR, void_type_node, TREE_VALUE (handler)); tsi_link_after (&stmts_i, x, TSI_CONTINUE_LINKING); x = build2 (CATCH_EXPR, void_type_node, eh_type, stmts); tsi_link_after (&catches_i, x, TSI_CONTINUE_LINKING); /* Throwable can match anything in Java, and therefore any subsequent handlers are unreachable. */ /* ??? If we're assured of no foreign language exceptions, we'd be better off using NULL as the exception type for the catch. */ if (type == throwable_type_node) break; } body = get_stmts (); *body = build2 (TRY_CATCH_EXPR, void_type_node, *body, catches); } #if defined(DEBUG_JAVA_BINDING_LEVELS) indent (); fprintf (stderr, "expand end handler pc %d <-- %d\n", current_pc, range->start_pc); #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ }
static void get_asm_expr_operands (funct_state local, tree stmt) { int noutputs = list_length (ASM_OUTPUTS (stmt)); const char **oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *)); int i; tree link; const char *constraint; bool allows_mem, allows_reg, is_inout; for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link)) { oconstraints[i] = constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg, &is_inout); check_lhs_var (local, TREE_VALUE (link)); } for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link)) { constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints, &allows_mem, &allows_reg); check_rhs_var (local, TREE_VALUE (link)); } for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link)) if (simple_cst_equal(TREE_VALUE (link), memory_identifier_string) == 1) /* Abandon all hope, ye who enter here. */ local->pure_const_state = IPA_NEITHER; if (ASM_VOLATILE_P (stmt)) local->pure_const_state = IPA_NEITHER; }
const struct attribute_spec * lookup_attribute_spec (const_tree name) { tree ns; if (TREE_CODE (name) == TREE_LIST) { ns = TREE_PURPOSE (name); name = TREE_VALUE (name); } else ns = get_identifier ("gnu"); return lookup_scoped_attribute_spec (ns, name); }
void java_init_lex () { #ifndef JC1_LITE int java_lang_imported = 0; if (!java_lang_id) java_lang_id = get_identifier ("java.lang"); if (!java_lang_cloneable) java_lang_cloneable = get_identifier ("java.lang.Cloneable"); if (!java_lang_imported) { tree node = build_tree_list (build_expr_wfl (java_lang_id, NULL, 0, 0), NULL_TREE); read_import_dir (TREE_PURPOSE (node)); TREE_CHAIN (node) = ctxp->import_demand_list; ctxp->import_demand_list = node; java_lang_imported = 1; } if (!wfl_operator) wfl_operator = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0); if (!label_id) label_id = get_identifier ("$L"); if (!wfl_append) wfl_append = build_expr_wfl (get_identifier ("append"), NULL, 0, 0); if (!wfl_string_buffer) wfl_string_buffer = build_expr_wfl (get_identifier ("java.lang.StringBuffer"), NULL, 0, 0); if (!wfl_to_string) wfl_to_string = build_expr_wfl (get_identifier ("toString"), NULL, 0, 0); ctxp->static_initialized = ctxp->non_static_initialized = ctxp->incomplete_class = NULL_TREE; bzero ((PTR) ctxp->modifier_ctx, 11*sizeof (ctxp->modifier_ctx[0])); bzero ((PTR) current_jcf, sizeof (JCF)); ctxp->current_parsed_class = NULL; ctxp->package = NULL_TREE; #endif ctxp->filename = input_filename; ctxp->lineno = lineno = 0; ctxp->p_line = NULL; ctxp->c_line = NULL; ctxp->unget_utf8_value = 0; ctxp->minus_seen = 0; ctxp->java_error_flag = 0; }
static void pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t) { t = TREE_OPERAND (t, 0); pp_cxx_whitespace (pp); pp_colon (pp); pp_cxx_whitespace (pp); for (; t; t = TREE_CHAIN (t)) { pp_cxx_primary_expression (pp, TREE_PURPOSE (t)); pp_cxx_call_argument_list (pp, TREE_VALUE (t)); if (TREE_CHAIN (t)) pp_cxx_separate_with (pp, ','); } }
static void finish_cdtor (tree body) { tree scope; tree block; scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); block = poplevel (0, 0, 0); SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block; SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block; RECHAIN_STMTS (body, COMPOUND_BODY (body)); finish_function (); }
tree add_objc_string (tree ident, string_section section) { tree *chain, decl, type; char buf[BUFSIZE]; switch (section) { case class_names: chain = &class_names_chain; snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident)); break; case meth_var_names: chain = &meth_var_names_chain; snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); break; case meth_var_types: chain = &meth_var_types_chain; snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); break; case prop_names_attr: chain = &prop_names_attr_chain; snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++); break; default: gcc_unreachable (); } while (*chain) { if (TREE_VALUE (*chain) == ident) return convert (string_type_node, build_unary_op (input_location, ADDR_EXPR, TREE_PURPOSE (*chain), 1)); chain = &TREE_CHAIN (*chain); } type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1); /* Get a runtime-specific string decl which will be finish_var()'ed in generate_strings (). */ decl = (*runtime.string_decl) (type, buf, section); TREE_CONSTANT (decl) = 1; *chain = tree_cons (decl, ident, NULL_TREE); return convert (string_type_node, build_unary_op (input_location, ADDR_EXPR, decl, 1)); }
void register_capture_members (tree captures) { if (captures == NULL_TREE) return; register_capture_members (TREE_CHAIN (captures)); tree field = TREE_PURPOSE (captures); if (PACK_EXPANSION_P (field)) field = PACK_EXPANSION_PATTERN (field); /* We set this in add_capture to avoid duplicates. */ IDENTIFIER_MARKED (DECL_NAME (field)) = false; finish_member_declaration (field); }
/* * Same as `tree_cons', but save this node * if the function's RTL is saved. */ tree saveable_tree_cons (tree purpose, tree value, tree chain) { register tree node; register OBSTACK *ambient_obstack = current_obstack; current_obstack = saveable_obstack; node = make_node (TREE_LIST); TREE_CHAIN (node) = chain; TREE_PURPOSE (node) = purpose; TREE_VALUE (node) = value; current_obstack = ambient_obstack; return (node); } /* end saveable_tree_cons */
void handle_pre_generic (void *event_data, void *data) { tree fndecl = (tree) event_data; tree arg; for (arg = DECL_ARGUMENTS(fndecl); arg; arg = DECL_CHAIN (arg)) { tree attr; for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) { tree attrname = TREE_PURPOSE (attr); tree attrargs = TREE_VALUE (attr); warning (0, G_("attribute '%s' on param '%s' of function %s"), IDENTIFIER_POINTER (attrname), IDENTIFIER_POINTER (DECL_NAME (arg)), IDENTIFIER_POINTER (DECL_NAME (fndecl)) ); } } }
tree extract_lock_attributes (tree attrs) { tree lock_attrs = NULL_TREE; tree next; for ( ; attrs; attrs = next) { next = TREE_CHAIN (attrs); if (is_lock_attribute_p (TREE_PURPOSE (attrs))) { TREE_CHAIN (attrs) = lock_attrs; lock_attrs = attrs; } } return lock_attrs; }
static int mangle_record_type (tree type, int for_pointer) { tree current; int match; int nadded_p = 0; int qualified; /* Does this name have a package qualifier? */ qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type))); #define ADD_N() \ do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0) gcc_assert (TREE_CODE (type) == RECORD_TYPE); if (!TYPE_PACKAGE_LIST (type)) set_type_package_list (type); match = find_compression_record_match (type, ¤t); if (match >= 0) { /* If we had a pointer, and there's more, we need to emit 'N' after 'P' (for_pointer tells us we already emitted it.) */ if (for_pointer && current) ADD_N(); emit_compression_string (match); } while (current) { /* Add the new type to the table */ compression_table_add (TREE_PURPOSE (current)); /* Add 'N' if we never got a chance to, but only if we have a qualified name. For non-pointer elements, the name is always qualified. */ if ((qualified || !for_pointer) && !nadded_p) ADD_N(); /* Use the bare type name for the mangle. */ append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)), IDENTIFIER_LENGTH (TREE_VALUE (current))); current = TREE_CHAIN (current); } return nadded_p; #undef ADD_N }
/* Return false if the function FNDECL cannot be inlined on account of its attributes, true otherwise. */ bool function_attribute_inlinable_p (const_tree fndecl) { if (targetm.attribute_table) { const_tree a; for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a)) { const_tree name = TREE_PURPOSE (a); int i; for (i = 0; targetm.attribute_table[i].name != NULL; i++) if (is_attribute_p (targetm.attribute_table[i].name, name)) return targetm.function_attribute_inlinable_p (fndecl); } } return true; }
static int find_compression_record_match (tree type, tree *next_current) { int i, match = -1; tree current, saved_current = NULL_TREE; current = TYPE_PACKAGE_LIST (type); for (i = 0; i < compression_next; i++) { tree compression_entry = TREE_VEC_ELT (compression_table, i); if (current && compression_entry == TREE_PURPOSE (current)) { match = i; saved_current = current; current = TREE_CHAIN (current); } else /* We don't want to match an element that appears in the middle of a package name, so skip forward to the next complete type name. IDENTIFIER_NODEs (except for a "6JArray") are partial package names while RECORD_TYPEs represent complete type names. */ while (i < compression_next && TREE_CODE (compression_entry) == IDENTIFIER_NODE && compression_entry != atms) compression_entry = TREE_VEC_ELT (compression_table, ++i); } if (!next_current) return match; /* If we have a match, set next_current to the item next to the last matched value. */ if (match >= 0) *next_current = TREE_CHAIN (saved_current); /* We had no match: we'll have to start from the beginning. */ if (match < 0) *next_current = TYPE_PACKAGE_LIST (type); return match; }
void pp_c_attributes (c_pretty_printer *pp, tree attributes) { if (attributes == NULL_TREE) return; pp_c_identifier (pp, "__attribute__"); pp_c_left_paren (pp); pp_c_left_paren (pp); for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes)) { pp_tree_identifier (pp, TREE_PURPOSE (attributes)); if (TREE_VALUE (attributes)) pp_c_call_argument_list (pp, TREE_VALUE (attributes)); if (TREE_CHAIN (attributes)) pp_separate_with (pp, ','); } pp_c_right_paren (pp); pp_c_right_paren (pp); }
void genrtl_case_label (tree case_label) { tree duplicate; tree cleanup; cleanup = last_cleanup_this_contour (); if (cleanup) { static int explained = 0; warning ("destructor needed for `%D'", (TREE_PURPOSE (cleanup))); warning ("where case label appears here"); if (!explained) { warning ("(enclose actions of previous case statements requiring destructors in their own scope.)"); explained = 1; } } add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label), CASE_LABEL_DECL (case_label), &duplicate); }
static void lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data) { tree stmt = tsi_stmt (*tsi); tree value, t, label; /* Extract the value being returned. */ value = TREE_OPERAND (stmt, 0); if (value && TREE_CODE (value) == MODIFY_EXPR) value = TREE_OPERAND (value, 1); /* Match this up with an existing return statement that's been created. */ for (t = data->return_statements; t ; t = TREE_CHAIN (t)) { tree tvalue = TREE_OPERAND (TREE_VALUE (t), 0); if (tvalue && TREE_CODE (tvalue) == MODIFY_EXPR) tvalue = TREE_OPERAND (tvalue, 1); if (value == tvalue) { label = TREE_PURPOSE (t); goto found; } } /* Not found. Create a new label and record the return statement. */ label = create_artificial_label (); data->return_statements = tree_cons (label, stmt, data->return_statements); /* Generate a goto statement and remove the return statement. */ found: t = build (GOTO_EXPR, void_type_node, label); SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt)); tsi_link_before (tsi, t, TSI_SAME_STMT); tsi_delink (tsi); }
static bool pp_c_enumeration_constant (c_pretty_printer *pp, tree e) { bool value_is_named = true; tree type = TREE_TYPE (e); tree value; /* Find the name of this constant. */ for (value = TYPE_VALUES (type); value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e); value = TREE_CHAIN (value)) ; if (value != NULL_TREE) pp_id_expression (pp, TREE_PURPOSE (value)); else { /* Value must have been cast. */ pp_c_type_cast (pp, type); value_is_named = false; } return value_is_named; }
static void merge_lock_attr_args (tree attr, tree additional_args) { tree identifier = TREE_PURPOSE (attr); if (is_attribute_p ("acquired_after", identifier) || is_attribute_p ("acquired_before", identifier) || is_attribute_p ("exclusive_lock", identifier) || is_attribute_p ("shared_lock", identifier) || is_attribute_p ("exclusive_trylock", identifier) || is_attribute_p ("shared_trylock", identifier) || is_attribute_p ("unlock", identifier) || is_attribute_p ("exclusive_locks_required", identifier) || is_attribute_p ("shared_locks_required", identifier) || is_attribute_p ("locks_excluded", identifier)) TREE_VALUE (attr) = chainon (TREE_VALUE (attr), additional_args); /* We don't allow the following lock attributes to appear multiple times on a decl. */ else if (is_attribute_p ("guarded_by", identifier) || is_attribute_p ("point_to_guarded_by", identifier) || is_attribute_p ("lock_returned", identifier)) warning (OPT_Wattributes, "Additional %qs attribute ignored", IDENTIFIER_POINTER (identifier)); }
tree build_lambda_object (tree lambda_expr) { /* Build aggregate constructor call. - cp_parser_braced_list - cp_parser_functional_cast */ vec<constructor_elt, va_gc> *elts = NULL; tree node, expr, type; location_t saved_loc; if (processing_template_decl) return lambda_expr; /* Make sure any error messages refer to the lambda-introducer. */ saved_loc = input_location; input_location = LAMBDA_EXPR_LOCATION (lambda_expr); for (node = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); node; node = TREE_CHAIN (node)) { tree field = TREE_PURPOSE (node); tree val = TREE_VALUE (node); if (field == error_mark_node) { expr = error_mark_node; goto out; } if (DECL_P (val)) mark_used (val); /* Mere mortals can't copy arrays with aggregate initialization, so do some magic to make it work here. */ if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE) val = build_array_copy (val); else if (DECL_NORMAL_CAPTURE_P (field) && !DECL_VLA_CAPTURE_P (field) && TREE_CODE (TREE_TYPE (field)) != REFERENCE_TYPE) { /* "the entities that are captured by copy are used to direct-initialize each corresponding non-static data member of the resulting closure object." There's normally no way to express direct-initialization from an element of a CONSTRUCTOR, so we build up a special TARGET_EXPR to bypass the usual copy-initialization. */ val = force_rvalue (val, tf_warning_or_error); if (TREE_CODE (val) == TARGET_EXPR) TARGET_EXPR_DIRECT_INIT_P (val) = true; } CONSTRUCTOR_APPEND_ELT (elts, DECL_NAME (field), val); } expr = build_constructor (init_list_type_node, elts); CONSTRUCTOR_IS_DIRECT_INIT (expr) = 1; /* N2927: "[The closure] class type is not an aggregate." But we briefly treat it as an aggregate to make this simpler. */ type = LAMBDA_EXPR_CLOSURE (lambda_expr); CLASSTYPE_NON_AGGREGATE (type) = 0; expr = finish_compound_literal (type, expr, tf_warning_or_error); CLASSTYPE_NON_AGGREGATE (type) = 1; out: input_location = saved_loc; return expr; }
static const char * gen_type (const char *ret_val, tree t, formals_style style) { tree chain_p; /* If there is a typedef name for this type, use it. */ if (TYPE_NAME (t) && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL) data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); else { switch (TREE_CODE (t)) { case POINTER_TYPE: if (TYPE_READONLY (t)) ret_val = concat ("const ", ret_val, NULL); if (TYPE_VOLATILE (t)) ret_val = concat ("volatile ", ret_val, NULL); ret_val = concat ("*", ret_val, NULL); if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) ret_val = concat ("(", ret_val, ")", NULL); ret_val = gen_type (ret_val, TREE_TYPE (t), style); return ret_val; case ARRAY_TYPE: if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) ret_val = gen_type (concat (ret_val, "[]", NULL), TREE_TYPE (t), style); else if (int_size_in_bytes (t) == 0) ret_val = gen_type (concat (ret_val, "[0]", NULL), TREE_TYPE (t), style); else { int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); char buff[10]; sprintf (buff, "[%d]", size); ret_val = gen_type (concat (ret_val, buff, NULL), TREE_TYPE (t), style); } break; case FUNCTION_TYPE: ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style), NULL), TREE_TYPE (t), style); break; case IDENTIFIER_NODE: data_type = IDENTIFIER_POINTER (t); break; /* The following three cases are complicated by the fact that a user may do something really stupid, like creating a brand new "anonymous" type specification in a formal argument list (or as part of a function return type specification). For example: int f (enum { red, green, blue } color); In such cases, we have no name that we can put into the prototype to represent the (anonymous) type. Thus, we have to generate the whole darn type specification. Yuck! */ case RECORD_TYPE: if (TYPE_NAME (t)) data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); else { data_type = ""; chain_p = TYPE_FIELDS (t); while (chain_p) { data_type = concat (data_type, gen_decl (chain_p, 0, ansi), NULL); chain_p = TREE_CHAIN (chain_p); data_type = concat (data_type, "; ", NULL); } data_type = concat ("{ ", data_type, "}", NULL); } data_type = concat ("struct ", data_type, NULL); break; case UNION_TYPE: if (TYPE_NAME (t)) data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); else { data_type = ""; chain_p = TYPE_FIELDS (t); while (chain_p) { data_type = concat (data_type, gen_decl (chain_p, 0, ansi), NULL); chain_p = TREE_CHAIN (chain_p); data_type = concat (data_type, "; ", NULL); } data_type = concat ("{ ", data_type, "}", NULL); } data_type = concat ("union ", data_type, NULL); break; case ENUMERAL_TYPE: if (TYPE_NAME (t)) data_type = IDENTIFIER_POINTER (TYPE_NAME (t)); else { data_type = ""; chain_p = TYPE_VALUES (t); while (chain_p) { data_type = concat (data_type, IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL); chain_p = TREE_CHAIN (chain_p); if (chain_p) data_type = concat (data_type, ", ", NULL); } data_type = concat ("{ ", data_type, " }", NULL); } data_type = concat ("enum ", data_type, NULL); break; case TYPE_DECL: data_type = IDENTIFIER_POINTER (DECL_NAME (t)); break; case INTEGER_TYPE: data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); /* Normally, `unsigned' is part of the deal. Not so if it comes with a type qualifier. */ if (TYPE_UNSIGNED (t) && TYPE_QUALS (t)) data_type = concat ("unsigned ", data_type, NULL); break; case REAL_TYPE: data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t))); break; case VOID_TYPE: data_type = "void"; break; case ERROR_MARK: data_type = "[ERROR]"; break; default: gcc_unreachable (); } } if (TYPE_READONLY (t)) ret_val = concat ("const ", ret_val, NULL); if (TYPE_VOLATILE (t)) ret_val = concat ("volatile ", ret_val, NULL); if (TYPE_RESTRICT (t)) ret_val = concat ("restrict ", ret_val, NULL); return ret_val; }