1/* Prints out trees in human readable form. 2 Copyright (C) 1992-2022 Free Software Foundation, Inc. 3 Hacked by Michael Tiemann (tiemann@cygnus.com) 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "cp-tree.h" 26#include "print-tree.h" 27 28void 29cxx_print_decl (FILE *file, tree node, int indent) 30{ 31 if (TREE_CODE (node) == FIELD_DECL) 32 { 33 if (DECL_MUTABLE_P (node)) 34 { 35 indent_to (file, indent + 3); 36 fprintf (file, " mutable "); 37 } 38 return; 39 } 40 41 if (!CODE_CONTAINS_STRUCT (TREE_CODE (node), TS_DECL_COMMON) 42 || !DECL_LANG_SPECIFIC (node)) 43 return; 44 45 if (TREE_CODE (node) == FUNCTION_DECL) 46 { 47 int flags = TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE 48 |TFF_FUNCTION_DEFAULT_ARGUMENTS|TFF_EXCEPTION_SPECIFICATION ; 49 indent_to (file, indent + 3); 50 fprintf (file, " full-name \"%s\"", decl_as_string (node, flags)); 51 } 52 else if (TREE_CODE (node) == TEMPLATE_DECL) 53 { 54 print_node (file, "result", DECL_TEMPLATE_RESULT (node), indent + 4); 55 print_node (file, "parms", DECL_TEMPLATE_PARMS (node), indent + 4); 56 indent_to (file, indent + 3); 57 fprintf (file, " full-name \"%s\"", 58 decl_as_string (node, TFF_TEMPLATE_HEADER)); 59 } 60 61 bool need_indent = true; 62 63 tree ntnode = STRIP_TEMPLATE (node); 64 if (TREE_CODE (ntnode) == FUNCTION_DECL 65 || TREE_CODE (ntnode) == VAR_DECL 66 || TREE_CODE (ntnode) == TYPE_DECL 67 || TREE_CODE (ntnode) == CONCEPT_DECL 68 || TREE_CODE (ntnode) == NAMESPACE_DECL) 69 { 70 unsigned m = 0; 71 if (DECL_LANG_SPECIFIC (ntnode) && DECL_MODULE_IMPORT_P (ntnode)) 72 m = get_importing_module (ntnode, true); 73 74 if (const char *name = m == ~0u ? "" : module_name (m, true)) 75 { 76 if (need_indent) 77 indent_to (file, indent + 3); 78 fprintf (file, " module %d:%s", m, name); 79 need_indent = false; 80 } 81 82 if (DECL_LANG_SPECIFIC (ntnode) && DECL_MODULE_PURVIEW_P (ntnode)) 83 { 84 if (need_indent) 85 indent_to (file, indent + 3); 86 fprintf (file, " purview"); 87 need_indent = false; 88 } 89 } 90 91 if (DECL_MODULE_EXPORT_P (node)) 92 { 93 if (need_indent) 94 indent_to (file, indent + 3); 95 fprintf (file, " exported"); 96 need_indent = false; 97 } 98 99 if (DECL_EXTERNAL (node) && DECL_NOT_REALLY_EXTERN (node)) 100 { 101 if (need_indent) 102 indent_to (file, indent + 3); 103 fprintf (file, " not-really-extern"); 104 need_indent = false; 105 } 106 107 if (TREE_CODE (node) == FUNCTION_DECL 108 && DECL_PENDING_INLINE_INFO (node)) 109 { 110 if (need_indent) 111 indent_to (file, indent + 3); 112 fprintf (file, " pending-inline-info %p", 113 (void *) DECL_PENDING_INLINE_INFO (node)); 114 need_indent = false; 115 } 116 117 if (VAR_OR_FUNCTION_DECL_P (node) 118 && DECL_TEMPLATE_INFO (node)) 119 print_node (file, "template-info", DECL_TEMPLATE_INFO (node), 120 indent + 4); 121} 122 123void 124cxx_print_type (FILE *file, tree node, int indent) 125{ 126 switch (TREE_CODE (node)) 127 { 128 case BOUND_TEMPLATE_TEMPLATE_PARM: 129 print_node (file, "args", TYPE_TI_ARGS (node), indent + 4); 130 gcc_fallthrough (); 131 132 case TEMPLATE_TYPE_PARM: 133 case TEMPLATE_TEMPLATE_PARM: 134 indent_to (file, indent + 3); 135 fprintf (file, "index %d level %d orig_level %d", 136 TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node), 137 TEMPLATE_TYPE_ORIG_LEVEL (node)); 138 return; 139 140 case FUNCTION_TYPE: 141 case METHOD_TYPE: 142 if (TYPE_RAISES_EXCEPTIONS (node)) 143 print_node (file, "throws", TYPE_RAISES_EXCEPTIONS (node), indent + 4); 144 return; 145 146 case RECORD_TYPE: 147 case UNION_TYPE: 148 break; 149 150 case DECLTYPE_TYPE: 151 print_node (file, "expr", DECLTYPE_TYPE_EXPR (node), indent + 4); 152 return; 153 154 case DEPENDENT_OPERATOR_TYPE: 155 print_node (file, "saved_lookups", 156 DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS (node), 157 indent + 4); 158 return; 159 160 case TYPENAME_TYPE: 161 print_node (file, "fullname", TYPENAME_TYPE_FULLNAME (node), 162 indent + 4); 163 return; 164 165 case TYPEOF_TYPE: 166 print_node (file, "expr", TYPEOF_TYPE_EXPR (node), indent + 4); 167 return; 168 169 case BASES: 170 if (BASES_DIRECT (node)) 171 fputs (" direct", file); 172 print_node (file, "type", BASES_TYPE (node), indent + 4); 173 return; 174 175 case TYPE_PACK_EXPANSION: 176 print_node (file, "pattern", PACK_EXPANSION_PATTERN (node), indent + 4); 177 print_node (file, "args", PACK_EXPANSION_EXTRA_ARGS (node), indent + 4); 178 return; 179 180 default: 181 return; 182 } 183 184 if (TYPE_PTRMEMFUNC_P (node)) 185 print_node (file, "ptrmemfunc fn type", TYPE_PTRMEMFUNC_FN_TYPE (node), 186 indent + 4); 187 188 if (! CLASS_TYPE_P (node)) 189 return; 190 191 indent_to (file, indent + 4); 192 fprintf (file, "full-name \"%s\"", 193 type_as_string (node, TFF_CLASS_KEY_OR_ENUM)); 194 195 indent_to (file, indent + 3); 196 197 if (TYPE_NEEDS_CONSTRUCTING (node)) 198 fputs ( " needs-constructor", file); 199 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (node)) 200 fputs (" needs-destructor", file); 201 if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node)) 202 fputs (" X()", file); 203 if (TYPE_HAS_CONVERSION (node)) 204 fputs (" has-type-conversion", file); 205 if (TYPE_HAS_COPY_CTOR (node)) 206 { 207 if (TYPE_HAS_CONST_COPY_CTOR (node)) 208 fputs (" X(constX&)", file); 209 else 210 fputs (" X(X&)", file); 211 } 212 if (TYPE_HAS_NEW_OPERATOR (node)) 213 fputs (" new", file); 214 if (TYPE_HAS_ARRAY_NEW_OPERATOR (node)) 215 fputs (" new[]", file); 216 if (TYPE_GETS_DELETE (node) & 1) 217 fputs (" delete", file); 218 if (TYPE_GETS_DELETE (node) & 2) 219 fputs (" delete[]", file); 220 if (TYPE_HAS_COPY_ASSIGN (node)) 221 fputs (" this=(X&)", file); 222 223 if (TREE_CODE (node) == RECORD_TYPE) 224 { 225 if (TYPE_BINFO (node)) 226 fprintf (file, " n_parents=%d", 227 BINFO_N_BASE_BINFOS (TYPE_BINFO (node))); 228 else 229 fprintf (file, " no-binfo"); 230 231 fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node)); 232 if (CLASSTYPE_INTERFACE_ONLY (node)) 233 fprintf (file, " interface-only"); 234 if (CLASSTYPE_INTERFACE_UNKNOWN (node)) 235 fprintf (file, " interface-unknown"); 236 } 237} 238 239void 240cxx_print_identifier (FILE *file, tree node, int indent) 241{ 242 if (indent == 0) 243 fprintf (file, " "); 244 else 245 indent_to (file, indent + 4); 246 fprintf (file, "%s local bindings <%p>", get_identifier_kind_name (node), 247 (void *) IDENTIFIER_BINDING (node)); 248} 249 250void 251cxx_print_lambda_node (FILE *file, tree node, int indent) 252{ 253 if (LAMBDA_EXPR_MUTABLE_P (node)) 254 fprintf (file, " /mutable"); 255 fprintf (file, " default_capture_mode=["); 256 switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (node)) 257 { 258 case CPLD_NONE: 259 fprintf (file, "NONE"); 260 break; 261 case CPLD_COPY: 262 fprintf (file, "COPY"); 263 break; 264 case CPLD_REFERENCE: 265 fprintf (file, "CPLD_REFERENCE"); 266 break; 267 default: 268 fprintf (file, "??"); 269 break; 270 } 271 fprintf (file, "] "); 272 print_node (file, "capture_list", LAMBDA_EXPR_CAPTURE_LIST (node), indent + 4); 273 print_node (file, "this_capture", LAMBDA_EXPR_THIS_CAPTURE (node), indent + 4); 274} 275 276void 277cxx_print_xnode (FILE *file, tree node, int indent) 278{ 279 switch (TREE_CODE (node)) 280 { 281 case BASELINK: 282 print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4); 283 print_node (file, "binfo", BASELINK_BINFO (node), indent + 4); 284 print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node), 285 indent + 4); 286 print_node (file, "optype", BASELINK_OPTYPE (node), indent + 4); 287 break; 288 case OVERLOAD: 289 print_node (file, "function", OVL_FUNCTION (node), indent + 4); 290 print_node (file, "next", OVL_CHAIN (node), indent + 4); 291 break; 292 case BINDING_VECTOR: 293 { 294 unsigned len = BINDING_VECTOR_NUM_CLUSTERS (node); 295 print_node (file, "name", BINDING_VECTOR_NAME (node), indent + 4); 296 fprintf (file, " clusters %u, alloc %u", len, 297 BINDING_VECTOR_ALLOC_CLUSTERS (node)); 298 for (unsigned ix = 0; ix != len; ix++) 299 { 300 binding_cluster *cluster = &BINDING_VECTOR_CLUSTER (node, ix); 301 char pfx[32]; 302 for (unsigned jx = 0; jx != BINDING_VECTOR_SLOTS_PER_CLUSTER; jx++) 303 if (cluster->indices[jx].span) 304 { 305 int len = sprintf (pfx, "module:%u", 306 cluster->indices[jx].base); 307 if (cluster->indices[jx].span > 1) 308 len += sprintf (&pfx[len], "(+%u)", 309 cluster->indices[jx].span); 310 len += sprintf (&pfx[len], " cluster:%u/%u", ix, jx); 311 binding_slot &slot = cluster->slots[jx]; 312 if (slot.is_lazy ()) 313 { 314 indent_to (file, indent + 4); 315 unsigned lazy = slot.get_lazy (); 316 fprintf (file, "%s snum:%u", pfx, lazy); 317 } 318 else if (slot) 319 print_node (file, pfx, slot, indent + 4); 320 else 321 { 322 indent_to (file, indent + 4); 323 fprintf (file, "%s NULL", pfx); 324 } 325 } 326 } 327 } 328 break; 329 case TEMPLATE_PARM_INDEX: 330 print_node (file, "decl", TEMPLATE_PARM_DECL (node), indent+4); 331 indent_to (file, indent + 3); 332 fprintf (file, "index %d level %d orig_level %d", 333 TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node), 334 TEMPLATE_PARM_ORIG_LEVEL (node)); 335 break; 336 case TEMPLATE_INFO: 337 print_node (file, "template", TI_TEMPLATE (node), indent+4); 338 print_node (file, "args", TI_ARGS (node), indent+4); 339 if (TI_PENDING_TEMPLATE_FLAG (node)) 340 { 341 indent_to (file, indent + 3); 342 fprintf (file, "pending_template"); 343 } 344 break; 345 case CONSTRAINT_INFO: 346 { 347 tree_constraint_info *cinfo = (tree_constraint_info *)node; 348 if (cinfo->template_reqs) 349 print_node (file, "template_reqs", cinfo->template_reqs, indent+4); 350 if (cinfo->declarator_reqs) 351 print_node (file, "declarator_reqs", cinfo->declarator_reqs, 352 indent+4); 353 print_node (file, "associated_constr", 354 cinfo->associated_constr, indent+4); 355 break; 356 } 357 case ARGUMENT_PACK_SELECT: 358 print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node), 359 indent+4); 360 indent_to (file, indent + 3); 361 fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node)); 362 break; 363 case DEFERRED_NOEXCEPT: 364 print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4); 365 print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4); 366 break; 367 case TRAIT_EXPR: 368 indent_to (file, indent+4); 369 fprintf (file, "kind %d", TRAIT_EXPR_KIND (node)); 370 print_node (file, "type 1", TRAIT_EXPR_TYPE1 (node), indent+4); 371 if (TRAIT_EXPR_TYPE2 (node)) 372 print_node (file, "type 2", TRAIT_EXPR_TYPE2 (node), indent+4); 373 break; 374 case LAMBDA_EXPR: 375 cxx_print_lambda_node (file, node, indent); 376 break; 377 case STATIC_ASSERT: 378 if (location_t loc = STATIC_ASSERT_SOURCE_LOCATION (node)) 379 { 380 expanded_location xloc = expand_location (loc); 381 indent_to (file, indent+4); 382 fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column); 383 } 384 print_node (file, "condition", STATIC_ASSERT_CONDITION (node), indent+4); 385 if (tree message = STATIC_ASSERT_MESSAGE (node)) 386 print_node (file, "message", message, indent+4); 387 break; 388 case PTRMEM_CST: 389 print_node (file, "member", PTRMEM_CST_MEMBER (node), indent+4); 390 break; 391 default: 392 break; 393 } 394} 395 396/* Print the node NODE on standard error, for debugging. */ 397 398DEBUG_FUNCTION void 399debug_tree (cp_expr node) 400{ 401 debug_tree (node.get_value()); 402} 403 404DEBUG_FUNCTION void 405debug_overload (tree node) 406{ 407 FILE *file = stdout; 408 409 for (lkp_iterator iter (node); iter; ++iter) 410 { 411 tree decl = *iter; 412 auto xloc = expand_location (DECL_SOURCE_LOCATION (decl)); 413 auto fullname = decl_as_string (decl, 0); 414 bool using_p = iter.using_p (); 415 bool hidden_p = iter.hidden_p (); 416 417 fprintf (file, "%p:%c%c %s:%d:%d \"%s\"\n", (void *)decl, 418 hidden_p ? 'H' : '-', 419 using_p ? 'U' : '-', 420 xloc.file, xloc.line, xloc.column, fullname); 421 } 422} 423