123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- /* Tree-dumping functionality for intermediate representation.
- Copyright (C) 1999-2015 Free Software Foundation, Inc.
- Written by Mark Mitchell <mark@codesourcery.com>
- 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 3, 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 COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #include "config.h"
- #include "system.h"
- #include "coretypes.h"
- #include "tm.h"
- #include "hash-set.h"
- #include "machmode.h"
- #include "vec.h"
- #include "double-int.h"
- #include "input.h"
- #include "alias.h"
- #include "symtab.h"
- #include "wide-int.h"
- #include "inchash.h"
- #include "tree.h"
- #include "cp-tree.h"
- #include "tree-dump.h"
- static void dump_access (dump_info_p, tree);
- static void dump_op (dump_info_p, tree);
- /* Dump a representation of the accessibility information associated
- with T. */
- static void
- dump_access (dump_info_p di, tree t)
- {
- if (TREE_PROTECTED(t))
- dump_string_field (di, "accs", "prot");
- else if (TREE_PRIVATE(t))
- dump_string_field (di, "accs", "priv");
- else
- dump_string_field (di, "accs", "pub");
- }
- /* Dump a representation of the specific operator for an overloaded
- operator associated with node t. */
- static void
- dump_op (dump_info_p di, tree t)
- {
- switch (DECL_OVERLOADED_OPERATOR_P (t)) {
- case NEW_EXPR:
- dump_string (di, "new");
- break;
- case VEC_NEW_EXPR:
- dump_string (di, "vecnew");
- break;
- case DELETE_EXPR:
- dump_string (di, "delete");
- break;
- case VEC_DELETE_EXPR:
- dump_string (di, "vecdelete");
- break;
- case UNARY_PLUS_EXPR:
- dump_string (di, "pos");
- break;
- case NEGATE_EXPR:
- dump_string (di, "neg");
- break;
- case ADDR_EXPR:
- dump_string (di, "addr");
- break;
- case INDIRECT_REF:
- dump_string(di, "deref");
- break;
- case BIT_NOT_EXPR:
- dump_string(di, "not");
- break;
- case TRUTH_NOT_EXPR:
- dump_string(di, "lnot");
- break;
- case PREINCREMENT_EXPR:
- dump_string(di, "preinc");
- break;
- case PREDECREMENT_EXPR:
- dump_string(di, "predec");
- break;
- case PLUS_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "plusassign");
- else
- dump_string(di, "plus");
- break;
- case MINUS_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "minusassign");
- else
- dump_string(di, "minus");
- break;
- case MULT_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "multassign");
- else
- dump_string (di, "mult");
- break;
- case TRUNC_DIV_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "divassign");
- else
- dump_string (di, "div");
- break;
- case TRUNC_MOD_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "modassign");
- else
- dump_string (di, "mod");
- break;
- case BIT_AND_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "andassign");
- else
- dump_string (di, "and");
- break;
- case BIT_IOR_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "orassign");
- else
- dump_string (di, "or");
- break;
- case BIT_XOR_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "xorassign");
- else
- dump_string (di, "xor");
- break;
- case LSHIFT_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "lshiftassign");
- else
- dump_string (di, "lshift");
- break;
- case RSHIFT_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "rshiftassign");
- else
- dump_string (di, "rshift");
- break;
- case EQ_EXPR:
- dump_string (di, "eq");
- break;
- case NE_EXPR:
- dump_string (di, "ne");
- break;
- case LT_EXPR:
- dump_string (di, "lt");
- break;
- case GT_EXPR:
- dump_string (di, "gt");
- break;
- case LE_EXPR:
- dump_string (di, "le");
- break;
- case GE_EXPR:
- dump_string (di, "ge");
- break;
- case TRUTH_ANDIF_EXPR:
- dump_string (di, "land");
- break;
- case TRUTH_ORIF_EXPR:
- dump_string (di, "lor");
- break;
- case COMPOUND_EXPR:
- dump_string (di, "compound");
- break;
- case MEMBER_REF:
- dump_string (di, "memref");
- break;
- case COMPONENT_REF:
- dump_string (di, "ref");
- break;
- case ARRAY_REF:
- dump_string (di, "subs");
- break;
- case POSTINCREMENT_EXPR:
- dump_string (di, "postinc");
- break;
- case POSTDECREMENT_EXPR:
- dump_string (di, "postdec");
- break;
- case CALL_EXPR:
- dump_string (di, "call");
- break;
- case NOP_EXPR:
- if (DECL_ASSIGNMENT_OPERATOR_P (t))
- dump_string (di, "assign");
- break;
- default:
- break;
- }
- }
- /* Dump information common to statements from STMT. */
- static void
- dump_stmt (dump_info_p di, const_tree t)
- {
- if (EXPR_HAS_LOCATION (t))
- dump_int (di, "line", EXPR_LINENO (t));
- }
- bool
- cp_dump_tree (void* dump_info, tree t)
- {
- enum tree_code code;
- dump_info_p di = (dump_info_p) dump_info;
- /* Figure out what kind of node this is. */
- code = TREE_CODE (t);
- if (DECL_P (t))
- {
- if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
- dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t)));
- }
- switch (code)
- {
- case IDENTIFIER_NODE:
- if (IDENTIFIER_OPNAME_P (t))
- {
- dump_string_field (di, "note", "operator");
- return true;
- }
- else if (IDENTIFIER_TYPENAME_P (t))
- {
- dump_child ("tynm", TREE_TYPE (t));
- return true;
- }
- break;
- case OFFSET_TYPE:
- dump_string_field (di, "note", "ptrmem");
- dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
- dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
- return true;
- case RECORD_TYPE:
- if (TYPE_PTRMEMFUNC_P (t))
- {
- dump_string_field (di, "note", "ptrmem");
- dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
- dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
- return true;
- }
- /* Fall through. */
- case UNION_TYPE:
- /* Is it a type used as a base? */
- if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t)
- && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
- {
- dump_child ("bfld", TYPE_CONTEXT (t));
- return true;
- }
- if (! MAYBE_CLASS_TYPE_P (t))
- break;
- dump_child ("vfld", TYPE_VFIELD (t));
- if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
- dump_string(di, "spec");
- if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t))
- {
- int i;
- tree binfo;
- tree base_binfo;
- for (binfo = TYPE_BINFO (t), i = 0;
- BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
- {
- dump_child ("base", BINFO_TYPE (base_binfo));
- if (BINFO_VIRTUAL_P (base_binfo))
- dump_string_field (di, "spec", "virt");
- dump_access (di, base_binfo);
- }
- }
- break;
- case FIELD_DECL:
- dump_access (di, t);
- if (DECL_MUTABLE_P (t))
- dump_string_field (di, "spec", "mutable");
- break;
- case VAR_DECL:
- if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE)
- dump_access (di, t);
- if (TREE_STATIC (t) && !TREE_PUBLIC (t))
- dump_string_field (di, "link", "static");
- break;
- case FUNCTION_DECL:
- if (!DECL_THUNK_P (t))
- {
- if (DECL_OVERLOADED_OPERATOR_P (t)) {
- dump_string_field (di, "note", "operator");
- dump_op (di, t);
- }
- if (DECL_FUNCTION_MEMBER_P (t))
- {
- dump_string_field (di, "note", "member");
- dump_access (di, t);
- }
- if (DECL_PURE_VIRTUAL_P (t))
- dump_string_field (di, "spec", "pure");
- if (DECL_VIRTUAL_P (t))
- dump_string_field (di, "spec", "virt");
- if (DECL_CONSTRUCTOR_P (t))
- dump_string_field (di, "note", "constructor");
- if (DECL_DESTRUCTOR_P (t))
- dump_string_field (di, "note", "destructor");
- if (DECL_CONV_FN_P (t))
- dump_string_field (di, "note", "conversion");
- if (DECL_GLOBAL_CTOR_P (t))
- dump_string_field (di, "note", "global init");
- if (DECL_GLOBAL_DTOR_P (t))
- dump_string_field (di, "note", "global fini");
- if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
- dump_string_field (di, "note", "pseudo tmpl");
- }
- else
- {
- tree virt = THUNK_VIRTUAL_OFFSET (t);
- dump_string_field (di, "note", "thunk");
- if (DECL_THIS_THUNK_P (t))
- dump_string_field (di, "note", "this adjusting");
- else
- {
- dump_string_field (di, "note", "result adjusting");
- if (virt)
- virt = BINFO_VPTR_FIELD (virt);
- }
- dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
- if (virt)
- dump_int (di, "virt", tree_to_shwi (virt));
- dump_child ("fn", DECL_INITIAL (t));
- }
- break;
- case NAMESPACE_DECL:
- if (DECL_NAMESPACE_ALIAS (t))
- dump_child ("alis", DECL_NAMESPACE_ALIAS (t));
- else if (!dump_flag (di, TDF_SLIM, t))
- dump_child ("dcls", cp_namespace_decls (t));
- break;
- case TEMPLATE_DECL:
- dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
- dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
- dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
- dump_child ("prms", DECL_TEMPLATE_PARMS (t));
- break;
- case OVERLOAD:
- dump_child ("crnt", OVL_CURRENT (t));
- dump_child ("chan", OVL_CHAIN (t));
- break;
- case TRY_BLOCK:
- dump_stmt (di, t);
- if (CLEANUP_P (t))
- dump_string_field (di, "note", "cleanup");
- dump_child ("body", TRY_STMTS (t));
- dump_child ("hdlr", TRY_HANDLERS (t));
- break;
- case EH_SPEC_BLOCK:
- dump_stmt (di, t);
- dump_child ("body", EH_SPEC_STMTS (t));
- dump_child ("raises", EH_SPEC_RAISES (t));
- break;
- case PTRMEM_CST:
- dump_child ("clas", PTRMEM_CST_CLASS (t));
- dump_child ("mbr", PTRMEM_CST_MEMBER (t));
- break;
- case THROW_EXPR:
- /* These nodes are unary, but do not have code class `1'. */
- dump_child ("op 0", TREE_OPERAND (t, 0));
- break;
- case AGGR_INIT_EXPR:
- {
- int i = 0;
- tree arg;
- aggr_init_expr_arg_iterator iter;
- dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
- dump_child ("fn", AGGR_INIT_EXPR_FN (t));
- FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
- {
- char buffer[32];
- sprintf (buffer, "%u", i);
- dump_child (buffer, arg);
- i++;
- }
- dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
- }
- break;
- case HANDLER:
- dump_stmt (di, t);
- dump_child ("parm", HANDLER_PARMS (t));
- dump_child ("body", HANDLER_BODY (t));
- break;
- case MUST_NOT_THROW_EXPR:
- dump_stmt (di, t);
- dump_child ("body", TREE_OPERAND (t, 0));
- dump_child ("cond", MUST_NOT_THROW_COND (t));
- break;
- case USING_STMT:
- dump_stmt (di, t);
- dump_child ("nmsp", USING_STMT_NAMESPACE (t));
- break;
- case CLEANUP_STMT:
- dump_stmt (di, t);
- dump_child ("decl", CLEANUP_DECL (t));
- dump_child ("expr", CLEANUP_EXPR (t));
- dump_child ("body", CLEANUP_BODY (t));
- break;
- case IF_STMT:
- dump_stmt (di, t);
- dump_child ("cond", IF_COND (t));
- dump_child ("then", THEN_CLAUSE (t));
- dump_child ("else", ELSE_CLAUSE (t));
- break;
- case BREAK_STMT:
- case CONTINUE_STMT:
- dump_stmt (di, t);
- break;
- case DO_STMT:
- dump_stmt (di, t);
- dump_child ("body", DO_BODY (t));
- dump_child ("cond", DO_COND (t));
- break;
- case FOR_STMT:
- dump_stmt (di, t);
- dump_child ("init", FOR_INIT_STMT (t));
- dump_child ("cond", FOR_COND (t));
- dump_child ("expr", FOR_EXPR (t));
- dump_child ("body", FOR_BODY (t));
- break;
- case RANGE_FOR_STMT:
- dump_stmt (di, t);
- dump_child ("decl", RANGE_FOR_DECL (t));
- dump_child ("expr", RANGE_FOR_EXPR (t));
- dump_child ("body", RANGE_FOR_BODY (t));
- break;
- case SWITCH_STMT:
- dump_stmt (di, t);
- dump_child ("cond", SWITCH_STMT_COND (t));
- dump_child ("body", SWITCH_STMT_BODY (t));
- break;
- case WHILE_STMT:
- dump_stmt (di, t);
- dump_child ("cond", WHILE_COND (t));
- dump_child ("body", WHILE_BODY (t));
- break;
- case STMT_EXPR:
- dump_child ("stmt", STMT_EXPR_STMT (t));
- break;
- case EXPR_STMT:
- dump_stmt (di, t);
- dump_child ("expr", EXPR_STMT_EXPR (t));
- break;
- default:
- break;
- }
- return c_dump_tree (di, t);
- }
|