118334Speter/* Output sdb-format symbol table information from GNU compiler. 290075Sobrien Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 3169689Skan 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 2118334Speter 2218334Speter/* mike@tredysvr.Tredydev.Unisys.COM says: 2318334SpeterI modified the struct.c example and have a nm of a .o resulting from the 2418334SpeterAT&T C compiler. From the example below I would conclude the following: 2518334Speter 2618334Speter1. All .defs from structures are emitted as scanned. The example below 2718334Speter clearly shows the symbol table entries for BoxRec2 are after the first 2818334Speter function. 2918334Speter 3018334Speter2. All functions and their locals (including statics) are emitted as scanned. 3118334Speter 3218334Speter3. All nested unnamed union and structure .defs must be emitted before 3318334Speter the structure in which they are nested. The AT&T assembler is a 3418334Speter one pass beast as far as symbolics are concerned. 3518334Speter 3618334Speter4. All structure .defs are emitted before the typedefs that refer to them. 3718334Speter 3818334Speter5. All top level static and external variable definitions are moved to the 3918334Speter end of file with all top level statics occurring first before externs. 4018334Speter 4118334Speter6. All undefined references are at the end of the file. 4218334Speter*/ 4318334Speter 4418334Speter#include "config.h" 45117395Skan#include "system.h" 46132718Skan#include "coretypes.h" 47132718Skan#include "tm.h" 48117395Skan#include "debug.h" 49117395Skan#include "tree.h" 50117395Skan#include "ggc.h" 51169689Skan#include "varray.h" 5218334Speter 53117395Skanstatic GTY(()) tree anonymous_types; 54117395Skan 55132718Skan/* Counter to generate unique "names" for nameless struct members. */ 56132718Skan 57132718Skanstatic GTY(()) int unnamed_struct_number; 58132718Skan 59169689Skan/* Declarations whose debug info was deferred till end of compilation. */ 60169689Skan 61169689Skanstatic GTY(()) varray_type deferred_global_decls; 62169689Skan 63169689Skan/* The C front end may call sdbout_symbol before sdbout_init runs. 64169689Skan We save all such decls in this list and output them when we get 65169689Skan to sdbout_init. */ 66169689Skan 67169689Skanstatic GTY(()) tree preinit_symbols; 68169689Skanstatic GTY(()) bool sdbout_initialized; 69169689Skan 7018334Speter#ifdef SDB_DEBUGGING_INFO 7118334Speter 7218334Speter#include "rtl.h" 7318334Speter#include "regs.h" 7418334Speter#include "flags.h" 7518334Speter#include "insn-config.h" 7618334Speter#include "reload.h" 7750397Sobrien#include "output.h" 7850397Sobrien#include "toplev.h" 7990075Sobrien#include "tm_p.h" 8018334Speter#include "gsyms.h" 81117395Skan#include "langhooks.h" 82132718Skan#include "target.h" 8318334Speter 8418334Speter/* 1 if PARM is passed to this function in memory. */ 8518334Speter 8618334Speter#define PARM_PASSED_IN_MEMORY(PARM) \ 87169689Skan (MEM_P (DECL_INCOMING_RTL (PARM))) 8818334Speter 8918334Speter/* A C expression for the integer offset value of an automatic variable 9018334Speter (C_AUTO) having address X (an RTX). */ 9118334Speter#ifndef DEBUGGER_AUTO_OFFSET 9218334Speter#define DEBUGGER_AUTO_OFFSET(X) \ 9318334Speter (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) 9418334Speter#endif 9518334Speter 9618334Speter/* A C expression for the integer offset value of an argument (C_ARG) 9718334Speter having address X (an RTX). The nominal offset is OFFSET. */ 9818334Speter#ifndef DEBUGGER_ARG_OFFSET 9918334Speter#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) 10018334Speter#endif 10118334Speter 10218334Speter/* Line number of beginning of current function, minus one. 10318334Speter Negative means not in a function or not using sdb. */ 10418334Speter 10518334Speterint sdb_begin_function_line = -1; 10618334Speter 10718334Speter 10818334Speterextern FILE *asm_out_file; 10918334Speter 11018334Speterextern tree current_function_decl; 11118334Speter 11250397Sobrien#include "sdbout.h" 11318334Speter 114132718Skanstatic void sdbout_init (const char *); 115132718Skanstatic void sdbout_finish (const char *); 116132718Skanstatic void sdbout_start_source_file (unsigned int, const char *); 117132718Skanstatic void sdbout_end_source_file (unsigned int); 118132718Skanstatic void sdbout_begin_block (unsigned int, unsigned int); 119132718Skanstatic void sdbout_end_block (unsigned int, unsigned int); 120132718Skanstatic void sdbout_source_line (unsigned int, const char *); 121132718Skanstatic void sdbout_end_epilogue (unsigned int, const char *); 122132718Skanstatic void sdbout_global_decl (tree); 12390075Sobrien#ifndef MIPS_DEBUGGING_INFO 124132718Skanstatic void sdbout_begin_prologue (unsigned int, const char *); 12518334Speter#endif 126132718Skanstatic void sdbout_end_prologue (unsigned int, const char *); 127132718Skanstatic void sdbout_begin_function (tree); 128132718Skanstatic void sdbout_end_function (unsigned int); 129132718Skanstatic void sdbout_toplevel_data (tree); 130132718Skanstatic void sdbout_label (rtx); 131132718Skanstatic char *gen_fake_label (void); 132132718Skanstatic int plain_type (tree); 133132718Skanstatic int template_name_p (tree); 134132718Skanstatic void sdbout_record_type_name (tree); 135132718Skanstatic int plain_type_1 (tree, int); 136132718Skanstatic void sdbout_block (tree); 137132718Skanstatic void sdbout_syms (tree); 13890075Sobrien#ifdef SDB_ALLOW_FORWARD_REFERENCES 139132718Skanstatic void sdbout_queue_anonymous_type (tree); 140132718Skanstatic void sdbout_dequeue_anonymous_types (void); 14118334Speter#endif 142132718Skanstatic void sdbout_type (tree); 143132718Skanstatic void sdbout_field_types (tree); 144132718Skanstatic void sdbout_one_type (tree); 145132718Skanstatic void sdbout_parms (tree); 146132718Skanstatic void sdbout_reg_parms (tree); 147132718Skanstatic void sdbout_global_decl (tree); 148132718Skan 14918334Speter/* Random macros describing parts of SDB data. */ 15018334Speter 15118334Speter/* Default value of delimiter is ";". */ 15218334Speter#ifndef SDB_DELIM 15318334Speter#define SDB_DELIM ";" 15418334Speter#endif 15518334Speter 15618334Speter/* Maximum number of dimensions the assembler will allow. */ 15718334Speter#ifndef SDB_MAX_DIM 15818334Speter#define SDB_MAX_DIM 4 15918334Speter#endif 16018334Speter 16118334Speter#ifndef PUT_SDB_SCL 16218334Speter#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM) 16318334Speter#endif 16418334Speter 16518334Speter#ifndef PUT_SDB_INT_VAL 16650397Sobrien#define PUT_SDB_INT_VAL(a) \ 16750397Sobrien do { \ 168132718Skan fprintf (asm_out_file, "\t.val\t" HOST_WIDE_INT_PRINT_DEC "%s", \ 169132718Skan (HOST_WIDE_INT) (a), SDB_DELIM); \ 17050397Sobrien } while (0) 17150397Sobrien 17218334Speter#endif 17318334Speter 17418334Speter#ifndef PUT_SDB_VAL 17518334Speter#define PUT_SDB_VAL(a) \ 17618334Speter( fputs ("\t.val\t", asm_out_file), \ 17718334Speter output_addr_const (asm_out_file, (a)), \ 17818334Speter fprintf (asm_out_file, SDB_DELIM)) 17918334Speter#endif 18018334Speter 18118334Speter#ifndef PUT_SDB_DEF 18218334Speter#define PUT_SDB_DEF(a) \ 18318334Speterdo { fprintf (asm_out_file, "\t.def\t"); \ 184132718Skan assemble_name (asm_out_file, a); \ 18518334Speter fprintf (asm_out_file, SDB_DELIM); } while (0) 18618334Speter#endif 18718334Speter 18818334Speter#ifndef PUT_SDB_PLAIN_DEF 18918334Speter#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM) 19018334Speter#endif 19118334Speter 19218334Speter#ifndef PUT_SDB_ENDEF 19318334Speter#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file) 19418334Speter#endif 19518334Speter 19618334Speter#ifndef PUT_SDB_TYPE 19718334Speter#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM) 19818334Speter#endif 19918334Speter 20018334Speter#ifndef PUT_SDB_SIZE 20150397Sobrien#define PUT_SDB_SIZE(a) \ 20250397Sobrien do { \ 203132718Skan fprintf (asm_out_file, "\t.size\t" HOST_WIDE_INT_PRINT_DEC "%s", \ 204132718Skan (HOST_WIDE_INT) (a), SDB_DELIM); \ 20550397Sobrien } while(0) 20618334Speter#endif 20718334Speter 20818334Speter#ifndef PUT_SDB_START_DIM 20918334Speter#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t") 21018334Speter#endif 21118334Speter 21218334Speter#ifndef PUT_SDB_NEXT_DIM 21318334Speter#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a) 21418334Speter#endif 21518334Speter 21618334Speter#ifndef PUT_SDB_LAST_DIM 21718334Speter#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM) 21818334Speter#endif 21918334Speter 22018334Speter#ifndef PUT_SDB_TAG 22118334Speter#define PUT_SDB_TAG(a) \ 22218334Speterdo { fprintf (asm_out_file, "\t.tag\t"); \ 22390075Sobrien assemble_name (asm_out_file, a); \ 22418334Speter fprintf (asm_out_file, SDB_DELIM); } while (0) 22518334Speter#endif 22618334Speter 22718334Speter#ifndef PUT_SDB_BLOCK_START 22818334Speter#define PUT_SDB_BLOCK_START(LINE) \ 22918334Speter fprintf (asm_out_file, \ 23018334Speter "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ 23118334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 23218334Speter#endif 23318334Speter 23418334Speter#ifndef PUT_SDB_BLOCK_END 23518334Speter#define PUT_SDB_BLOCK_END(LINE) \ 23618334Speter fprintf (asm_out_file, \ 23718334Speter "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ 23818334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 23918334Speter#endif 24018334Speter 24118334Speter#ifndef PUT_SDB_FUNCTION_START 24218334Speter#define PUT_SDB_FUNCTION_START(LINE) \ 24318334Speter fprintf (asm_out_file, \ 24418334Speter "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ 24518334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 24618334Speter#endif 24718334Speter 24818334Speter#ifndef PUT_SDB_FUNCTION_END 24918334Speter#define PUT_SDB_FUNCTION_END(LINE) \ 25018334Speter fprintf (asm_out_file, \ 25118334Speter "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ 25218334Speter SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) 25318334Speter#endif 25418334Speter 25518334Speter/* Return the sdb tag identifier string for TYPE 25690075Sobrien if TYPE has already been defined; otherwise return a null pointer. */ 25718334Speter 25818334Speter#define KNOWN_TYPE_TAG(type) TYPE_SYMTAB_POINTER (type) 25918334Speter 26018334Speter/* Set the sdb tag identifier string for TYPE to NAME. */ 26118334Speter 26218334Speter#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \ 263132718Skan TYPE_SYMTAB_POINTER (TYPE) = (char *)(NAME) 26418334Speter 26518334Speter/* Return the name (a string) of the struct, union or enum tag 26618334Speter described by the TREE_LIST node LINK. This is 0 for an anonymous one. */ 26718334Speter 26818334Speter#define TAG_NAME(link) \ 26918334Speter (((link) && TREE_PURPOSE ((link)) \ 27018334Speter && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \ 27118334Speter ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0) 27218334Speter 27318334Speter/* Ensure we don't output a negative line number. */ 27418334Speter#define MAKE_LINE_SAFE(line) \ 27590075Sobrien if ((int) line <= sdb_begin_function_line) \ 27690075Sobrien line = sdb_begin_function_line + 1 27750397Sobrien 27850397Sobrien/* Perform linker optimization of merging header file definitions together 27950397Sobrien for targets with MIPS_DEBUGGING_INFO defined. This won't work without a 28050397Sobrien post 960826 version of GAS. Nothing breaks with earlier versions of GAS, 28150397Sobrien the optimization just won't be done. The native assembler already has the 28250397Sobrien necessary support. */ 28350397Sobrien 28450397Sobrien#ifdef MIPS_DEBUGGING_INFO 28550397Sobrien 28650397Sobrien/* ECOFF linkers have an optimization that does the same kind of thing as 28750397Sobrien N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the 28850397Sobrien executable. To achieve this, GCC must output a .file for each file 28950397Sobrien name change. */ 29050397Sobrien 29150397Sobrien/* This is a stack of input files. */ 29250397Sobrien 29350397Sobrienstruct sdb_file 29450397Sobrien{ 29550397Sobrien struct sdb_file *next; 29690075Sobrien const char *name; 29750397Sobrien}; 29850397Sobrien 29950397Sobrien/* This is the top of the stack. */ 30050397Sobrien 30150397Sobrienstatic struct sdb_file *current_file; 30250397Sobrien 30350397Sobrien#endif /* MIPS_DEBUGGING_INFO */ 304132718Skan 30590075Sobrien/* The debug hooks structure. */ 306117395Skanconst struct gcc_debug_hooks sdb_debug_hooks = 30718334Speter{ 308169689Skan sdbout_init, /* init */ 309169689Skan sdbout_finish, /* finish */ 310169689Skan debug_nothing_int_charstar, /* define */ 311169689Skan debug_nothing_int_charstar, /* undef */ 312169689Skan sdbout_start_source_file, /* start_source_file */ 313169689Skan sdbout_end_source_file, /* end_source_file */ 314169689Skan sdbout_begin_block, /* begin_block */ 315169689Skan sdbout_end_block, /* end_block */ 316169689Skan debug_true_tree, /* ignore_block */ 317169689Skan sdbout_source_line, /* source_line */ 31850397Sobrien#ifdef MIPS_DEBUGGING_INFO 31990075Sobrien /* Defer on MIPS systems so that parameter descriptions follow 32090075Sobrien function entry. */ 321169689Skan debug_nothing_int_charstar, /* begin_prologue */ 322169689Skan sdbout_end_prologue, /* end_prologue */ 32390075Sobrien#else 324169689Skan sdbout_begin_prologue, /* begin_prologue */ 325169689Skan debug_nothing_int_charstar, /* end_prologue */ 32650397Sobrien#endif 327169689Skan sdbout_end_epilogue, /* end_epilogue */ 328169689Skan sdbout_begin_function, /* begin_function */ 329169689Skan sdbout_end_function, /* end_function */ 330169689Skan debug_nothing_tree, /* function_decl */ 331169689Skan sdbout_global_decl, /* global_decl */ 332169689Skan sdbout_symbol, /* type_decl */ 333169689Skan debug_nothing_tree_tree, /* imported_module_or_decl */ 334169689Skan debug_nothing_tree, /* deferred_inline_function */ 335169689Skan debug_nothing_tree, /* outlining_inline_function */ 336169689Skan sdbout_label, /* label */ 337169689Skan debug_nothing_int, /* handle_pch */ 338169689Skan debug_nothing_rtx, /* var_location */ 339169689Skan debug_nothing_void, /* switch_text_section */ 340169689Skan 0 /* start_end_main_source_file */ 34190075Sobrien}; 34218334Speter 34318334Speter/* Return a unique string to name an anonymous type. */ 34418334Speter 34518334Speterstatic char * 346132718Skangen_fake_label (void) 34718334Speter{ 34818334Speter char label[10]; 34918334Speter char *labelstr; 350169689Skan sprintf (label, ".%dfake", unnamed_struct_number); 35118334Speter unnamed_struct_number++; 352117395Skan labelstr = xstrdup (label); 35318334Speter return labelstr; 35418334Speter} 355132718Skan 35618334Speter/* Return the number which describes TYPE for SDB. 35718334Speter For pointers, etc., this function is recursive. 35818334Speter Each record, union or enumeral type must already have had a 35918334Speter tag number output. */ 36018334Speter 36118334Speter/* The number is given by d6d5d4d3d2d1bbbb 36218334Speter where bbbb is 4 bit basic type, and di indicate one of notype,ptr,fn,array. 36318334Speter Thus, char *foo () has bbbb=T_CHAR 36418334Speter d1=D_FCN 36518334Speter d2=D_PTR 36618334Speter N_BTMASK= 017 1111 basic type field. 36718334Speter N_TSHIFT= 2 derived type shift 36818334Speter N_BTSHFT= 4 Basic type shift */ 36918334Speter 37018334Speter/* Produce the number that describes a pointer, function or array type. 37118334Speter PREV is the number describing the target, value or element type. 37218334Speter DT_type describes how to transform that type. */ 37318334Speter#define PUSH_DERIVED_LEVEL(DT_type,PREV) \ 37490075Sobrien ((((PREV) & ~(int) N_BTMASK) << (int) N_TSHIFT) \ 37590075Sobrien | ((int) DT_type << (int) N_BTSHFT) \ 37690075Sobrien | ((PREV) & (int) N_BTMASK)) 37718334Speter 37818334Speter/* Number of elements used in sdb_dims. */ 37918334Speterstatic int sdb_n_dims = 0; 38018334Speter 38118334Speter/* Table of array dimensions of current type. */ 38218334Speterstatic int sdb_dims[SDB_MAX_DIM]; 38318334Speter 38418334Speter/* Size of outermost array currently being processed. */ 38518334Speterstatic int sdb_type_size = -1; 38618334Speter 38718334Speterstatic int 388132718Skanplain_type (tree type) 38918334Speter{ 39018334Speter int val = plain_type_1 (type, 0); 39118334Speter 39218334Speter /* If we have already saved up some array dimensions, print them now. */ 39318334Speter if (sdb_n_dims > 0) 39418334Speter { 39518334Speter int i; 39618334Speter PUT_SDB_START_DIM; 39718334Speter for (i = sdb_n_dims - 1; i > 0; i--) 39818334Speter PUT_SDB_NEXT_DIM (sdb_dims[i]); 39918334Speter PUT_SDB_LAST_DIM (sdb_dims[0]); 40018334Speter sdb_n_dims = 0; 40118334Speter 40218334Speter sdb_type_size = int_size_in_bytes (type); 40318334Speter /* Don't kill sdb if type is not laid out or has variable size. */ 40418334Speter if (sdb_type_size < 0) 40518334Speter sdb_type_size = 0; 40618334Speter } 40718334Speter /* If we have computed the size of an array containing this type, 40818334Speter print it now. */ 40918334Speter if (sdb_type_size >= 0) 41018334Speter { 41118334Speter PUT_SDB_SIZE (sdb_type_size); 41218334Speter sdb_type_size = -1; 41318334Speter } 41418334Speter return val; 41518334Speter} 41618334Speter 41718334Speterstatic int 418132718Skantemplate_name_p (tree name) 41918334Speter{ 42090075Sobrien const char *ptr = IDENTIFIER_POINTER (name); 42118334Speter while (*ptr && *ptr != '<') 42218334Speter ptr++; 42318334Speter 42418334Speter return *ptr != '\0'; 42518334Speter} 42618334Speter 42718334Speterstatic void 428132718Skansdbout_record_type_name (tree type) 42918334Speter{ 43090075Sobrien const char *name = 0; 43118334Speter int no_name; 43218334Speter 43318334Speter if (KNOWN_TYPE_TAG (type)) 43418334Speter return; 43518334Speter 43618334Speter if (TYPE_NAME (type) != 0) 43718334Speter { 43818334Speter tree t = 0; 43990075Sobrien 44018334Speter /* Find the IDENTIFIER_NODE for the type name. */ 44118334Speter if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) 44218334Speter t = TYPE_NAME (type); 44318334Speter else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) 44418334Speter { 44518334Speter t = DECL_NAME (TYPE_NAME (type)); 44618334Speter /* The DECL_NAME for templates includes "<>", which breaks 44718334Speter most assemblers. Use its assembler name instead, which 44818334Speter has been mangled into being safe. */ 44918334Speter if (t && template_name_p (t)) 45018334Speter t = DECL_ASSEMBLER_NAME (TYPE_NAME (type)); 45118334Speter } 45218334Speter 45318334Speter /* Now get the name as a string, or invent one. */ 45418334Speter if (t != NULL_TREE) 45518334Speter name = IDENTIFIER_POINTER (t); 45618334Speter } 45718334Speter 45818334Speter no_name = (name == 0 || *name == 0); 45918334Speter if (no_name) 46018334Speter name = gen_fake_label (); 46118334Speter 46218334Speter SET_KNOWN_TYPE_TAG (type, name); 46318334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 46418334Speter if (no_name) 46518334Speter sdbout_queue_anonymous_type (type); 46618334Speter#endif 46718334Speter} 46818334Speter 46918334Speter/* Return the .type value for type TYPE. 47018334Speter 47118334Speter LEVEL indicates how many levels deep we have recursed into the type. 47218334Speter The SDB debug format can only represent 6 derived levels of types. 47318334Speter After that, we must output inaccurate debug info. We deliberately 47418334Speter stop before the 7th level, so that ADA recursive types will not give an 47518334Speter infinite loop. */ 47618334Speter 47718334Speterstatic int 478132718Skanplain_type_1 (tree type, int level) 47918334Speter{ 48018334Speter if (type == 0) 48118334Speter type = void_type_node; 48218334Speter else if (type == error_mark_node) 48318334Speter type = integer_type_node; 48418334Speter else 48518334Speter type = TYPE_MAIN_VARIANT (type); 48618334Speter 48718334Speter switch (TREE_CODE (type)) 48818334Speter { 48918334Speter case VOID_TYPE: 49018334Speter return T_VOID; 49152284Sobrien case BOOLEAN_TYPE: 49218334Speter case INTEGER_TYPE: 49318334Speter { 49418334Speter int size = int_size_in_bytes (type) * BITS_PER_UNIT; 49518334Speter 49618334Speter /* Carefully distinguish all the standard types of C, 49718334Speter without messing up if the language is not C. 49818334Speter Note that we check only for the names that contain spaces; 49918334Speter other names might occur by coincidence in other languages. */ 50018334Speter if (TYPE_NAME (type) != 0 50118334Speter && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 50218334Speter && DECL_NAME (TYPE_NAME (type)) != 0 50318334Speter && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) 50418334Speter { 50590075Sobrien const char *const name 50690075Sobrien = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 50718334Speter 50850397Sobrien if (!strcmp (name, "char")) 50950397Sobrien return T_CHAR; 51018334Speter if (!strcmp (name, "unsigned char")) 51118334Speter return T_UCHAR; 51218334Speter if (!strcmp (name, "signed char")) 51318334Speter return T_CHAR; 51450397Sobrien if (!strcmp (name, "int")) 51550397Sobrien return T_INT; 51618334Speter if (!strcmp (name, "unsigned int")) 51718334Speter return T_UINT; 51818334Speter if (!strcmp (name, "short int")) 51918334Speter return T_SHORT; 52018334Speter if (!strcmp (name, "short unsigned int")) 52118334Speter return T_USHORT; 52218334Speter if (!strcmp (name, "long int")) 52318334Speter return T_LONG; 52418334Speter if (!strcmp (name, "long unsigned int")) 52518334Speter return T_ULONG; 52618334Speter } 52718334Speter 52850397Sobrien if (size == INT_TYPE_SIZE) 529169689Skan return (TYPE_UNSIGNED (type) ? T_UINT : T_INT); 53018334Speter if (size == CHAR_TYPE_SIZE) 531169689Skan return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR); 53218334Speter if (size == SHORT_TYPE_SIZE) 533169689Skan return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT); 53418334Speter if (size == LONG_TYPE_SIZE) 535169689Skan return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG); 53618334Speter if (size == LONG_LONG_TYPE_SIZE) /* better than nothing */ 537169689Skan return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG); 53818334Speter return 0; 53918334Speter } 54018334Speter 54118334Speter case REAL_TYPE: 54218334Speter { 54350397Sobrien int precision = TYPE_PRECISION (type); 54450397Sobrien if (precision == FLOAT_TYPE_SIZE) 54518334Speter return T_FLOAT; 54650397Sobrien if (precision == DOUBLE_TYPE_SIZE) 54718334Speter return T_DOUBLE; 54850397Sobrien#ifdef EXTENDED_SDB_BASIC_TYPES 54950397Sobrien if (precision == LONG_DOUBLE_TYPE_SIZE) 55050397Sobrien return T_LNGDBL; 55150397Sobrien#else 55250397Sobrien if (precision == LONG_DOUBLE_TYPE_SIZE) 55350397Sobrien return T_DOUBLE; /* better than nothing */ 55450397Sobrien#endif 55518334Speter return 0; 55618334Speter } 55718334Speter 55818334Speter case ARRAY_TYPE: 55918334Speter { 56018334Speter int m; 56118334Speter if (level >= 6) 56218334Speter return T_VOID; 56318334Speter else 56418334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 56518334Speter if (sdb_n_dims < SDB_MAX_DIM) 56618334Speter sdb_dims[sdb_n_dims++] 56718334Speter = (TYPE_DOMAIN (type) 56890075Sobrien && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0 56990075Sobrien && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0 57090075Sobrien && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0) 57190075Sobrien && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) 57290075Sobrien ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0) 57390075Sobrien - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1) 57418334Speter : 0); 57590075Sobrien 57618334Speter return PUSH_DERIVED_LEVEL (DT_ARY, m); 57718334Speter } 57818334Speter 57918334Speter case RECORD_TYPE: 58018334Speter case UNION_TYPE: 58118334Speter case QUAL_UNION_TYPE: 58218334Speter case ENUMERAL_TYPE: 58318334Speter { 58418334Speter char *tag; 58518334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 58618334Speter sdbout_record_type_name (type); 58718334Speter#endif 58818334Speter#ifndef SDB_ALLOW_UNKNOWN_REFERENCES 58918334Speter if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0) 59018334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 59118334Speter || TYPE_MODE (type) != VOIDmode 59218334Speter#endif 59318334Speter ) 59418334Speter#endif 59518334Speter { 59618334Speter /* Output the referenced structure tag name 59718334Speter only if the .def has already been finished. 59818334Speter At least on 386, the Unix assembler 59918334Speter cannot handle forward references to tags. */ 60050397Sobrien /* But the 88100, it requires them, sigh... */ 60150397Sobrien /* And the MIPS requires unknown refs as well... */ 60218334Speter tag = KNOWN_TYPE_TAG (type); 60318334Speter PUT_SDB_TAG (tag); 60418334Speter /* These 3 lines used to follow the close brace. 60518334Speter However, a size of 0 without a tag implies a tag of 0, 60618334Speter so if we don't know a tag, we can't mention the size. */ 60718334Speter sdb_type_size = int_size_in_bytes (type); 60818334Speter if (sdb_type_size < 0) 60918334Speter sdb_type_size = 0; 61018334Speter } 61118334Speter return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT 61218334Speter : (TREE_CODE (type) == UNION_TYPE) ? T_UNION 61318334Speter : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION 61418334Speter : T_ENUM); 61518334Speter } 61618334Speter case POINTER_TYPE: 61718334Speter case REFERENCE_TYPE: 61818334Speter { 61918334Speter int m; 62018334Speter if (level >= 6) 62118334Speter return T_VOID; 62218334Speter else 62318334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 62418334Speter return PUSH_DERIVED_LEVEL (DT_PTR, m); 62518334Speter } 62618334Speter case FUNCTION_TYPE: 62718334Speter case METHOD_TYPE: 62818334Speter { 62918334Speter int m; 63018334Speter if (level >= 6) 63118334Speter return T_VOID; 63218334Speter else 63318334Speter m = plain_type_1 (TREE_TYPE (type), level+1); 63418334Speter return PUSH_DERIVED_LEVEL (DT_FCN, m); 63518334Speter } 63618334Speter default: 63718334Speter return 0; 63818334Speter } 63918334Speter} 640132718Skan 64118334Speter/* Output the symbols defined in block number DO_BLOCK. 64218334Speter 64318334Speter This function works by walking the tree structure of blocks, 64418334Speter counting blocks until it finds the desired block. */ 64518334Speter 64618334Speterstatic int do_block = 0; 64718334Speter 64818334Speterstatic void 649132718Skansdbout_block (tree block) 65018334Speter{ 65118334Speter while (block) 65218334Speter { 65318334Speter /* Ignore blocks never expanded or otherwise marked as real. */ 65418334Speter if (TREE_USED (block)) 65518334Speter { 65618334Speter /* When we reach the specified block, output its symbols. */ 65790075Sobrien if (BLOCK_NUMBER (block) == do_block) 65890075Sobrien sdbout_syms (BLOCK_VARS (block)); 65918334Speter 66018334Speter /* If we are past the specified block, stop the scan. */ 66190075Sobrien if (BLOCK_NUMBER (block) > do_block) 66218334Speter return; 66318334Speter 66418334Speter /* Scan the blocks within this block. */ 66518334Speter sdbout_block (BLOCK_SUBBLOCKS (block)); 66618334Speter } 66718334Speter 66818334Speter block = BLOCK_CHAIN (block); 66918334Speter } 67018334Speter} 671132718Skan 67218334Speter/* Call sdbout_symbol on each decl in the chain SYMS. */ 67318334Speter 67418334Speterstatic void 675132718Skansdbout_syms (tree syms) 67618334Speter{ 67718334Speter while (syms) 67818334Speter { 67918334Speter if (TREE_CODE (syms) != LABEL_DECL) 68018334Speter sdbout_symbol (syms, 1); 68118334Speter syms = TREE_CHAIN (syms); 68218334Speter } 68318334Speter} 68418334Speter 68518334Speter/* Output SDB information for a symbol described by DECL. 68618334Speter LOCAL is nonzero if the symbol is not file-scope. */ 68718334Speter 68818334Spetervoid 689132718Skansdbout_symbol (tree decl, int local) 69018334Speter{ 69118334Speter tree type = TREE_TYPE (decl); 69218334Speter tree context = NULL_TREE; 69318334Speter rtx value; 69418334Speter int regno = -1; 69590075Sobrien const char *name; 69618334Speter 697169689Skan /* If we are called before sdbout_init is run, just save the symbol 698169689Skan for later. */ 699169689Skan if (!sdbout_initialized) 700169689Skan { 701169689Skan preinit_symbols = tree_cons (0, decl, preinit_symbols); 702169689Skan return; 703169689Skan } 704169689Skan 70518334Speter sdbout_one_type (type); 70618334Speter 70718334Speter switch (TREE_CODE (decl)) 70818334Speter { 70918334Speter case CONST_DECL: 71018334Speter /* Enum values are defined by defining the enum type. */ 71118334Speter return; 71218334Speter 71318334Speter case FUNCTION_DECL: 71418334Speter /* Don't mention a nested function under its parent. */ 71518334Speter context = decl_function_context (decl); 71618334Speter if (context == current_function_decl) 71718334Speter return; 71850397Sobrien /* Check DECL_INITIAL to distinguish declarations from definitions. 71950397Sobrien Don't output debug info here for declarations; they will have 72050397Sobrien a DECL_INITIAL value of 0. */ 72150397Sobrien if (! DECL_INITIAL (decl)) 72218334Speter return; 723169689Skan if (!MEM_P (DECL_RTL (decl)) 72418334Speter || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) 72518334Speter return; 72618334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 72718334Speter PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); 72818334Speter PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT); 72918334Speter break; 73018334Speter 73118334Speter case TYPE_DECL: 73218334Speter /* Done with tagged types. */ 73318334Speter if (DECL_NAME (decl) == 0) 73418334Speter return; 73518334Speter if (DECL_IGNORED_P (decl)) 73618334Speter return; 737169689Skan /* Don't output intrinsic types. GAS chokes on SDB .def 738169689Skan statements that contain identifiers with embedded spaces 739169689Skan (eg "unsigned long"). */ 740169689Skan if (DECL_IS_BUILTIN (decl)) 741169689Skan return; 74218334Speter 74318334Speter /* Output typedef name. */ 74418334Speter if (template_name_p (DECL_NAME (decl))) 74518334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 74618334Speter else 74718334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl))); 74818334Speter PUT_SDB_SCL (C_TPDEF); 74918334Speter break; 75018334Speter 75118334Speter case PARM_DECL: 75218334Speter /* Parm decls go in their own separate chains 75318334Speter and are output by sdbout_reg_parms and sdbout_parms. */ 754169689Skan gcc_unreachable (); 75518334Speter 75618334Speter case VAR_DECL: 75718334Speter /* Don't mention a variable that is external. 75818334Speter Let the file that defines it describe it. */ 75918334Speter if (DECL_EXTERNAL (decl)) 76018334Speter return; 76118334Speter 76218334Speter /* Ignore __FUNCTION__, etc. */ 76318334Speter if (DECL_IGNORED_P (decl)) 76418334Speter return; 76518334Speter 76618334Speter /* If there was an error in the declaration, don't dump core 76718334Speter if there is no RTL associated with the variable doesn't 76818334Speter exist. */ 76990075Sobrien if (!DECL_RTL_SET_P (decl)) 77018334Speter return; 77118334Speter 772117395Skan SET_DECL_RTL (decl, 77390075Sobrien eliminate_regs (DECL_RTL (decl), 0, NULL_RTX)); 77418334Speter#ifdef LEAF_REG_REMAP 77552284Sobrien if (current_function_uses_only_leaf_regs) 77618334Speter leaf_renumber_regs_insn (DECL_RTL (decl)); 77718334Speter#endif 77818334Speter value = DECL_RTL (decl); 77918334Speter 78018334Speter /* Don't mention a variable at all 78118334Speter if it was completely optimized into nothingness. 78218334Speter 78318334Speter If DECL was from an inline function, then its rtl 78418334Speter is not identically the rtl that was used in this 78518334Speter particular compilation. */ 786169689Skan if (REG_P (value)) 78718334Speter { 78890075Sobrien regno = REGNO (value); 78918334Speter if (regno >= FIRST_PSEUDO_REGISTER) 79018334Speter return; 79118334Speter } 79218334Speter else if (GET_CODE (value) == SUBREG) 79318334Speter { 79418334Speter while (GET_CODE (value) == SUBREG) 79590075Sobrien value = SUBREG_REG (value); 796169689Skan if (REG_P (value)) 79718334Speter { 79890075Sobrien if (REGNO (value) >= FIRST_PSEUDO_REGISTER) 79918334Speter return; 80018334Speter } 80190075Sobrien regno = REGNO (alter_subreg (&value)); 80290075Sobrien SET_DECL_RTL (decl, value); 80318334Speter } 80418334Speter /* Don't output anything if an auto variable 80518334Speter gets RTL that is static. 80618334Speter GAS version 2.2 can't handle such output. */ 807169689Skan else if (MEM_P (value) && CONSTANT_P (XEXP (value, 0)) 80818334Speter && ! TREE_STATIC (decl)) 80918334Speter return; 81018334Speter 81118334Speter /* Emit any structure, union, or enum type that has not been output. 81218334Speter This occurs for tag-less structs (et al) used to declare variables 81318334Speter within functions. */ 81418334Speter if (TREE_CODE (type) == ENUMERAL_TYPE 81518334Speter || TREE_CODE (type) == RECORD_TYPE 81618334Speter || TREE_CODE (type) == UNION_TYPE 81718334Speter || TREE_CODE (type) == QUAL_UNION_TYPE) 81818334Speter { 81990075Sobrien if (COMPLETE_TYPE_P (type) /* not a forward reference */ 82018334Speter && KNOWN_TYPE_TAG (type) == 0) /* not yet declared */ 82118334Speter sdbout_one_type (type); 82218334Speter } 82318334Speter 82418334Speter /* Defer SDB information for top-level initialized variables! */ 82518334Speter if (! local 826169689Skan && MEM_P (value) 82718334Speter && DECL_INITIAL (decl)) 82818334Speter return; 82918334Speter 83018334Speter /* C++ in 2.3 makes nameless symbols. That will be fixed later. 83118334Speter For now, avoid crashing. */ 83218334Speter if (DECL_NAME (decl) == NULL_TREE) 83318334Speter return; 83418334Speter 83518334Speter /* Record the name for, starting a symtab entry. */ 83690075Sobrien if (local) 83790075Sobrien name = IDENTIFIER_POINTER (DECL_NAME (decl)); 83890075Sobrien else 83990075Sobrien name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 84018334Speter 841169689Skan if (MEM_P (value) 84218334Speter && GET_CODE (XEXP (value, 0)) == SYMBOL_REF) 84318334Speter { 84418334Speter PUT_SDB_DEF (name); 84518334Speter if (TREE_PUBLIC (decl)) 84618334Speter { 84718334Speter PUT_SDB_VAL (XEXP (value, 0)); 848117395Skan PUT_SDB_SCL (C_EXT); 84918334Speter } 85018334Speter else 85118334Speter { 85218334Speter PUT_SDB_VAL (XEXP (value, 0)); 853117395Skan PUT_SDB_SCL (C_STAT); 85418334Speter } 85518334Speter } 85618334Speter else if (regno >= 0) 85718334Speter { 85818334Speter PUT_SDB_DEF (name); 85918334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno)); 86018334Speter PUT_SDB_SCL (C_REG); 86118334Speter } 862169689Skan else if (MEM_P (value) 863169689Skan && (MEM_P (XEXP (value, 0)) 864169689Skan || (REG_P (XEXP (value, 0)) 86518334Speter && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM 86618334Speter && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM))) 86718334Speter /* If the value is indirect by memory or by a register 86818334Speter that isn't the frame pointer 86918334Speter then it means the object is variable-sized and address through 87018334Speter that register or stack slot. COFF has no way to represent this 87118334Speter so all we can do is output the variable as a pointer. */ 87218334Speter { 87318334Speter PUT_SDB_DEF (name); 874169689Skan if (REG_P (XEXP (value, 0))) 87518334Speter { 87618334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0)))); 87718334Speter PUT_SDB_SCL (C_REG); 87818334Speter } 87918334Speter else 88018334Speter { 88118334Speter /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) 88218334Speter (CONST_INT...)))). 88318334Speter We want the value of that CONST_INT. */ 88418334Speter /* Encore compiler hates a newline in a macro arg, it seems. */ 88518334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET 88618334Speter (XEXP (XEXP (value, 0), 0))); 88718334Speter PUT_SDB_SCL (C_AUTO); 88818334Speter } 88918334Speter 89052284Sobrien /* Effectively do build_pointer_type, but don't cache this type, 89152284Sobrien since it might be temporary whereas the type it points to 89252284Sobrien might have been saved for inlining. */ 89352284Sobrien /* Don't use REFERENCE_TYPE because dbx can't handle that. */ 89452284Sobrien type = make_node (POINTER_TYPE); 89552284Sobrien TREE_TYPE (type) = TREE_TYPE (decl); 89618334Speter } 897169689Skan else if (MEM_P (value) 89818334Speter && ((GET_CODE (XEXP (value, 0)) == PLUS 899169689Skan && REG_P (XEXP (XEXP (value, 0), 0)) 90018334Speter && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT) 90118334Speter /* This is for variables which are at offset zero from 90218334Speter the frame pointer. This happens on the Alpha. 90318334Speter Non-frame pointer registers are excluded above. */ 904169689Skan || (REG_P (XEXP (value, 0))))) 90518334Speter { 90618334Speter /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) 90718334Speter or (MEM (REG...)). We want the value of that CONST_INT 90818334Speter or zero. */ 90918334Speter PUT_SDB_DEF (name); 91018334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0))); 91118334Speter PUT_SDB_SCL (C_AUTO); 91218334Speter } 91318334Speter else 91418334Speter { 91518334Speter /* It is something we don't know how to represent for SDB. */ 91618334Speter return; 91718334Speter } 91818334Speter break; 91950397Sobrien 92050397Sobrien default: 92150397Sobrien break; 92218334Speter } 92318334Speter PUT_SDB_TYPE (plain_type (type)); 92418334Speter PUT_SDB_ENDEF; 92518334Speter} 926132718Skan 92718334Speter/* Output SDB information for a top-level initialized variable 92818334Speter that has been delayed. */ 92918334Speter 93090075Sobrienstatic void 931132718Skansdbout_toplevel_data (tree decl) 93218334Speter{ 93318334Speter tree type = TREE_TYPE (decl); 93418334Speter 93518334Speter if (DECL_IGNORED_P (decl)) 93618334Speter return; 93718334Speter 938169689Skan gcc_assert (TREE_CODE (decl) == VAR_DECL); 939169689Skan gcc_assert (MEM_P (DECL_RTL (decl))); 940169689Skan gcc_assert (DECL_INITIAL (decl)); 94118334Speter 94218334Speter PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); 94318334Speter PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); 94418334Speter if (TREE_PUBLIC (decl)) 94518334Speter { 94618334Speter PUT_SDB_SCL (C_EXT); 94718334Speter } 94818334Speter else 94918334Speter { 95018334Speter PUT_SDB_SCL (C_STAT); 95118334Speter } 95218334Speter PUT_SDB_TYPE (plain_type (type)); 95318334Speter PUT_SDB_ENDEF; 95418334Speter} 955132718Skan 95618334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 95718334Speter 95850397Sobrien/* Machinery to record and output anonymous types. */ 95918334Speter 96018334Speterstatic void 961132718Skansdbout_queue_anonymous_type (tree type) 96218334Speter{ 96390075Sobrien anonymous_types = tree_cons (NULL_TREE, type, anonymous_types); 96418334Speter} 96518334Speter 96618334Speterstatic void 967132718Skansdbout_dequeue_anonymous_types (void) 96818334Speter{ 96990075Sobrien tree types, link; 97018334Speter 97118334Speter while (anonymous_types) 97218334Speter { 97318334Speter types = nreverse (anonymous_types); 97418334Speter anonymous_types = NULL_TREE; 97518334Speter 97618334Speter for (link = types; link; link = TREE_CHAIN (link)) 97718334Speter { 97890075Sobrien tree type = TREE_VALUE (link); 97918334Speter 98018334Speter if (type && ! TREE_ASM_WRITTEN (type)) 98118334Speter sdbout_one_type (type); 98218334Speter } 98318334Speter } 98418334Speter} 98518334Speter 98618334Speter#endif 987132718Skan 98818334Speter/* Given a chain of ..._TYPE nodes, all of which have names, 98918334Speter output definitions of those names, as typedefs. */ 99018334Speter 99118334Spetervoid 992132718Skansdbout_types (tree types) 99318334Speter{ 99490075Sobrien tree link; 99518334Speter 99618334Speter for (link = types; link; link = TREE_CHAIN (link)) 99718334Speter sdbout_one_type (link); 99818334Speter 99918334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 100018334Speter sdbout_dequeue_anonymous_types (); 100118334Speter#endif 100218334Speter} 100318334Speter 100418334Speterstatic void 1005132718Skansdbout_type (tree type) 100618334Speter{ 100718334Speter if (type == error_mark_node) 100818334Speter type = integer_type_node; 100918334Speter PUT_SDB_TYPE (plain_type (type)); 101018334Speter} 101118334Speter 101218334Speter/* Output types of the fields of type TYPE, if they are structs. 101318334Speter 101418334Speter Formerly did not chase through pointer types, since that could be circular. 101518334Speter They must come before TYPE, since forward refs are not allowed. 101618334Speter Now james@bigtex.cactus.org says to try them. */ 101718334Speter 101818334Speterstatic void 1019132718Skansdbout_field_types (tree type) 102018334Speter{ 102118334Speter tree tail; 102250397Sobrien 102318334Speter for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) 102490075Sobrien /* This condition should match the one for emitting the actual 102590075Sobrien members below. */ 102652284Sobrien if (TREE_CODE (tail) == FIELD_DECL 102790075Sobrien && DECL_NAME (tail) 102890075Sobrien && DECL_SIZE (tail) 102990075Sobrien && host_integerp (DECL_SIZE (tail), 1) 103090075Sobrien && host_integerp (bit_position (tail), 0)) 103152284Sobrien { 103252284Sobrien if (POINTER_TYPE_P (TREE_TYPE (tail))) 103352284Sobrien sdbout_one_type (TREE_TYPE (TREE_TYPE (tail))); 103452284Sobrien else 103552284Sobrien sdbout_one_type (TREE_TYPE (tail)); 103652284Sobrien } 103718334Speter} 103818334Speter 103918334Speter/* Use this to put out the top level defined record and union types 104018334Speter for later reference. If this is a struct with a name, then put that 104118334Speter name out. Other unnamed structs will have .xxfake labels generated so 104218334Speter that they may be referred to later. 104318334Speter The label will be stored in the KNOWN_TYPE_TAG slot of a type. 104418334Speter It may NOT be called recursively. */ 104518334Speter 104618334Speterstatic void 1047132718Skansdbout_one_type (tree type) 104818334Speter{ 104918334Speter if (current_function_decl != NULL_TREE 105018334Speter && DECL_SECTION_NAME (current_function_decl) != NULL_TREE) 105118334Speter ; /* Don't change section amid function. */ 105218334Speter else 1053169689Skan switch_to_section (text_section); 105418334Speter 105518334Speter switch (TREE_CODE (type)) 105618334Speter { 105718334Speter case RECORD_TYPE: 105818334Speter case UNION_TYPE: 105918334Speter case QUAL_UNION_TYPE: 106018334Speter case ENUMERAL_TYPE: 106118334Speter type = TYPE_MAIN_VARIANT (type); 106218334Speter /* Don't output a type twice. */ 106318334Speter if (TREE_ASM_WRITTEN (type)) 106418334Speter /* James said test TREE_ASM_BEING_WRITTEN here. */ 106518334Speter return; 106618334Speter 106718334Speter /* Output nothing if type is not yet defined. */ 106890075Sobrien if (!COMPLETE_TYPE_P (type)) 106918334Speter return; 107018334Speter 107118334Speter TREE_ASM_WRITTEN (type) = 1; 1072132718Skan 107318334Speter /* This is reputed to cause trouble with the following case, 107418334Speter but perhaps checking TYPE_SIZE above will fix it. */ 107518334Speter 1076132718Skan /* Here is a testcase: 107718334Speter 107818334Speter struct foo { 107918334Speter struct badstr *bbb; 108018334Speter } forwardref; 108118334Speter 108218334Speter typedef struct intermediate { 108318334Speter int aaaa; 108418334Speter } intermediate_ref; 108518334Speter 108618334Speter typedef struct badstr { 108718334Speter int ccccc; 108818334Speter } badtype; */ 108918334Speter 109018334Speter /* This change, which ought to make better output, 109118334Speter used to make the COFF assembler unhappy. 109218334Speter Changes involving KNOWN_TYPE_TAG may fix the problem. */ 109318334Speter /* Before really doing anything, output types we want to refer to. */ 109418334Speter /* Note that in version 1 the following two lines 109518334Speter are not used if forward references are in use. */ 109618334Speter if (TREE_CODE (type) != ENUMERAL_TYPE) 109718334Speter sdbout_field_types (type); 109818334Speter 109918334Speter /* Output a structure type. */ 110018334Speter { 110118334Speter int size = int_size_in_bytes (type); 110290075Sobrien int member_scl = 0; 110318334Speter tree tem; 110418334Speter 110518334Speter /* Record the type tag, but not in its permanent place just yet. */ 110618334Speter sdbout_record_type_name (type); 110718334Speter 110818334Speter PUT_SDB_DEF (KNOWN_TYPE_TAG (type)); 110918334Speter 111018334Speter switch (TREE_CODE (type)) 111118334Speter { 111218334Speter case UNION_TYPE: 111318334Speter case QUAL_UNION_TYPE: 111418334Speter PUT_SDB_SCL (C_UNTAG); 111518334Speter PUT_SDB_TYPE (T_UNION); 111618334Speter member_scl = C_MOU; 111718334Speter break; 111818334Speter 111918334Speter case RECORD_TYPE: 112018334Speter PUT_SDB_SCL (C_STRTAG); 112118334Speter PUT_SDB_TYPE (T_STRUCT); 112218334Speter member_scl = C_MOS; 112318334Speter break; 112418334Speter 112518334Speter case ENUMERAL_TYPE: 112618334Speter PUT_SDB_SCL (C_ENTAG); 112718334Speter PUT_SDB_TYPE (T_ENUM); 112818334Speter member_scl = C_MOE; 112918334Speter break; 113050397Sobrien 113150397Sobrien default: 113250397Sobrien break; 113318334Speter } 113418334Speter 113518334Speter PUT_SDB_SIZE (size); 113618334Speter PUT_SDB_ENDEF; 113718334Speter 113818334Speter /* Print out the base class information with fields 113918334Speter named after the types they hold. */ 114090075Sobrien /* This is only relevant to aggregate types. TYPE_BINFO is used 114152284Sobrien for other purposes in an ENUMERAL_TYPE, so we must exclude that 114252284Sobrien case. */ 1143169689Skan if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type)) 114418334Speter { 1145169689Skan int i; 1146169689Skan tree binfo, child; 1147169689Skan 1148169689Skan for (binfo = TYPE_BINFO (type), i = 0; 1149169689Skan BINFO_BASE_ITERATE (binfo, i, child); i++) 115018334Speter { 115152284Sobrien tree child_type = BINFO_TYPE (child); 115252284Sobrien tree child_type_name; 1153169689Skan 115452284Sobrien if (TYPE_NAME (child_type) == 0) 115552284Sobrien continue; 115652284Sobrien if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE) 115752284Sobrien child_type_name = TYPE_NAME (child_type); 115852284Sobrien else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL) 115952284Sobrien { 116052284Sobrien child_type_name = DECL_NAME (TYPE_NAME (child_type)); 116152284Sobrien if (child_type_name && template_name_p (child_type_name)) 116252284Sobrien child_type_name 116352284Sobrien = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type)); 116452284Sobrien } 116552284Sobrien else 116652284Sobrien continue; 116752284Sobrien 116852284Sobrien PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name)); 116990075Sobrien PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0)); 117052284Sobrien PUT_SDB_SCL (member_scl); 117152284Sobrien sdbout_type (BINFO_TYPE (child)); 117252284Sobrien PUT_SDB_ENDEF; 117318334Speter } 117418334Speter } 117518334Speter 1176132718Skan /* Output the individual fields. */ 117718334Speter 117818334Speter if (TREE_CODE (type) == ENUMERAL_TYPE) 117990075Sobrien { 1180169689Skan for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) 118190075Sobrien if (host_integerp (TREE_VALUE (tem), 0)) 118290075Sobrien { 118390075Sobrien PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem))); 118490075Sobrien PUT_SDB_INT_VAL (tree_low_cst (TREE_VALUE (tem), 0)); 118590075Sobrien PUT_SDB_SCL (C_MOE); 118690075Sobrien PUT_SDB_TYPE (T_MOE); 118790075Sobrien PUT_SDB_ENDEF; 118890075Sobrien } 118990075Sobrien } 119018334Speter else /* record or union type */ 119118334Speter for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) 119218334Speter /* Output the name, type, position (in bits), size (in bits) 119318334Speter of each field. */ 119418334Speter 119518334Speter /* Omit here the nameless fields that are used to skip bits. 119618334Speter Also omit fields with variable size or position. 119718334Speter Also omit non FIELD_DECL nodes that GNU C++ may put here. */ 119818334Speter if (TREE_CODE (tem) == FIELD_DECL 119990075Sobrien && DECL_NAME (tem) 120090075Sobrien && DECL_SIZE (tem) 120190075Sobrien && host_integerp (DECL_SIZE (tem), 1) 120290075Sobrien && host_integerp (bit_position (tem), 0)) 120318334Speter { 120490075Sobrien const char *name; 120518334Speter 120690075Sobrien name = IDENTIFIER_POINTER (DECL_NAME (tem)); 120718334Speter PUT_SDB_DEF (name); 120818334Speter if (DECL_BIT_FIELD_TYPE (tem)) 120918334Speter { 121090075Sobrien PUT_SDB_INT_VAL (int_bit_position (tem)); 121118334Speter PUT_SDB_SCL (C_FIELD); 121218334Speter sdbout_type (DECL_BIT_FIELD_TYPE (tem)); 121390075Sobrien PUT_SDB_SIZE (tree_low_cst (DECL_SIZE (tem), 1)); 121418334Speter } 121518334Speter else 121618334Speter { 121790075Sobrien PUT_SDB_INT_VAL (int_bit_position (tem) / BITS_PER_UNIT); 121818334Speter PUT_SDB_SCL (member_scl); 121918334Speter sdbout_type (TREE_TYPE (tem)); 122018334Speter } 122118334Speter PUT_SDB_ENDEF; 122218334Speter } 1223132718Skan /* Output end of a structure,union, or enumeral definition. */ 122418334Speter 122518334Speter PUT_SDB_PLAIN_DEF ("eos"); 122618334Speter PUT_SDB_INT_VAL (size); 122718334Speter PUT_SDB_SCL (C_EOS); 122818334Speter PUT_SDB_TAG (KNOWN_TYPE_TAG (type)); 122918334Speter PUT_SDB_SIZE (size); 123018334Speter PUT_SDB_ENDEF; 123118334Speter break; 123250397Sobrien 123350397Sobrien default: 123450397Sobrien break; 123518334Speter } 123618334Speter } 123718334Speter} 1238132718Skan 123918334Speter/* The following two functions output definitions of function parameters. 124018334Speter Each parameter gets a definition locating it in the parameter list. 124118334Speter Each parameter that is a register variable gets a second definition 124218334Speter locating it in the register. 124318334Speter 124418334Speter Printing or argument lists in gdb uses the definitions that 124518334Speter locate in the parameter list. But reference to the variable in 124618334Speter expressions uses preferentially the definition as a register. */ 124718334Speter 124818334Speter/* Output definitions, referring to storage in the parmlist, 124918334Speter of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ 125018334Speter 125118334Speterstatic void 1252132718Skansdbout_parms (tree parms) 125318334Speter{ 125418334Speter for (; parms; parms = TREE_CHAIN (parms)) 125518334Speter if (DECL_NAME (parms)) 125618334Speter { 125718334Speter int current_sym_value = 0; 125890075Sobrien const char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); 125918334Speter 126018334Speter if (name == 0 || *name == 0) 126118334Speter name = gen_fake_label (); 126218334Speter 126318334Speter /* Perform any necessary register eliminations on the parameter's rtl, 126418334Speter so that the debugging output will be accurate. */ 126550397Sobrien DECL_INCOMING_RTL (parms) 126650397Sobrien = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); 126790075Sobrien SET_DECL_RTL (parms, 126890075Sobrien eliminate_regs (DECL_RTL (parms), 0, NULL_RTX)); 126918334Speter 127018334Speter if (PARM_PASSED_IN_MEMORY (parms)) 127118334Speter { 127218334Speter rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); 127318334Speter tree type; 127418334Speter 127518334Speter /* ??? Here we assume that the parm address is indexed 127618334Speter off the frame pointer or arg pointer. 127718334Speter If that is not true, we produce meaningless results, 127818334Speter but do not crash. */ 127918334Speter if (GET_CODE (addr) == PLUS 128018334Speter && GET_CODE (XEXP (addr, 1)) == CONST_INT) 128118334Speter current_sym_value = INTVAL (XEXP (addr, 1)); 128218334Speter else 128318334Speter current_sym_value = 0; 128418334Speter 1285169689Skan if (REG_P (DECL_RTL (parms)) 128618334Speter && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 128718334Speter type = DECL_ARG_TYPE (parms); 128818334Speter else 128918334Speter { 129018334Speter int original_sym_value = current_sym_value; 129118334Speter 129218334Speter /* This is the case where the parm is passed as an int or 129318334Speter double and it is converted to a char, short or float 129418334Speter and stored back in the parmlist. In this case, describe 129518334Speter the parm with the variable's declared type, and adjust 129618334Speter the address if the least significant bytes (which we are 129718334Speter using) are not the first ones. */ 129818334Speter if (BYTES_BIG_ENDIAN 129918334Speter && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) 130018334Speter current_sym_value += 130118334Speter (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) 130218334Speter - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); 130318334Speter 1304169689Skan if (MEM_P (DECL_RTL (parms)) 130518334Speter && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS 130618334Speter && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) 130718334Speter == CONST_INT) 130818334Speter && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) 130918334Speter == current_sym_value)) 131018334Speter type = TREE_TYPE (parms); 131118334Speter else 131218334Speter { 131318334Speter current_sym_value = original_sym_value; 131418334Speter type = DECL_ARG_TYPE (parms); 131518334Speter } 131618334Speter } 131718334Speter 131818334Speter PUT_SDB_DEF (name); 131918334Speter PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr)); 132018334Speter PUT_SDB_SCL (C_ARG); 132118334Speter PUT_SDB_TYPE (plain_type (type)); 132218334Speter PUT_SDB_ENDEF; 132318334Speter } 1324169689Skan else if (REG_P (DECL_RTL (parms))) 132518334Speter { 132618334Speter rtx best_rtl; 132718334Speter /* Parm passed in registers and lives in registers or nowhere. */ 132818334Speter 132918334Speter /* If parm lives in a register, use that register; 133018334Speter pretend the parm was passed there. It would be more consistent 133118334Speter to describe the register where the parm was passed, 133218334Speter but in practice that register usually holds something else. */ 133390075Sobrien if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 133418334Speter best_rtl = DECL_RTL (parms); 133518334Speter /* If the parm lives nowhere, 133618334Speter use the register where it was passed. */ 133718334Speter else 133818334Speter best_rtl = DECL_INCOMING_RTL (parms); 133918334Speter 134018334Speter PUT_SDB_DEF (name); 134118334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl))); 134218334Speter PUT_SDB_SCL (C_REGPARM); 134350397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 134418334Speter PUT_SDB_ENDEF; 134518334Speter } 1346169689Skan else if (MEM_P (DECL_RTL (parms)) 134718334Speter && XEXP (DECL_RTL (parms), 0) != const0_rtx) 134818334Speter { 134918334Speter /* Parm was passed in registers but lives on the stack. */ 135018334Speter 135118334Speter /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), 135218334Speter in which case we want the value of that CONST_INT, 135318334Speter or (MEM (REG ...)) or (MEM (MEM ...)), 135418334Speter in which case we use a value of zero. */ 1355169689Skan if (REG_P (XEXP (DECL_RTL (parms), 0)) 1356169689Skan || MEM_P (XEXP (DECL_RTL (parms), 0))) 135718334Speter current_sym_value = 0; 135818334Speter else 135918334Speter current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); 136018334Speter 136118334Speter /* Again, this assumes the offset is based on the arg pointer. */ 136218334Speter PUT_SDB_DEF (name); 136318334Speter PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, 136418334Speter XEXP (DECL_RTL (parms), 0))); 136518334Speter PUT_SDB_SCL (C_ARG); 136650397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 136718334Speter PUT_SDB_ENDEF; 136818334Speter } 136918334Speter } 137018334Speter} 137118334Speter 137218334Speter/* Output definitions for the places where parms live during the function, 137318334Speter when different from where they were passed, when the parms were passed 137418334Speter in memory. 137518334Speter 137618334Speter It is not useful to do this for parms passed in registers 137718334Speter that live during the function in different registers, because it is 137818334Speter impossible to look in the passed register for the passed value, 137918334Speter so we use the within-the-function register to begin with. 138018334Speter 138118334Speter PARMS is a chain of PARM_DECL nodes. */ 138218334Speter 138318334Speterstatic void 1384132718Skansdbout_reg_parms (tree parms) 138518334Speter{ 138618334Speter for (; parms; parms = TREE_CHAIN (parms)) 138718334Speter if (DECL_NAME (parms)) 138818334Speter { 138990075Sobrien const char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); 139018334Speter 139118334Speter /* Report parms that live in registers during the function 139218334Speter but were passed in memory. */ 1393169689Skan if (REG_P (DECL_RTL (parms)) 139418334Speter && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER 139518334Speter && PARM_PASSED_IN_MEMORY (parms)) 139618334Speter { 139718334Speter if (name == 0 || *name == 0) 139818334Speter name = gen_fake_label (); 139918334Speter PUT_SDB_DEF (name); 140018334Speter PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)))); 140118334Speter PUT_SDB_SCL (C_REG); 140250397Sobrien PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 140318334Speter PUT_SDB_ENDEF; 140418334Speter } 140518334Speter /* Report parms that live in memory but not where they were passed. */ 1406169689Skan else if (MEM_P (DECL_RTL (parms)) 140718334Speter && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS 140818334Speter && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT 140918334Speter && PARM_PASSED_IN_MEMORY (parms) 141018334Speter && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) 141118334Speter { 141218334Speter#if 0 /* ??? It is not clear yet what should replace this. */ 141318334Speter int offset = DECL_OFFSET (parms) / BITS_PER_UNIT; 141418334Speter /* A parm declared char is really passed as an int, 141518334Speter so it occupies the least significant bytes. 141618334Speter On a big-endian machine those are not the low-numbered ones. */ 141718334Speter if (BYTES_BIG_ENDIAN 141818334Speter && offset != -1 141918334Speter && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) 142018334Speter offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) 142118334Speter - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); 142218334Speter if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...} 142318334Speter#endif 142418334Speter { 142518334Speter if (name == 0 || *name == 0) 142618334Speter name = gen_fake_label (); 142718334Speter PUT_SDB_DEF (name); 142818334Speter PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET 142918334Speter (XEXP (DECL_RTL (parms), 0))); 143018334Speter PUT_SDB_SCL (C_AUTO); 143118334Speter PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); 143218334Speter PUT_SDB_ENDEF; 143318334Speter } 143418334Speter } 143518334Speter } 143618334Speter} 1437132718Skan 143890075Sobrien/* Output debug information for a global DECL. Called from toplev.c 143990075Sobrien after compilation proper has finished. */ 144090075Sobrien 144190075Sobrienstatic void 1442132718Skansdbout_global_decl (tree decl) 144390075Sobrien{ 144490075Sobrien if (TREE_CODE (decl) == VAR_DECL 144590075Sobrien && !DECL_EXTERNAL (decl) 144690075Sobrien && DECL_RTL_SET_P (decl)) 144790075Sobrien { 144890075Sobrien /* The COFF linker can move initialized global vars to the end. 144990075Sobrien And that can screw up the symbol ordering. Defer those for 145090075Sobrien sdbout_finish (). */ 145190075Sobrien if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl)) 145290075Sobrien sdbout_symbol (decl, 0); 1453169689Skan else 1454169689Skan VARRAY_PUSH_TREE (deferred_global_decls, decl); 145590075Sobrien 145690075Sobrien /* Output COFF information for non-global file-scope initialized 145790075Sobrien variables. */ 1458169689Skan if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl))) 145990075Sobrien sdbout_toplevel_data (decl); 146090075Sobrien } 146190075Sobrien} 146290075Sobrien 146390075Sobrien/* Output initialized global vars at the end, in the order of 146490075Sobrien definition. See comment in sdbout_global_decl. */ 146590075Sobrien 146690075Sobrienstatic void 1467132718Skansdbout_finish (const char *main_filename ATTRIBUTE_UNUSED) 146890075Sobrien{ 1469169689Skan size_t i; 147090075Sobrien 1471169689Skan for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++) 1472169689Skan sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0); 147390075Sobrien} 1474132718Skan 147518334Speter/* Describe the beginning of an internal block within a function. 147618334Speter Also output descriptions of variables defined in this block. 147718334Speter 147818334Speter N is the number of the block, by order of beginning, counting from 1, 147918334Speter and not counting the outermost (function top-level) block. 148018334Speter The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), 148118334Speter if the count starts at 0 for the outermost one. */ 148218334Speter 148390075Sobrienstatic void 1484132718Skansdbout_begin_block (unsigned int line, unsigned int n) 148518334Speter{ 148618334Speter tree decl = current_function_decl; 148718334Speter MAKE_LINE_SAFE (line); 148818334Speter 148918334Speter /* The SCO compiler does not emit a separate block for the function level 149018334Speter scope, so we avoid it here also. However, mips ECOFF compilers do emit 149118334Speter a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ 149218334Speter#ifndef MIPS_DEBUGGING_INFO 149318334Speter if (n != 1) 149418334Speter#endif 149518334Speter PUT_SDB_BLOCK_START (line - sdb_begin_function_line); 149618334Speter 149718334Speter if (n == 1) 149818334Speter { 149918334Speter /* Include the outermost BLOCK's variables in block 1. */ 150090075Sobrien do_block = BLOCK_NUMBER (DECL_INITIAL (decl)); 150118334Speter sdbout_block (DECL_INITIAL (decl)); 150218334Speter } 150318334Speter /* If -g1, suppress all the internal symbols of functions 150418334Speter except for arguments. */ 150518334Speter if (debug_info_level != DINFO_LEVEL_TERSE) 150618334Speter { 150718334Speter do_block = n; 150818334Speter sdbout_block (DECL_INITIAL (decl)); 150918334Speter } 151018334Speter 151118334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 151218334Speter sdbout_dequeue_anonymous_types (); 151318334Speter#endif 151418334Speter} 151518334Speter 151618334Speter/* Describe the end line-number of an internal block within a function. */ 151718334Speter 151890075Sobrienstatic void 1519132718Skansdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED) 152018334Speter{ 152118334Speter MAKE_LINE_SAFE (line); 152218334Speter 152318334Speter /* The SCO compiler does not emit a separate block for the function level 152418334Speter scope, so we avoid it here also. However, mips ECOFF compilers do emit 152518334Speter a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined. */ 152618334Speter#ifndef MIPS_DEBUGGING_INFO 152718334Speter if (n != 1) 152818334Speter#endif 152918334Speter PUT_SDB_BLOCK_END (line - sdb_begin_function_line); 153018334Speter} 153118334Speter 1532132718Skan/* Output a line number symbol entry for source file FILENAME and line 1533132718Skan number LINE. */ 1534132718Skan 153590075Sobrienstatic void 1536132718Skansdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED) 153790075Sobrien{ 153890075Sobrien /* COFF relative line numbers must be positive. */ 153990075Sobrien if ((int) line > sdb_begin_function_line) 154090075Sobrien { 1541169689Skan#ifdef SDB_OUTPUT_SOURCE_LINE 1542169689Skan SDB_OUTPUT_SOURCE_LINE (asm_out_file, line); 154390075Sobrien#else 154490075Sobrien fprintf (asm_out_file, "\t.ln\t%d\n", 154590075Sobrien ((sdb_begin_function_line > -1) 154690075Sobrien ? line - sdb_begin_function_line : 1)); 154790075Sobrien#endif 154890075Sobrien } 154990075Sobrien} 155090075Sobrien 155118334Speter/* Output sdb info for the current function name. 155218334Speter Called from assemble_start_function. */ 155318334Speter 155490075Sobrienstatic void 1555132718Skansdbout_begin_function (tree decl ATTRIBUTE_UNUSED) 155618334Speter{ 155718334Speter sdbout_symbol (current_function_decl, 0); 155818334Speter} 155918334Speter 156090075Sobrien/* Called at beginning of function body (before or after prologue, 156190075Sobrien depending on MIPS_DEBUGGING_INFO). Record the function's starting 156290075Sobrien line number, so we can output relative line numbers for the other 156390075Sobrien lines. Describe beginning of outermost block. Also describe the 156490075Sobrien parameter list. */ 156518334Speter 156690075Sobrien#ifndef MIPS_DEBUGGING_INFO 156790075Sobrienstatic void 1568132718Skansdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED) 156918334Speter{ 1570117395Skan sdbout_end_prologue (line, file); 157190075Sobrien} 157290075Sobrien#endif 157390075Sobrien 157490075Sobrienstatic void 1575132718Skansdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED) 157690075Sobrien{ 157718334Speter sdb_begin_function_line = line - 1; 157818334Speter PUT_SDB_FUNCTION_START (line); 157918334Speter sdbout_parms (DECL_ARGUMENTS (current_function_decl)); 158018334Speter sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl)); 158118334Speter} 158218334Speter 158318334Speter/* Called at end of function (before epilogue). 158418334Speter Describe end of outermost block. */ 158518334Speter 158690075Sobrienstatic void 1587132718Skansdbout_end_function (unsigned int line) 158818334Speter{ 158918334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES 159018334Speter sdbout_dequeue_anonymous_types (); 159118334Speter#endif 159218334Speter 159318334Speter MAKE_LINE_SAFE (line); 159418334Speter PUT_SDB_FUNCTION_END (line - sdb_begin_function_line); 159518334Speter 159618334Speter /* Indicate we are between functions, for line-number output. */ 159718334Speter sdb_begin_function_line = -1; 159818334Speter} 159918334Speter 160018334Speter/* Output sdb info for the absolute end of a function. 160118334Speter Called after the epilogue is output. */ 160218334Speter 160390075Sobrienstatic void 1604132718Skansdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, 1605132718Skan const char *file ATTRIBUTE_UNUSED) 160618334Speter{ 160790075Sobrien const char *const name ATTRIBUTE_UNUSED 160890075Sobrien = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); 160990075Sobrien 161090075Sobrien#ifdef PUT_SDB_EPILOGUE_END 161118334Speter PUT_SDB_EPILOGUE_END (name); 161290075Sobrien#else 161390075Sobrien fprintf (asm_out_file, "\t.def\t"); 161490075Sobrien assemble_name (asm_out_file, name); 161590075Sobrien fprintf (asm_out_file, "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", 161690075Sobrien SDB_DELIM, SDB_DELIM, SDB_DELIM); 161790075Sobrien#endif 161818334Speter} 161918334Speter 162018334Speter/* Output sdb info for the given label. Called only if LABEL_NAME (insn) 162118334Speter is present. */ 162218334Speter 162390075Sobrienstatic void 1624132718Skansdbout_label (rtx insn) 162518334Speter{ 162618334Speter PUT_SDB_DEF (LABEL_NAME (insn)); 162718334Speter PUT_SDB_VAL (insn); 162818334Speter PUT_SDB_SCL (C_LABEL); 162918334Speter PUT_SDB_TYPE (T_NULL); 163018334Speter PUT_SDB_ENDEF; 163118334Speter} 163218334Speter 163350397Sobrien/* Change to reading from a new source file. */ 163450397Sobrien 163590075Sobrienstatic void 1636132718Skansdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED, 1637132718Skan const char *filename ATTRIBUTE_UNUSED) 163850397Sobrien{ 163950397Sobrien#ifdef MIPS_DEBUGGING_INFO 1640132718Skan struct sdb_file *n = xmalloc (sizeof *n); 164150397Sobrien 164250397Sobrien n->next = current_file; 164350397Sobrien n->name = filename; 164450397Sobrien current_file = n; 1645169689Skan output_file_directive (asm_out_file, filename); 164650397Sobrien#endif 164750397Sobrien} 164850397Sobrien 164950397Sobrien/* Revert to reading a previous source file. */ 165050397Sobrien 165190075Sobrienstatic void 1652132718Skansdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED) 165350397Sobrien{ 165450397Sobrien#ifdef MIPS_DEBUGGING_INFO 165550397Sobrien struct sdb_file *next; 165650397Sobrien 165750397Sobrien next = current_file->next; 165850397Sobrien free (current_file); 165950397Sobrien current_file = next; 1660169689Skan output_file_directive (asm_out_file, current_file->name); 166150397Sobrien#endif 166250397Sobrien} 166350397Sobrien 166490075Sobrien/* Set up for SDB output at the start of compilation. */ 166590075Sobrien 166690075Sobrienstatic void 1667132718Skansdbout_init (const char *input_file_name ATTRIBUTE_UNUSED) 166890075Sobrien{ 1669169689Skan tree t; 1670169689Skan 167190075Sobrien#ifdef MIPS_DEBUGGING_INFO 1672132718Skan current_file = xmalloc (sizeof *current_file); 167390075Sobrien current_file->next = NULL; 167490075Sobrien current_file->name = input_file_name; 167590075Sobrien#endif 1676169689Skan 1677169689Skan VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls"); 1678169689Skan 1679169689Skan /* Emit debug information which was queued by sdbout_symbol before 1680169689Skan we got here. */ 1681169689Skan sdbout_initialized = true; 1682169689Skan 1683169689Skan for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t)) 1684169689Skan sdbout_symbol (TREE_VALUE (t), 0); 1685169689Skan preinit_symbols = 0; 168690075Sobrien} 168790075Sobrien 1688117395Skan#else /* SDB_DEBUGGING_INFO */ 1689117395Skan 1690117395Skan/* This should never be used, but its address is needed for comparisons. */ 1691117395Skanconst struct gcc_debug_hooks sdb_debug_hooks; 1692117395Skan 169318334Speter#endif /* SDB_DEBUGGING_INFO */ 1694117395Skan 1695117395Skan#include "gt-sdbout.h" 1696