8sa1-gcc/gcc/print-tree.c
Diego Novillo 953ff28998 [multiple changes]
2006-01-18  Richard Henderson  <rth@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

	* libgomp: New directory.
	* Makefile.def: Add target_module libgomp.
	* Makefile.in: Regenerate.
	* configure.in (target_libraries): Add target-libgomp.
	* configure: Regenerate.


contrib/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

	* gcc_update (files_and_dependencies): Add libgomp files.


gcc/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Aldy Hernandez  <aldyh@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

	* omp-low.c: New file.
	* c-omp.c: New file.

2006-01-18  Richard Henderson  <rth@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

	* doc/invoke.texi: Document -fopenmp.
	* tree-dump.h (debug_function): Declare.

	* hooks.c (hook_bool_tree_bool_false): New function.
	(hook_tree_tree_null): Remove.
	(hook_tree_tree_tree_null): New.
	* hooks.h: Update to match.

	* tree-pretty-print.c (debug_tree_chain): New.
	(print_generic_expr): Handle TDF_CHAIN.
	(dump_generic_node): Handle BLOCK.
	Do not abort with incomplete SWITCH_EXPRs.
	Do not dump body of an OpenMP directive if TDF_SLIM is given.
	<case OMP_PARALLEL, OMP_FOR, OMP_SECTIONS>: Don't
	print space after directive name.
	<OMP_FOR>: Handle printing OMP_FOR_PRE_BODY.
	Handle OMP_MASTER and OMP_ORDERED.
	Handle printing of OMP_BODY just in one place, goto
	dump_omp_body in the rest of OMP_* nodes that have
	OMP_BODY.
	Don't handle clause nodes here.  Update omp statements to
	use dump_omp_clauses.
	Handle OMP_SINGLE, OMP_SECTIONS, OMP_SECTION,
	OMP_CLAUSE_ORDERED, OMP_CLAUSE_SCHEDULE, OMP_ATOMIC,
	OMP_CRITICAL, OMP_CLAUSE_NOWAIT, GOMP_CLAUSE_IF,
	GOMP_CLAUSE_NUM_THREADS, GOMP_FOR, GOMP_CLAUSE_SHARED,
	GOMP_CLAUSE_FIRSTPRIVATE, GOMP_CLAUSE_LASTPRIVATE,
	GOMP_CLAUSE_COPYIN and GOMP_CLAUSE_COPYPRIVATE.
	Adjust output for GOMP_PARALLEL.
	(dump_omp_clauses): New.
	(print_declaration): Dump DECL_VALUE_EXPR.
	(op_symbol_1): Split out of op_symbol.
	(dumping_stmts): Remove.  Update all users.

	* cgraph.c (cgraph_analyze_queue): New.
	(cgraph_add_new_function): New.
	* cgraph.h (cgraph_analyze_queue): Declare.
	(cgraph_add_new_function): Declare.
	(cgraph_lower_function): Remove.

	* tree.c (walk_tree): Walk OMP_CLAUSE_CHAIN of OMP_CLAUSE_*
	nodes.  Use switch for all nodes, handle most of IS_EXPR_CODE_CLASS
	and TYPE_P nodes in its default clause.
	(empty_body_p): New.
	(tree_range_check_failed): New.
	(build5_stat): New.

	* tree.h (OMP_CLAUSE_REDUCTION_INIT,
	OMP_CLAUSE_REDUCTION_MERGE,
	OMP_CLAUSE_REDUCTION_PLACEHOLDER,
	OMP_CLAUSE_PRIVATE_DEBUG,
	OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE, OMP_FOR_PRE_BODY,
	OMP_MASTER_BODY, OMP_ORDERED_BODY OMP_BODY,
	OMP_CLAUSES, OMP_CLAUSE_DECL, OMP_CLAUSE_DEFAULT_KIND,
	OMP_CLAUSE_CHAIN, OMP_CLAUSE_OUTER_DECL,
	OMP_CLAUSE_INNER_DECL, OMP_CLAUSE_NUM_THREADS_EXPR,
	OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR,
	OMP_CLAUSE_SCHEDULE_CHUNK_SIZE. OMP_PARALLEL_VAR_INIT,
	OMP_PARALLEL_VAR_REDUC, OMP_FOR_VAR_INIT,
	OMP_FOR_VAR_LAST, OMP_FOR_VAR_REDUC,
	OMP_SECTIONS_VAR_INIT, OMP_SECTIONS_VAR_LAST,
	OMP_SECTIONS_VAR_REDUC, OMP_CLAUSE_REDUCTION_CODE
	OMP_SINGLE_CLAUSES, OMP_SINGLE_BODY,
	OMP_CLAUSE_SCHEDULE_CHUNK_SIZE, OMP_SECTION_BODY,
	OMP_CRITICAL_NAME, OMP_CRITICAL_BODY): New.
	(TREE_RANGE_CHECK): New.
	(empty_body_p): Declare.
	(enum omp_clause_default_kind): New.
	(build_string_literal): Declare.
	(enum omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_KIND): New.
	(build5_stat, build5): Declare.

	* tree-pass.h (TDF_CHAIN): Define.
	* tree-pass.h (PROP_gimple_lomp): Define.
	(pass_lower_omp): Declare.

	* diagnostic.h (debug_tree_chain): Declare.

	* builtins.c (get_builtin_sync_mode): Use 0 as last argument to
	mode_for_size.
	(expand_builtin): Handle sync BUILT_IN_*_16 builtins.
	* builtins.c (build_string_literal): Make extern.

	* gcc.c (include_spec_function): New.
	(static_spec_functions): Add it.
	(main): Move load of libgomp.spec ...
	(LINK_COMMAND_SPEC): ... here.
	(link_gomp_spec): New.
	(static_specs): Include it.
	(LINK_COMMAND_SPEC): Add link_gomp.
	(GOMP_SELF_SPECS): New.
	(driver_self_specs): Include it.
	(switch_matches): Don't mark inline.
	(main): Load libgomp.spec.

	* tree-gimple.c (is_gimple_stmt): True for OMP_MASTER,
	OMP_ORDERED, OMP_CRITICAL, OMP_SECTIONS, OMP_SECTION,
	and OMP_SINGLE, OMP_FOR and OMP_PARALLEL.

	* tree-gimple.h (enum omp_parallel): Declare.
	(determine_parallel_type): Declare.
	(omp_firstprivatize_variable): Declare.
	(omp_reduction_init): Declare.
	(diagnose_omp_structured_block_errors): Declare.
	(struct walk_stmt_info): Add want_return_expr.
	(struct walk_stmt_info): Add want_bind_expr, want_locations.
	(find_omp_clause): Declare.
	(insert_field_into_struct): Declare.
	(struct walk_stmt_info): Move from tree-nested.c
	(walk_stmts): Declare.

	* c-cppbuiltin.c (c_cpp_builtins): If -fopenmp, #define _OPENMP
	to 200505.

	* cgraphunit.c (cgraph_lower_function): Make static.
	(cgraph_finalize_pending_functions): New.
	(cgraph_finalize_function): Call it.
	(cgraph_finalize_compilation_unit): Likewise.

	* builtin-types.def (BT_I16, BT_FN_I16_VPTR_I16,
	BT_FN_BOOL_VPTR_I16_I16, BT_FN_I16_VPTR_I16_I16): Add.
	(BT_FN_UINT_UINT): New.
	(DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7,
	DEF_FUNCTION_TYPE_VAR_4): Document.
	(BT_PTR_LONG, BT_PTR_PTR, BT_FN_BOOL, BT_FN_INT,
	BT_FN_VOID_PTRPTR, BT_PTR_FN_VOID_PTR,
	BT_FN_BOOL_LONGPTR_LONGPTR, BT_FN_VOID_OMPFN_PTR_UINT,
	BT_FN_VOID_OMPFN_PTR_UINT_UINT,
	BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
	BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
	BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG): New.

	* builtins.def: Update DEF_BUILTIN comment to include COND argument.
	Move all DEF_SYNC_BUILTIN () and DEF_GOMP_BUILTIN () builtins
	into separate files.
	(DEF_GOMP_BUILTIN): New.
	(BUILT_IN_OMP_GET_THREAD_NUM, BUILT_IN_GOMP_BARRIER,
	BUILT_IN_GOMP_CRITICAL_START, BUILT_IN_GOMP_CRITICAL_END,
	BUILT_IN_GOMP_CRITICAL_NAME_START, BUILT_IN_GOMP_CRITICAL_NAME_END,
	BUILT_IN_GOMP_LOOP_STATIC_START, BUILT_IN_GOMP_LOOP_DYNAMIC_START,
	BUILT_IN_GOMP_LOOP_GUIDED_START, BUILT_IN_GOMP_LOOP_RUNTIME_START,
	BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
	BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_START,
	BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_START,
	BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_START,
	BUILT_IN_GOMP_LOOP_STATIC_NEXT, BUILT_IN_GOMP_LOOP_DYNAMIC_NEXT,
	BUILT_IN_GOMP_LOOP_GUIDED_NEXT, BUILT_IN_GOMP_LOOP_RUNTIME_NEXT,
	BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
	BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_NEXT,
	BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_NEXT,
	BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_NEXT,
	BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
	BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
	BUILT_IN_GOMP_LOOP_END, BUILT_IN_GOMP_LOOP_END_NOWAIT,
	BUILT_IN_GOMP_ORDERED_START, BUILT_IN_GOMP_ORDERED_END,
	BUILT_IN_GOMP_PARALLEL_START, BUILT_IN_GOMP_PARALLEL_END,
	BUILT_IN_GOMP_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_NEXT,
	BUILT_IN_GOMP_PARALLEL_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_END,
	BUILT_IN_GOMP_SECTIONS_END_NOWAIT, BUILT_IN_GOMP_SINGLE_START,
	BUILT_IN_GOMP_SINGLE_COPY_START, BUILT_IN_GOMP_SINGLE_COPY_END): New.
	* sync-builtins.def: New file, moved from builtins.def.
	* omp-builtins.def: New file, moved from builtins.def.

	* c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_SHARING): Redefine.

	* gimple-low.c (lower_function_body): Clear data.
	(lower_stmt): Do not handle COMPOUND_EXPR.
	Remove call to print_node_brief.

	* c-tree.h (c_finish_omp_clauses): New prototype.
	(C_DECL_THREADPRIVATE_P): Define.
	(lookup_name_no_remap, c_omp_remap_private): Remove
	(c_begin_omp_parallel, c_finish_omp_parallel): Update.
	(check_for_loop_decls): Update decl.
	(lookup_name_no_remap, c_omp_remap_private): Declare.
	(build_indirect_ref, build_modify_expr, pushdecl,
	pushdecl_top_level): Move to c-common.h.

	* dwarf2out.c (loc_descriptor_from_tree_1): Don't set unsignedp
	before the switch, but just in the 2 places that need it.

	* c-decl.c (diagnose_mismatched_decls): Do not check for
	mismatched thread-local attributes when OLDDECL is marked
	threadprivate and NEWDECL has no thread-local attributes.
	(merge_decls): Merge C_DECL_THREADPRIVATE_P.
	(c_gimple_diagnostics_recursively): Rename from
	c_warn_unused_result_recursively.  Invoke
	diagnose_omp_structured_block_errors.
	(check_for_loop_decls): Return a singular decl found.

	* langhooks.c (lhd_omp_predetermined_sharing): Return
	OMP_CLAUSE_DEFAULT_SHARED for DECL_ARTIFICIAL decls.
	(lhd_omp_firstprivatize_type_sizes): New.
	(lhd_omp_assignment): New.
	(lhd_omp_predetermined_sharing): New.

	* langhooks.h (struct gimplify_omp_ctx): Forward declare.
	(struct lang_hooks_for_types): Add
	omp_firstprivatize_type_sizes, omp_privatize_by_reference,
	omp_predetermined_sharing, omp_disregard_value_expr,
	omp_private_debug_clause, omp_clause_default_ctor,
	omp_clause_copy_ctor, omp_clause_assign_op, omp_clause_dtor.

	(c_finish_omp_clauses): New.
	(c_finish_bc_stmt): Diagnose break within omp for.
	(c_begin_omp_parallel, c_finish_omp_parallel): New.
	(build_unary_op): Return error_mark after reporting
	a readonly_error.
	(build_modify_expr): Likewise.

	* gimplify.c: Include optabs.h and pointer-set.h.
	(enum gimplify_omp_var_data): Declare.
	(struct gimplify_omp_ctx): Declare.
	(struct gimplify_ctx): Add fields prev_context, combined_pre_p
	and combined_ctxp.
	(gimplify_ctxp, gimplify_omp_ctxp): New local variables.
	(push_gimplify_context, pop_gimplify_context): Allow nesting.
	(splay_tree_compare_decl_uid): New.
	(new_omp_context): New.
	(delete_omp_context): New.
	(gimple_add_tmp_var): Call omp_add_variable.
	(gimplify_bind_expr): Likewise.
	(gimplify_var_or_parm_decl): If omp_notice_variable returned
	true, disregard DECL_VALUE_EXPR on the decl if any.
	(gimplify_expr_in_ctx): New.
	(omp_firstprivatize_variable, omp_firstprivatize_type_sizes
	omp_add_variable, omp_notice_variable, omp_is_private
	gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses_1
	gimplify_adjust_omp_clauses, gimplify_omp_parallel
	gimplify_omp_for, gimplify_omp_workshare, goa_lhs_expr_p
	gimplify_omp_atomic_fetch_op, goa_stabilize_expr
	gimplify_omp_atomic_pipeline, gimplify_omp_atomic_mutex
	gimplify_omp_atomic): New.
	(gimplify_expr): Handle OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
	OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
	OMP_CRITICAL and OMP_ATOMIC.
	(gimplify_body): Verify gimplify_ctxp is empty after gimplification.

	* c-pragma.h (enum pragma_kind): Add
	PRAGMA_OMP_ATOMIC, PRAGMA_OMP_BARRIER,
	PRAGMA_OMP_CRITICAL, PRAGMA_OMP_FLUSH, PRAGMA_OMP_FOR,
	PRAGMA_OMP_MASTER, PRAGMA_OMP_ORDERED,
	PRAGMA_OMP_PARALLEL, PRAGMA_OMP_PARALLEL_FOR,
	PRAGMA_OMP_PARALLEL_SECTIONS, PRAGMA_OMP_SECTION,
	PRAGMA_OMP_SECTIONS, PRAGMA_OMP_SINGLE,
	PRAGMA_OMP_THREADPRIVATE.

	* tree.def (OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
	OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
	OMP_CRITICAL, OMP_ATOMIC, OMP_CLAUSE_PRIVATE,
	OMP_CLAUSE_SHARED, OMP_CLAUSE_FIRSTPRIVATE,
	OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_REDUCTION,
	OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE,
	OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS,
	OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_NOWAIT,
	OMP_CLAUSE_ORDERED, OMP_CLAUSE_DEFAULT): Define.

	* print-tree.c (print_node): Dump DECL_VALUE_EXPR.

	* tree-ssa-dce.c (find_control_dependence): Do not assume that
	ENTRY_BLOCK_PTR->next_bb == single_succ (ENTRY_BLOCK_PTR).

	* tree-nested.c (convert_call_expr): Call walk_body on OMP_BODY for
	OpenMP directives.
	(struct nesting_info): Add field_map,
	suppress_expansion, debug_var_chain.
	(create_nesting_tree): Initialize them.
	(lookup_field_for_decl): Use field_map.
	(get_nonlocal_debug_decl, get_local_debug_decl): New.
	(convert_local_omp_clauses): New.
	(finalize_nesting_tree_1): Add debug_var_chain to toplevel block.
	(walk_body): Split out of walk_function.
	(convert_nonlocal_omp_clauses, convert_local_omp_clauses): New.
	(convert_nonlocal_reference): Handle omp statements.
	(convert_local_reference): Likewise.
	(unnest_nesting_tree_1): Split out of finalize_nesting_tree_1.
	(unnest_nesting_tree): New.
	(lower_nested_functions): Call it.
	(insert_field_into_struct): Make extern.
	(struct walk_stmt_info): Move to tree-gimple.h.
	(walk_stmts): Make extern.

	* omp-builtins.def: New file.

	* tree-iterator.c (expr_only): Clarify comment.

	* c-common.h (pushdecl_top_level, pushdecl,
	build_modify_expr, build_indirect_ref,
	c_finish_omp_master, c_finish_omp_critical,
	c_finish_omp_ordered, c_finish_omp_barrier,
	c_finish_omp_atomic, c_finish_omp_flush,
	c_finish_omp_for, c_split_parallel_clauses,
	omp_clause_default_kind, c_omp_sharing_predetermined,
	c_omp_remap_decl): Declare.

	* Makefile.in (BUILTINS_DEF): Add omp-builtins.def.
	(OBJS-common): Add omp-low.o.
	(c-omp.o, omp-low.o): Add.
	(gimplify.o): Add dependency on $(OPTABS_H).
	(GTFILES): Add omp-low.c.
	(gt-stringpool.h): Add.

	* tree-cfg.c (set_bb_for_stmt): Do not update the
	block-to-labels map if we are currently expanding to RTL.
	(tree_node_can_be_shared): Remove unnecessary CONSTANT_CLASS_P
	checks.
	Handle IDENTIFIER_NODE.
	(tree_verify_flow_info): Do not ICE when emitting error
	messages about invalid labels.
	(dump_function_to_file): Reset CFUN before emitting the body
	of the function.
	(debug_function): New.

	* passes.c (init_optimization_passes): Schedule
	pass_lower_omp.

	* langhooks-def.h (lhd_omp_predetermined_sharing,
	lhd_omp_assignment, lhd_omp_firstprivatize_type_sizes):
	Declare.
	(LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES): Define.
	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it.
	(LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE,
	LANG_HOOKS_OMP_PREDETERMINED_SHARING,
	LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR,
	LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE,
	LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR,
	LANG_HOOKS_OMP_CLAUSE_COPY_CTOR,
	LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP,
	LANG_HOOKS_OMP_CLAUSE_DTOR): Define.
	(LANG_HOOK_DECLS): Use them.


2006-01-18  Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
	    Richard Henderson  <rth@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

	* c-parser.c (pragma_omp_clause): Define.
	(c_parser_declaration_or_fndef): Document OpenMP syntax.
	(c_parser_compound_statement): Likewise.
	(c_parser_statement): Likewise.
	(c_parser_pragma): Handle omp pragmas.
	(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
	OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK): Define.
	(c_parser_omp_clause_name, check_no_duplicate_clause,
	c_parser_omp_variable_list,
	c_parser_omp_var_list_parens, c_parser_omp_clause_copyin,
	c_parser_omp_clause_copyprivate,
	c_parser_omp_clause_default,
	c_parser_omp_clause_firstprivate, c_parser_omp_clause_if,
	c_parser_omp_clause_lastprivate,
	c_parser_omp_clause_nowait,
	c_parser_omp_clause_num_threads,
	c_parser_omp_clause_ordered, c_parser_omp_clause_private,
	c_parser_omp_clause_reduction,
	c_parser_omp_clause_schedule, c_parser_omp_clause_shared,
	c_parser_omp_all_clauses, c_parser_omp_structured_block,
	c_parser_omp_atomic, c_parser_omp_barrier,
	c_parser_omp_critical, c_parser_omp_flush,
	c_parser_omp_for_loop, c_parser_omp_for,
	c_parser_omp_master, c_parser_omp_ordered,
	c_parser_omp_sections_scope, c_parser_omp_sections,
	c_parser_omp_parallel, c_parser_omp_single,
	c_parser_omp_construct, c_parser_omp_threadprivate): New.
	* c-pragma.c (init_pragma): Do omp pragma registration here.
	* c.opt (fopenmp): New flag.


2006-01-18  Eric Christopher  <echristo@apple.com>

	* gcc.c (GOMP_SELF_SPECS): Bracket in #ifndef/#endif.
	* config/darwin.h (GOMP_SELF_SPECS): Define.


testsuite/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Aldy Hernandez  <aldyh@redhat.com>
	    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>
            Uros Bizjak  <uros@kss-loka.si>

	* testsuite/gcc.dg/gomp: New directory.

From-SVN: r109902
2006-01-18 14:21:25 -05:00

846 lines
24 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Prints out tree in human readable form - GCC
Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "real.h"
#include "ggc.h"
#include "langhooks.h"
#include "tree-iterator.h"
/* Define the hash table of nodes already seen.
Such nodes are not repeated; brief cross-references are used. */
#define HASH_SIZE 37
struct bucket
{
tree node;
struct bucket *next;
};
static struct bucket **table;
/* Print the node NODE on standard error, for debugging.
Most nodes referred to by this one are printed recursively
down to a depth of six. */
void
debug_tree (tree node)
{
table = xcalloc (HASH_SIZE, sizeof (struct bucket *));
print_node (stderr, "", node, 0);
free (table);
table = 0;
putc ('\n', stderr);
}
/* Print a node in brief fashion, with just the code, address and name. */
void
print_node_brief (FILE *file, const char *prefix, tree node, int indent)
{
enum tree_code_class class;
if (node == 0)
return;
class = TREE_CODE_CLASS (TREE_CODE (node));
/* Always print the slot this node is in, and its code, address and
name if any. */
if (indent > 0)
fprintf (file, " ");
fprintf (file, "%s <%s %p",
prefix, tree_code_name[(int) TREE_CODE (node)], (char *) node);
if (class == tcc_declaration)
{
if (DECL_NAME (node))
fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
else if (TREE_CODE (node) == LABEL_DECL
&& LABEL_DECL_UID (node) != -1)
fprintf (file, " L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
else
fprintf (file, " %c.%u", TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
DECL_UID (node));
}
else if (class == tcc_type)
{
if (TYPE_NAME (node))
{
if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
&& DECL_NAME (TYPE_NAME (node)))
fprintf (file, " %s",
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
}
}
if (TREE_CODE (node) == IDENTIFIER_NODE)
fprintf (file, " %s", IDENTIFIER_POINTER (node));
/* We might as well always print the value of an integer or real. */
if (TREE_CODE (node) == INTEGER_CST)
{
if (TREE_CONSTANT_OVERFLOW (node))
fprintf (file, " overflow");
fprintf (file, " ");
if (TREE_INT_CST_HIGH (node) == 0)
fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
else if (TREE_INT_CST_HIGH (node) == -1
&& TREE_INT_CST_LOW (node) != 0)
fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
-TREE_INT_CST_LOW (node));
else
fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
}
if (TREE_CODE (node) == REAL_CST)
{
REAL_VALUE_TYPE d;
if (TREE_OVERFLOW (node))
fprintf (file, " overflow");
d = TREE_REAL_CST (node);
if (REAL_VALUE_ISINF (d))
fprintf (file, " Inf");
else if (REAL_VALUE_ISNAN (d))
fprintf (file, " Nan");
else
{
char string[60];
real_to_decimal (string, &d, sizeof (string), 0, 1);
fprintf (file, " %s", string);
}
}
fprintf (file, ">");
}
void
indent_to (FILE *file, int column)
{
int i;
/* Since this is the long way, indent to desired column. */
if (column > 0)
fprintf (file, "\n");
for (i = 0; i < column; i++)
fprintf (file, " ");
}
/* Print the node NODE in full on file FILE, preceded by PREFIX,
starting in column INDENT. */
void
print_node (FILE *file, const char *prefix, tree node, int indent)
{
int hash;
struct bucket *b;
enum machine_mode mode;
enum tree_code_class class;
int len;
int i;
expanded_location xloc;
enum tree_code code;
if (node == 0)
return;
code = TREE_CODE (node);
class = TREE_CODE_CLASS (code);
/* Don't get too deep in nesting. If the user wants to see deeper,
it is easy to use the address of a lowest-level node
as an argument in another call to debug_tree. */
if (indent > 24)
{
print_node_brief (file, prefix, node, indent);
return;
}
if (indent > 8 && (class == tcc_type || class == tcc_declaration))
{
print_node_brief (file, prefix, node, indent);
return;
}
/* It is unsafe to look at any other fields of an ERROR_MARK node. */
if (TREE_CODE (node) == ERROR_MARK)
{
print_node_brief (file, prefix, node, indent);
return;
}
hash = ((unsigned long) node) % HASH_SIZE;
/* If node is in the table, just mention its address. */
for (b = table[hash]; b; b = b->next)
if (b->node == node)
{
print_node_brief (file, prefix, node, indent);
return;
}
/* Add this node to the table. */
b = xmalloc (sizeof (struct bucket));
b->node = node;
b->next = table[hash];
table[hash] = b;
/* Indent to the specified column, since this is the long form. */
indent_to (file, indent);
/* Print the slot this node is in, and its code, and address. */
fprintf (file, "%s <%s %p",
prefix, tree_code_name[(int) TREE_CODE (node)], (void *) node);
/* Print the name, if any. */
if (class == tcc_declaration)
{
if (DECL_NAME (node))
fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node)));
else if (TREE_CODE (node) == LABEL_DECL
&& LABEL_DECL_UID (node) != -1)
fprintf (file, " L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
else
fprintf (file, " %c.%u", TREE_CODE (node) == CONST_DECL ? 'C' : 'D',
DECL_UID (node));
}
else if (class == tcc_type)
{
if (TYPE_NAME (node))
{
if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node)));
else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
&& DECL_NAME (TYPE_NAME (node)))
fprintf (file, " %s",
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
}
}
if (TREE_CODE (node) == IDENTIFIER_NODE)
fprintf (file, " %s", IDENTIFIER_POINTER (node));
if (TREE_CODE (node) == INTEGER_CST)
{
if (indent <= 4)
print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
}
else
{
print_node (file, "type", TREE_TYPE (node), indent + 4);
if (TREE_TYPE (node))
indent_to (file, indent + 3);
}
if (!TYPE_P (node) && TREE_SIDE_EFFECTS (node))
fputs (" side-effects", file);
if (TYPE_P (node) ? TYPE_READONLY (node) : TREE_READONLY (node))
fputs (" readonly", file);
if (!TYPE_P (node) && TREE_CONSTANT (node))
fputs (" constant", file);
else if (TYPE_P (node) && TYPE_SIZES_GIMPLIFIED (node))
fputs (" sizes-gimplified", file);
if (TREE_INVARIANT (node))
fputs (" invariant", file);
if (TREE_ADDRESSABLE (node))
fputs (" addressable", file);
if (TREE_THIS_VOLATILE (node))
fputs (" volatile", file);
if (TREE_ASM_WRITTEN (node))
fputs (" asm_written", file);
if (TREE_USED (node))
fputs (" used", file);
if (TREE_NOTHROW (node))
fputs (TYPE_P (node) ? " align-ok" : " nothrow", file);
if (TREE_PUBLIC (node))
fputs (" public", file);
if (TREE_PRIVATE (node))
fputs (" private", file);
if (TREE_PROTECTED (node))
fputs (" protected", file);
if (TREE_STATIC (node))
fputs (" static", file);
if (TREE_DEPRECATED (node))
fputs (" deprecated", file);
if (TREE_VISITED (node))
fputs (" visited", file);
if (TREE_LANG_FLAG_0 (node))
fputs (" tree_0", file);
if (TREE_LANG_FLAG_1 (node))
fputs (" tree_1", file);
if (TREE_LANG_FLAG_2 (node))
fputs (" tree_2", file);
if (TREE_LANG_FLAG_3 (node))
fputs (" tree_3", file);
if (TREE_LANG_FLAG_4 (node))
fputs (" tree_4", file);
if (TREE_LANG_FLAG_5 (node))
fputs (" tree_5", file);
if (TREE_LANG_FLAG_6 (node))
fputs (" tree_6", file);
/* DECL_ nodes have additional attributes. */
switch (TREE_CODE_CLASS (TREE_CODE (node)))
{
case tcc_declaration:
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
if (DECL_UNSIGNED (node))
fputs (" unsigned", file);
if (DECL_IGNORED_P (node))
fputs (" ignored", file);
if (DECL_ABSTRACT (node))
fputs (" abstract", file);
if (DECL_EXTERNAL (node))
fputs (" external", file);
if (DECL_NONLOCAL (node))
fputs (" nonlocal", file);
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
if (DECL_WEAK (node))
fputs (" weak", file);
if (DECL_IN_SYSTEM_HEADER (node))
fputs (" in_system_header", file);
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)
&& TREE_CODE (node) != LABEL_DECL
&& TREE_CODE (node) != FUNCTION_DECL
&& DECL_REGISTER (node))
fputs (" regdecl", file);
if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
fputs (" suppress-debug", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
fputs (" built-in", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
fputs (" no-static-chain", file);
if (TREE_CODE (node) == FIELD_DECL && DECL_PACKED (node))
fputs (" packed", file);
if (TREE_CODE (node) == FIELD_DECL && DECL_BIT_FIELD (node))
fputs (" bit-field", file);
if (TREE_CODE (node) == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
fputs (" nonaddressable", file);
if (TREE_CODE (node) == LABEL_DECL && DECL_ERROR_ISSUED (node))
fputs (" error-issued", file);
if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
fputs (" in-text-section", file);
if (TREE_CODE (node) == VAR_DECL && DECL_COMMON (node))
fputs (" common", file);
if (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL_P (node))
{
enum tls_model kind = DECL_TLS_MODEL (node);
switch (kind)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
fputs (" tls-global-dynamic", file);
break;
case TLS_MODEL_LOCAL_DYNAMIC:
fputs (" tls-local-dynamic", file);
break;
case TLS_MODEL_INITIAL_EXEC:
fputs (" tls-initial-exec", file);
break;
case TLS_MODEL_LOCAL_EXEC:
fputs (" tls-local-exec", file);
break;
default:
gcc_unreachable ();
}
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
if (DECL_VIRTUAL_P (node))
fputs (" virtual", file);
if (DECL_PRESERVE_P (node))
fputs (" preserve", file);
if (DECL_LANG_FLAG_0 (node))
fputs (" decl_0", file);
if (DECL_LANG_FLAG_1 (node))
fputs (" decl_1", file);
if (DECL_LANG_FLAG_2 (node))
fputs (" decl_2", file);
if (DECL_LANG_FLAG_3 (node))
fputs (" decl_3", file);
if (DECL_LANG_FLAG_4 (node))
fputs (" decl_4", file);
if (DECL_LANG_FLAG_5 (node))
fputs (" decl_5", file);
if (DECL_LANG_FLAG_6 (node))
fputs (" decl_6", file);
if (DECL_LANG_FLAG_7 (node))
fputs (" decl_7", file);
mode = DECL_MODE (node);
fprintf (file, " %s", GET_MODE_NAME (mode));
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS) && DECL_DEFER_OUTPUT (node))
fputs (" defer-output", file);
xloc = expand_location (DECL_SOURCE_LOCATION (node));
fprintf (file, " file %s line %d", xloc.file, xloc.line);
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
print_node (file, "size", DECL_SIZE (node), indent + 4);
print_node (file, "unit size", DECL_SIZE_UNIT (node), indent + 4);
if (TREE_CODE (node) != FUNCTION_DECL
|| DECL_INLINE (node) || DECL_BUILT_IN (node))
indent_to (file, indent + 3);
if (TREE_CODE (node) != FUNCTION_DECL)
{
if (DECL_USER_ALIGN (node))
fprintf (file, " user");
fprintf (file, " align %d", DECL_ALIGN (node));
if (TREE_CODE (node) == FIELD_DECL)
fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
DECL_OFFSET_ALIGN (node));
}
else if (DECL_BUILT_IN (node))
{
if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node));
else
fprintf (file, " built-in %s:%s",
built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
built_in_names[(int) DECL_FUNCTION_CODE (node)]);
}
if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
fprintf (file, " alias set " HOST_WIDE_INT_PRINT_DEC,
DECL_POINTER_ALIAS_SET (node));
}
if (TREE_CODE (node) == FIELD_DECL)
{
print_node (file, "offset", DECL_FIELD_OFFSET (node), indent + 4);
print_node (file, "bit offset", DECL_FIELD_BIT_OFFSET (node),
indent + 4);
}
print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
print_node_brief (file, "attributes",
DECL_ATTRIBUTES (node), indent + 4);
print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4);
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
{
print_node_brief (file, "abstract_origin",
DECL_ABSTRACT_ORIGIN (node), indent + 4);
}
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{
print_node (file, "arguments", DECL_ARGUMENT_FLD (node), indent + 4);
print_node (file, "result", DECL_RESULT_FLD (node), indent + 4);
}
lang_hooks.print_decl (file, node, indent);
if (DECL_RTL_SET_P (node))
{
indent_to (file, indent + 4);
print_rtl (file, DECL_RTL (node));
}
if (TREE_CODE (node) == PARM_DECL)
{
print_node (file, "arg-type", DECL_ARG_TYPE (node), indent + 4);
if (DECL_INCOMING_RTL (node) != 0)
{
indent_to (file, indent + 4);
fprintf (file, "incoming-rtl ");
print_rtl (file, DECL_INCOMING_RTL (node));
}
}
else if (TREE_CODE (node) == FUNCTION_DECL
&& DECL_STRUCT_FUNCTION (node) != 0)
{
indent_to (file, indent + 4);
fprintf (file, "saved-insns %p",
(void *) DECL_STRUCT_FUNCTION (node));
}
if ((TREE_CODE (node) == VAR_DECL || TREE_CODE (node) == PARM_DECL)
&& DECL_HAS_VALUE_EXPR_P (node))
print_node (file, "value-expr", DECL_VALUE_EXPR (node), indent + 4);
/* Print the decl chain only if decl is at second level. */
if (indent == 4)
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
else
print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case tcc_type:
if (TYPE_UNSIGNED (node))
fputs (" unsigned", file);
/* The no-force-blk flag is used for different things in
different types. */
if ((TREE_CODE (node) == RECORD_TYPE
|| TREE_CODE (node) == UNION_TYPE
|| TREE_CODE (node) == QUAL_UNION_TYPE)
&& TYPE_NO_FORCE_BLK (node))
fputs (" no-force-blk", file);
else if (TREE_CODE (node) == INTEGER_TYPE
&& TYPE_IS_SIZETYPE (node))
fputs (" sizetype", file);
else if (TREE_CODE (node) == FUNCTION_TYPE
&& TYPE_RETURNS_STACK_DEPRESSED (node))
fputs (" returns-stack-depressed", file);
if (TYPE_STRING_FLAG (node))
fputs (" string-flag", file);
if (TYPE_NEEDS_CONSTRUCTING (node))
fputs (" needs-constructing", file);
/* The transparent-union flag is used for different things in
different nodes. */
if (TREE_CODE (node) == UNION_TYPE && TYPE_TRANSPARENT_UNION (node))
fputs (" transparent-union", file);
else if (TREE_CODE (node) == ARRAY_TYPE
&& TYPE_NONALIASED_COMPONENT (node))
fputs (" nonaliased-component", file);
if (TYPE_PACKED (node))
fputs (" packed", file);
if (TYPE_RESTRICT (node))
fputs (" restrict", file);
if (TYPE_LANG_FLAG_0 (node))
fputs (" type_0", file);
if (TYPE_LANG_FLAG_1 (node))
fputs (" type_1", file);
if (TYPE_LANG_FLAG_2 (node))
fputs (" type_2", file);
if (TYPE_LANG_FLAG_3 (node))
fputs (" type_3", file);
if (TYPE_LANG_FLAG_4 (node))
fputs (" type_4", file);
if (TYPE_LANG_FLAG_5 (node))
fputs (" type_5", file);
if (TYPE_LANG_FLAG_6 (node))
fputs (" type_6", file);
mode = TYPE_MODE (node);
fprintf (file, " %s", GET_MODE_NAME (mode));
print_node (file, "size", TYPE_SIZE (node), indent + 4);
print_node (file, "unit size", TYPE_SIZE_UNIT (node), indent + 4);
indent_to (file, indent + 3);
if (TYPE_USER_ALIGN (node))
fprintf (file, " user");
fprintf (file, " align %d symtab %d alias set " HOST_WIDE_INT_PRINT_DEC,
TYPE_ALIGN (node), TYPE_SYMTAB_ADDRESS (node),
TYPE_ALIAS_SET (node));
print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
if (INTEGRAL_TYPE_P (node) || TREE_CODE (node) == REAL_TYPE)
{
fprintf (file, " precision %d", TYPE_PRECISION (node));
print_node_brief (file, "min", TYPE_MIN_VALUE (node), indent + 4);
print_node_brief (file, "max", TYPE_MAX_VALUE (node), indent + 4);
}
if (TREE_CODE (node) == ENUMERAL_TYPE)
print_node (file, "values", TYPE_VALUES (node), indent + 4);
else if (TREE_CODE (node) == ARRAY_TYPE)
print_node (file, "domain", TYPE_DOMAIN (node), indent + 4);
else if (TREE_CODE (node) == VECTOR_TYPE)
fprintf (file, " nunits %d", (int) TYPE_VECTOR_SUBPARTS (node));
else if (TREE_CODE (node) == RECORD_TYPE
|| TREE_CODE (node) == UNION_TYPE
|| TREE_CODE (node) == QUAL_UNION_TYPE)
print_node (file, "fields", TYPE_FIELDS (node), indent + 4);
else if (TREE_CODE (node) == FUNCTION_TYPE
|| TREE_CODE (node) == METHOD_TYPE)
{
if (TYPE_METHOD_BASETYPE (node))
print_node_brief (file, "method basetype",
TYPE_METHOD_BASETYPE (node), indent + 4);
print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4);
}
else if (TREE_CODE (node) == OFFSET_TYPE)
print_node_brief (file, "basetype", TYPE_OFFSET_BASETYPE (node),
indent + 4);
if (TYPE_CONTEXT (node))
print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4);
lang_hooks.print_type (file, node, indent);
if (TYPE_POINTER_TO (node) || TREE_CHAIN (node))
indent_to (file, indent + 3);
print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node),
indent + 4);
print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node),
indent + 4);
print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case tcc_expression:
case tcc_comparison:
case tcc_unary:
case tcc_binary:
case tcc_reference:
case tcc_statement:
if (TREE_CODE (node) == BIT_FIELD_REF && BIT_FIELD_REF_UNSIGNED (node))
fputs (" unsigned", file);
if (TREE_CODE (node) == BIND_EXPR)
{
print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4);
print_node (file, "body", TREE_OPERAND (node, 1), indent + 4);
print_node (file, "block", TREE_OPERAND (node, 2), indent + 4);
break;
}
len = TREE_CODE_LENGTH (TREE_CODE (node));
for (i = 0; i < len; i++)
{
char temp[10];
sprintf (temp, "arg %d", i);
print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
}
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case tcc_constant:
case tcc_exceptional:
switch (TREE_CODE (node))
{
case INTEGER_CST:
if (TREE_CONSTANT_OVERFLOW (node))
fprintf (file, " overflow");
fprintf (file, " ");
if (TREE_INT_CST_HIGH (node) == 0)
fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
TREE_INT_CST_LOW (node));
else if (TREE_INT_CST_HIGH (node) == -1
&& TREE_INT_CST_LOW (node) != 0)
fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
-TREE_INT_CST_LOW (node));
else
fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
break;
case REAL_CST:
{
REAL_VALUE_TYPE d;
if (TREE_OVERFLOW (node))
fprintf (file, " overflow");
d = TREE_REAL_CST (node);
if (REAL_VALUE_ISINF (d))
fprintf (file, " Inf");
else if (REAL_VALUE_ISNAN (d))
fprintf (file, " Nan");
else
{
char string[64];
real_to_decimal (string, &d, sizeof (string), 0, 1);
fprintf (file, " %s", string);
}
}
break;
case VECTOR_CST:
{
tree vals = TREE_VECTOR_CST_ELTS (node);
char buf[10];
tree link;
int i;
i = 0;
for (link = vals; link; link = TREE_CHAIN (link), ++i)
{
sprintf (buf, "elt%d: ", i);
print_node (file, buf, TREE_VALUE (link), indent + 4);
}
}
break;
case COMPLEX_CST:
print_node (file, "real", TREE_REALPART (node), indent + 4);
print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
break;
case STRING_CST:
{
const char *p = TREE_STRING_POINTER (node);
int i = TREE_STRING_LENGTH (node);
fputs (" \"", file);
while (--i >= 0)
{
char ch = *p++;
if (ch >= ' ' && ch < 127)
putc (ch, file);
else
fprintf(file, "\\%03o", ch & 0xFF);
}
fputc ('\"', file);
}
/* Print the chain at second level. */
if (indent == 4)
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
else
print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case IDENTIFIER_NODE:
lang_hooks.print_identifier (file, node, indent);
break;
case TREE_LIST:
print_node (file, "purpose", TREE_PURPOSE (node), indent + 4);
print_node (file, "value", TREE_VALUE (node), indent + 4);
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case TREE_VEC:
len = TREE_VEC_LENGTH (node);
for (i = 0; i < len; i++)
if (TREE_VEC_ELT (node, i))
{
char temp[10];
sprintf (temp, "elt %d", i);
indent_to (file, indent + 4);
print_node_brief (file, temp, TREE_VEC_ELT (node, i), 0);
}
break;
case STATEMENT_LIST:
fprintf (file, " head %p tail %p stmts",
(void *) node->stmt_list.head, (void *) node->stmt_list.tail);
{
tree_stmt_iterator i;
for (i = tsi_start (node); !tsi_end_p (i); tsi_next (&i))
{
/* Not printing the addresses of the (not-a-tree)
'struct tree_stmt_list_node's. */
fprintf (file, " %p", (void *)tsi_stmt (i));
}
fprintf (file, "\n");
for (i = tsi_start (node); !tsi_end_p (i); tsi_next (&i))
{
/* Not printing the addresses of the (not-a-tree)
'struct tree_stmt_list_node's. */
print_node (file, "stmt", tsi_stmt (i), indent + 4);
}
}
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
break;
case BLOCK:
print_node (file, "vars", BLOCK_VARS (node), indent + 4);
print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node),
indent + 4);
print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4);
print_node (file, "chain", BLOCK_CHAIN (node), indent + 4);
print_node (file, "abstract_origin",
BLOCK_ABSTRACT_ORIGIN (node), indent + 4);
break;
case SSA_NAME:
print_node_brief (file, "var", SSA_NAME_VAR (node), indent + 4);
print_node_brief (file, "def_stmt",
SSA_NAME_DEF_STMT (node), indent + 4);
indent_to (file, indent + 4);
fprintf (file, "version %u", SSA_NAME_VERSION (node));
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
fprintf (file, " in-abnormal-phi");
if (SSA_NAME_IN_FREE_LIST (node))
fprintf (file, " in-free-list");
if (SSA_NAME_PTR_INFO (node)
|| SSA_NAME_VALUE (node)
|| SSA_NAME_AUX (node))
{
indent_to (file, indent + 3);
if (SSA_NAME_PTR_INFO (node))
fprintf (file, " ptr-info %p",
(void *) SSA_NAME_PTR_INFO (node));
if (SSA_NAME_VALUE (node))
fprintf (file, " value %p",
(void *) SSA_NAME_VALUE (node));
if (SSA_NAME_AUX (node))
fprintf (file, " aux %p", SSA_NAME_AUX (node));
}
break;
default:
if (EXCEPTIONAL_CLASS_P (node))
lang_hooks.print_xnode (file, node, indent);
break;
}
break;
}
if (EXPR_HAS_LOCATION (node))
{
expanded_location xloc = expand_location (EXPR_LOCATION (node));
indent_to (file, indent+4);
fprintf (file, "%s:%d", xloc.file, xloc.line);
}
fprintf (file, ">");
}