190075Sobrien/* Tree-dumping functionality for intermediate representation. 2169689Skan Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 3169689Skan Free Software Foundation, Inc. 490075Sobrien Written by Mark Mitchell <mark@codesourcery.com> 590075Sobrien 6132718SkanThis file is part of GCC. 790075Sobrien 8132718SkanGCC is free software; you can redistribute it and/or modify 990075Sobrienit under the terms of the GNU General Public License as published by 1090075Sobrienthe Free Software Foundation; either version 2, or (at your option) 1190075Sobrienany later version. 1290075Sobrien 13132718SkanGCC is distributed in the hope that it will be useful, 1490075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1590075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1690075SobrienGNU General Public License for more details. 1790075Sobrien 1890075SobrienYou should have received a copy of the GNU General Public License 19132718Skanalong with GCC; see the file COPYING. If not, write to 20169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 21169689SkanBoston, MA 02110-1301, USA. */ 2290075Sobrien 2390075Sobrien#include "config.h" 2490075Sobrien#include "system.h" 25132718Skan#include "coretypes.h" 26132718Skan#include "tm.h" 2790075Sobrien#include "tree.h" 2890075Sobrien#include "cp-tree.h" 2990075Sobrien#include "tree-dump.h" 3090075Sobrien 31132718Skanstatic void dump_access (dump_info_p, tree); 3290075Sobrien 33132718Skanstatic void dump_op (dump_info_p, tree); 3490075Sobrien 3590075Sobrien/* Dump a representation of the accessibility information associated 3690075Sobrien with T. */ 3790075Sobrien 3890075Sobrienstatic void 39132718Skandump_access (dump_info_p di, tree t) 4090075Sobrien{ 4190075Sobrien if (TREE_PROTECTED(t)) 42169689Skan dump_string_field (di, "accs", "prot"); 4390075Sobrien else if (TREE_PRIVATE(t)) 44169689Skan dump_string_field (di, "accs", "priv"); 4590075Sobrien else 46169689Skan dump_string_field (di, "accs", "pub"); 4790075Sobrien} 4890075Sobrien 4990075Sobrien/* Dump a representation of the specific operator for an overloaded 50117395Skan operator associated with node t. */ 5190075Sobrien 5290075Sobrienstatic void 53132718Skandump_op (dump_info_p di, tree t) 5490075Sobrien{ 5590075Sobrien switch (DECL_OVERLOADED_OPERATOR_P (t)) { 5690075Sobrien case NEW_EXPR: 5790075Sobrien dump_string (di, "new"); 5890075Sobrien break; 5990075Sobrien case VEC_NEW_EXPR: 6090075Sobrien dump_string (di, "vecnew"); 6190075Sobrien break; 6290075Sobrien case DELETE_EXPR: 6390075Sobrien dump_string (di, "delete"); 6490075Sobrien break; 6590075Sobrien case VEC_DELETE_EXPR: 6690075Sobrien dump_string (di, "vecdelete"); 6790075Sobrien break; 68169689Skan case UNARY_PLUS_EXPR: 6990075Sobrien dump_string (di, "pos"); 7090075Sobrien break; 7190075Sobrien case NEGATE_EXPR: 7290075Sobrien dump_string (di, "neg"); 7390075Sobrien break; 7490075Sobrien case ADDR_EXPR: 7590075Sobrien dump_string (di, "addr"); 7690075Sobrien break; 7790075Sobrien case INDIRECT_REF: 7890075Sobrien dump_string(di, "deref"); 7990075Sobrien break; 8090075Sobrien case BIT_NOT_EXPR: 8190075Sobrien dump_string(di, "not"); 8290075Sobrien break; 8390075Sobrien case TRUTH_NOT_EXPR: 8490075Sobrien dump_string(di, "lnot"); 8590075Sobrien break; 8690075Sobrien case PREINCREMENT_EXPR: 8790075Sobrien dump_string(di, "preinc"); 8890075Sobrien break; 8990075Sobrien case PREDECREMENT_EXPR: 9090075Sobrien dump_string(di, "predec"); 9190075Sobrien break; 9290075Sobrien case PLUS_EXPR: 9390075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 94169689Skan dump_string (di, "plusassign"); 9590075Sobrien else 96169689Skan dump_string(di, "plus"); 9790075Sobrien break; 9890075Sobrien case MINUS_EXPR: 9990075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 100169689Skan dump_string (di, "minusassign"); 10190075Sobrien else 102169689Skan dump_string(di, "minus"); 10390075Sobrien break; 10490075Sobrien case MULT_EXPR: 10590075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 106169689Skan dump_string (di, "multassign"); 10790075Sobrien else 108169689Skan dump_string (di, "mult"); 10990075Sobrien break; 11090075Sobrien case TRUNC_DIV_EXPR: 11190075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 112169689Skan dump_string (di, "divassign"); 11390075Sobrien else 114169689Skan dump_string (di, "div"); 11590075Sobrien break; 11690075Sobrien case TRUNC_MOD_EXPR: 11790075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 118169689Skan dump_string (di, "modassign"); 11990075Sobrien else 120169689Skan dump_string (di, "mod"); 12190075Sobrien break; 12290075Sobrien case BIT_AND_EXPR: 12390075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 124169689Skan dump_string (di, "andassign"); 12590075Sobrien else 126169689Skan dump_string (di, "and"); 12790075Sobrien break; 12890075Sobrien case BIT_IOR_EXPR: 12990075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 130169689Skan dump_string (di, "orassign"); 13190075Sobrien else 132169689Skan dump_string (di, "or"); 13390075Sobrien break; 13490075Sobrien case BIT_XOR_EXPR: 13590075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 136169689Skan dump_string (di, "xorassign"); 13790075Sobrien else 138169689Skan dump_string (di, "xor"); 13990075Sobrien break; 14090075Sobrien case LSHIFT_EXPR: 14190075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 142169689Skan dump_string (di, "lshiftassign"); 14390075Sobrien else 144169689Skan dump_string (di, "lshift"); 14590075Sobrien break; 14690075Sobrien case RSHIFT_EXPR: 14790075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 148169689Skan dump_string (di, "rshiftassign"); 14990075Sobrien else 150169689Skan dump_string (di, "rshift"); 15190075Sobrien break; 15290075Sobrien case EQ_EXPR: 15390075Sobrien dump_string (di, "eq"); 15490075Sobrien break; 15590075Sobrien case NE_EXPR: 15690075Sobrien dump_string (di, "ne"); 15790075Sobrien break; 15890075Sobrien case LT_EXPR: 15990075Sobrien dump_string (di, "lt"); 16090075Sobrien break; 16190075Sobrien case GT_EXPR: 16290075Sobrien dump_string (di, "gt"); 16390075Sobrien break; 16490075Sobrien case LE_EXPR: 16590075Sobrien dump_string (di, "le"); 16690075Sobrien break; 16790075Sobrien case GE_EXPR: 16890075Sobrien dump_string (di, "ge"); 16990075Sobrien break; 17090075Sobrien case TRUTH_ANDIF_EXPR: 17190075Sobrien dump_string (di, "land"); 17290075Sobrien break; 17390075Sobrien case TRUTH_ORIF_EXPR: 17490075Sobrien dump_string (di, "lor"); 17590075Sobrien break; 17690075Sobrien case COMPOUND_EXPR: 17790075Sobrien dump_string (di, "compound"); 17890075Sobrien break; 17990075Sobrien case MEMBER_REF: 18090075Sobrien dump_string (di, "memref"); 18190075Sobrien break; 18290075Sobrien case COMPONENT_REF: 18390075Sobrien dump_string (di, "ref"); 18490075Sobrien break; 18590075Sobrien case ARRAY_REF: 18690075Sobrien dump_string (di, "subs"); 18790075Sobrien break; 18890075Sobrien case POSTINCREMENT_EXPR: 189169689Skan dump_string (di, "postinc"); 19090075Sobrien break; 19190075Sobrien case POSTDECREMENT_EXPR: 19290075Sobrien dump_string (di, "postdec"); 19390075Sobrien break; 19490075Sobrien case CALL_EXPR: 19590075Sobrien dump_string (di, "call"); 19690075Sobrien break; 19790075Sobrien case NOP_EXPR: 19890075Sobrien if (DECL_ASSIGNMENT_OPERATOR_P (t)) 199169689Skan dump_string (di, "assign"); 20090075Sobrien break; 20190075Sobrien default: 20290075Sobrien break; 20390075Sobrien } 20490075Sobrien} 20590075Sobrien 206132718Skanbool 207132718Skancp_dump_tree (void* dump_info, tree t) 20890075Sobrien{ 20990075Sobrien enum tree_code code; 21090075Sobrien dump_info_p di = (dump_info_p) dump_info; 21190075Sobrien 21290075Sobrien /* Figure out what kind of node this is. */ 21390075Sobrien code = TREE_CODE (t); 21490075Sobrien 21590075Sobrien if (DECL_P (t)) 21690075Sobrien { 21790075Sobrien if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus) 218169689Skan dump_string_field (di, "lang", language_to_string (DECL_LANGUAGE (t))); 21990075Sobrien } 22090075Sobrien 22190075Sobrien switch (code) 22290075Sobrien { 22390075Sobrien case IDENTIFIER_NODE: 22490075Sobrien if (IDENTIFIER_OPNAME_P (t)) 22590075Sobrien { 226169689Skan dump_string_field (di, "note", "operator"); 227132718Skan return true; 22890075Sobrien } 22990075Sobrien else if (IDENTIFIER_TYPENAME_P (t)) 23090075Sobrien { 23190075Sobrien dump_child ("tynm", TREE_TYPE (t)); 232132718Skan return true; 23390075Sobrien } 23490075Sobrien break; 23590075Sobrien 236132718Skan case OFFSET_TYPE: 237169689Skan dump_string_field (di, "note", "ptrmem"); 238132718Skan dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); 239132718Skan dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); 240132718Skan return true; 24190075Sobrien 24290075Sobrien case RECORD_TYPE: 24390075Sobrien if (TYPE_PTRMEMFUNC_P (t)) 24490075Sobrien { 245169689Skan dump_string_field (di, "note", "ptrmem"); 24690075Sobrien dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t)); 24790075Sobrien dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t)); 248132718Skan return true; 24990075Sobrien } 250132718Skan /* Fall through. */ 25190075Sobrien 252132718Skan case UNION_TYPE: 253117395Skan /* Is it a type used as a base? */ 254117395Skan if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t) 255117395Skan && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t) 256117395Skan { 257117395Skan dump_child ("bfld", TYPE_CONTEXT (t)); 258132718Skan return true; 259117395Skan } 260169689Skan 261132718Skan if (! IS_AGGR_TYPE (t)) 262132718Skan break; 263132718Skan 26490075Sobrien dump_child ("vfld", TYPE_VFIELD (t)); 26590075Sobrien if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t)) 266169689Skan dump_string(di, "spec"); 26790075Sobrien 268169689Skan if (!dump_flag (di, TDF_SLIM, t) && TYPE_BINFO (t)) 26990075Sobrien { 27090075Sobrien int i; 271169689Skan tree binfo; 272169689Skan tree base_binfo; 273169689Skan 274169689Skan for (binfo = TYPE_BINFO (t), i = 0; 275169689Skan BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) 27690075Sobrien { 27790075Sobrien dump_child ("base", BINFO_TYPE (base_binfo)); 278169689Skan if (BINFO_VIRTUAL_P (base_binfo)) 279169689Skan dump_string_field (di, "spec", "virt"); 28090075Sobrien dump_access (di, base_binfo); 28190075Sobrien } 28290075Sobrien } 28390075Sobrien break; 28490075Sobrien 28590075Sobrien case FIELD_DECL: 28690075Sobrien dump_access (di, t); 28790075Sobrien if (DECL_MUTABLE_P (t)) 288169689Skan dump_string_field (di, "spec", "mutable"); 28990075Sobrien break; 29090075Sobrien 29190075Sobrien case VAR_DECL: 29290075Sobrien if (TREE_CODE (CP_DECL_CONTEXT (t)) == RECORD_TYPE) 293169689Skan dump_access (di, t); 29490075Sobrien if (TREE_STATIC (t) && !TREE_PUBLIC (t)) 295169689Skan dump_string_field (di, "link", "static"); 296169689Skan break; 29790075Sobrien 29890075Sobrien case FUNCTION_DECL: 29990075Sobrien if (!DECL_THUNK_P (t)) 30090075Sobrien { 301169689Skan if (DECL_OVERLOADED_OPERATOR_P (t)) { 302169689Skan dump_string_field (di, "note", "operator"); 303169689Skan dump_op (di, t); 304169689Skan } 305169689Skan if (DECL_FUNCTION_MEMBER_P (t)) 30690075Sobrien { 307169689Skan dump_string_field (di, "note", "member"); 30890075Sobrien dump_access (di, t); 30990075Sobrien } 310169689Skan if (DECL_PURE_VIRTUAL_P (t)) 311169689Skan dump_string_field (di, "spec", "pure"); 312169689Skan if (DECL_VIRTUAL_P (t)) 313169689Skan dump_string_field (di, "spec", "virt"); 31490075Sobrien if (DECL_CONSTRUCTOR_P (t)) 315169689Skan dump_string_field (di, "note", "constructor"); 31690075Sobrien if (DECL_DESTRUCTOR_P (t)) 317169689Skan dump_string_field (di, "note", "destructor"); 31890075Sobrien if (DECL_CONV_FN_P (t)) 319169689Skan dump_string_field (di, "note", "conversion"); 320132718Skan if (DECL_GLOBAL_CTOR_P (t)) 321169689Skan dump_string_field (di, "note", "global init"); 322132718Skan if (DECL_GLOBAL_DTOR_P (t)) 323169689Skan dump_string_field (di, "note", "global fini"); 32490075Sobrien if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)) 325169689Skan dump_string_field (di, "note", "pseudo tmpl"); 32690075Sobrien } 32790075Sobrien else 32890075Sobrien { 329132718Skan tree virt = THUNK_VIRTUAL_OFFSET (t); 330169689Skan 331169689Skan dump_string_field (di, "note", "thunk"); 332132718Skan if (DECL_THIS_THUNK_P (t)) 333169689Skan dump_string_field (di, "note", "this adjusting"); 334132718Skan else 335132718Skan { 336169689Skan dump_string_field (di, "note", "result adjusting"); 337132718Skan if (virt) 338132718Skan virt = BINFO_VPTR_FIELD (virt); 339132718Skan } 340132718Skan dump_int (di, "fixd", THUNK_FIXED_OFFSET (t)); 341132718Skan if (virt) 342132718Skan dump_int (di, "virt", tree_low_cst (virt, 0)); 34390075Sobrien dump_child ("fn", DECL_INITIAL (t)); 34490075Sobrien } 34590075Sobrien break; 34690075Sobrien 34790075Sobrien case NAMESPACE_DECL: 34890075Sobrien if (DECL_NAMESPACE_ALIAS (t)) 34990075Sobrien dump_child ("alis", DECL_NAMESPACE_ALIAS (t)); 35090075Sobrien else if (!dump_flag (di, TDF_SLIM, t)) 35190075Sobrien dump_child ("dcls", cp_namespace_decls (t)); 35290075Sobrien break; 35390075Sobrien 35490075Sobrien case TEMPLATE_DECL: 35590075Sobrien dump_child ("rslt", DECL_TEMPLATE_RESULT (t)); 35690075Sobrien dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t)); 35790075Sobrien dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t)); 35890075Sobrien dump_child ("prms", DECL_TEMPLATE_PARMS (t)); 35990075Sobrien break; 36090075Sobrien 36190075Sobrien case OVERLOAD: 36290075Sobrien dump_child ("crnt", OVL_CURRENT (t)); 36390075Sobrien dump_child ("chan", OVL_CHAIN (t)); 36490075Sobrien break; 36590075Sobrien 36690075Sobrien case TRY_BLOCK: 36790075Sobrien dump_stmt (di, t); 36890075Sobrien if (CLEANUP_P (t)) 369169689Skan dump_string_field (di, "note", "cleanup"); 37090075Sobrien dump_child ("body", TRY_STMTS (t)); 37190075Sobrien dump_child ("hdlr", TRY_HANDLERS (t)); 37290075Sobrien break; 37390075Sobrien 37490075Sobrien case EH_SPEC_BLOCK: 37590075Sobrien dump_stmt (di, t); 37690075Sobrien dump_child ("body", EH_SPEC_STMTS (t)); 37790075Sobrien dump_child ("raises", EH_SPEC_RAISES (t)); 37890075Sobrien break; 37990075Sobrien 38090075Sobrien case PTRMEM_CST: 38190075Sobrien dump_child ("clas", PTRMEM_CST_CLASS (t)); 38290075Sobrien dump_child ("mbr", PTRMEM_CST_MEMBER (t)); 38390075Sobrien break; 38490075Sobrien 38590075Sobrien case THROW_EXPR: 38690075Sobrien /* These nodes are unary, but do not have code class `1'. */ 38790075Sobrien dump_child ("op 0", TREE_OPERAND (t, 0)); 38890075Sobrien break; 38990075Sobrien 39090075Sobrien case AGGR_INIT_EXPR: 39190075Sobrien dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t)); 39290075Sobrien dump_child ("fn", TREE_OPERAND (t, 0)); 39390075Sobrien dump_child ("args", TREE_OPERAND (t, 1)); 39490075Sobrien dump_child ("decl", TREE_OPERAND (t, 2)); 39590075Sobrien break; 396169689Skan 39790075Sobrien case HANDLER: 39890075Sobrien dump_stmt (di, t); 39990075Sobrien dump_child ("parm", HANDLER_PARMS (t)); 40090075Sobrien dump_child ("body", HANDLER_BODY (t)); 40190075Sobrien break; 40290075Sobrien 40390075Sobrien case MUST_NOT_THROW_EXPR: 40490075Sobrien dump_stmt (di, t); 40590075Sobrien dump_child ("body", TREE_OPERAND (t, 0)); 40690075Sobrien break; 40790075Sobrien 40890075Sobrien case USING_STMT: 40990075Sobrien dump_stmt (di, t); 41090075Sobrien dump_child ("nmsp", USING_STMT_NAMESPACE (t)); 41190075Sobrien break; 412169689Skan 413169689Skan case CLEANUP_STMT: 414169689Skan dump_stmt (di, t); 415169689Skan dump_child ("decl", CLEANUP_DECL (t)); 416169689Skan dump_child ("expr", CLEANUP_EXPR (t)); 417169689Skan dump_child ("body", CLEANUP_BODY (t)); 418169689Skan break; 419169689Skan 420169689Skan case IF_STMT: 421169689Skan dump_stmt (di, t); 422169689Skan dump_child ("cond", IF_COND (t)); 423169689Skan dump_child ("then", THEN_CLAUSE (t)); 424169689Skan dump_child ("else", ELSE_CLAUSE (t)); 425169689Skan break; 426169689Skan 427169689Skan case BREAK_STMT: 428169689Skan case CONTINUE_STMT: 429169689Skan dump_stmt (di, t); 430169689Skan break; 431169689Skan 432169689Skan case DO_STMT: 433169689Skan dump_stmt (di, t); 434169689Skan dump_child ("body", DO_BODY (t)); 435169689Skan dump_child ("cond", DO_COND (t)); 436260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 437260918Spfg dump_child ("attrs", DO_ATTRIBUTES (t)); 438260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 439169689Skan break; 440169689Skan 441169689Skan case FOR_STMT: 442169689Skan dump_stmt (di, t); 443169689Skan dump_child ("init", FOR_INIT_STMT (t)); 444169689Skan dump_child ("cond", FOR_COND (t)); 445169689Skan dump_child ("expr", FOR_EXPR (t)); 446169689Skan dump_child ("body", FOR_BODY (t)); 447260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 448260918Spfg dump_child ("attrs", FOR_ATTRIBUTES (t)); 449260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 450169689Skan break; 451169689Skan 452169689Skan case SWITCH_STMT: 453169689Skan dump_stmt (di, t); 454169689Skan dump_child ("cond", SWITCH_STMT_COND (t)); 455169689Skan dump_child ("body", SWITCH_STMT_BODY (t)); 456169689Skan break; 457169689Skan 458169689Skan case WHILE_STMT: 459169689Skan dump_stmt (di, t); 460169689Skan dump_child ("cond", WHILE_COND (t)); 461169689Skan dump_child ("body", WHILE_BODY (t)); 462260918Spfg/* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ 463260918Spfg dump_child ("attrs", WHILE_ATTRIBUTES (t)); 464260918Spfg/* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ 465169689Skan break; 466169689Skan 467169689Skan case STMT_EXPR: 468169689Skan dump_child ("stmt", STMT_EXPR_STMT (t)); 469169689Skan break; 470169689Skan 471169689Skan case EXPR_STMT: 472169689Skan dump_stmt (di, t); 473169689Skan dump_child ("expr", EXPR_STMT_EXPR (t)); 474169689Skan break; 475169689Skan 47690075Sobrien default: 47790075Sobrien break; 47890075Sobrien } 47990075Sobrien 480117395Skan return c_dump_tree (di, t); 48190075Sobrien} 482