sdbout.c revision 52284
118334Speter/* Output sdb-format symbol table information from GNU compiler. 250397Sobrien Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. 318334Speter 418334SpeterThis file is part of GNU CC. 518334Speter 618334SpeterGNU CC is free software; you can redistribute it and/or modify 718334Speterit under the terms of the GNU General Public License as published by 818334Speterthe Free Software Foundation; either version 2, or (at your option) 918334Speterany later version. 1018334Speter 1118334SpeterGNU CC is distributed in the hope that it will be useful, 1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1418334SpeterGNU General Public License for more details. 1518334Speter 1618334SpeterYou should have received a copy of the GNU General Public License 1718334Speteralong with GNU CC; see the file COPYING. If not, write to 1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 1918334SpeterBoston, MA 02111-1307, USA. */ 2018334Speter 2118334Speter/* mike@tredysvr.Tredydev.Unisys.COM says: 2218334SpeterI modified the struct.c example and have a nm of a .o resulting from the 2318334SpeterAT&T C compiler. From the example below I would conclude the following: 2418334Speter 2518334Speter1. All .defs from structures are emitted as scanned. The example below 2618334Speter clearly shows the symbol table entries for BoxRec2 are after the first 2718334Speter function. 2818334Speter 2918334Speter2. All functions and their locals (including statics) are emitted as scanned. 3018334Speter 3118334Speter3. All nested unnamed union and structure .defs must be emitted before 3218334Speter the structure in which they are nested. The AT&T assembler is a 3318334Speter one pass beast as far as symbolics are concerned. 3418334Speter 3518334Speter4. All structure .defs are emitted before the typedefs that refer to them. 3618334Speter 3718334Speter5. All top level static and external variable definitions are moved to the 3818334Speter end of file with all top level statics occurring first before externs. 3918334Speter 4018334Speter6. All undefined references are at the end of the file. 4118334Speter*/ 4218334Speter 4318334Speter#include "config.h" 4418334Speter 4518334Speter#ifdef SDB_DEBUGGING_INFO 4618334Speter 4750397Sobrien#include "system.h" 4818334Speter#include "tree.h" 4918334Speter#include "rtl.h" 5018334Speter#include "regs.h" 5150397Sobrien#include "defaults.h" 5218334Speter#include "flags.h" 5318334Speter#include "insn-config.h" 5418334Speter#include "reload.h" 5550397Sobrien#include "output.h" 5650397Sobrien#include "toplev.h" 5718334Speter 5850397Sobrien/* Mips systems use the SDB functions to dump out symbols, but do not 5950397Sobrien supply usable syms.h include files. Which syms.h file to use is a 6050397Sobrien target parameter so don't use the native one if we're cross compiling. */ 6150397Sobrien 6252284Sobrien#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(__INTERIX) && !defined(CROSS_COMPILE) 6318334Speter#include <syms.h> 6418334Speter/* Use T_INT if we don't have T_VOID. */ 6518334Speter#ifndef T_VOID 6618334Speter#define T_VOID T_INT 6718334Speter#endif 6850397Sobrien#else 6918334Speter#include "gsyms.h" 7050397Sobrien#endif 7118334Speter 7218334Speter/* #include <storclass.h> used to be this instead of syms.h. */ 7318334Speter 7418334Speter/* 1 if PARM is passed to this function in memory. */ 7518334Speter 7618334Speter#define PARM_PASSED_IN_MEMORY(PARM) \ 7718334Speter (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM) 7818334Speter 7918334Speter/* A C expression for the integer offset value of an automatic variable 8018334Speter (C_AUTO) having address X (an RTX). */ 8118334Speter#ifndef DEBUGGER_AUTO_OFFSET 8218334Speter#define DEBUGGER_AUTO_OFFSET(X) \ 8318334Speter (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) 8418334Speter#endif 8518334Speter 8618334Speter/* A C expression for the integer offset value of an argument (C_ARG) 8718334Speter having address X (an RTX). The nominal offset is OFFSET. */ 8818334Speter#ifndef DEBUGGER_ARG_OFFSET 8918334Speter#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) 9018334Speter#endif 9118334Speter 9218334Speter/* Line number of beginning of current function, minus one. 9318334Speter Negative means not in a function or not using sdb. */ 9418334Speter 9518334Speterint sdb_begin_function_line = -1; 9618334Speter 9718334Speter/* Counter to generate unique "names" for nameless struct members. */ 9818334Speter 9918334Speterstatic int unnamed_struct_number = 0; 10018334Speter 10118334Speterextern FILE *asm_out_file; 10218334Speter 10318334Speterextern tree current_function_decl; 10418334Speter 10550397Sobrien#include "sdbout.h" 10618334Speter 10750397Sobrienstatic char *gen_fake_label PROTO((void)); 10850397Sobrienstatic int plain_type PROTO((tree)); 10950397Sobrienstatic int template_name_p PROTO((tree)); 11050397Sobrienstatic void sdbout_record_type_name PROTO((tree)); 11150397Sobrienstatic int plain_type_1 PROTO((tree, int)); 11250397Sobrienstatic void sdbout_block PROTO((tree)); 11350397Sobrienstatic void sdbout_syms PROTO((tree)); 11450397Sobrienstatic void sdbout_queue_anonymous_type PROTO((tree)); 11550397Sobrienstatic void sdbout_dequeue_anonymous_types PROTO((void)); 11650397Sobrienstatic void sdbout_type PROTO((tree)); 11750397Sobrienstatic void sdbout_field_types PROTO((tree)); 11850397Sobrienstatic void sdbout_one_type PROTO((tree)); 11950397Sobrienstatic void sdbout_parms PROTO((tree)); 12050397Sobrienstatic void sdbout_reg_parms PROTO((tree)); 12118334Speter 12218334Speter/* Define the default sizes for various types. */ 12318334Speter 12418334Speter#ifndef CHAR_TYPE_SIZE 12518334Speter#define CHAR_TYPE_SIZE BITS_PER_UNIT 12618334Speter#endif 12718334Speter 12818334Speter#ifndef SHORT_TYPE_SIZE 12918334Speter#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) 13018334Speter#endif 13118334Speter 13218334Speter#ifndef INT_TYPE_SIZE 13318334Speter#define INT_TYPE_SIZE BITS_PER_WORD 13418334Speter#endif 13518334Speter 13618334Speter#ifndef LONG_TYPE_SIZE 13718334Speter#define LONG_TYPE_SIZE BITS_PER_WORD 13818334Speter#endif 13918334Speter 14018334Speter#ifndef LONG_LONG_TYPE_SIZE 14118334Speter#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) 14218334Speter#endif 14318334Speter 14418334Speter#ifndef FLOAT_TYPE_SIZE 14518334Speter#define FLOAT_TYPE_SIZE BITS_PER_WORD 14618334Speter#endif 14718334Speter 14818334Speter#ifndef DOUBLE_TYPE_SIZE 14918334Speter#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 15018334Speter#endif 15118334Speter 15218334Speter#ifndef LONG_DOUBLE_TYPE_SIZE 15318334Speter#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 15418334Speter#endif 15518334Speter 15618334Speter/* Random macros describing parts of SDB data. */ 15718334Speter 15818334Speter/* Put something here if lines get too long */ 15918334Speter#define CONTIN 16018334Speter 16118334Speter/* Default value of delimiter is ";". */ 16218334Speter#ifndef SDB_DELIM 16318334Speter#define SDB_DELIM ";" 16418334Speter#endif 16518334Speter 16618334Speter/* Maximum number of dimensions the assembler will allow. */ 16718334Speter#ifndef SDB_MAX_DIM 16818334Speter#define SDB_MAX_DIM 4 16918334Speter#endif 17018334Speter 17118334Speter#ifndef PUT_SDB_SCL 17218334Speter#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM) 17318334Speter#endif 17418334Speter 17518334Speter#ifndef PUT_SDB_INT_VAL 17650397Sobrien#define PUT_SDB_INT_VAL(a) \ 17750397Sobrien do { \ 17850397Sobrien fputs ("\t.val\t", asm_out_file); \ 17950397Sobrien fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \ 18050397Sobrien fprintf (asm_out_file, "%s", SDB_DELIM); \ 18150397Sobrien } while (0) 18250397Sobrien 18318334Speter#endif 18418334Speter 18518334Speter#ifndef PUT_SDB_VAL 18618334Speter#define PUT_SDB_VAL(a) \ 18718334Speter( fputs ("\t.val\t", asm_out_file), \ 18818334Speter output_addr_const (asm_out_file, (a)), \ 18918334Speter fprintf (asm_out_file, SDB_DELIM)) 19018334Speter#endif 19118334Speter 19218334Speter#ifndef PUT_SDB_DEF 19318334Speter#define PUT_SDB_DEF(a) \ 19418334Speterdo { fprintf (asm_out_file, "\t.def\t"); \ 19518334Speter ASM_OUTPUT_LABELREF (asm_out_file, a); \ 19618334Speter fprintf (asm_out_file, SDB_DELIM); } while (0) 19718334Speter#endif 19818334Speter 19918334Speter#ifndef PUT_SDB_PLAIN_DEF 20018334Speter#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM) 20118334Speter#endif 20218334Speter 20318334Speter#ifndef PUT_SDB_ENDEF 20418334Speter#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file) 20518334Speter#endif 20618334Speter 20718334Speter#ifndef PUT_SDB_TYPE 20818334Speter#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM) 20918334Speter#endif 21018334Speter 21118334Speter#ifndef PUT_SDB_SIZE 21250397Sobrien#define PUT_SDB_SIZE(a) \ 21350397Sobrien do { \ 21450397Sobrien fputs ("\t.size\t", asm_out_file); \ 21550397Sobrien fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(a)); \ 21650397Sobrien fprintf (asm_out_file, "%s", SDB_DELIM); \ 21750397Sobrien } while(0) 21818334Speter#endif 21918334Speter 22018334Speter#ifndef PUT_SDB_START_DIM 22118334Speter#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t") 22218334Speter#endif 22318334Speter 22418334Speter#ifndef PUT_SDB_NEXT_DIM 22518334Speter#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a) 22618334Speter#endif 22718334Speter 22818334Speter#ifndef PUT_SDB_LAST_DIM 22918334Speter#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM) 23018334Speter#endif 23118334Speter 23218334Speter#ifndef PUT_SDB_TAG 23318334Speter#define PUT_SDB_TAG(a) \ 23418334Speterdo { fprintf (asm_out_file, "\t.tag\t"); \ 23518334Speter ASM_OUTPUT_LABELREF (asm_out_file, a); \ 23618334Speter fprintf (asm_out_file, SDB_DELIM); } while (0) 23718334Speter#endif 23818334Speter 23918334Speter#ifndef PUT_SDB_BLOCK_START 24018334Speter#define PUT_SDB_BLOCK_START(LINE) \ 24118334Speter fprintf (asm_out_file, \ 24218334Speter "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ 24318334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 24418334Speter#endif 24518334Speter 24618334Speter#ifndef PUT_SDB_BLOCK_END 24718334Speter#define PUT_SDB_BLOCK_END(LINE) \ 24818334Speter fprintf (asm_out_file, \ 24918334Speter "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ 25018334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 25118334Speter#endif 25218334Speter 25318334Speter#ifndef PUT_SDB_FUNCTION_START 25418334Speter#define PUT_SDB_FUNCTION_START(LINE) \ 25518334Speter fprintf (asm_out_file, \ 25618334Speter "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ 25718334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 25818334Speter#endif 25918334Speter 26018334Speter#ifndef PUT_SDB_FUNCTION_END 26118334Speter#define PUT_SDB_FUNCTION_END(LINE) \ 26218334Speter fprintf (asm_out_file, \ 26318334Speter "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ 26418334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 26518334Speter#endif 26618334Speter 26718334Speter#ifndef PUT_SDB_EPILOGUE_END 26818334Speter#define PUT_SDB_EPILOGUE_END(NAME) \ 26918334Speterdo { fprintf (asm_out_file, "\t.def\t"); \ 27018334Speter ASM_OUTPUT_LABELREF (asm_out_file, NAME); \ 27118334Speter fprintf (asm_out_file, \ 27218334Speter "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \ 27318334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0) 27418334Speter#endif 27518334Speter 27618334Speter#ifndef SDB_GENERATE_FAKE 27718334Speter#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \ 27818334Speter sprintf ((BUFFER), ".%dfake", (NUMBER)); 27918334Speter#endif 28018334Speter 28118334Speter/* Return the sdb tag identifier string for TYPE 28218334Speter if TYPE has already been defined; otherwise return a null pointer. */ 28318334Speter 28418334Speter#define KNOWN_TYPE_TAG(type) TYPE_SYMTAB_POINTER (type) 28518334Speter 28618334Speter/* Set the sdb tag identifier string for TYPE to NAME. */ 28718334Speter 28818334Speter#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \ 28918334Speter TYPE_SYMTAB_POINTER (TYPE) = (NAME) 29018334Speter 29118334Speter/* Return the name (a string) of the struct, union or enum tag 29218334Speter described by the TREE_LIST node LINK. This is 0 for an anonymous one. */ 29318334Speter 29418334Speter#define TAG_NAME(link) \ 29518334Speter (((link) && TREE_PURPOSE ((link)) \ 29618334Speter && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \ 29718334Speter ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0) 29818334Speter 29918334Speter/* Ensure we don't output a negative line number. */ 30018334Speter#define MAKE_LINE_SAFE(line) \ 30118334Speter if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1 30250397Sobrien 30350397Sobrien/* Perform linker optimization of merging header file definitions together 30450397Sobrien for targets with MIPS_DEBUGGING_INFO defined. This won't work without a 30550397Sobrien post 960826 version of GAS. Nothing breaks with earlier versions of GAS, 30650397Sobrien the optimization just won't be done. The native assembler already has the 30750397Sobrien necessary support. */ 30850397Sobrien 30950397Sobrien#ifdef MIPS_DEBUGGING_INFO 31050397Sobrien 31150397Sobrien#ifndef PUT_SDB_SRC_FILE 31250397Sobrien#define PUT_SDB_SRC_FILE(FILENAME) \ 31350397Sobrienoutput_file_directive (asm_out_file, (FILENAME)) 31450397Sobrien#endif 31550397Sobrien 31650397Sobrien/* ECOFF linkers have an optimization that does the same kind of thing as 31750397Sobrien N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the 31850397Sobrien executable. To achieve this, GCC must output a .file for each file 31950397Sobrien name change. */ 32050397Sobrien 32150397Sobrien/* This is a stack of input files. */ 32250397Sobrien 32350397Sobrienstruct sdb_file 32450397Sobrien{ 32550397Sobrien struct sdb_file *next; 32650397Sobrien char *name; 32750397Sobrien}; 32850397Sobrien 32950397Sobrien/* This is the top of the stack. */ 33050397Sobrien 33150397Sobrienstatic struct sdb_file *current_file; 33250397Sobrien 33350397Sobrien#endif /* MIPS_DEBUGGING_INFO */ 33418334Speter 33518334Speter/* Set up for SDB output at the start of compilation. */ 33618334Speter 33718334Spetervoid 33818334Spetersdbout_init (asm_file, input_file_name, syms) 33918334Speter FILE *asm_file; 34018334Speter char *input_file_name; 34152284Sobrien tree syms ATTRIBUTE_UNUSED; 34218334Speter{ 34350397Sobrien#ifdef MIPS_DEBUGGING_INFO 34450397Sobrien current_file = (struct sdb_file *) xmalloc (sizeof *current_file); 34550397Sobrien current_file->next = NULL; 34650397Sobrien current_file->name = input_file_name; 34750397Sobrien#endif 34850397Sobrien 34918334Speter#ifdef RMS_QUICK_HACK_1 35018334Speter tree t; 35118334Speter for (t = syms; t; t = TREE_CHAIN (t)) 35218334Speter if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0 35318334Speter && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type")) 35418334Speter sdbout_symbol (t, 0); 35518334Speter#endif 35618334Speter} 35718334Speter 35818334Speter#if 0 35918334Speter 36018334Speter/* return the tag identifier for type 36118334Speter */ 36218334Speter 36318334Speterchar * 36418334Spetertag_of_ru_type (type,link) 36518334Speter tree type,link; 36618334Speter{ 36718334Speter if (TYPE_SYMTAB_ADDRESS (type)) 36818334Speter return TYPE_SYMTAB_ADDRESS (type); 36918334Speter if (link && TREE_PURPOSE (link) 37018334Speter && IDENTIFIER_POINTER (TREE_PURPOSE (link))) 37118334Speter TYPE_SYMTAB_ADDRESS (type) = IDENTIFIER_POINTER (TREE_PURPOSE (link)); 37218334Speter else 37318334Speter return (char *) TYPE_SYMTAB_ADDRESS (type); 37418334Speter} 37518334Speter#endif 37618334Speter 37718334Speter/* Return a unique string to name an anonymous type. */ 37818334Speter 37918334Speterstatic char * 38018334Spetergen_fake_label () 38118334Speter{ 38218334Speter char label[10]; 38318334Speter char *labelstr; 38418334Speter SDB_GENERATE_FAKE (label, unnamed_struct_number); 38518334Speter unnamed_struct_number++; 38618334Speter labelstr = (char *) permalloc (strlen (label) + 1); 38718334Speter strcpy (labelstr, label); 38818334Speter return labelstr; 38918334Speter} 39018334Speter 39118334Speter/* Return the number which describes TYPE for SDB. 39218334Speter For pointers, etc., this function is recursive. 39318334Speter Each record, union or enumeral type must already have had a 39418334Speter tag number output. */ 39518334Speter 39618334Speter/* The number is given by d6d5d4d3d2d1bbbb 39718334Speter where bbbb is 4 bit basic type, and di indicate one of notype,ptr,fn,array. 39818334Speter Thus, char *foo () has bbbb=T_CHAR 39918334Speter d1=D_FCN 40018334Speter d2=D_PTR 40118334Speter N_BTMASK= 017 1111 basic type field. 40218334Speter N_TSHIFT= 2 derived type shift 40318334Speter N_BTSHFT= 4 Basic type shift */ 40418334Speter 40518334Speter/* Produce the number that describes a pointer, function or array type. 40618334Speter PREV is the number describing the target, value or element type. 40718334Speter DT_type describes how to transform that type. */ 40818334Speter#define PUSH_DERIVED_LEVEL(DT_type,PREV) \ 40918334Speter ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT) \ 41018334Speter | ((int)DT_type << (int)N_BTSHFT) \ 41118334Speter | ((PREV) & (int)N_BTMASK)) 41218334Speter 41318334Speter/* Number of elements used in sdb_dims. */ 41418334Speterstatic int sdb_n_dims = 0; 41518334Speter 41618334Speter/* Table of array dimensions of current type. */ 41718334Speterstatic int sdb_dims[SDB_MAX_DIM]; 41818334Speter 41918334Speter/* Size of outermost array currently being processed. */ 42018334Speterstatic int sdb_type_size = -1; 42118334Speter 42218334Speterstatic int 42318334Speterplain_type (type) 42418334Speter tree type; 42518334Speter{ 42618334Speter int val = plain_type_1 (type, 0); 42718334Speter 42818334Speter /* If we have already saved up some array dimensions, print them now. */ 42918334Speter if (sdb_n_dims > 0) 43018334Speter { 43118334Speter int i; 43218334Speter PUT_SDB_START_DIM; 43318334Speter for (i = sdb_n_dims - 1; i > 0; i--) 43418334Speter PUT_SDB_NEXT_DIM (sdb_dims[i]); 43518334Speter PUT_SDB_LAST_DIM (sdb_dims[0]); 43618334Speter sdb_n_dims = 0; 43718334Speter 43818334Speter sdb_type_size = int_size_in_bytes (type); 43918334Speter /* Don't kill sdb if type is not laid out or has variable size. */ 44018334Speter if (sdb_type_size < 0) 44118334Speter sdb_type_size = 0; 44218334Speter } 44318334Speter /* If we have computed the size of an array containing this type, 44418334Speter print it now. */ 44518334Speter if (sdb_type_size >= 0) 44618334Speter { 44718334Speter PUT_SDB_SIZE (sdb_type_size); 44818334Speter sdb_type_size = -1; 44918334Speter } 45018334Speter return val; 45118334Speter} 45218334Speter 45318334Speterstatic int 45418334Spetertemplate_name_p (name) 45518334Speter tree name; 45618334Speter{ 45718334Speter register char *ptr = IDENTIFIER_POINTER (name); 45818334Speter while (*ptr && *ptr != '<') 45918334Speter ptr++; 46018334Speter 46118334Speter return *ptr != '\0'; 46218334Speter} 46318334Speter 46418334Speterstatic void 46518334Spetersdbout_record_type_name (type) 46618334Speter tree type; 46718334Speter{ 46818334Speter char *name = 0; 46918334Speter int no_name; 47018334Speter 47118334Speter if (KNOWN_TYPE_TAG (type)) 47218334Speter return; 47318334Speter 47418334Speter if (TYPE_NAME (type) != 0) 47518334Speter { 47618334Speter tree t = 0; 47718334Speter /* Find the IDENTIFIER_NODE for the type name. */ 47818334Speter if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 47918334Speter t = TYPE_NAME (type); 48018334Speter else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) 48118334Speter { 48218334Speter t = DECL_NAME (TYPE_NAME (type)); 48318334Speter /* The DECL_NAME for templates includes "<>", which breaks 48418334Speter most assemblers. Use its assembler name instead, which 48518334Speter has been mangled into being safe. */ 48618334Speter if (t && template_name_p (t)) 48718334Speter t = DECL_ASSEMBLER_NAME (TYPE_NAME (type)); 48818334Speter } 48918334Speter 49018334Speter /* Now get the name as a string, or invent one. */ 49118334Speter if (t != NULL_TREE) 49218334Speter name = IDENTIFIER_POINTER (t); 49318334Speter } 49418334Speter 49518334Speter no_name = (name == 0 || *name == 0); 49618334Speter if (no_name) 49718334Speter name = gen_fake_label (); 49818334Speter 49918334Speter SET_KNOWN_TYPE_TAG (type, name); 50018334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 50118334Speter if (no_name) 50218334Speter sdbout_queue_anonymous_type (type); 50318334Speter#endif 50418334Speter} 50518334Speter 50618334Speter/* Return the .type value for type TYPE. 50718334Speter 50818334Speter LEVEL indicates how many levels deep we have recursed into the type. 50918334Speter The SDB debug format can only represent 6 derived levels of types. 51018334Speter After that, we must output inaccurate debug info. We deliberately 51118334Speter stop before the 7th level, so that ADA recursive types will not give an 51218334Speter infinite loop. */ 51318334Speter 51418334Speterstatic int 51518334Speterplain_type_1 (type, level) 51618334Speter tree type; 51718334Speter int level; 51818334Speter{ 51918334Speter if (type == 0) 52018334Speter type = void_type_node; 52118334Speter else if (type == error_mark_node) 52218334Speter type = integer_type_node; 52318334Speter else 52418334Speter type = TYPE_MAIN_VARIANT (type); 52518334Speter 52618334Speter switch (TREE_CODE (type)) 52718334Speter { 52818334Speter case VOID_TYPE: 52918334Speter return T_VOID; 53052284Sobrien case BOOLEAN_TYPE: 53118334Speter case INTEGER_TYPE: 53218334Speter { 53318334Speter int size = int_size_in_bytes (type) * BITS_PER_UNIT; 53418334Speter 53518334Speter /* Carefully distinguish all the standard types of C, 53618334Speter without messing up if the language is not C. 53718334Speter Note that we check only for the names that contain spaces; 53818334Speter other names might occur by coincidence in other languages. */ 53918334Speter if (TYPE_NAME (type) != 0 54018334Speter && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 54118334Speter && DECL_NAME (TYPE_NAME (type)) != 0 54218334Speter && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) 54318334Speter { 54418334Speter char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 54518334Speter 54650397Sobrien if (!strcmp (name, "char")) 54750397Sobrien return T_CHAR; 54818334Speter if (!strcmp (name, "unsigned char")) 54918334Speter return T_UCHAR; 55018334Speter if (!strcmp (name, "signed char")) 55118334Speter return T_CHAR; 55250397Sobrien if (!strcmp (name, "int")) 55350397Sobrien return T_INT; 55418334Speter if (!strcmp (name, "unsigned int")) 55518334Speter return T_UINT; 55618334Speter if (!strcmp (name, "short int")) 55718334Speter return T_SHORT; 55818334Speter if (!strcmp (name, "short unsigned int")) 55918334Speter return T_USHORT; 56018334Speter if (!strcmp (name, "long int")) 56118334Speter return T_LONG; 56218334Speter if (!strcmp (name, "long unsigned int")) 56318334Speter return T_ULONG; 56418334Speter } 56518334Speter 56650397Sobrien if (size == INT_TYPE_SIZE) 56750397Sobrien return (TREE_UNSIGNED (type) ? T_UINT : T_INT); 56818334Speter if (size == CHAR_TYPE_SIZE) 56918334Speter return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR); 57018334Speter if (size == SHORT_TYPE_SIZE) 57118334Speter return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT); 57218334Speter if (size == LONG_TYPE_SIZE) 57318334Speter return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG); 57418334Speter if (size == LONG_LONG_TYPE_SIZE) /* better than nothing */ 57518334Speter return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG); 57618334Speter return 0; 57718334Speter } 57818334Speter 57918334Speter case REAL_TYPE: 58018334Speter { 58150397Sobrien int precision = TYPE_PRECISION (type); 58250397Sobrien if (precision == FLOAT_TYPE_SIZE) 58318334Speter return T_FLOAT; 58450397Sobrien if (precision == DOUBLE_TYPE_SIZE) 58518334Speter return T_DOUBLE; 58650397Sobrien#ifdef EXTENDED_SDB_BASIC_TYPES 58750397Sobrien if (precision == LONG_DOUBLE_TYPE_SIZE) 58850397Sobrien return T_LNGDBL; 58950397Sobrien#else 59050397Sobrien if (precision == LONG_DOUBLE_TYPE_SIZE) 59150397Sobrien return T_DOUBLE; /* better than nothing */ 59250397Sobrien#endif 59318334Speter return 0; 59418334Speter } 59518334Speter 59618334Speter case ARRAY_TYPE: 59718334Speter { 59818334Speter int m; 59918334Speter if (level >= 6) 60018334Speter return T_VOID; 60118334Speter else 60218334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 60318334Speter if (sdb_n_dims < SDB_MAX_DIM) 60418334Speter sdb_dims[sdb_n_dims++] 60518334Speter = (TYPE_DOMAIN (type) 60650397Sobrien && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) 60750397Sobrien && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST 60850397Sobrien && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST 60950397Sobrien ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) 61050397Sobrien - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1) 61118334Speter : 0); 61218334Speter return PUSH_DERIVED_LEVEL (DT_ARY, m); 61318334Speter } 61418334Speter 61518334Speter case RECORD_TYPE: 61618334Speter case UNION_TYPE: 61718334Speter case QUAL_UNION_TYPE: 61818334Speter case ENUMERAL_TYPE: 61918334Speter { 62018334Speter char *tag; 62118334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 62218334Speter sdbout_record_type_name (type); 62318334Speter#endif 62418334Speter#ifndef SDB_ALLOW_UNKNOWN_REFERENCES 62518334Speter if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0) 62618334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 62718334Speter || TYPE_MODE (type) != VOIDmode 62818334Speter#endif 62918334Speter ) 63018334Speter#endif 63118334Speter { 63218334Speter /* Output the referenced structure tag name 63318334Speter only if the .def has already been finished. 63418334Speter At least on 386, the Unix assembler 63518334Speter cannot handle forward references to tags. */ 63650397Sobrien /* But the 88100, it requires them, sigh... */ 63750397Sobrien /* And the MIPS requires unknown refs as well... */ 63818334Speter tag = KNOWN_TYPE_TAG (type); 63918334Speter PUT_SDB_TAG (tag); 64018334Speter /* These 3 lines used to follow the close brace. 64118334Speter However, a size of 0 without a tag implies a tag of 0, 64218334Speter so if we don't know a tag, we can't mention the size. */ 64318334Speter sdb_type_size = int_size_in_bytes (type); 64418334Speter if (sdb_type_size < 0) 64518334Speter sdb_type_size = 0; 64618334Speter } 64718334Speter return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT 64818334Speter : (TREE_CODE (type) == UNION_TYPE) ? T_UNION 64918334Speter : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION 65018334Speter : T_ENUM); 65118334Speter } 65218334Speter case POINTER_TYPE: 65318334Speter case REFERENCE_TYPE: 65418334Speter { 65518334Speter int m; 65618334Speter if (level >= 6) 65718334Speter return T_VOID; 65818334Speter else 65918334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 66018334Speter return PUSH_DERIVED_LEVEL (DT_PTR, m); 66118334Speter } 66218334Speter case FUNCTION_TYPE: 66318334Speter case METHOD_TYPE: 66418334Speter { 66518334Speter int m; 66618334Speter if (level >= 6) 66718334Speter return T_VOID; 66818334Speter else 66918334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 67018334Speter return PUSH_DERIVED_LEVEL (DT_FCN, m); 67118334Speter } 67218334Speter default: 67318334Speter return 0; 67418334Speter } 67518334Speter} 67618334Speter 67718334Speter/* Output the symbols defined in block number DO_BLOCK. 67818334Speter Set NEXT_BLOCK_NUMBER to 0 before calling. 67918334Speter 68018334Speter This function works by walking the tree structure of blocks, 68118334Speter counting blocks until it finds the desired block. */ 68218334Speter 68318334Speterstatic int do_block = 0; 68418334Speter 68518334Speterstatic int next_block_number; 68618334Speter 68718334Speterstatic void 68818334Spetersdbout_block (block) 68918334Speter register tree block; 69018334Speter{ 69118334Speter while (block) 69218334Speter { 69318334Speter /* Ignore blocks never expanded or otherwise marked as real. */ 69418334Speter if (TREE_USED (block)) 69518334Speter { 69618334Speter /* When we reach the specified block, output its symbols. */ 69718334Speter if (next_block_number == do_block) 69818334Speter { 69918334Speter sdbout_syms (BLOCK_VARS (block)); 70018334Speter } 70118334Speter 70218334Speter /* If we are past the specified block, stop the scan. */ 70318334Speter if (next_block_number > do_block) 70418334Speter return; 70518334Speter 70618334Speter next_block_number++; 70718334Speter 70818334Speter /* Scan the blocks within this block. */ 70918334Speter sdbout_block (BLOCK_SUBBLOCKS (block)); 71018334Speter } 71118334Speter 71218334Speter block = BLOCK_CHAIN (block); 71318334Speter } 71418334Speter} 71518334Speter 71618334Speter/* Call sdbout_symbol on each decl in the chain SYMS. */ 71718334Speter 71818334Speterstatic void 71918334Spetersdbout_syms (syms) 72018334Speter tree syms; 72118334Speter{ 72218334Speter while (syms) 72318334Speter { 72418334Speter if (TREE_CODE (syms) != LABEL_DECL) 72518334Speter sdbout_symbol (syms, 1); 72618334Speter syms = TREE_CHAIN (syms); 72718334Speter } 72818334Speter} 72918334Speter 73018334Speter/* Output SDB information for a symbol described by DECL. 73118334Speter LOCAL is nonzero if the symbol is not file-scope. */ 73218334Speter 73318334Spetervoid 73418334Spetersdbout_symbol (decl, local) 73518334Speter tree decl; 73618334Speter int local; 73718334Speter{ 73818334Speter tree type = TREE_TYPE (decl); 73918334Speter tree context = NULL_TREE; 74018334Speter rtx value; 74118334Speter int regno = -1; 74218334Speter char *name; 74318334Speter 74418334Speter sdbout_one_type (type); 74518334Speter 74618334Speter#if 0 /* This loses when functions are marked to be ignored, 74718334Speter which happens in the C++ front end. */ 74818334Speter if (DECL_IGNORED_P (decl)) 74918334Speter return; 75018334Speter#endif 75118334Speter 75218334Speter switch (TREE_CODE (decl)) 75318334Speter { 75418334Speter case CONST_DECL: 75518334Speter /* Enum values are defined by defining the enum type. */ 75618334Speter return; 75718334Speter 75818334Speter case FUNCTION_DECL: 75918334Speter /* Don't mention a nested function under its parent. */ 76018334Speter context = decl_function_context (decl); 76118334Speter if (context == current_function_decl) 76218334Speter return; 76350397Sobrien /* Check DECL_INITIAL to distinguish declarations from definitions. 76450397Sobrien Don't output debug info here for declarations; they will have 76550397Sobrien a DECL_INITIAL value of 0. */ 76650397Sobrien if (! DECL_INITIAL (decl)) 76718334Speter return; 76818334Speter if (GET_CODE (DECL_RTL (decl)) != MEM 76918334Speter || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) 77018334Speter return; 77118334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 77218334Speter PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); 77318334Speter PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT); 77418334Speter break; 77518334Speter 77618334Speter case TYPE_DECL: 77718334Speter /* Done with tagged types. */ 77818334Speter if (DECL_NAME (decl) == 0) 77918334Speter return; 78018334Speter if (DECL_IGNORED_P (decl)) 78118334Speter return; 78218334Speter 78318334Speter /* Output typedef name. */ 78418334Speter if (template_name_p (DECL_NAME (decl))) 78518334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 78618334Speter else 78718334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl))); 78818334Speter PUT_SDB_SCL (C_TPDEF); 78918334Speter break; 79018334Speter 79118334Speter case PARM_DECL: 79218334Speter /* Parm decls go in their own separate chains 79318334Speter and are output by sdbout_reg_parms and sdbout_parms. */ 79418334Speter abort (); 79518334Speter 79618334Speter case VAR_DECL: 79718334Speter /* Don't mention a variable that is external. 79818334Speter Let the file that defines it describe it. */ 79918334Speter if (DECL_EXTERNAL (decl)) 80018334Speter return; 80118334Speter 80218334Speter /* Ignore __FUNCTION__, etc. */ 80318334Speter if (DECL_IGNORED_P (decl)) 80418334Speter return; 80518334Speter 80618334Speter /* If there was an error in the declaration, don't dump core 80718334Speter if there is no RTL associated with the variable doesn't 80818334Speter exist. */ 80918334Speter if (DECL_RTL (decl) == 0) 81018334Speter return; 81118334Speter 81218334Speter DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); 81318334Speter#ifdef LEAF_REG_REMAP 81452284Sobrien if (current_function_uses_only_leaf_regs) 81518334Speter leaf_renumber_regs_insn (DECL_RTL (decl)); 81618334Speter#endif 81718334Speter value = DECL_RTL (decl); 81818334Speter 81918334Speter /* Don't mention a variable at all 82018334Speter if it was completely optimized into nothingness. 82118334Speter 82218334Speter If DECL was from an inline function, then its rtl 82318334Speter is not identically the rtl that was used in this 82418334Speter particular compilation. */ 82518334Speter if (GET_CODE (value) == REG) 82618334Speter { 82718334Speter regno = REGNO (DECL_RTL (decl)); 82818334Speter if (regno >= FIRST_PSEUDO_REGISTER) 82918334Speter return; 83018334Speter } 83118334Speter else if (GET_CODE (value) == SUBREG) 83218334Speter { 83318334Speter int offset = 0; 83418334Speter while (GET_CODE (value) == SUBREG) 83518334Speter { 83618334Speter offset += SUBREG_WORD (value); 83718334Speter value = SUBREG_REG (value); 83818334Speter } 83918334Speter if (GET_CODE (value) == REG) 84018334Speter { 84118334Speter regno = REGNO (value); 84218334Speter if (regno >= FIRST_PSEUDO_REGISTER) 84318334Speter return; 84418334Speter regno += offset; 84518334Speter } 84618334Speter alter_subreg (DECL_RTL (decl)); 84718334Speter value = DECL_RTL (decl); 84818334Speter } 84918334Speter /* Don't output anything if an auto variable 85018334Speter gets RTL that is static. 85118334Speter GAS version 2.2 can't handle such output. */ 85218334Speter else if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0)) 85318334Speter && ! TREE_STATIC (decl)) 85418334Speter return; 85518334Speter 85618334Speter /* Emit any structure, union, or enum type that has not been output. 85718334Speter This occurs for tag-less structs (et al) used to declare variables 85818334Speter within functions. */ 85918334Speter if (TREE_CODE (type) == ENUMERAL_TYPE 86018334Speter || TREE_CODE (type) == RECORD_TYPE 86118334Speter || TREE_CODE (type) == UNION_TYPE 86218334Speter || TREE_CODE (type) == QUAL_UNION_TYPE) 86318334Speter { 86418334Speter if (TYPE_SIZE (type) != 0 /* not a forward reference */ 86518334Speter && KNOWN_TYPE_TAG (type) == 0) /* not yet declared */ 86618334Speter sdbout_one_type (type); 86718334Speter } 86818334Speter 86918334Speter /* Defer SDB information for top-level initialized variables! */ 87018334Speter if (! local 87118334Speter && GET_CODE (value) == MEM 87218334Speter && DECL_INITIAL (decl)) 87318334Speter return; 87418334Speter 87518334Speter /* C++ in 2.3 makes nameless symbols. That will be fixed later. 87618334Speter For now, avoid crashing. */ 87718334Speter if (DECL_NAME (decl) == NULL_TREE) 87818334Speter return; 87918334Speter 88018334Speter /* Record the name for, starting a symtab entry. */ 88118334Speter name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 88218334Speter 88318334Speter if (GET_CODE (value) == MEM 88418334Speter && GET_CODE (XEXP (value, 0)) == SYMBOL_REF) 88518334Speter { 88618334Speter PUT_SDB_DEF (name); 88718334Speter if (TREE_PUBLIC (decl)) 88818334Speter { 88918334Speter PUT_SDB_VAL (XEXP (value, 0)); 89018334Speter PUT_SDB_SCL (C_EXT); 89118334Speter } 89218334Speter else 89318334Speter { 89418334Speter PUT_SDB_VAL (XEXP (value, 0)); 89518334Speter PUT_SDB_SCL (C_STAT); 89618334Speter } 89718334Speter } 89818334Speter else if (regno >= 0) 89918334Speter { 90018334Speter PUT_SDB_DEF (name); 90118334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno)); 90218334Speter PUT_SDB_SCL (C_REG); 90318334Speter } 90418334Speter else if (GET_CODE (value) == MEM 90518334Speter && (GET_CODE (XEXP (value, 0)) == MEM 90618334Speter || (GET_CODE (XEXP (value, 0)) == REG 90718334Speter && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM 90818334Speter && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM))) 90918334Speter /* If the value is indirect by memory or by a register 91018334Speter that isn't the frame pointer 91118334Speter then it means the object is variable-sized and address through 91218334Speter that register or stack slot. COFF has no way to represent this 91318334Speter so all we can do is output the variable as a pointer. */ 91418334Speter { 91518334Speter PUT_SDB_DEF (name); 91618334Speter if (GET_CODE (XEXP (value, 0)) == REG) 91718334Speter { 91818334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0)))); 91918334Speter PUT_SDB_SCL (C_REG); 92018334Speter } 92118334Speter else 92218334Speter { 92318334Speter /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) 92418334Speter (CONST_INT...)))). 92518334Speter We want the value of that CONST_INT. */ 92618334Speter /* Encore compiler hates a newline in a macro arg, it seems. */ 92718334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET 92818334Speter (XEXP (XEXP (value, 0), 0))); 92918334Speter PUT_SDB_SCL (C_AUTO); 93018334Speter } 93118334Speter 93252284Sobrien /* Effectively do build_pointer_type, but don't cache this type, 93352284Sobrien since it might be temporary whereas the type it points to 93452284Sobrien might have been saved for inlining. */ 93552284Sobrien /* Don't use REFERENCE_TYPE because dbx can't handle that. */ 93652284Sobrien type = make_node (POINTER_TYPE); 93752284Sobrien TREE_TYPE (type) = TREE_TYPE (decl); 93818334Speter } 93918334Speter else if (GET_CODE (value) == MEM 94018334Speter && ((GET_CODE (XEXP (value, 0)) == PLUS 94118334Speter && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG 94218334Speter && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT) 94318334Speter /* This is for variables which are at offset zero from 94418334Speter the frame pointer. This happens on the Alpha. 94518334Speter Non-frame pointer registers are excluded above. */ 94618334Speter || (GET_CODE (XEXP (value, 0)) == REG))) 94718334Speter { 94818334Speter /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) 94918334Speter or (MEM (REG...)). We want the value of that CONST_INT 95018334Speter or zero. */ 95118334Speter PUT_SDB_DEF (name); 95218334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0))); 95318334Speter PUT_SDB_SCL (C_AUTO); 95418334Speter } 95518334Speter else if (GET_CODE (value) == MEM && GET_CODE (XEXP (value, 0)) == CONST) 95618334Speter { 95718334Speter /* Handle an obscure case which can arise when optimizing and 95818334Speter when there are few available registers. (This is *always* 95918334Speter the case for i386/i486 targets). The DECL_RTL looks like 96018334Speter (MEM (CONST ...)) even though this variable is a local `auto' 96118334Speter or a local `register' variable. In effect, what has happened 96218334Speter is that the reload pass has seen that all assignments and 96318334Speter references for one such a local variable can be replaced by 96418334Speter equivalent assignments and references to some static storage 96518334Speter variable, thereby avoiding the need for a register. In such 96618334Speter cases we're forced to lie to debuggers and tell them that 96718334Speter this variable was itself `static'. */ 96818334Speter PUT_SDB_DEF (name); 96918334Speter PUT_SDB_VAL (XEXP (XEXP (value, 0), 0)); 97018334Speter PUT_SDB_SCL (C_STAT); 97118334Speter } 97218334Speter else 97318334Speter { 97418334Speter /* It is something we don't know how to represent for SDB. */ 97518334Speter return; 97618334Speter } 97718334Speter break; 97850397Sobrien 97950397Sobrien default: 98050397Sobrien break; 98118334Speter } 98218334Speter PUT_SDB_TYPE (plain_type (type)); 98318334Speter PUT_SDB_ENDEF; 98418334Speter} 98518334Speter 98618334Speter/* Output SDB information for a top-level initialized variable 98718334Speter that has been delayed. */ 98818334Speter 98918334Spetervoid 99018334Spetersdbout_toplevel_data (decl) 99118334Speter tree decl; 99218334Speter{ 99318334Speter tree type = TREE_TYPE (decl); 99418334Speter 99518334Speter if (DECL_IGNORED_P (decl)) 99618334Speter return; 99718334Speter 99818334Speter if (! (TREE_CODE (decl) == VAR_DECL 99918334Speter && GET_CODE (DECL_RTL (decl)) == MEM 100018334Speter && DECL_INITIAL (decl))) 100118334Speter abort (); 100218334Speter 100318334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 100418334Speter PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); 100518334Speter if (TREE_PUBLIC (decl)) 100618334Speter { 100718334Speter PUT_SDB_SCL (C_EXT); 100818334Speter } 100918334Speter else 101018334Speter { 101118334Speter PUT_SDB_SCL (C_STAT); 101218334Speter } 101318334Speter PUT_SDB_TYPE (plain_type (type)); 101418334Speter PUT_SDB_ENDEF; 101518334Speter} 101618334Speter 101718334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 101818334Speter 101950397Sobrien/* Machinery to record and output anonymous types. */ 102018334Speter 102118334Speterstatic tree anonymous_types; 102218334Speter 102318334Speterstatic void 102418334Spetersdbout_queue_anonymous_type (type) 102518334Speter tree type; 102618334Speter{ 102718334Speter anonymous_types = saveable_tree_cons (NULL_TREE, type, anonymous_types); 102818334Speter} 102918334Speter 103018334Speterstatic void 103118334Spetersdbout_dequeue_anonymous_types () 103218334Speter{ 103318334Speter register tree types, link; 103418334Speter 103518334Speter while (anonymous_types) 103618334Speter { 103718334Speter types = nreverse (anonymous_types); 103818334Speter anonymous_types = NULL_TREE; 103918334Speter 104018334Speter for (link = types; link; link = TREE_CHAIN (link)) 104118334Speter { 104218334Speter register tree type = TREE_VALUE (link); 104318334Speter 104418334Speter if (type && ! TREE_ASM_WRITTEN (type)) 104518334Speter sdbout_one_type (type); 104618334Speter } 104718334Speter } 104818334Speter} 104918334Speter 105018334Speter#endif 105118334Speter 105218334Speter/* Given a chain of ..._TYPE nodes, all of which have names, 105318334Speter output definitions of those names, as typedefs. */ 105418334Speter 105518334Spetervoid 105618334Spetersdbout_types (types) 105718334Speter register tree types; 105818334Speter{ 105918334Speter register tree link; 106018334Speter 106118334Speter for (link = types; link; link = TREE_CHAIN (link)) 106218334Speter sdbout_one_type (link); 106318334Speter 106418334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 106518334Speter sdbout_dequeue_anonymous_types (); 106618334Speter#endif 106718334Speter} 106818334Speter 106918334Speterstatic void 107018334Spetersdbout_type (type) 107118334Speter tree type; 107218334Speter{ 107318334Speter if (type == error_mark_node) 107418334Speter type = integer_type_node; 107518334Speter PUT_SDB_TYPE (plain_type (type)); 107618334Speter} 107718334Speter 107818334Speter/* Output types of the fields of type TYPE, if they are structs. 107918334Speter 108018334Speter Formerly did not chase through pointer types, since that could be circular. 108118334Speter They must come before TYPE, since forward refs are not allowed. 108218334Speter Now james@bigtex.cactus.org says to try them. */ 108318334Speter 108418334Speterstatic void 108518334Spetersdbout_field_types (type) 108618334Speter tree type; 108718334Speter{ 108818334Speter tree tail; 108950397Sobrien 109018334Speter for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) 109152284Sobrien /* This condition should match the one for emitting the actual members 109252284Sobrien below. */ 109352284Sobrien if (TREE_CODE (tail) == FIELD_DECL 109452284Sobrien && DECL_NAME (tail) != 0 109552284Sobrien && TREE_CODE (DECL_SIZE (tail)) == INTEGER_CST 109652284Sobrien && TREE_CODE (DECL_FIELD_BITPOS (tail)) == INTEGER_CST) 109752284Sobrien { 109852284Sobrien if (POINTER_TYPE_P (TREE_TYPE (tail))) 109952284Sobrien sdbout_one_type (TREE_TYPE (TREE_TYPE (tail))); 110052284Sobrien else 110152284Sobrien sdbout_one_type (TREE_TYPE (tail)); 110252284Sobrien } 110318334Speter} 110418334Speter 110518334Speter/* Use this to put out the top level defined record and union types 110618334Speter for later reference. If this is a struct with a name, then put that 110718334Speter name out. Other unnamed structs will have .xxfake labels generated so 110818334Speter that they may be referred to later. 110918334Speter The label will be stored in the KNOWN_TYPE_TAG slot of a type. 111018334Speter It may NOT be called recursively. */ 111118334Speter 111218334Speterstatic void 111318334Spetersdbout_one_type (type) 111418334Speter tree type; 111518334Speter{ 111618334Speter if (current_function_decl != NULL_TREE 111718334Speter && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) 111818334Speter ; /* Don't change section amid function. */ 111918334Speter else 112018334Speter text_section (); 112118334Speter 112218334Speter switch (TREE_CODE (type)) 112318334Speter { 112418334Speter case RECORD_TYPE: 112518334Speter case UNION_TYPE: 112618334Speter case QUAL_UNION_TYPE: 112718334Speter case ENUMERAL_TYPE: 112818334Speter type = TYPE_MAIN_VARIANT (type); 112918334Speter /* Don't output a type twice. */ 113018334Speter if (TREE_ASM_WRITTEN (type)) 113118334Speter /* James said test TREE_ASM_BEING_WRITTEN here. */ 113218334Speter return; 113318334Speter 113418334Speter /* Output nothing if type is not yet defined. */ 113518334Speter if (TYPE_SIZE (type) == 0) 113618334Speter return; 113718334Speter 113818334Speter TREE_ASM_WRITTEN (type) = 1; 113918334Speter#if 1 114018334Speter /* This is reputed to cause trouble with the following case, 114118334Speter but perhaps checking TYPE_SIZE above will fix it. */ 114218334Speter 114318334Speter /* Here is a test case: 114418334Speter 114518334Speter struct foo { 114618334Speter struct badstr *bbb; 114718334Speter } forwardref; 114818334Speter 114918334Speter typedef struct intermediate { 115018334Speter int aaaa; 115118334Speter } intermediate_ref; 115218334Speter 115318334Speter typedef struct badstr { 115418334Speter int ccccc; 115518334Speter } badtype; */ 115618334Speter 115718334Speter#if 0 115818334Speter TREE_ASM_BEING_WRITTEN (type) = 1; 115918334Speter#endif 116018334Speter /* This change, which ought to make better output, 116118334Speter used to make the COFF assembler unhappy. 116218334Speter Changes involving KNOWN_TYPE_TAG may fix the problem. */ 116318334Speter /* Before really doing anything, output types we want to refer to. */ 116418334Speter /* Note that in version 1 the following two lines 116518334Speter are not used if forward references are in use. */ 116618334Speter if (TREE_CODE (type) != ENUMERAL_TYPE) 116718334Speter sdbout_field_types (type); 116818334Speter#if 0 116918334Speter TREE_ASM_WRITTEN (type) = 1; 117018334Speter#endif 117118334Speter#endif 117218334Speter 117318334Speter /* Output a structure type. */ 117418334Speter { 117518334Speter int size = int_size_in_bytes (type); 117618334Speter int member_scl; 117718334Speter tree tem; 117818334Speter int i, n_baseclasses = 0; 117918334Speter 118018334Speter /* Record the type tag, but not in its permanent place just yet. */ 118118334Speter sdbout_record_type_name (type); 118218334Speter 118318334Speter PUT_SDB_DEF (KNOWN_TYPE_TAG (type)); 118418334Speter 118518334Speter switch (TREE_CODE (type)) 118618334Speter { 118718334Speter case UNION_TYPE: 118818334Speter case QUAL_UNION_TYPE: 118918334Speter PUT_SDB_SCL (C_UNTAG); 119018334Speter PUT_SDB_TYPE (T_UNION); 119118334Speter member_scl = C_MOU; 119218334Speter break; 119318334Speter 119418334Speter case RECORD_TYPE: 119518334Speter PUT_SDB_SCL (C_STRTAG); 119618334Speter PUT_SDB_TYPE (T_STRUCT); 119718334Speter member_scl = C_MOS; 119818334Speter break; 119918334Speter 120018334Speter case ENUMERAL_TYPE: 120118334Speter PUT_SDB_SCL (C_ENTAG); 120218334Speter PUT_SDB_TYPE (T_ENUM); 120318334Speter member_scl = C_MOE; 120418334Speter break; 120550397Sobrien 120650397Sobrien default: 120750397Sobrien break; 120818334Speter } 120918334Speter 121018334Speter PUT_SDB_SIZE (size); 121118334Speter PUT_SDB_ENDEF; 121218334Speter 121318334Speter /* Print out the base class information with fields 121418334Speter named after the types they hold. */ 121552284Sobrien /* This is only relevent to aggregate types. TYPE_BINFO is used 121652284Sobrien for other purposes in an ENUMERAL_TYPE, so we must exclude that 121752284Sobrien case. */ 121852284Sobrien if (TREE_CODE (type) != ENUMERAL_TYPE) 121918334Speter { 122052284Sobrien if (TYPE_BINFO (type) 122152284Sobrien && TYPE_BINFO_BASETYPES (type)) 122252284Sobrien n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); 122352284Sobrien for (i = 0; i < n_baseclasses; i++) 122418334Speter { 122552284Sobrien tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 122652284Sobrien i); 122752284Sobrien tree child_type = BINFO_TYPE (child); 122852284Sobrien tree child_type_name; 122952284Sobrien if (TYPE_NAME (child_type) == 0) 123052284Sobrien continue; 123152284Sobrien if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE) 123252284Sobrien child_type_name = TYPE_NAME (child_type); 123352284Sobrien else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL) 123452284Sobrien { 123552284Sobrien child_type_name = DECL_NAME (TYPE_NAME (child_type)); 123652284Sobrien if (child_type_name && template_name_p (child_type_name)) 123752284Sobrien child_type_name 123852284Sobrien = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type)); 123952284Sobrien } 124052284Sobrien else 124152284Sobrien continue; 124252284Sobrien 124352284Sobrien CONTIN; 124452284Sobrien PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name)); 124552284Sobrien PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child))); 124652284Sobrien PUT_SDB_SCL (member_scl); 124752284Sobrien sdbout_type (BINFO_TYPE (child)); 124852284Sobrien PUT_SDB_ENDEF; 124918334Speter } 125018334Speter } 125118334Speter 125218334Speter /* output the individual fields */ 125318334Speter 125418334Speter if (TREE_CODE (type) == ENUMERAL_TYPE) 125518334Speter for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) 125618334Speter { 125718334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem))); 125818334Speter PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem))); 125918334Speter PUT_SDB_SCL (C_MOE); 126018334Speter PUT_SDB_TYPE (T_MOE); 126118334Speter PUT_SDB_ENDEF; 126218334Speter } 126318334Speter 126418334Speter else /* record or union type */ 126518334Speter for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) 126618334Speter /* Output the name, type, position (in bits), size (in bits) 126718334Speter of each field. */ 126818334Speter 126918334Speter /* Omit here the nameless fields that are used to skip bits. 127018334Speter Also omit fields with variable size or position. 127118334Speter Also omit non FIELD_DECL nodes that GNU C++ may put here. */ 127218334Speter if (TREE_CODE (tem) == FIELD_DECL 127318334Speter && DECL_NAME (tem) != 0 127418334Speter && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST 127518334Speter && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) 127618334Speter { 127718334Speter char *name; 127818334Speter 127918334Speter CONTIN; 128018334Speter name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); 128118334Speter PUT_SDB_DEF (name); 128218334Speter if (DECL_BIT_FIELD_TYPE (tem)) 128318334Speter { 128418334Speter PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); 128518334Speter PUT_SDB_SCL (C_FIELD); 128618334Speter sdbout_type (DECL_BIT_FIELD_TYPE (tem)); 128718334Speter PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem))); 128818334Speter } 128918334Speter else 129018334Speter { 129118334Speter PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)) 129218334Speter / BITS_PER_UNIT); 129318334Speter PUT_SDB_SCL (member_scl); 129418334Speter sdbout_type (TREE_TYPE (tem)); 129518334Speter } 129618334Speter PUT_SDB_ENDEF; 129718334Speter } 129818334Speter /* output end of a structure,union, or enumeral definition */ 129918334Speter 130018334Speter PUT_SDB_PLAIN_DEF ("eos"); 130118334Speter PUT_SDB_INT_VAL (size); 130218334Speter PUT_SDB_SCL (C_EOS); 130318334Speter PUT_SDB_TAG (KNOWN_TYPE_TAG (type)); 130418334Speter PUT_SDB_SIZE (size); 130518334Speter PUT_SDB_ENDEF; 130618334Speter break; 130750397Sobrien 130850397Sobrien default: 130950397Sobrien break; 131018334Speter } 131118334Speter } 131218334Speter} 131318334Speter 131418334Speter/* The following two functions output definitions of function parameters. 131518334Speter Each parameter gets a definition locating it in the parameter list. 131618334Speter Each parameter that is a register variable gets a second definition 131718334Speter locating it in the register. 131818334Speter 131918334Speter Printing or argument lists in gdb uses the definitions that 132018334Speter locate in the parameter list. But reference to the variable in 132118334Speter expressions uses preferentially the definition as a register. */ 132218334Speter 132318334Speter/* Output definitions, referring to storage in the parmlist, 132418334Speter of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ 132518334Speter 132618334Speterstatic void 132718334Spetersdbout_parms (parms) 132818334Speter tree parms; 132918334Speter{ 133018334Speter for (; parms; parms = TREE_CHAIN (parms)) 133118334Speter if (DECL_NAME (parms)) 133218334Speter { 133318334Speter int current_sym_value = 0; 133418334Speter char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); 133518334Speter 133618334Speter if (name == 0 || *name == 0) 133718334Speter name = gen_fake_label (); 133818334Speter 133918334Speter /* Perform any necessary register eliminations on the parameter's rtl, 134018334Speter so that the debugging output will be accurate. */ 134150397Sobrien DECL_INCOMING_RTL (parms) 134250397Sobrien = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); 134318334Speter DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); 134418334Speter 134518334Speter if (PARM_PASSED_IN_MEMORY (parms)) 134618334Speter { 134718334Speter rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); 134818334Speter tree type; 134918334Speter 135018334Speter /* ??? Here we assume that the parm address is indexed 135118334Speter off the frame pointer or arg pointer. 135218334Speter If that is not true, we produce meaningless results, 135318334Speter but do not crash. */ 135418334Speter if (GET_CODE (addr) == PLUS 135518334Speter && GET_CODE (XEXP (addr, 1)) == CONST_INT) 135618334Speter current_sym_value = INTVAL (XEXP (addr, 1)); 135718334Speter else 135818334Speter current_sym_value = 0; 135918334Speter 136018334Speter if (GET_CODE (DECL_RTL (parms)) == REG 136118334Speter && REGNO (DECL_RTL (parms)) >= 0 136218334Speter && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 136318334Speter type = DECL_ARG_TYPE (parms); 136418334Speter else 136518334Speter { 136618334Speter int original_sym_value = current_sym_value; 136718334Speter 136818334Speter /* This is the case where the parm is passed as an int or 136918334Speter double and it is converted to a char, short or float 137018334Speter and stored back in the parmlist. In this case, describe 137118334Speter the parm with the variable's declared type, and adjust 137218334Speter the address if the least significant bytes (which we are 137318334Speter using) are not the first ones. */ 137418334Speter if (BYTES_BIG_ENDIAN 137518334Speter && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) 137618334Speter current_sym_value += 137718334Speter (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) 137818334Speter - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); 137918334Speter 138018334Speter if (GET_CODE (DECL_RTL (parms)) == MEM 138118334Speter && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS 138218334Speter && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) 138318334Speter == CONST_INT) 138418334Speter && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) 138518334Speter == current_sym_value)) 138618334Speter type = TREE_TYPE (parms); 138718334Speter else 138818334Speter { 138918334Speter current_sym_value = original_sym_value; 139018334Speter type = DECL_ARG_TYPE (parms); 139118334Speter } 139218334Speter } 139318334Speter 139418334Speter PUT_SDB_DEF (name); 139518334Speter PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr)); 139618334Speter PUT_SDB_SCL (C_ARG); 139718334Speter PUT_SDB_TYPE (plain_type (type)); 139818334Speter PUT_SDB_ENDEF; 139918334Speter } 140018334Speter else if (GET_CODE (DECL_RTL (parms)) == REG) 140118334Speter { 140218334Speter rtx best_rtl; 140318334Speter /* Parm passed in registers and lives in registers or nowhere. */ 140418334Speter 140518334Speter /* If parm lives in a register, use that register; 140618334Speter pretend the parm was passed there. It would be more consistent 140718334Speter to describe the register where the parm was passed, 140818334Speter but in practice that register usually holds something else. */ 140918334Speter if (REGNO (DECL_RTL (parms)) >= 0 141018334Speter && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 141118334Speter best_rtl = DECL_RTL (parms); 141218334Speter /* If the parm lives nowhere, 141318334Speter use the register where it was passed. */ 141418334Speter else 141518334Speter best_rtl = DECL_INCOMING_RTL (parms); 141618334Speter 141718334Speter PUT_SDB_DEF (name); 141818334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl))); 141918334Speter PUT_SDB_SCL (C_REGPARM); 142050397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 142118334Speter PUT_SDB_ENDEF; 142218334Speter } 142318334Speter else if (GET_CODE (DECL_RTL (parms)) == MEM 142418334Speter && XEXP (DECL_RTL (parms), 0) != const0_rtx) 142518334Speter { 142618334Speter /* Parm was passed in registers but lives on the stack. */ 142718334Speter 142818334Speter /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), 142918334Speter in which case we want the value of that CONST_INT, 143018334Speter or (MEM (REG ...)) or (MEM (MEM ...)), 143118334Speter in which case we use a value of zero. */ 143218334Speter if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG 143318334Speter || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) 143418334Speter current_sym_value = 0; 143518334Speter else 143618334Speter current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); 143718334Speter 143818334Speter /* Again, this assumes the offset is based on the arg pointer. */ 143918334Speter PUT_SDB_DEF (name); 144018334Speter PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, 144118334Speter XEXP (DECL_RTL (parms), 0))); 144218334Speter PUT_SDB_SCL (C_ARG); 144350397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 144418334Speter PUT_SDB_ENDEF; 144518334Speter } 144618334Speter } 144718334Speter} 144818334Speter 144918334Speter/* Output definitions for the places where parms live during the function, 145018334Speter when different from where they were passed, when the parms were passed 145118334Speter in memory. 145218334Speter 145318334Speter It is not useful to do this for parms passed in registers 145418334Speter that live during the function in different registers, because it is 145518334Speter impossible to look in the passed register for the passed value, 145618334Speter so we use the within-the-function register to begin with. 145718334Speter 145818334Speter PARMS is a chain of PARM_DECL nodes. */ 145918334Speter 146018334Speterstatic void 146118334Spetersdbout_reg_parms (parms) 146218334Speter tree parms; 146318334Speter{ 146418334Speter for (; parms; parms = TREE_CHAIN (parms)) 146518334Speter if (DECL_NAME (parms)) 146618334Speter { 146718334Speter char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); 146818334Speter 146918334Speter /* Report parms that live in registers during the function 147018334Speter but were passed in memory. */ 147118334Speter if (GET_CODE (DECL_RTL (parms)) == REG 147218334Speter && REGNO (DECL_RTL (parms)) >= 0 147318334Speter && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER 147418334Speter && PARM_PASSED_IN_MEMORY (parms)) 147518334Speter { 147618334Speter if (name == 0 || *name == 0) 147718334Speter name = gen_fake_label (); 147818334Speter PUT_SDB_DEF (name); 147918334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)))); 148018334Speter PUT_SDB_SCL (C_REG); 148150397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 148218334Speter PUT_SDB_ENDEF; 148318334Speter } 148418334Speter /* Report parms that live in memory but not where they were passed. */ 148518334Speter else if (GET_CODE (DECL_RTL (parms)) == MEM 148618334Speter && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS 148718334Speter && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT 148818334Speter && PARM_PASSED_IN_MEMORY (parms) 148918334Speter && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) 149018334Speter { 149118334Speter#if 0 /* ??? It is not clear yet what should replace this. */ 149218334Speter int offset = DECL_OFFSET (parms) / BITS_PER_UNIT; 149318334Speter /* A parm declared char is really passed as an int, 149418334Speter so it occupies the least significant bytes. 149518334Speter On a big-endian machine those are not the low-numbered ones. */ 149618334Speter if (BYTES_BIG_ENDIAN 149718334Speter && offset != -1 149818334Speter && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) 149918334Speter offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) 150018334Speter - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); 150118334Speter if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...} 150218334Speter#endif 150318334Speter { 150418334Speter if (name == 0 || *name == 0) 150518334Speter name = gen_fake_label (); 150618334Speter PUT_SDB_DEF (name); 150718334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET 150818334Speter (XEXP (DECL_RTL (parms), 0))); 150918334Speter PUT_SDB_SCL (C_AUTO); 151018334Speter PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 151118334Speter PUT_SDB_ENDEF; 151218334Speter } 151318334Speter } 151418334Speter } 151518334Speter} 151618334Speter 151718334Speter/* Describe the beginning of an internal block within a function. 151818334Speter Also output descriptions of variables defined in this block. 151918334Speter 152018334Speter N is the number of the block, by order of beginning, counting from 1, 152118334Speter and not counting the outermost (function top-level) block. 152218334Speter The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), 152318334Speter if the count starts at 0 for the outermost one. */ 152418334Speter 152518334Spetervoid 152618334Spetersdbout_begin_block (file, line, n) 152718334Speter FILE *file; 152818334Speter int line; 152918334Speter int n; 153018334Speter{ 153118334Speter tree decl = current_function_decl; 153218334Speter MAKE_LINE_SAFE (line); 153318334Speter 153418334Speter /* The SCO compiler does not emit a separate block for the function level 153518334Speter scope, so we avoid it here also. However, mips ECOFF compilers do emit 153618334Speter a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ 153718334Speter#ifndef MIPS_DEBUGGING_INFO 153818334Speter if (n != 1) 153918334Speter#endif 154018334Speter PUT_SDB_BLOCK_START (line - sdb_begin_function_line); 154118334Speter 154218334Speter if (n == 1) 154318334Speter { 154418334Speter /* Include the outermost BLOCK's variables in block 1. */ 154518334Speter next_block_number = 0; 154618334Speter do_block = 0; 154718334Speter sdbout_block (DECL_INITIAL (decl)); 154818334Speter } 154918334Speter /* If -g1, suppress all the internal symbols of functions 155018334Speter except for arguments. */ 155118334Speter if (debug_info_level != DINFO_LEVEL_TERSE) 155218334Speter { 155318334Speter next_block_number = 0; 155418334Speter do_block = n; 155518334Speter sdbout_block (DECL_INITIAL (decl)); 155618334Speter } 155718334Speter 155818334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 155918334Speter sdbout_dequeue_anonymous_types (); 156018334Speter#endif 156118334Speter} 156218334Speter 156318334Speter/* Describe the end line-number of an internal block within a function. */ 156418334Speter 156518334Spetervoid 156618334Spetersdbout_end_block (file, line, n) 156718334Speter FILE *file; 156818334Speter int line; 156952284Sobrien int n ATTRIBUTE_UNUSED; 157018334Speter{ 157118334Speter MAKE_LINE_SAFE (line); 157218334Speter 157318334Speter /* The SCO compiler does not emit a separate block for the function level 157418334Speter scope, so we avoid it here also. However, mips ECOFF compilers do emit 157518334Speter a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ 157618334Speter#ifndef MIPS_DEBUGGING_INFO 157718334Speter if (n != 1) 157818334Speter#endif 157918334Speter PUT_SDB_BLOCK_END (line - sdb_begin_function_line); 158018334Speter} 158118334Speter 158218334Speter/* Output sdb info for the current function name. 158318334Speter Called from assemble_start_function. */ 158418334Speter 158518334Spetervoid 158618334Spetersdbout_mark_begin_function () 158718334Speter{ 158818334Speter sdbout_symbol (current_function_decl, 0); 158918334Speter} 159018334Speter 159118334Speter/* Called at beginning of function body (after prologue). 159218334Speter Record the function's starting line number, so we can output 159318334Speter relative line numbers for the other lines. 159418334Speter Describe beginning of outermost block. 159518334Speter Also describe the parameter list. */ 159618334Speter 159718334Spetervoid 159818334Spetersdbout_begin_function (line) 159918334Speter int line; 160018334Speter{ 160118334Speter sdb_begin_function_line = line - 1; 160218334Speter PUT_SDB_FUNCTION_START (line); 160318334Speter sdbout_parms (DECL_ARGUMENTS (current_function_decl)); 160418334Speter sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl)); 160518334Speter} 160618334Speter 160718334Speter/* Called at end of function (before epilogue). 160818334Speter Describe end of outermost block. */ 160918334Speter 161018334Spetervoid 161118334Spetersdbout_end_function (line) 161218334Speter int line; 161318334Speter{ 161418334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 161518334Speter sdbout_dequeue_anonymous_types (); 161618334Speter#endif 161718334Speter 161818334Speter MAKE_LINE_SAFE (line); 161918334Speter PUT_SDB_FUNCTION_END (line - sdb_begin_function_line); 162018334Speter 162118334Speter /* Indicate we are between functions, for line-number output. */ 162218334Speter sdb_begin_function_line = -1; 162318334Speter} 162418334Speter 162518334Speter/* Output sdb info for the absolute end of a function. 162618334Speter Called after the epilogue is output. */ 162718334Speter 162818334Spetervoid 162918334Spetersdbout_end_epilogue () 163018334Speter{ 163118334Speter char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); 163218334Speter PUT_SDB_EPILOGUE_END (name); 163318334Speter} 163418334Speter 163518334Speter/* Output sdb info for the given label. Called only if LABEL_NAME (insn) 163618334Speter is present. */ 163718334Speter 163818334Spetervoid 163918334Spetersdbout_label (insn) 164018334Speter register rtx insn; 164118334Speter{ 164218334Speter PUT_SDB_DEF (LABEL_NAME (insn)); 164318334Speter PUT_SDB_VAL (insn); 164418334Speter PUT_SDB_SCL (C_LABEL); 164518334Speter PUT_SDB_TYPE (T_NULL); 164618334Speter PUT_SDB_ENDEF; 164718334Speter} 164818334Speter 164950397Sobrien/* Change to reading from a new source file. */ 165050397Sobrien 165150397Sobrienvoid 165250397Sobriensdbout_start_new_source_file (filename) 165350397Sobrien char *filename; 165450397Sobrien{ 165550397Sobrien#ifdef MIPS_DEBUGGING_INFO 165650397Sobrien struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n); 165750397Sobrien 165850397Sobrien n->next = current_file; 165950397Sobrien n->name = filename; 166050397Sobrien current_file = n; 166150397Sobrien PUT_SDB_SRC_FILE (filename); 166250397Sobrien#endif 166350397Sobrien} 166450397Sobrien 166550397Sobrien/* Revert to reading a previous source file. */ 166650397Sobrien 166750397Sobrienvoid 166850397Sobriensdbout_resume_previous_source_file () 166950397Sobrien{ 167050397Sobrien#ifdef MIPS_DEBUGGING_INFO 167150397Sobrien struct sdb_file *next; 167250397Sobrien 167350397Sobrien next = current_file->next; 167450397Sobrien free (current_file); 167550397Sobrien current_file = next; 167650397Sobrien PUT_SDB_SRC_FILE (current_file->name); 167750397Sobrien#endif 167850397Sobrien} 167950397Sobrien 168018334Speter#endif /* SDB_DEBUGGING_INFO */ 1681