|
|
1.1 ! root 1: /* Prints out tree in human readable form - GNU C-compiler ! 2: Copyright (C) 1990, 1991 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: #include "config.h" ! 22: #include "tree.h" ! 23: #include <stdio.h> ! 24: ! 25: extern char **tree_code_name; ! 26: ! 27: extern char *mode_name[]; ! 28: ! 29: void print_node (); ! 30: void indent_to (); ! 31: ! 32: /* Define the hash table of nodes already seen. ! 33: Such nodes are not repeated; brief cross-references are used. */ ! 34: ! 35: #define HASH_SIZE 37 ! 36: ! 37: struct bucket ! 38: { ! 39: tree node; ! 40: struct bucket *next; ! 41: }; ! 42: ! 43: static struct bucket **table; ! 44: ! 45: /* Print the node NODE on standard error, for debugging. ! 46: Most nodes referred to by this one are printed recursively ! 47: down to a depth of six. */ ! 48: ! 49: void ! 50: debug_tree (node) ! 51: tree node; ! 52: { ! 53: char *object = (char *) oballoc (0); ! 54: table = (struct bucket **) oballoc (HASH_SIZE * sizeof (struct bucket *)); ! 55: bzero (table, HASH_SIZE * sizeof (struct bucket *)); ! 56: print_node (stderr, "", node, 0); ! 57: table = 0; ! 58: obfree (object); ! 59: fprintf (stderr, "\n"); ! 60: } ! 61: ! 62: /* Print a node in brief fashion, with just the code, address and name. */ ! 63: ! 64: void ! 65: print_node_brief (file, prefix, node, indent) ! 66: FILE *file; ! 67: char *prefix; ! 68: tree node; ! 69: int indent; ! 70: { ! 71: char class; ! 72: ! 73: if (node == 0) ! 74: return; ! 75: ! 76: class = TREE_CODE_CLASS (TREE_CODE (node)); ! 77: ! 78: /* Always print the slot this node is in, and its code, address and ! 79: name if any. */ ! 80: if (indent > 0) ! 81: fprintf (file, " "); ! 82: fprintf (file, "%s <%s %x", prefix, ! 83: tree_code_name[(int) TREE_CODE (node)], (int) node); ! 84: ! 85: if (class == 'd') ! 86: { ! 87: if (DECL_NAME (node)) ! 88: fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node))); ! 89: } ! 90: else if (class == 't') ! 91: { ! 92: if (TYPE_NAME (node)) ! 93: { ! 94: if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) ! 95: fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node))); ! 96: else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL ! 97: && DECL_NAME (TYPE_NAME (node))) ! 98: fprintf (file, " %s", ! 99: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)))); ! 100: } ! 101: } ! 102: if (TREE_CODE (node) == IDENTIFIER_NODE) ! 103: fprintf (file, " %s", IDENTIFIER_POINTER (node)); ! 104: /* We might as well always print the value of an integer. */ ! 105: if (TREE_CODE (node) == INTEGER_CST) ! 106: { ! 107: if (TREE_INT_CST_HIGH (node) == 0) ! 108: fprintf (file, " %1u", TREE_INT_CST_LOW (node)); ! 109: else if (TREE_INT_CST_HIGH (node) == -1 ! 110: && TREE_INT_CST_LOW (node) != 0) ! 111: fprintf (file, " -%1u", -TREE_INT_CST_LOW (node)); ! 112: else ! 113: fprintf (file, " 0x%x%08x", ! 114: TREE_INT_CST_HIGH (node), ! 115: TREE_INT_CST_LOW (node)); ! 116: } ! 117: if (TREE_CODE (node) == REAL_CST) ! 118: { ! 119: #ifndef REAL_IS_NOT_DOUBLE ! 120: fprintf (file, " %e", TREE_REAL_CST (node)); ! 121: #else ! 122: { ! 123: int i; ! 124: char *p = (char *) &TREE_REAL_CST (node); ! 125: fprintf (file, " 0x"); ! 126: for (i = 0; i < sizeof TREE_REAL_CST (node); i++) ! 127: fprintf (file, "%02x", *p++); ! 128: fprintf (file, ""); ! 129: } ! 130: #endif /* REAL_IS_NOT_DOUBLE */ ! 131: } ! 132: ! 133: fprintf (file, ">"); ! 134: } ! 135: ! 136: void ! 137: indent_to (file, column) ! 138: FILE *file; ! 139: int column; ! 140: { ! 141: int i; ! 142: ! 143: /* Since this is the long way, indent to desired column. */ ! 144: if (column > 0) ! 145: fprintf (file, "\n"); ! 146: for (i = 0; i < column; i++) ! 147: fprintf (file, " "); ! 148: } ! 149: ! 150: /* Print the node NODE in full on file FILE, preceded by PREFIX, ! 151: starting in column INDENT. */ ! 152: ! 153: void ! 154: print_node (file, prefix, node, indent) ! 155: FILE *file; ! 156: char *prefix; ! 157: tree node; ! 158: int indent; ! 159: { ! 160: int hash; ! 161: struct bucket *b; ! 162: enum machine_mode mode; ! 163: char class; ! 164: int len; ! 165: int first_rtl; ! 166: int i; ! 167: ! 168: if (node == 0) ! 169: return; ! 170: ! 171: class = TREE_CODE_CLASS (TREE_CODE (node)); ! 172: ! 173: /* Don't get too deep in nesting. If the user wants to see deeper, ! 174: it is easy to use the address of a lowest-level node ! 175: as an argument in another call to debug_tree. */ ! 176: ! 177: if (indent > 24) ! 178: { ! 179: print_node_brief (file, prefix, node, indent); ! 180: return; ! 181: } ! 182: ! 183: if (indent > 8 && (class == 't' || class == 'd')) ! 184: { ! 185: print_node_brief (file, prefix, node, indent); ! 186: return; ! 187: } ! 188: ! 189: /* It is unsafe to look at any other filds of an ERROR_MARK node. */ ! 190: if (TREE_CODE (node) == ERROR_MARK) ! 191: { ! 192: print_node_brief (file, prefix, node, indent); ! 193: return; ! 194: } ! 195: ! 196: hash = ((int) node & ~(1 << (HOST_BITS_PER_INT - 1))) % HASH_SIZE; ! 197: ! 198: /* If node is in the table, just mention its address. */ ! 199: for (b = table[hash]; b; b = b->next) ! 200: if (b->node == node) ! 201: { ! 202: print_node_brief (file, prefix, node, indent); ! 203: return; ! 204: } ! 205: ! 206: /* Add this node to the table. */ ! 207: b = (struct bucket *) oballoc (sizeof (struct bucket)); ! 208: b->node = node; ! 209: b->next = table[hash]; ! 210: table[hash] = b; ! 211: ! 212: /* Indent to the specified column, since this is the long form. */ ! 213: indent_to (file, indent); ! 214: ! 215: /* Print the slot this node is in, and its code, and address. */ ! 216: fprintf (file, "%s <%s %x", prefix, ! 217: tree_code_name[(int) TREE_CODE (node)], (int) node); ! 218: ! 219: /* Print the name, if any. */ ! 220: if (class == 'd') ! 221: { ! 222: if (DECL_NAME (node)) ! 223: fprintf (file, " %s", IDENTIFIER_POINTER (DECL_NAME (node))); ! 224: } ! 225: else if (class == 't') ! 226: { ! 227: if (TYPE_NAME (node)) ! 228: { ! 229: if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) ! 230: fprintf (file, " %s", IDENTIFIER_POINTER (TYPE_NAME (node))); ! 231: else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL ! 232: && DECL_NAME (TYPE_NAME (node))) ! 233: fprintf (file, " %s", ! 234: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)))); ! 235: } ! 236: } ! 237: if (TREE_CODE (node) == IDENTIFIER_NODE) ! 238: fprintf (file, " %s", IDENTIFIER_POINTER (node)); ! 239: ! 240: if (TREE_CODE (node) == INTEGER_CST) ! 241: { ! 242: if (indent <= 4) ! 243: print_node_brief (file, "type", TREE_TYPE (node), indent + 4); ! 244: } ! 245: else ! 246: { ! 247: print_node (file, "type", TREE_TYPE (node), indent + 4); ! 248: if (TREE_TYPE (node)) ! 249: indent_to (file, indent + 3); ! 250: } ! 251: ! 252: /* If a permanent object is in the wrong obstack, or the reverse, warn. */ ! 253: if (object_permanent_p (node) != TREE_PERMANENT (node)) ! 254: { ! 255: if (TREE_PERMANENT (node)) ! 256: fputs (" !!permanent object in non-permanent obstack!!", file); ! 257: else ! 258: fputs (" !!non-permanent object in permanent obstack!!", file); ! 259: indent_to (file, indent + 3); ! 260: } ! 261: ! 262: if (TREE_SIDE_EFFECTS (node)) ! 263: fputs (" side-effects", file); ! 264: if (TREE_READONLY (node)) ! 265: fputs (" readonly", file); ! 266: if (TREE_CONSTANT (node)) ! 267: fputs (" constant", file); ! 268: if (TREE_ADDRESSABLE (node)) ! 269: fputs (" addressable", file); ! 270: if (TREE_THIS_VOLATILE (node)) ! 271: fputs (" volatile", file); ! 272: if (TREE_UNSIGNED (node)) ! 273: fputs (" unsigned", file); ! 274: if (TREE_ASM_WRITTEN (node)) ! 275: fputs (" asm_written", file); ! 276: if (TREE_USED (node)) ! 277: fputs (" used", file); ! 278: if (TREE_PERMANENT (node)) ! 279: fputs (" permanent", file); ! 280: if (TREE_PUBLIC (node)) ! 281: fputs (" public", file); ! 282: if (TREE_STATIC (node)) ! 283: fputs (" static", file); ! 284: if (TREE_LANG_FLAG_0 (node)) ! 285: fputs (" tree_0", file); ! 286: if (TREE_LANG_FLAG_1 (node)) ! 287: fputs (" tree_1", file); ! 288: if (TREE_LANG_FLAG_2 (node)) ! 289: fputs (" tree_2", file); ! 290: if (TREE_LANG_FLAG_3 (node)) ! 291: fputs (" tree_3", file); ! 292: if (TREE_LANG_FLAG_4 (node)) ! 293: fputs (" tree_4", file); ! 294: if (TREE_LANG_FLAG_5 (node)) ! 295: fputs (" tree_5", file); ! 296: if (TREE_LANG_FLAG_6 (node)) ! 297: fputs (" tree_6", file); ! 298: ! 299: /* DECL_ nodes have additional attributes. */ ! 300: ! 301: switch (TREE_CODE_CLASS (TREE_CODE (node))) ! 302: { ! 303: case 'd': ! 304: mode = DECL_MODE (node); ! 305: ! 306: if (TREE_EXTERNAL (node)) ! 307: fputs (" external", file); ! 308: if (TREE_NONLOCAL (node)) ! 309: fputs (" nonlocal", file); ! 310: if (TREE_REGDECL (node)) ! 311: fputs (" regdecl", file); ! 312: if (TREE_INLINE (node)) ! 313: fputs (" inline", file); ! 314: if (DECL_BIT_FIELD (node)) ! 315: fputs (" bit-field", file); ! 316: if (DECL_VIRTUAL_P (node)) ! 317: fputs (" virtual", file); ! 318: if (DECL_FROM_INLINE (node)) ! 319: fputs (" from_inline", file); ! 320: if (DECL_IGNORED_P (node)) ! 321: fputs (" ignored", file); ! 322: if (DECL_LANG_FLAG_0 (node)) ! 323: fputs (" decl_0", file); ! 324: if (DECL_LANG_FLAG_1 (node)) ! 325: fputs (" decl_1", file); ! 326: if (DECL_LANG_FLAG_2 (node)) ! 327: fputs (" decl_2", file); ! 328: if (DECL_LANG_FLAG_3 (node)) ! 329: fputs (" decl_3", file); ! 330: if (DECL_LANG_FLAG_4 (node)) ! 331: fputs (" decl_4", file); ! 332: if (DECL_LANG_FLAG_5 (node)) ! 333: fputs (" decl_5", file); ! 334: if (DECL_LANG_FLAG_6 (node)) ! 335: fputs (" decl_6", file); ! 336: if (DECL_LANG_FLAG_7 (node)) ! 337: fputs (" decl_7", file); ! 338: ! 339: fprintf (file, " %s", mode_name[(int) mode]); ! 340: ! 341: fprintf (file, " file %s line %d", ! 342: DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node)); ! 343: ! 344: print_node (file, "size", DECL_SIZE (node), indent + 4); ! 345: indent_to (file, indent + 3); ! 346: fprintf (file, " align %d", DECL_ALIGN (node)); ! 347: fprintf (file, " frame_size %d", DECL_FRAME_SIZE (node)); ! 348: if (TREE_CODE (node) == FIELD_DECL) ! 349: print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4); ! 350: print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4); ! 351: ! 352: print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4); ! 353: print_node (file, "result", DECL_RESULT (node), indent + 4); ! 354: print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4); ! 355: ! 356: print_lang_decl (file, node, indent); ! 357: ! 358: if (DECL_RTL (node) != 0) ! 359: { ! 360: indent_to (file, indent + 4); ! 361: print_rtl (file, DECL_RTL (node)); ! 362: } ! 363: ! 364: if (DECL_SAVED_INSNS (node) != 0) ! 365: { ! 366: indent_to (file, indent + 4); ! 367: if (TREE_CODE (node) == PARM_DECL) ! 368: { ! 369: fprintf (file, "incoming-rtl "); ! 370: print_rtl (file, DECL_INCOMING_RTL (node)); ! 371: } ! 372: else if (TREE_CODE (node) == FUNCTION_DECL) ! 373: fprintf (file, "saved-insns 0x%x", DECL_SAVED_INSNS (node)); ! 374: } ! 375: ! 376: /* Print the decl chain only if decl is at second level. */ ! 377: if (indent == 4) ! 378: print_node (file, "chain", TREE_CHAIN (node), indent + 4); ! 379: else ! 380: print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4); ! 381: break; ! 382: ! 383: case 't': ! 384: if (TYPE_NO_FORCE_BLK (node)) ! 385: fputs (" no_force_blk", file); ! 386: if (TYPE_LANG_FLAG_0 (node)) ! 387: fputs (" type_0", file); ! 388: if (TYPE_LANG_FLAG_1 (node)) ! 389: fputs (" type_1", file); ! 390: if (TYPE_LANG_FLAG_2 (node)) ! 391: fputs (" type_2", file); ! 392: if (TYPE_LANG_FLAG_3 (node)) ! 393: fputs (" type_3", file); ! 394: if (TYPE_LANG_FLAG_4 (node)) ! 395: fputs (" type_4", file); ! 396: if (TYPE_LANG_FLAG_5 (node)) ! 397: fputs (" type_5", file); ! 398: if (TYPE_LANG_FLAG_6 (node)) ! 399: fputs (" type_6", file); ! 400: ! 401: mode = TYPE_MODE (node); ! 402: fprintf (file, " %s", mode_name[(int) mode]); ! 403: ! 404: print_node (file, "size", TYPE_SIZE (node), indent + 4); ! 405: indent_to (file, indent + 3); ! 406: ! 407: fprintf (file, " align %d", TYPE_ALIGN (node)); ! 408: fprintf (file, " symtab %d", TYPE_SYMTAB_ADDRESS (node)); ! 409: ! 410: if (TREE_CODE (node) == ARRAY_TYPE || TREE_CODE (node) == SET_TYPE) ! 411: print_node (file, "domain", TYPE_DOMAIN (node), indent + 4); ! 412: else if (TREE_CODE (node) == INTEGER_TYPE) ! 413: { ! 414: fprintf (file, " precision %d", TYPE_PRECISION (node)); ! 415: print_node (file, "min", TYPE_MIN_VALUE (node), indent + 4); ! 416: print_node (file, "max", TYPE_MAX_VALUE (node), indent + 4); ! 417: } ! 418: else if (TREE_CODE (node) == ENUMERAL_TYPE) ! 419: { ! 420: fprintf (file, " precision %d", TYPE_PRECISION (node)); ! 421: print_node (file, "min", TYPE_MIN_VALUE (node), indent + 4); ! 422: print_node (file, "max", TYPE_MAX_VALUE (node), indent + 4); ! 423: print_node (file, "values", TYPE_VALUES (node), indent + 4); ! 424: } ! 425: else if (TREE_CODE (node) == REAL_TYPE) ! 426: fprintf (file, " precision %d", TYPE_PRECISION (node)); ! 427: else if (TREE_CODE (node) == RECORD_TYPE || TREE_CODE (node) == UNION_TYPE) ! 428: print_node (file, "fields", TYPE_FIELDS (node), indent + 4); ! 429: else if (TREE_CODE (node) == FUNCTION_TYPE || TREE_CODE (node) == METHOD_TYPE) ! 430: { ! 431: if (TYPE_METHOD_BASETYPE (node)) ! 432: print_node_brief (file, "method basetype", TYPE_METHOD_BASETYPE (node), indent + 4); ! 433: print_node (file, "arg-types", TYPE_ARG_TYPES (node), indent + 4); ! 434: } ! 435: if (TYPE_CONTEXT (node)) ! 436: print_node_brief (file, "context", TYPE_CONTEXT (node), indent + 4); ! 437: ! 438: print_lang_type (file, node, indent); ! 439: ! 440: if (TYPE_POINTER_TO (node) || TREE_CHAIN (node)) ! 441: indent_to (file, indent + 3); ! 442: print_node_brief (file, "pointer_to_this", TYPE_POINTER_TO (node), indent + 4); ! 443: print_node_brief (file, "reference_to_this", TYPE_REFERENCE_TO (node), indent + 4); ! 444: print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4); ! 445: break; ! 446: ! 447: case 'e': ! 448: case '<': ! 449: case '1': ! 450: case '2': ! 451: case 'r': ! 452: case 's': ! 453: switch (TREE_CODE (node)) ! 454: { ! 455: case BLOCK: ! 456: print_node (file, "vars", BLOCK_VARS (node), indent + 4); ! 457: print_node (file, "tags", BLOCK_TYPE_TAGS (node), indent + 4); ! 458: print_node (file, "supercontext", BLOCK_SUPERCONTEXT (node), indent + 4); ! 459: print_node (file, "subblocks", BLOCK_SUBBLOCKS (node), indent + 4); ! 460: print_node (file, "chain", BLOCK_CHAIN (node), indent + 4); ! 461: return; ! 462: ! 463: case BIND_EXPR: ! 464: print_node (file, "vars", TREE_OPERAND (node, 0), indent + 4); ! 465: print_node (file, "body", TREE_OPERAND (node, 1), indent + 4); ! 466: return; ! 467: } ! 468: ! 469: first_rtl = len = tree_code_length[(int) TREE_CODE (node)]; ! 470: /* These kinds of nodes contain rtx's, not trees, ! 471: after a certain point. Print the rtx's as rtx's. */ ! 472: switch (TREE_CODE (node)) ! 473: { ! 474: case SAVE_EXPR: ! 475: first_rtl = 2; ! 476: break; ! 477: case CALL_EXPR: ! 478: first_rtl = 2; ! 479: break; ! 480: case METHOD_CALL_EXPR: ! 481: first_rtl = 3; ! 482: break; ! 483: case WITH_CLEANUP_EXPR: ! 484: /* Should be defined to be 2. */ ! 485: first_rtl = 1; ! 486: break; ! 487: case RTL_EXPR: ! 488: first_rtl = 0; ! 489: } ! 490: for (i = 0; i < len; i++) ! 491: { ! 492: if (i >= first_rtl) ! 493: { ! 494: indent_to (file, indent + 4); ! 495: fprintf (file, "rtl %d ", i); ! 496: if (TREE_OPERAND (node, i)) ! 497: print_rtl (file, TREE_OPERAND (node, i)); ! 498: else ! 499: fprintf (file, "(nil)"); ! 500: fprintf (file, "\n"); ! 501: } ! 502: else ! 503: { ! 504: char temp[10]; ! 505: ! 506: sprintf (temp, "arg %d", i); ! 507: print_node (file, temp, TREE_OPERAND (node, i), indent + 4); ! 508: } ! 509: } ! 510: break; ! 511: ! 512: case 'c': ! 513: case 'x': ! 514: switch (TREE_CODE (node)) ! 515: { ! 516: case INTEGER_CST: ! 517: if (TREE_INT_CST_HIGH (node) == 0) ! 518: fprintf (file, " %1u", TREE_INT_CST_LOW (node)); ! 519: else if (TREE_INT_CST_HIGH (node) == -1 ! 520: && TREE_INT_CST_LOW (node) != 0) ! 521: fprintf (file, " -%1u", -TREE_INT_CST_LOW (node)); ! 522: else ! 523: fprintf (file, " 0x%x%08x", ! 524: TREE_INT_CST_HIGH (node), ! 525: TREE_INT_CST_LOW (node)); ! 526: break; ! 527: ! 528: case REAL_CST: ! 529: #ifndef REAL_IS_NOT_DOUBLE ! 530: fprintf (file, " %e", TREE_REAL_CST (node)); ! 531: #else ! 532: { ! 533: char *p = (char *) &TREE_REAL_CST (node); ! 534: fprintf (file, " 0x"); ! 535: for (i = 0; i < sizeof TREE_REAL_CST (node); i++) ! 536: fprintf (file, "%02x", *p++); ! 537: fprintf (file, ""); ! 538: } ! 539: #endif /* REAL_IS_NOT_DOUBLE */ ! 540: break; ! 541: ! 542: case COMPLEX_CST: ! 543: print_node (file, "real", TREE_REALPART (node), indent + 4); ! 544: print_node (file, "imag", TREE_IMAGPART (node), indent + 4); ! 545: break; ! 546: ! 547: case STRING_CST: ! 548: fprintf (file, " \"%s\"", TREE_STRING_POINTER (node)); ! 549: break; ! 550: ! 551: case IDENTIFIER_NODE: ! 552: print_lang_identifier (file, node, indent); ! 553: break; ! 554: ! 555: case TREE_LIST: ! 556: print_node (file, "purpose", TREE_PURPOSE (node), indent + 4); ! 557: print_node (file, "value", TREE_VALUE (node), indent + 4); ! 558: print_node (file, "chain", TREE_CHAIN (node), indent + 4); ! 559: break; ! 560: ! 561: case TREE_VEC: ! 562: len = TREE_VEC_LENGTH (node); ! 563: for (i = 0; i < len; i++) ! 564: { ! 565: char temp[10]; ! 566: sprintf (temp, "elt %d", i); ! 567: indent_to (file, indent + 4); ! 568: print_node_brief (file, temp, TREE_VEC_ELT (node, i), 0); ! 569: } ! 570: break; ! 571: ! 572: case OP_IDENTIFIER: ! 573: print_node (file, "op1", TREE_PURPOSE (node), indent + 4); ! 574: print_node (file, "op2", TREE_VALUE (node), indent + 4); ! 575: } ! 576: ! 577: break; ! 578: } ! 579: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.