4. All structure .defs are emitted before the typedefs that refer to them.
5. All top level static and external variable definitions are moved to the
- end of file with all top level statics occuring first before externs.
+ end of file with all top level statics occurring first before externs.
6. All undefined references are at the end of the file.
*/
/* Mips systems use the SDB functions to dump out symbols, but
do not supply usable syms.h include files. */
-#if defined(USG) && !defined(MIPS)
+#if defined(USG) && !defined(MIPS) && !defined (hpux)
#include <syms.h>
/* Use T_INT if we don't have T_VOID. */
#ifndef T_VOID
/* Produce the number that describes a pointer, function or array type.
PREV is the number describing the target, value or element type.
DT_type describes how to transform that type. */
-#define PUSH_DERIVED_LEVEL(DT_type,PREV) \
- ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))
+#define PUSH_DERIVED_LEVEL(DT_type,PREV) \
+ ((((PREV) & ~(int)N_BTMASK) << (int)N_TSHIFT) \
+ | ((int)DT_type << (int)N_BTSHFT) \
+ | ((PREV) & (int)N_BTMASK))
/* Number of elements used in sdb_dims. */
static int sdb_n_dims = 0;
return val;
}
+static int
+template_name_p (name)
+ tree name;
+{
+ register char *ptr = IDENTIFIER_POINTER (name);
+ while (*ptr && *ptr != '<')
+ ptr++;
+
+ return *ptr != '\0';
+}
+
static void
sdbout_record_type_name (type)
tree type;
{
t = TYPE_NAME (type);
}
-#if 1 /* As a temprary hack, use typedef names for C++ only. */
+#if 1 /* As a temporary hack, use typedef names for C++ only. */
else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& TYPE_LANG_SPECIFIC (type))
{
t = DECL_NAME (TYPE_NAME (type));
+ /* The DECL_NAME for templates includes "<>", which breaks
+ most assemblers. Use its assembler name instead, which
+ has been mangled into being safe. */
+ if (t && template_name_p (t))
+ t = DECL_ASSEMBLER_NAME (TYPE_NAME (type));
}
#endif
/* Now get the name as a string, or invent one. */
- if (t != 0)
+ if (t != NULL_TREE)
name = IDENTIFIER_POINTER (t);
}
case INTEGER_TYPE:
{
int size = int_size_in_bytes (type) * BITS_PER_UNIT;
+
+ /* Carefully distinguish all the standard types of C,
+ without messing up if the language is not C.
+ Note that we check only for the names that contain spaces;
+ other names might occur by coincidence in other languages. */
+ if (TYPE_NAME (type) != 0
+ && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (type)) != 0
+ && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
+ {
+ char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+
+ if (!strcmp (name, "unsigned char"))
+ return T_UCHAR;
+ if (!strcmp (name, "signed char"))
+ return T_CHAR;
+ if (!strcmp (name, "unsigned int"))
+ return T_UINT;
+ if (!strcmp (name, "short int"))
+ return T_SHORT;
+ if (!strcmp (name, "short unsigned int"))
+ return T_USHORT;
+ if (!strcmp (name, "long int"))
+ return T_LONG;
+ if (!strcmp (name, "long unsigned int"))
+ return T_ULONG;
+ }
+
if (size == CHAR_TYPE_SIZE)
return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
if (size == SHORT_TYPE_SIZE)
return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
if (size == INT_TYPE_SIZE)
return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
+ if (size == LONG_TYPE_SIZE)
+ return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
return 0;
}
case RECORD_TYPE:
case UNION_TYPE:
+ case QUAL_UNION_TYPE:
case ENUMERAL_TYPE:
{
char *tag;
}
return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
: (TREE_CODE (type) == UNION_TYPE) ? T_UNION
+ : (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION
: T_ENUM);
}
case POINTER_TYPE:
sdbout_one_type (type);
+#if 0 /* This loses when functions are marked to be ignored,
+ which happens in the C++ front end. */
+ if (DECL_IGNORED_P (decl))
+ return;
+#endif
+
switch (TREE_CODE (decl))
{
case CONST_DECL:
context = decl_function_context (decl);
if (context == current_function_decl)
return;
- if (TREE_EXTERNAL (decl))
+ if (DECL_EXTERNAL (decl))
return;
if (GET_CODE (DECL_RTL (decl)) != MEM
|| GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
/* Done with tagged types. */
if (DECL_NAME (decl) == 0)
return;
+ if (DECL_IGNORED_P (decl))
+ return;
/* Output typedef name. */
- PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ if (template_name_p (DECL_NAME (decl)))
+ PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+ else
+ PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
PUT_SDB_SCL (C_TPDEF);
break;
case VAR_DECL:
/* Don't mention a variable that is external.
Let the file that defines it describe it. */
- if (TREE_EXTERNAL (decl))
+ if (DECL_EXTERNAL (decl))
+ return;
+
+ /* Ignore __FUNCTION__, etc. */
+ if (DECL_IGNORED_P (decl))
return;
/* If there was an error in the declaration, don't dump core
if (DECL_RTL (decl) == 0)
return;
- value = eliminate_regs (DECL_RTL (decl), 0, 0);
+ DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
+#ifdef LEAF_REG_REMAP
+ if (leaf_function)
+ leaf_renumber_regs_insn (DECL_RTL (decl));
+#endif
+ value = DECL_RTL (decl);
/* Don't mention a variable at all
if it was completely optimized into nothingness.
{
regno = REGNO (DECL_RTL (decl));
if (regno >= FIRST_PSEUDO_REGISTER)
- regno = reg_renumber[REGNO (DECL_RTL (decl))];
- if (regno < 0)
return;
}
- else if (GET_CODE (DECL_RTL (decl)) == SUBREG)
+ else if (GET_CODE (value) == SUBREG)
{
int offset = 0;
while (GET_CODE (value) == SUBREG)
{
regno = REGNO (value);
if (regno >= FIRST_PSEUDO_REGISTER)
- regno = reg_renumber[REGNO (value)];
- if (regno >= 0)
- regno += offset;
+ return;
+ regno += offset;
}
+ alter_subreg (DECL_RTL (decl));
+ value = DECL_RTL (decl);
}
/* Emit any structure, union, or enum type that has not been output.
within functions. */
if (TREE_CODE (type) == ENUMERAL_TYPE
|| TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE)
{
if (TYPE_SIZE (type) != 0 /* not a forward reference */
&& KNOWN_TYPE_TAG (type) == 0) /* not yet declared */
&& DECL_INITIAL (decl))
return;
+ /* C++ in 2.3 makes nameless symbols. That will be fixed later.
+ For now, avoid crashing. */
+ if (DECL_NAME (decl) == NULL_TREE)
+ return;
+
/* Record the name for, starting a symtab entry. */
name = IDENTIFIER_POINTER (DECL_NAME (decl));
{
tree type = TREE_TYPE (decl);
+ if (DECL_IGNORED_P (decl))
+ return;
+
if (! (TREE_CODE (decl) == VAR_DECL
&& GET_CODE (DECL_RTL (decl)) == MEM
&& DECL_INITIAL (decl)))
{
case RECORD_TYPE:
case UNION_TYPE:
+ case QUAL_UNION_TYPE:
case ENUMERAL_TYPE:
type = TYPE_MAIN_VARIANT (type);
/* Don't output a type twice. */
TREE_ASM_WRITTEN (type) = 1;
#if 1
/* This is reputed to cause trouble with the following case,
- but perhaps checking TYPE_SIZE above will fix it.
+ but perhaps checking TYPE_SIZE above will fix it. */
/* Here is a test case:
switch (TREE_CODE (type))
{
case UNION_TYPE:
+ case QUAL_UNION_TYPE:
PUT_SDB_SCL (C_UNTAG);
PUT_SDB_TYPE (T_UNION);
member_scl = C_MOU;
/* Perform any necessary register eliminations on the parameter's rtl,
so that the debugging output will be accurate. */
DECL_INCOMING_RTL (parms) =
- eliminate_regs (DECL_INCOMING_RTL (parms), 0, 0);
- DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, 0);
+ eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
+ DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
if (PARM_PASSED_IN_MEMORY (parms))
{