Merge gcc-2.95.3 changes onto mainline. Update FreeBSD changes to converge

with changes made in the FSF tree.
This commit is contained in:
obrien 2001-03-19 19:50:16 +00:00
parent a093aec887
commit 6830f79554
10 changed files with 168 additions and 2666 deletions

View File

@ -75,6 +75,7 @@ extern void output_file_directive ();
.ident string is patterned after the ones produced by native svr4
C compilers. */
#undef IDENT_ASM_OP
#define IDENT_ASM_OP ".ident"
#ifdef IDENTIFY_WITH_IDENT
@ -103,6 +104,7 @@ do { \
/* This is how to allocate empty space in some section. The .zero
pseudo-op is used for this on most svr4 assemblers. */
#undef SKIP_ASM_OP
#define SKIP_ASM_OP ".zero"
#undef ASM_OUTPUT_SKIP
@ -117,6 +119,7 @@ do { \
make sure that the location counter for the .rodata section gets pro-
perly re-aligned prior to the actual beginning of the jump table. */
#undef ALIGN_ASM_OP
#define ALIGN_ASM_OP ".align"
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
@ -144,6 +147,7 @@ do { \
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#undef COMMON_ASM_OP
#define COMMON_ASM_OP ".comm"
#undef ASM_OUTPUT_ALIGNED_COMMON
@ -217,6 +221,7 @@ do { \
#undef USE_CONST_SECTION
#define USE_CONST_SECTION 1
#undef CONST_SECTION_ASM_OP
#define CONST_SECTION_ASM_OP ".section\t.rodata"
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
@ -234,7 +239,9 @@ do { \
errors unless the .ctors and .dtors sections are marked as writable
via the SHF_WRITE attribute.) */
#undef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
#undef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
/* Handle the small data sections. */
@ -248,7 +255,9 @@ do { \
The definitions say how to change sections to the .init and .fini
sections. This is the same for all known svr4 assemblers. */
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP ".section\t.init"
#undef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP ".section\t.fini"
/* A default list of other sections which we might be "in" at any given
@ -383,7 +392,9 @@ void FN () \
different pseudo-op names for these, they may be overridden in the
file which includes this one. */
#undef TYPE_ASM_OP
#define TYPE_ASM_OP ".type"
#undef SIZE_ASM_OP
#define SIZE_ASM_OP ".size"
/* This is how we tell the assembler that a symbol is weak. */
@ -504,6 +515,7 @@ do { \
should define this to zero. */
#define STRING_LIMIT ((unsigned) 256)
#undef STRING_ASM_OP
#define STRING_ASM_OP ".string"
/* GAS is the only Alpha/ELF assembler. */

View File

@ -1,26 +0,0 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha, using
encapsulated stabs and OSF V1.2.
Copyright (C) 1994 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "alpha/osf12.h"
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG

View File

@ -1,26 +0,0 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha, using
encapsulated stabs.
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
Contributed by Peter Schauer (pes@regent.e-technik.tu-muenchen.de).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "alpha/osf2.h"
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG

View File

@ -1,32 +0,0 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "alpha/alpha.h"
/* In OSF 2.0, the size of wchar_t was changed from short unsigned
to unsigned int. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "unsigned int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32

View File

@ -1,9 +1,8 @@
/* Definitions for Intel 386 running FreeBSD with either a.out or ELF format
Copyright (C) 1996-2000 Free Software Foundation, Inc.
/* Definitions for Intel 386 running FreeBSD with ELF format
Copyright (C) 1996 Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
Adapted from GNU/Linux version by John Polstra.
Added support for generating "old a.out gas" on the fly by Peter Wemm.
Continued development by David O'Brien <obrien@freebsd.org>
This file is part of GNU CC.
@ -23,548 +22,50 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* $FreeBSD$ */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/ELF)");
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-Di386 -Acpu(i386) -Amachine(i386)" \
FBSD_CPP_PREDEFINES
/* The svr4 ABI for the i386 says that records and unions are returned
in memory. */
/* On FreeBSD, we do not. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0
#undef CC1_SPEC
#define CC1_SPEC "\
%{gline:%{!g:%{!g0:%{!g1:%{!g2: -g1}}}}} \
%{maout: %{!mno-underscores: %{!munderscores: -munderscores }}}"
/* This gets defined in tm.h->linux.h->svr4.h, and keeps us from using
libraries compiled with the native cc, so undef it. */
#undef NO_DOLLAR_IN_LABEL
#undef ASM_SPEC
#define ASM_SPEC "%{v*: -v} %{maout: %{fpic:-k} %{fPIC:-k}}"
/* Use more efficient ``thunks'' to implement C++ vtables. */
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 1
#undef ASM_FINAL_SPEC
#define ASM_FINAL_SPEC "%|"
/* Override the default comment-starter of "/". */
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
/* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support
for the special GCC options -static and -shared, which allow us to
link things in one of these three modes by applying the appropriate
combinations of options at link-time. We like to support here for
as many of the other GNU linker options as possible. But I don't
have the time to search for those flags. I am sure how to add
support for -soname shared_object_name. H.J.
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
I took out %{v:%{!V:-V}}. It is too much :-(. They can use
-Wl,-V.
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
When the -shared link option is used a final link is not being
done. */
#undef LINK_SPEC
#define LINK_SPEC "\
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{maout: %{shared:-Bshareable} \
%{!shared:%{!nostdlib:%{!r:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} \
%{pg:-Bstatic} %{Z}} \
%{assert*} %{R*}} \
%{!maout: \
-m elf_i386 \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
%{symbolic:-Bsymbolic} \
%{!shared: \
%{!static: \
%{rdynamic: -export-dynamic} \
%{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-Bstatic}}}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
%{maout: %{shared:c++rt0.o%s} \
%{!shared: \
%{pg:gcrt0.o%s}%{!pg: \
%{static:scrt0.o%s} \
%{!static:crt0.o%s}}}} \
%{!maout: \
%{!shared: \
%{pg:gcrt1.o%s} \
%{!pg: \
%{p:gcrt1.o%s} \
%{!p:crt1.o%s}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
/* Provide an ENDFILE_SPEC appropriate for FreeBSD/i386. Here we tack on our
own magical crtend.o file (compare w/crtstuff.c) which provides part of the
support for getting C++ file-scope static object constructed before
entering `main', followed by the normal "finalizer" file, `crtn.o'. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "\
%{!maout: \
%{!shared:crtend.o%s} \
%{shared:crtendS.o%s} crtn.o%s}"
/************************[ Target stuff ]***********************************/
/* Define the actual types of some ANSI-mandated types.
Needs to agree with <machine/ansi.h>. GCC defaults come from c-decl.c,
c-common.c, and config/<arch>/<arch>.h. */
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
/* This is the pseudo-op used to generate a 32-bit word of data with a
specific value in some section. */
#undef INT_ASM_OP
#define INT_ASM_OP ".long"
/* Biggest alignment supported by the object file format of this
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
not defined, the default value is `BIGGEST_ALIGNMENT'. */
#define MAX_OFILE_ALIGNMENT (32768*8)
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 FreeBSD/ELF)");
#define MASK_PROFILER_EPILOGUE 010000000000
#define MASK_AOUT 004000000000 /* a.out not elf */
#define MASK_UNDERSCORES 002000000000 /* use leading _ */
#define TARGET_PROFILER_EPILOGUE (target_flags & MASK_PROFILER_EPILOGUE)
#define TARGET_AOUT (target_flags & MASK_AOUT)
#define TARGET_ELF ((target_flags & MASK_AOUT) == 0)
#define TARGET_UNDERSCORES ((target_flags & MASK_UNDERSCORES) != 0)
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "profiler-epilogue", MASK_PROFILER_EPILOGUE}, \
{ "no-profiler-epilogue", -MASK_PROFILER_EPILOGUE}, \
{ "aout", MASK_AOUT}, \
{ "no-aout", -MASK_AOUT}, \
{ "underscores", MASK_UNDERSCORES}, \
{ "no-underscores", -MASK_UNDERSCORES},
/* This goes away when the math emulator is fixed. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
/* Prefix for internally generated assembler labels. If we aren't using
underscores, we are using prefix `.'s to identify labels that should
be ignored, as in `i386/gas.h' --karl@cs.umb.edu */
#undef LPREFIX
#define LPREFIX ((TARGET_UNDERSCORES) ? "L" : ".L")
/* The a.out tools do not support "linkonce" sections. */
#undef SUPPORTS_ONE_ONLY
#define SUPPORTS_ONE_ONLY TARGET_ELF
/* Enable alias attribute support. */
#undef SET_ASM_OP
#define SET_ASM_OP ".set"
/* The a.out tools do not support "Lscope" .stabs symbols. */
#undef NO_DBX_FUNCTION_END
#define NO_DBX_FUNCTION_END TARGET_AOUT
/* In ELF, the function stabs come first, before the relative offsets. */
#undef DBX_FUNCTION_FIRST
#define DBX_CHECK_FUNCTION_FIRST TARGET_ELF
/* supply our own hook for calling __main() from main() */
#undef INVOKE__main
#define INVOKE__main
#undef GEN_CALL__MAIN
#define GEN_CALL__MAIN \
do { \
if (!(TARGET_ELF)) \
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0, \
VOIDmode, 0); \
} while (0)
/* Indicate that jump tables go in the text section. This is
necessary when compiling PIC code. */
#undef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
/* override the exception table positioning */
#undef EXCEPTION_SECTION
#define EXCEPTION_SECTION() \
do { \
if (TARGET_ELF) \
{ \
named_section (NULL_TREE, ".gcc_except_table", 0); \
} \
else \
{ \
if (flag_pic) \
data_section (); \
else \
readonly_data_section (); \
} \
} while (0);
/* Tell final.c that we don't need a label passed to mcount. */
#undef NO_PROFILE_DATA
#define NO_PROFILE_DATA
/* Output assembler code to FILE to begin profiling of the current function.
LABELNO is an optional label. */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
do { \
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
if (flag_pic) \
fprintf ((FILE), "\tcall *%s@GOT(%%ebx)\n", _name); \
else \
fprintf ((FILE), "\tcall %s\n", _name); \
} while (0)
/* Output assembler code to FILE to end profiling of the current function. */
#undef FUNCTION_PROFILER_EPILOGUE
#define FUNCTION_PROFILER_EPILOGUE(FILE, DO_RTL) \
do { \
if (TARGET_PROFILER_EPILOGUE) \
{ \
if (DO_RTL) \
{ \
/* ".mexitcount" is specially handled in \
ASM_HACK_SYMBOLREF () so that we don't need to handle \
flag_pic or TARGET_AOUT here. */ \
rtx xop; \
xop = gen_rtx_MEM (FUNCTION_MODE, \
gen_rtx_SYMBOL_REF (Pmode, ".mexitcount")); \
emit_call_insn (gen_rtx (CALL, VOIDmode, xop, const0_rtx)); \
} \
else \
{ \
/* XXX this !DO_RTL case is broken but not actually used. */ \
char *_name = TARGET_AOUT ? "mcount" : ".mcount"; \
if (flag_pic) \
fprintf (FILE, "\tcall *%s@GOT(%%ebx)\n", _name); \
else \
fprintf (FILE, "\tcall %s\n", _name); \
} \
} \
} while (0)
/************************[ Assembler stuff ]********************************/
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
/* This is how to begin an assembly language file.
The .file command should always begin the output.
ELF also needs a .version. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
do { \
output_file_directive ((FILE), main_input_filename); \
if (TARGET_ELF) \
fprintf ((FILE), "\t.version\t\"01.01\"\n"); \
} while (0)
/* This is how to store into the string BUF
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
This is suitable for output with `assemble_name'. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF, PREFIX, NUMBER) \
sprintf ((BUF), "*%s%s%d", (TARGET_UNDERSCORES) ? "" : ".", \
(PREFIX), (NUMBER))
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
For most svr4/ELF systems, the convention is that any symbol which begins
with a period is not put into the linker symbol table by the assembler. */
#undef ASM_OUTPUT_INTERNAL_LABEL
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
fprintf ((FILE), "%s%s%d:\n", (TARGET_UNDERSCORES) ? "" : ".", \
(PREFIX), (NUM))
/* This is how to output a reference to a user-level label named NAME. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
do { \
char *_name = (NAME); \
/* Hack to avoid writing lots of rtl in \
FUNCTION_PROFILER_EPILOGUE (). */ \
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
{ \
if (TARGET_AOUT) \
_name++; \
if (flag_pic) \
fprintf ((FILE), "*%s@GOT(%%ebx)", _name); \
else \
fprintf ((FILE), "%s", _name); \
} \
else \
fprintf (FILE, "%s%s", TARGET_UNDERSCORES ? "_" : "", _name); \
} while (0)
/* This is how to hack on the symbol code of certain relcalcitrant
symbols to modify their output in output_pic_addr_const (). */
#undef ASM_HACK_SYMBOLREF_CODE
#define ASM_HACK_SYMBOLREF_CODE(NAME, CODE) \
do { \
/* Part of hack to avoid writing lots of rtl in \
FUNCTION_PROFILER_EPILOGUE (). */ \
char *_name = (NAME); \
if (*_name == '.' && strcmp(_name + 1, "mexitcount") == 0) \
(CODE) = 'X'; \
} while (0)
#undef SET_ASM_OP
#define SET_ASM_OP ".set"
/* This is how to output an element of a case-vector that is relative.
This is only used for PIC code. See comments by the `casesi' insn in
i386.md for an explanation of the expression this outputs. */
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf ((FILE), "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, (VALUE))
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE)
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE, LOG) \
if ((LOG)!=0) { \
if (in_text_section()) \
fprintf ((FILE), "\t.p2align %d,0x90\n", (LOG)); \
else \
fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
}
/* Indicate that jump tables go in the text section. This is
necessary when compiling PIC code. */
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
#undef ASM_OUTPUT_SOURCE_LINE
#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
do { \
static int sym_lineno = 1; \
if (TARGET_ELF) \
{ \
fprintf ((FILE), ".stabn 68,0,%d,.LM%d-", (LINE), sym_lineno); \
assemble_name ((FILE), \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
fprintf ((FILE), "\n.LM%d:\n", sym_lineno); \
sym_lineno += 1; \
} \
else \
{ \
fprintf ((FILE), "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, \
lineno); \
} \
} while (0)
/* These macros generate the special .type and .size directives which
are used to set the corresponding fields of the linker symbol table
entries in an ELF object file under SVR4. These macros also output
the starting labels for the relevant functions/objects. */
/* Write the extra assembler code needed to declare a function properly.
Some svr4 assemblers need to also have something extra said about the
function's return value. We allow for that here. */
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { \
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
putc ('\n', FILE); \
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
} while (0)
/* This is how to declare the size of a function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do { \
if (!flag_inhibit_size_directive) \
{ \
char label[256]; \
static int labelno; \
labelno++; \
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
fprintf (FILE, "-"); \
assemble_name (FILE, (FNAME)); \
putc ('\n', FILE); \
} \
} while (0)
/* The routine used to output NUL terminated strings. We use a special
version of this for most svr4 targets because doing so makes the
generated assembly code more compact (and thus faster to assemble)
as well as more readable, especially for targets like the i386
(where the only alternative is to output character sequences as
comma separated lists of numbers). */
#undef ASM_OUTPUT_LIMITED_STRING
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
do { \
register unsigned char *_limited_str = (unsigned char *) (STR); \
register unsigned ch; \
fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \
for (; (ch = *_limited_str); _limited_str++) \
{ \
register int escape; \
switch (escape = ESCAPES[ch]) \
{ \
case 0: \
putc (ch, (FILE)); \
break; \
case 1: \
fprintf ((FILE), "\\%03o", ch); \
break; \
default: \
putc ('\\', (FILE)); \
putc (escape, (FILE)); \
break; \
} \
} \
fprintf ((FILE), "\"\n"); \
} while (0)
/* Switch into a generic section.
We make the section read-only and executable for a function decl,
read-only for a const data decl, and writable for a non-const data decl.
If the section has already been defined, we must not
emit the attributes here. The SVR4 assembler does not
recognize section redefinitions.
If DECL is NULL, no attributes are emitted. */
#undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
do { \
static struct section_info \
{ \
struct section_info *next; \
char *name; \
enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
} *sections; \
struct section_info *s; \
char *mode; \
enum sect_enum type; \
\
for (s = sections; s; s = s->next) \
if (!strcmp (NAME, s->name)) \
break; \
\
if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
type = SECT_EXEC, mode = "ax"; \
else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
type = SECT_RO, mode = "a"; \
else \
type = SECT_RW, mode = "aw"; \
\
if (s == 0) \
{ \
s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
strcpy (s->name, NAME); \
s->type = type; \
s->next = sections; \
sections = s; \
fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode); \
} \
else \
{ \
if (DECL && s->type != type) \
error_with_decl (DECL, "%s causes a section type conflict"); \
\
fprintf (FILE, ".section\t%s\n", NAME); \
} \
} while (0)
#undef MAKE_DECL_ONE_ONLY
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#undef UNIQUE_SECTION_P
#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
#undef UNIQUE_SECTION
#define UNIQUE_SECTION(DECL,RELOC) \
do { \
int len; \
char *name, *string, *prefix; \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
\
if (! DECL_ONE_ONLY (DECL)) \
{ \
prefix = "."; \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
prefix = ".text."; \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \
prefix = ".rodata."; \
else \
prefix = ".data."; \
} \
else if (TREE_CODE (DECL) == FUNCTION_DECL) \
prefix = ".gnu.linkonce.t."; \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \
prefix = ".gnu.linkonce.r."; \
else \
prefix = ".gnu.linkonce.d."; \
\
len = strlen (name) + strlen (prefix); \
string = alloca (len + 1); \
sprintf (string, "%s%s", prefix, name); \
\
DECL_SECTION_NAME (DECL) = build_string (len, string); \
} while (0)
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations. */
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC) \
{ \
if (flag_pic && RELOC) \
data_section (); \
else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (! flag_writable_strings) \
const_section (); \
else \
data_section (); \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if (! DECL_READONLY_SECTION (DECL, RELOC)) \
data_section (); \
else \
const_section (); \
} \
else \
const_section (); \
}
/* Define macro used to output shift-double opcodes when the shift
count is in %cl. Some assemblers require %cl as an argument;
some don't.
*OLD* GAS requires the %cl argument, so override i386/unix.h. */
#undef AS3_SHIFT_DOUBLE
#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d)
/************************[ Debugger stuff ]*********************************/
/* Use stabs instead of DWARF debug format. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
/* Copy this from the svr4 specifications... */
/* Define the register numbers to be used in Dwarf debugging information.
@ -621,8 +122,8 @@ Boston, MA 02111-1307, USA. */
17 for %st(6) (gnu regno = 14)
18 for %st(7) (gnu regno = 15)
*/
#undef DWARF_DBX_REGISTER_NUMBER
#define DWARF_DBX_REGISTER_NUMBER(n) \
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) \
((n) == 0 ? 0 \
: (n) == 1 ? 2 \
: (n) == 2 ? 1 \
@ -634,59 +135,123 @@ Boston, MA 02111-1307, USA. */
: ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
: (-1))
/* Now what stabs expects in the register. */
#undef STABS_DBX_REGISTER_NUMBER
#define STABS_DBX_REGISTER_NUMBER(n) \
((n) == 0 ? 0 : \
(n) == 1 ? 2 : \
(n) == 2 ? 1 : \
(n) == 3 ? 3 : \
(n) == 4 ? 6 : \
(n) == 5 ? 7 : \
(n) == 6 ? 4 : \
(n) == 7 ? 5 : \
(n) + 4)
/* Tell final.c that we don't need a label passed to mcount. */
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) ((write_symbols == DWARF_DEBUG) \
? DWARF_DBX_REGISTER_NUMBER(n) \
: STABS_DBX_REGISTER_NUMBER(n))
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ \
if (flag_pic) \
fprintf (FILE, "\tcall *.mcount@GOT(%%ebx)\n"); \
else \
fprintf (FILE, "\tcall .mcount\n"); \
}
/* tag end of file in elf mode */
#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
do { \
if (TARGET_ELF) { \
fprintf ((FILE), "\t.text\n\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", \
N_SO); \
} \
} while (0)
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
/* stabs-in-elf has offsets relative to function beginning */
#undef DBX_OUTPUT_LBRAC
#define DBX_OUTPUT_LBRAC(FILE, NAME) \
do { \
fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC); \
assemble_name (asmfile, buf); \
if (TARGET_ELF) \
{ \
fputc ('-', asmfile); \
assemble_name (asmfile, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
} \
fprintf (asmfile, "\n"); \
} while (0)
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -Dunix -D__ELF__ -D__FreeBSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)"
#undef DBX_OUTPUT_RBRAC
#define DBX_OUTPUT_RBRAC(FILE, NAME) \
do { \
fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC); \
assemble_name (asmfile, buf); \
if (TARGET_ELF) \
{ \
fputc ('-', asmfile); \
assemble_name (asmfile, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
} \
fprintf (asmfile, "\n"); \
} while (0)
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
/* This defines which switch letters take arguments. On FreeBSD, most of
the normal cases (defined in gcc.c) apply, and we also have -h* and
-z* options (for the linker) (comming from svr4).
We also have -R (alias --rpath), no -z, --soname (-h), --assert etc. */
#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) \
|| (CHAR) == 'h' \
|| (CHAR) == 'z' \
|| (CHAR) == 'R')
/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add
the magical crtbegin.o file (see crtstuff.c) which provides part
of the support for getting C++ file-scope static object constructed
before entering `main'. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} \
%{!profile:crt1.o%s}}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
/* Provide a ENDFILE_SPEC appropriate for FreeBSD. Here we tack on
the magical crtend.o file (see crtstuff.c) which provides part of
the support for getting C++ file-scope static object constructed
before entering `main', followed by a normal "finalizer" file,
`crtn.o'. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
/* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate
libc, depending on whether we're doing profiling or need threads support.
(simular to the default, except no -lg, and no -p. */
#undef LIB_SPEC
#define LIB_SPEC "%{!shared: \
%{!pg:%{!pthread:%{!kthread:-lc} \
%{kthread:-lpthread -lc}} \
%{pthread:-lc_r}} \
%{pg:%{!pthread:%{!kthread:-lc_p} \
%{kthread:-lpthread_p -lc_p}} \
%{pthread:-lc_r_p}}}"
/* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support
for the special GCC options -static and -shared, which allow us to
link things in one of these three modes by applying the appropriate
combinations of options at link-time. We like to support here for
as many of the other GNU linker options as possible. But I don't
have the time to search for those flags. I am sure how to add
support for -soname shared_object_name. H.J.
I took out %{v:%{!V:-V}}. It is too much :-(. They can use
-Wl,-V.
When the -shared link option is used a final link is not being
done. */
#undef LINK_SPEC
#define LINK_SPEC "-m elf_i386 \
%{Wl,*:%*} \
%{v:-V} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
/* A C statement to output to the stdio stream FILE an assembler
command to advance the location counter to a multiple of 1<<LOG
bytes if it is within MAX_SKIP bytes.
This is used to align code labels according to Intel recommendations. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
if ((LOG) != 0) {\
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
#endif

View File

@ -1,4 +0,0 @@
# Don't run fixproto
STMP_FIXPROTO =
# Use only native include files
USER_H =

View File

@ -1,582 +0,0 @@
/* G++ preliminary semantic processing for the compiler driver.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
Contributed by Brendan Kehoe (brendan@cygnus.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This program is a wrapper to the main `gcc' driver. For GNU C++,
we need to do two special things: a) append `-lg++' in situations
where it's appropriate, to link in libg++, and b) add `-xc++'..`-xnone'
around file arguments named `foo.c' or `foo.i'. So, we do all of
this semantic processing then just exec gcc with the new argument
list.
We used to do all of this in a small shell script, but many users
found the performance of this as a shell script to be unacceptable.
In situations where your PATH has a lot of NFS-mounted directories,
using a script that runs sed and other things would be a nasty
performance hit. With this program, we never search the PATH at all. */
#include "config.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if !defined(_WIN32)
#include <sys/file.h> /* May get R_OK, etc. on some systems. */
#else
#include <process.h>
#endif
#include <errno.h>
/* Defined to the name of the compiler; if using a cross compiler, the
Makefile should compile this file with the proper name
(e.g., "i386-aout-gcc"). */
#ifndef GCC_NAME
#define GCC_NAME "gcc"
#endif
/* This bit is set if we saw a `-xfoo' language specification. */
#define LANGSPEC (1<<1)
/* This bit is set if they did `-lm' or `-lmath'. */
#define MATHLIB (1<<2)
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "-lm"
#endif
/* On MSDOS, write temp files in current dir
because there's no place else we can expect to use. */
#ifdef __MSDOS__
#ifndef P_tmpdir
#define P_tmpdir "."
#endif
#ifndef R_OK
#define R_OK 4
#define W_OK 2
#define X_OK 1
#endif
#endif
#ifndef VPROTO
#ifdef __STDC__
#define PVPROTO(ARGS) ARGS
#define VPROTO(ARGS) ARGS
#define VA_START(va_list,var) va_start(va_list,var)
#else
#define PVPROTO(ARGS) ()
#define VPROTO(ARGS) (va_alist) va_dcl
#define VA_START(va_list,var) va_start(va_list)
#endif
#endif
#ifndef errno
extern int errno;
#endif
extern int sys_nerr;
#ifndef HAVE_STRERROR
#if defined(bsd4_4)
extern const char *const sys_errlist[];
#else
extern char *sys_errlist[];
#endif
#else
extern char *strerror();
#endif
/* Name with which this program was invoked. */
static char *programname;
char *
my_strerror(e)
int e;
{
#ifdef HAVE_STRERROR
return strerror(e);
#else
static char buffer[30];
if (!e)
return "";
if (e > 0 && e < sys_nerr)
return sys_errlist[e];
sprintf (buffer, "Unknown error %d", e);
return buffer;
#endif
}
#ifdef HAVE_VPRINTF
/* Output an error message and exit */
static void
fatal VPROTO((char *format, ...))
{
#ifndef __STDC__
char *format;
#endif
va_list ap;
VA_START (ap, format);
#ifndef __STDC__
format = va_arg (ap, char*);
#endif
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, format, ap);
va_end (ap);
fprintf (stderr, "\n");
#if 0
/* XXX Not needed for g++ driver. */
delete_temp_files ();
#endif
exit (1);
}
static void
error VPROTO((char *format, ...))
{
#ifndef __STDC__
char *format;
#endif
va_list ap;
VA_START (ap, format);
#ifndef __STDC__
format = va_arg (ap, char*);
#endif
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, format, ap);
va_end (ap);
fprintf (stderr, "\n");
}
#else /* not HAVE_VPRINTF */
static void
error (msg, arg1, arg2)
char *msg, *arg1, *arg2;
{
fprintf (stderr, "%s: ", programname);
fprintf (stderr, msg, arg1, arg2);
fprintf (stderr, "\n");
}
static void
fatal (msg, arg1, arg2)
char *msg, *arg1, *arg2;
{
error (msg, arg1, arg2);
#if 0
/* XXX Not needed for g++ driver. */
delete_temp_files ();
#endif
exit (1);
}
#endif /* not HAVE_VPRINTF */
/* More 'friendly' abort that prints the line and file.
config.h can #define abort fancy_abort if you like that sort of thing. */
void
fancy_abort ()
{
fatal ("Internal g++ abort.");
}
char *
xmalloc (size)
unsigned size;
{
register char *value = (char *) malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
/* Return a newly-allocated string whose contents concatenate those
of s1, s2, s3. */
static char *
concat (s1, s2, s3)
char *s1, *s2, *s3;
{
int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
char *result = xmalloc (len1 + len2 + len3 + 1);
strcpy (result, s1);
strcpy (result + len1, s2);
strcpy (result + len1 + len2, s3);
*(result + len1 + len2 + len3) = 0;
return result;
}
static void
pfatal_with_name (name)
char *name;
{
fatal (concat ("%s: ", my_strerror (errno), ""), name);
}
#ifdef __MSDOS__
/* This is the common prefix we use to make temp file names. */
char *temp_filename;
/* Length of the prefix. */
int temp_filename_length;
/* Compute a string to use as the base of all temporary file names. */
static char *
choose_temp_base_try (try, base)
char *try;
char *base;
{
char *rv;
if (base)
rv = base;
else if (try == (char *)0)
rv = 0;
else if (access (try, R_OK | W_OK) != 0)
rv = 0;
else
rv = try;
return rv;
}
static void
choose_temp_base ()
{
char *base = 0;
int len;
base = choose_temp_base_try (getenv ("TMPDIR"), base);
base = choose_temp_base_try (getenv ("TMP"), base);
base = choose_temp_base_try (getenv ("TEMP"), base);
#ifdef P_tmpdir
base = choose_temp_base_try (P_tmpdir, base);
#endif
base = choose_temp_base_try ("/usr/tmp", base);
base = choose_temp_base_try ("/tmp", base);
/* If all else fails, use the current directory! */
if (base == (char *)0)
base = "./";
len = strlen (base);
temp_filename = xmalloc (len + sizeof("/ccXXXXXX"));
strcpy (temp_filename, base);
if (len > 0 && temp_filename[len-1] != '/')
temp_filename[len++] = '/';
strcpy (temp_filename + len, "ccXXXXXX");
mktemp (temp_filename);
temp_filename_length = strlen (temp_filename);
if (temp_filename_length == 0)
abort ();
}
static void
perror_exec (name)
char *name;
{
char *s;
if (errno < sys_nerr)
s = concat ("installation problem, cannot exec %s: ",
my_strerror( errno ), "");
else
s = "installation problem, cannot exec %s";
error (s, name);
}
/* This is almost exactly what's in gcc.c:pexecute for MSDOS. */
void
run_dos (program, argv)
char *program;
char *argv[];
{
char *scmd, *rf;
FILE *argfile;
int i;
choose_temp_base (); /* not in gcc.c */
scmd = (char *) malloc (strlen (program) + strlen (temp_filename) + 10);
rf = scmd + strlen (program) + 6;
sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);
argfile = fopen (rf, "w");
if (argfile == 0)
pfatal_with_name (rf);
for (i=1; argv[i]; i++)
{
char *cp;
for (cp = argv[i]; *cp; cp++)
{
if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))
fputc ('\\', argfile);
fputc (*cp, argfile);
}
fputc ('\n', argfile);
}
fclose (argfile);
i = system (scmd);
remove (rf);
if (i == -1)
perror_exec (program);
}
#endif /* __MSDOS__ */
int
main (argc, argv)
int argc;
char **argv;
{
register int i, j = 0;
register char *p;
int verbose = 0;
/* This will be 0 if we encounter a situation where we should not
link in libstdc++, or 2 if we should link in libg++ as well. */
int library = 1;
/* Used to track options that take arguments, so we don't go wrapping
those with -xc++/-xnone. */
char *quote = NULL;
/* The new argument list will be contained in this. */
char **arglist;
/* The name of the compiler we will want to run---by default, it
will be the definition of `GCC_NAME', e.g., `gcc'. */
char *gcc = GCC_NAME;
/* Non-zero if we saw a `-xfoo' language specification on the
command line. Used to avoid adding our own -xc++ if the user
already gave a language for the file. */
int saw_speclang = 0;
/* Non-zero if we saw `-lm' or `-lmath' on the command line. */
char *saw_math = 0;
/* The number of arguments being added to what's in argv, other than
libraries. We use this to track the number of times we've inserted
-xc++/-xnone. */
int added = 0;
/* An array used to flag each argument that needs a bit set for
LANGSPEC or MATHLIB. */
int *args;
p = argv[0] + strlen (argv[0]);
/* If we're called as g++ (or i386-aout-g++), link in libg++ as well. */
if (strcmp (p - 3, "g++") == 0)
{
library = 2;
}
while (p != argv[0] && p[-1] != '/')
--p;
programname = p;
if (argc == 1)
fatal ("No input files specified");
#ifndef __MSDOS__
/* We do a little magic to find out where the main gcc executable
is. If they ran us as /usr/local/bin/g++, then we will look
for /usr/local/bin/gcc; similarly, if they just ran us as `g++',
we'll just look for `gcc'. */
if (p != argv[0])
{
*--p = '\0';
gcc = (char *) malloc ((strlen (argv[0]) + 1 + strlen (GCC_NAME) + 1)
* sizeof (char));
sprintf (gcc, "%s/%s", argv[0], GCC_NAME);
}
#endif
args = (int *) malloc (argc * sizeof (int));
bzero ((char *) args, argc * sizeof (int));
for (i = 1; i < argc; i++)
{
/* If the previous option took an argument, we swallow it here. */
if (quote)
{
quote = NULL;
continue;
}
if (argv[i][0] == '\0' || argv[i][1] == '\0')
continue;
if (argv[i][0] == '-')
{
if (library != 0 && strcmp (argv[i], "-nostdlib") == 0)
{
library = 0;
}
else if (strcmp (argv[i], "-lm") == 0
|| strcmp (argv[i], "-lmath") == 0)
args[i] |= MATHLIB;
else if (strcmp (argv[i], "-v") == 0)
{
verbose = 1;
if (argc == 2)
{
/* If they only gave us `-v', don't try to link
in libg++. */
library = 0;
}
}
else if (strncmp (argv[i], "-x", 2) == 0)
saw_speclang = 1;
else if (((argv[i][2] == '\0'
&& (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
|| strcmp (argv[i], "-Tdata") == 0))
quote = argv[i];
else if (library != 0 && ((argv[i][2] == '\0'
&& (char *) strchr ("cSEM", argv[i][1]) != NULL)
|| strcmp (argv[i], "-MM") == 0))
{
/* Don't specify libraries if we won't link, since that would
cause a warning. */
library = 0;
}
else
/* Pass other options through. */
continue;
}
else
{
int len;
if (saw_speclang)
{
saw_speclang = 0;
continue;
}
/* If the filename ends in .c or .i, put options around it.
But not if a specified -x option is currently active. */
len = strlen (argv[i]);
if (len > 2
&& (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
&& argv[i][len - 2] == '.')
{
args[i] |= LANGSPEC;
added += 2;
}
}
}
if (quote)
fatal ("argument to `%s' missing\n", quote);
if (added || library)
{
arglist = (char **) malloc ((argc + added + 4) * sizeof (char *));
for (i = 1, j = 1; i < argc; i++, j++)
{
arglist[j] = argv[i];
/* Make sure -lg++ is before the math library, since libg++
itself uses those math routines. */
if (!saw_math && (args[i] & MATHLIB) && library)
{
--j;
saw_math = argv[i];
}
/* Wrap foo.c and foo.i files in a language specification to
force the gcc compiler driver to run cc1plus on them. */
if (args[i] & LANGSPEC)
{
int len = strlen (argv[i]);
if (argv[i][len - 1] == 'i')
arglist[j++] = "-xc++-cpp-output";
else
arglist[j++] = "-xc++";
arglist[j++] = argv[i];
arglist[j] = "-xnone";
}
}
/* Add `-lg++' if we haven't already done so. */
if (library == 2)
arglist[j++] = "-lg++";
if (library)
arglist[j++] = "-lstdc++";
if (saw_math)
arglist[j++] = saw_math;
else if (library)
arglist[j++] = MATH_LIBRARY;
arglist[j] = NULL;
}
else
/* No need to copy 'em all. */
arglist = argv;
arglist[0] = gcc;
if (verbose)
{
if (j == 0)
j = argc;
for (i = 0; i < j; i++)
fprintf (stderr, " %s", arglist[i]);
fprintf (stderr, "\n");
}
#if !defined(OS2) && !defined (_WIN32)
#ifdef __MSDOS__
run_dos (gcc, arglist);
#else /* !__MSDOS__ */
if (execvp (gcc, arglist) < 0)
pfatal_with_name (gcc);
#endif /* __MSDOS__ */
#else /* OS2 or _WIN32 */
if (spawnvp (1, gcc, arglist) < 0)
pfatal_with_name (gcc);
#endif
return 0;
}

View File

@ -1,752 +0,0 @@
\input texinfo @c -*- Texinfo -*-
@setfilename reno-1.info
@ifinfo
@format
START-INFO-DIR-ENTRY
* Reno 1: (reno). The GNU C++ Renovation Project, Phase 1.
END-INFO-DIR-ENTRY
@end format
@end ifinfo
@ifinfo
Copyright @copyright{} 1992, 1993, 1994 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries a copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ifinfo
@setchapternewpage odd
@settitle GNU C++ Renovation Project
@c @smallbook
@titlepage
@finalout
@title GNU C++ Renovation Project
@subtitle Phase 1.3
@author Brendan Kehoe, Jason Merrill,
@author Mike Stump, Michael Tiemann
@page
Edited March, 1994 by Roland Pesch (@code{pesch@@cygnus.com})
@vskip 0pt plus 1filll
Copyright @copyright{} 1992, 1993, 1994 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end titlepage
@ifinfo
@node Top
@top @sc{gnu} C++ Renovation Project
This file describes the goals of the @sc{gnu} C++ Renovation Project,
and its accomplishments to date (as of Phase 1.3).
It also discusses the remaining divergences from @sc{gnu} C++, and how the
name encoding in @sc{gnu} C++ differs from the sample encoding in
@cite{The Annotated C++ Reference Manual}.
@c This is not a good place to introduce the acronym ARM because it's
@c info-only.
@menu
* Introduction:: What is the GNU C++ Renovation Project?
* Changes:: Summary of changes since previous GNU C++ releases.
* Plans:: Plans for Reno-2.
* Templates:: The template implementation.
* ANSI:: GNU C++ conformance to ANSI C++.
* Encoding:: Name encoding in GNU C++.
@end menu
@end ifinfo
@node Introduction
@chapter Introduction
As you may remember, @sc{gnu} C++ was the first native-code C++
compiler available under Unix (December 1987). In November 1988, it was
judged superior to the AT&T compiler in a Unix World review. In 1990 it
won a Sun Observer ``Best-Of'' award. But now, with new requirements
coming out of the @sc{ansi} C++ committee and a growing backlog of bugs, it's
clear that @sc{gnu} C++ needs an overhaul.
The C++ language has been under development since 1982. It has
evolved significantly since its original incarnation (C with Classes),
addressing many commercial needs and incorporating many lessons
learned as more and more people started using ``object-oriented''
programming techniques. In 1989, the first X3J16 committee meeting
was held in Washington DC; in the interest of users, C++ was going to
be standardized.
As C++ has become more popular, more demands have been placed on its
compilers. Some compilers are up to the demands, others are not.
@sc{gnu} C++ was used to prototype several features which have since
been incorporated into the standard, most notably exception handling.
While @sc{gnu} C++ has been an excellent experimental vehicle, it did
not have the resources that AT&T, Borland, or Microsoft have at their
disposal.
We believe that @sc{gnu} C++ is an important compiler, providing users with
many of the features that have made @sc{gnu} C so popular: fast compilation,
good error messages, innovative features, and full sources that may be
freely redistributed. The purpose of this overhaul, dubbed the @var{@sc{gnu}
C++ Renovation Project}, is to take advantage of the functionality that
@sc{gnu} C++ offers today, to strengthen its base technology, and put it in a
position to remain---as other @sc{gnu} software currently is---the technical
leader in the field.
This release represents the latest phase of work in strengthening the
compiler on a variety of points. It includes many months of
work concentrated on fixing many of the more egregious bugs that
presented themselves in the compiler recently.
@ignore
@c FIXME-- update?
Nearly 85% of all bugs reported in the period of February to September
of 1992 were fixed as part of the work in the first phase.
@end ignore
In the coming months, we hope to continue expanding and enhancing the
quality and dependability of the industry's only freely redistributable
C++ compiler.
@node Changes
@chapter Changes in Behavior in @sc{gnu} C++
The @sc{gnu} C++ compiler continues to improve and change. A major goal
of our work has been to continue to bring the compiler into compliance
with the draft @sc{ansi} C++ standard, and with @cite{The Annotated C++
Reference Manual} (the @sc{arm}). This section outlines most of the
user-noticeable changes that might be encountered during the normal
course of use.
@menu
* Summary of Phase 1.3::
* Major changes::
* New features::
* Enhancements and bug fixes::
* Problems with debugging::
@end menu
@node Summary of Phase 1.3
@section Summary of Changes in Phase 1.3
The bulk of this note discusses the cumulative effects of the @sc{gnu} C++
Renovation Project to date. The work during its most recent phase (1.3)
had these major effects:
@itemize @bullet
@item The standard compiler driver @code{g++} is now the faster compiled
version, rather than a shell script.
@item Nested types work much better; notably, nesting is no longer
restricted to nine levels.
@item Better @sc{arm} conformance on member access control.
@item The compiler now always generates default assignment operators
(@samp{operator =}), copy constructors (@samp{X::X(X&)}), and default
constructors (@samp{X::X()}) whenever they are required.
@item The new draft @sc{ansi} standard keyword @code{mutable} is supported.
@item @samp{-fansi-overloading} is the default, to comply better with
the @sc{arm} (at some cost in compatibility to earlier versions of @sc{gnu} C++).
@item More informative error messages.
@item System include files are automatically treated as if they were
wrapped in @samp{extern "C" @{ @}}.
@item The new option @samp{-falt-external-templates} provides alternate
template instantiation semantics.
@item Operator declarations are now checked more strictly.
@item You can now use template type arguments in the template parameter list.
@item You can call the destructor for any type.
@item The compiler source code is better organized.
@item You can specify where to instantiate template definitions explicitly.
@end itemize
Much of the work in Phase 1.3 went to elimination of known bugs, as well
as the major items above.
During the span of Phase 1.3, there were also two changes associated
with the compiler that, while not specifically part of the C++
Renovation project, may be of interest:
@itemize @bullet
@item @code{gcov}, a code coverage tool for @sc{gnu cc}, is now available
from Cygnus Support. (@code{gcov} is free software, but the @sc{fsf} has not
yet accepted it.) @xref{Gcov,, @code{gcov}: a Test Coverage Program,
gcc.info, Using GNU CC}, for more information (in Cygnus releases of
that manual).
@item @sc{gnu} C++ now supports @dfn{signatures}, a language extension to
provide more flexibility in abstract type definitions. @xref{C++
Signatures,, Type Abstraction using Signatures, gcc.info, Using GNU CC}.
@end itemize
@node Major changes
@section Major Changes
This release includes four wholesale rewrites of certain areas of
compiler functionality:
@enumerate 1
@item Argument matching. @sc{gnu} C++ is more compliant with the rules
described in Chapter 13, ``Overloading'', of the @sc{arm}. This behavior is
the default, though you can specify it explicitly with
@samp{-fansi-overloading}. For compatibility with earlier releases of
@sc{gnu} C++, specify @samp{-fno-ansi-overloading}; this makes the compiler
behave as it used to with respect to argument matching and name overloading.
@item Default constructors/destructors. Section 12.8 of the @sc{arm}, ``Copying
Class Objects'', and Section 12.1, ``Constructors'', state that a
compiler must declare such default functions if the user does not
specify them. @sc{gnu} C++ now declares, and generates when necessary,
the defaults for constructors and destructors you might omit. In
particular, assignment operators (@samp{operator =}) behave the same way
whether you define them, or whether the compiler generates them by
default; taking the address of the default @samp{operator =} is now
guaranteed to work. Default copy constructors (@samp{X::X(X&)}) now
function correctly, rather than calling the copy assignment operator for
the base class. Finally, constructors (@samp{X::X()}), as well as
assignment operators and copy constructors, are now available whenever
they are required.
@c XXX This may be taken out eventually...
@item Binary incompatibility. There are no new binary incompatibilities
in Phase 1.3, but Phase 1.2 introduced two binary incompatibilities with
earlier releases. First, the functionality of @samp{operator
new} and @samp{operator delete} changed. Name encoding
(``mangling'') of virtual table names changed as well. Libraries
built with versions of the compiler earlier than Phase 1.2 must be
compiled with the new compiler. (This includes the Cygnus Q2
progressive release and the FSF 2.4.5 release.)
@item New @code{g++} driver.
A new binary @code{g++} compiler driver replaces the shell script.
The new driver executes faster.
@end enumerate
@node New features
@section New features
@itemize @bullet
@item
The compiler warns when a class contains only private constructors
or destructors, and has no friends. At the request of some of our
customers, we have added a new option, @samp{-Wctor-dtor-privacy} (on by
default), and its negation, @samp{-Wno-ctor-dtor-privacy}, to control
the emission of this warning. If, for example, you are working towards
making your code compile warning-free, you can use @w{@samp{-Wall
-Wno-ctor-dtor-privacy}} to find the most common warnings.
@item
There is now a mechanism which controls exactly when templates are
expanded, so that you can reduce memory usage and program size and also
instantiate them exactly once. You can control this mechanism with the
option @samp{-fexternal-templates} and its corresponding negation
@samp{-fno-external-templates}. Without this feature, space consumed by
template instantiations can grow unacceptably in large-scale projects
with many different source files. The default is
@samp{-fno-external-templates}.
You do not need to use the @samp{-fexternal-templates} option when
compiling a file that does not define and instantiate templates used in
other files, even if those files @emph{are} compiled with
@samp{-fexternal-templates}. The only side effect is an increase in
object size for each file that was compiled without
@samp{-fexternal-templates}.
When your code is compiled with @samp{-fexternal-templates}, all
template instantiations are external; this requires that the templates
be under the control of @samp{#pragma interface} and @samp{#pragma
implementation}. All instantiations that will be needed should be in
the implementation file; you can do this with a @code{typedef} that
references the instantiation needed. Conversely, when you compile using
the option @samp{-fno-external-templates}, all template instantiations are
explicitly internal.
@samp{-fexternal-templates} also allows you to finally separate class
template function definitions from their declarations, thus speeding up
compilation times for every file that includes the template declaration.
Now you can have tens or even hundreds of lines in template
declarations, and thousands or tens of thousands of lines in template
definitions, with the definitions only going through the compiler once
instead of once for each source file. It is important to note that you
must remember to externally instantiate @emph{all} templates that are
used from template declarations in interface files. If you forget to do
this, unresolved externals will occur.
In the example below, the object file generated (@file{example.o}) will
contain the global instantiation for @samp{Stack<int>}. If other types
of @samp{Stack} are needed, they can be added to @file{example.cc} or
placed in a new file, in the same spirit as @file{example.cc}.
@code{foo.h}:
@smallexample
@group
#pragma interface "foo.h"
template<class T>
class Stack @{
static int statc;
static T statc2;
Stack() @{ @}
virtual ~Stack() @{ @}
int bar();
@};
@end group
@end smallexample
@code{example.cc}:
@smallexample
@group
#pragma implementation "foo.h"
#include "foo.h"
typedef Stack<int> t;
int Stack<int>::statc;
int Stack<int>::statc2;
int Stack<int>::bar() @{ @}
@end group
@end smallexample
Note that using @samp{-fexternal-templates} does not reduce memory usage
from completely different instantiations (@samp{Stack<Name>} vs.
@samp{Stack<Net_Connection>}), but only collapses different occurrences
of @samp{Stack<Name>} so that only one @samp{Stack<Name>} is generated.
@samp{-falt-external-templates} selects a slight variation in the
semantics described above (incidentally, you need not specify both
options; @samp{-falt-external-templates} implies
@samp{-fexternal-templates}).
With @samp{-fexternal-templates}, the compiler emits a definition in the
implementation file that includes the header definition, @emph{even if}
instantiation is triggered from a @emph{different} implementation file
(e.g. with a template that uses another template).
With @samp{-falt-external-templates}, the definition always goes in the
implementation file that triggers instantiation.
For instance, with these two header files---
@example
@exdent @file{a.h}:
#pragma interface
template <class T> class A @{ @dots{} @};
@exdent @file{b.h}:
#pragma interface
class B @{ @dots{} @};
void f (A<B>);
@end example
Under @samp{-fexternal-templates}, the definition of @samp{A<B>} ends up
in the implementation file that includes @file{a.h}. Under
@samp{-falt-external-templates}, the same definition ends up in the
implementation file that includes @file{b.h}.
@item
You can control explicitly where a template is instantiated, without
having to @emph{use} the template to get an instantiation.
To instantiate a class template explicitly, write @samp{template
class @var{name}<paramvals>}, where @var{paramvals} is a list of values
for the template parameters. For example, you might write
@example
template class A<int>
@end example
Similarly, to instantiate a function template explicitly, write
@samp{template @var{fnsign}} where @var{fnsign} is the particular
function signature you need. For example, you might write
@example
template void foo (int, int)
@end example
This syntax for explicit template instantiation agrees with recent
extensions to the draft @sc{ansi} standard.
@item
The compiler's actions on @sc{ansi}-related warnings and errors have
been further enhanced. The @samp{-pedantic-errors} option produces
error messages in a number of new situations: using @code{return} in a
non-@code{void} function (one returning a value); declaring a local
variable that shadows a parameter (e.g., the function takes an argument
@samp{a}, and has a local variable @samp{a}); and use of the @samp{asm}
keyword. Finally, the compiler by default now issues a warning when
converting from an @code{int} to an enumerated type. This is likely to
cause many new warnings in code that hadn't triggered them before. For
example, when you compile this code,
@smallexample
@group
enum boolean @{ false, true @};
void
f ()
@{
boolean x;
x = 1; //@i{assigning an @code{int} to an @code{enum} now triggers a warning}
@}
@end group
@end smallexample
@noindent
you should see the warning ``@code{anachronistic conversion from integer
type to enumeral type `boolean'}''. Instead of assigning the value 1,
assign the original enumerated value @samp{true}.
@end itemize
@node Enhancements and bug fixes
@section Enhancements and bug fixes
@itemize @bullet
@cindex nested types in template parameters
@item
You can now use nested types in a template parameter list, even if the nested
type is defined within the same class that attempts to use the template.
For example, given a template @code{list}, the following now works:
@smallexample
struct glyph @{
@dots{}
struct stroke @{ @dots{} @};
list<stroke> l;
@dots{}
@}
@end smallexample
@cindex function pointers vs template parameters
@item
Function pointers now work in template parameter lists. For
example, you might want to instantiate a parameterized @code{list} class
in terms of a pointer to a function like this:
@smallexample
list<int (*)(int, void *)> fnlist;
@end smallexample
@item
@c FIXME! Really no limit? Jason said "deeper than 9" now OK...
Nested types are now handled correctly. In particular, there is no
longer a limit to how deeply you can nest type definitions.
@item
@sc{gnu} C++ now conforms to the specifications in Chapter 11 of the
@sc{arm}, ``Member Access Control''.
@item
The @sc{ansi} C++ committee has introduced a new keyword @code{mutable}.
@sc{gnu} C++ supports it. Use @code{mutable} to specify that some
particular members of a @code{const} class are @emph{not} constant. For
example, you can use this to include a cache in a data structure that
otherwise represents a read-only database.
@item
Error messages now explicitly specify the declaration, type, or
expression that contains an error.
@item
To avoid copying and editing all system include files during @sc{gnu}
C++ installation, the compiler now automatically recognizes system
include files as C language definitions, as if they were wrapped in
@samp{extern "C" @{ @dots{} @}}.
@item
The compiler checks operator declarations more strictly. For example,
you may no longer declare an @samp{operator +} with three arguments.
@item
You can now use template type arguments in the same template
parameter list where the type argument is specified (as well as in the
template body). For example, you may write
@example
template <class T, T t> class A @{ @dots{} @};
@end example
@item
Destructors are now available for all types, even built-in ones; for
example, you can call @samp{int::~int}. (Destructors for types like
@code{int} do not actually do anything, but their existence provides a
level of generality that permits smooth template expansion in more
cases.)
@item
Enumerated types declared inside a class are now handled correctly.
@item
An argument list for a function may not use an initializer list for its default
value. For example, @w{@samp{void foo ( T x = @{ 1, 2 @} )}} is not permitted.
@item
A significant amount of work went into improving the ability of the
compiler to act accurately on multiple inheritance and virtual
functions. Virtual function dispatch has been enhanced as well.
@item
The warning concerning a virtual inheritance environment with a
non-virtual destructor has been disabled, since it is not clear that
such a warning is warranted.
@item
Until exception handling is fully implemented in the Reno-2 release, use
of the identifiers @samp{catch}, @samp{throw}, or @samp{try} results
in the warning:
@smallexample
t.C:1: warning: `catch', `throw', and `try'
are all C++ reserved words
@end smallexample
@item
When giving a warning or error concerning initialization of a member in a
class, the compiler gives the name of the member if it has one.
@item
Detecting friendship between classes is more accurately checked.
@item
The syntaxes of @w{@samp{#pragma implementation "file.h"}} and
@samp{#pragma interface} are now more strictly controlled. The compiler
notices (and warns) when any text follows @file{file.h} in the
implementation pragma, or follows the word @samp{interface}. Any such
text is otherwise ignored.
@item
Trying to declare a template on a variable or type is now considered an
error, not an unimplemented feature.
@item
When an error occurs involving a template, the compiler attempts to
tell you at which point of instantiation the error occurred, in
addition to noting the line in the template declaration which had the
actual error.
@item
The symbol names for function templates in the resulting assembly file
are now encoded according to the arguments, rather than just being
emitted as, for example, two definitions of a function @samp{foo}.
@item
Template member functions that are declared @code{static} no longer
receive a @code{this} pointer.
@item
Case labels are no longer allowed to have commas to make up their
expressions.
@item
Warnings concerning the shift count of a left or right shift now tell
you if it was a @samp{left} or @samp{right} shift.
@item
The compiler now warns when a decimal constant is so large that it
becomes @code{unsigned}.
@item
Union initializers which are raw constructors are now handled properly.
@item
The compiler no longer gives incorrect errors when initializing a
union with an empty initializer list.
@item
Anonymous unions are now correctly used when nested inside a class.
@item
Anonymous unions declared as static class members are now handled
properly.
@item
The compiler now notices when a field in a class is declared both as
a type and a non-type.
@item
The compiler now warns when a user-defined function shadows a
built-in function, rather than emitting an error.
@item
A conflict between two function declarations now produces an error
regardless of their language context.
@item
Duplicate definitions of variables with @samp{extern "C"} linkage are no
longer considered in error. (Note in C++ linkage---the default---you may
not have more than one definition of a variable.)
@item
Referencing a label that is not defined in any function is now an error.
@item
The syntax for pointers to methods has been improved; there are still
some minor bugs, but a number of cases should now be accepted by the
compiler.
@item
In error messages, arguments are now numbered starting at 1, instead of
0. Therefore, in the function @samp{void foo (int a, int b)}, the
argument @samp{a} is argument 1, and @samp{b} is argument 2. There is
no longer an argument 0.
@item
The tag for an enumerator, rather than its value, used as a default
argument is now shown in all error messages. For example, @w{@samp{void
foo (enum x (= true))}} is shown instead of @w{@samp{void foo (enum x (=
1))}}.
@item
The @samp{__asm__} keyword is now accepted by the C++ front-end.
@item
Expressions of the form @samp{foo->~Class()} are now handled properly.
@item
The compiler now gives better warnings for situations which result in
integer overflows (e.g., in storage sizes, enumerators, unary
expressions, etc).
@item
@code{unsigned} bitfields are now promoted to @code{signed int} if the
field isn't as wide as an @code{int}.
@item
Declaration and usage of prefix and postfix @samp{operator ++} and
@samp{operator --} are now handled correctly. For example,
@smallexample
@group
class foo
@{
public:
operator ++ ();
operator ++ (int);
operator -- ();
operator -- (int);
@};
void
f (foo *f)
@{
f++; // @i{call @code{f->operator++(int)}}
++f; // @i{call @code{f->operator++()}}
f--; // @i{call @code{f->operator++(int)}}
--f; // @i{call @code{f->operator++()}}
@}
@end group
@end smallexample
@item
In accordance with @sc{arm} section 10.1.1, ambiguities and dominance are now
handled properly. The rules described in section 10.1.1 are now fully
implemented.
@end itemize
@node Problems with debugging
@section Problems with debugging
Two problems remain with regard to debugging:
@itemize @bullet
@item
Debugging of anonymous structures on the IBM RS/6000 host is incorrect.
@item
Symbol table size is overly large due to redundant symbol information;
this can make @code{gdb} coredump under certain circumstances. This
problem is not host-specific.
@end itemize
@node Plans
@chapter Plans for Reno-2
The overall goal for the second phase of the @sc{gnu} C++ Renovation
Project is to bring @sc{gnu} C++ to a new level of reliability, quality,
and competitiveness. As particular elements of this strategy, we intend
to:
@enumerate 0
@item
Fully implement @sc{ansi} exception handling.
@item
With the exception handling, add Runtime Type Identification
(@sc{rtti}), if the @sc{ansi} committee adopts it into the standard.
@item
Bring the compiler into closer compliance with the @sc{arm} and the draft
@sc{ansi} standard, and document what points in the @sc{arm} we do not yet comply,
or agree, with.
@item
Add further support for the @sc{dwarf} debugging format.
@item
Finish the work to make the compiler compliant with @sc{arm} Section 12.6.2,
initializing base classes in declaration order, rather than in the order
that you specify them in a @var{mem-initializer} list.
@item
Perform a full coverage analysis on the compiler, and weed out unused
code, for a gain in performance and a reduction in the size of the compiler.
@item
Further improve the multiple inheritance implementation in the
compiler to make it cleaner and more complete.
@end enumerate
@noindent
As always, we encourage you to make suggestions and ask questions about
@sc{gnu} C++ as a whole, so we can be sure that the end of this project
will bring a compiler that everyone will find essential for C++ and will
meet the needs of the world's C++ community.
@include templates.texi
@include gpcompare.texi
@contents
@bye

View File

@ -1706,9 +1706,9 @@ static void
profile_function (file)
FILE *file;
{
#ifndef NO_PROFILE_DATA
#ifndef NO_PROFILE_COUNTERS
int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
#endif /* not NO_PROFILE_DATA */
#endif
#if defined(ASM_OUTPUT_REG_PUSH)
#if defined(STRUCT_VALUE_INCOMING_REGNUM) || defined(STRUCT_VALUE_REGNUM)
int sval = current_function_returns_struct;
@ -1718,12 +1718,12 @@ profile_function (file)
#endif
#endif /* ASM_OUTPUT_REG_PUSH */
#ifndef NO_PROFILE_DATA
#ifndef NO_PROFILE_COUNTERS
data_section ();
ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no);
assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, 1);
#endif /* not NO_PROFILE_DATA */
#endif
function_section (current_function_decl);
@ -3115,7 +3115,7 @@ alter_subreg (x)
PUT_CODE (x, MEM);
MEM_COPY_ATTRIBUTES (x, y);
MEM_ALIAS_SET (x) = MEM_ALIAS_SET (y);
XEXP (x, 0) = plus_constant (XEXP (y, 0), offset);
XEXP (x, 0) = plus_constant_for_output (XEXP (y, 0), offset);
}
return x;

View File

@ -1,653 +0,0 @@
/* GNU Objective C Runtime message lookup
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
/* $FreeBSD$ */
#include "../tconfig.h"
#include "runtime.h"
#include "sarray.h"
#include "encoding.h"
#include "runtime-info.h"
/* this is how we hack STRUCT_VALUE to be 1 or 0 */
#define gen_rtx(args...) 1
#define gen_rtx_MEM(args...) 1
#define rtx int
#if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0
#define INVISIBLE_STRUCT_RETURN 1
#else
#define INVISIBLE_STRUCT_RETURN 0
#endif
/* The uninstalled dispatch table */
struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */
/* Send +initialize to class */
static void __objc_send_initialize(Class);
static void __objc_install_dispatch_table_for_class (Class);
/* Forward declare some functions */
static void __objc_init_install_dtable(id, SEL);
/* Various forwarding functions that are used based upon the
return type for the selector.
__objc_block_forward for structures.
__objc_double_forward for floats/doubles.
__objc_word_forward for pointers or types that fit in registers.
*/
static double __objc_double_forward(id, SEL, ...);
static id __objc_word_forward(id, SEL, ...);
typedef struct { id many[8]; } __big;
#if INVISIBLE_STRUCT_RETURN
static __big
#else
static id
#endif
__objc_block_forward(id, SEL, ...);
static Method_t search_for_method_in_hierarchy (Class class, SEL sel);
Method_t search_for_method_in_list(MethodList_t list, SEL op);
id nil_method(id, SEL, ...);
/* Given a selector, return the proper forwarding implementation. */
__inline__
IMP
__objc_get_forward_imp (SEL sel)
{
const char *t = sel->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{')
#ifdef OBJC_MAX_STRUCT_BY_VALUE
&& objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE
#endif
)
return (IMP)__objc_block_forward;
else if (t && (*t == 'f' || *t == 'd'))
return (IMP)__objc_double_forward;
else
return (IMP)__objc_word_forward;
}
/* Given a class and selector, return the selector's implementation. */
__inline__
IMP
get_imp (Class class, SEL sel)
{
void* res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
if (res == 0)
{
/* Not a valid method */
if(class->dtable == __objc_uninstalled_dtable)
{
/* The dispatch table needs to be installed. */
objc_mutex_lock(__objc_runtime_mutex);
__objc_install_dispatch_table_for_class (class);
objc_mutex_unlock(__objc_runtime_mutex);
/* Call ourselves with the installed dispatch table
and get the real method */
res = get_imp(class, sel);
}
else
{
/* The dispatch table has been installed so the
method just doesn't exist for the class.
Return the forwarding implementation. */
res = __objc_get_forward_imp(sel);
}
}
return res;
}
/* Query if an object can respond to a selector, returns YES if the
object implements the selector otherwise NO. Does not check if the
method can be forwarded. */
__inline__
BOOL
__objc_responds_to (id object, SEL sel)
{
void* res;
/* Install dispatch table if need be */
if (object->class_pointer->dtable == __objc_uninstalled_dtable)
{
objc_mutex_lock(__objc_runtime_mutex);
__objc_install_dispatch_table_for_class (object->class_pointer);
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Get the method from the dispatch table */
res = sarray_get_safe (object->class_pointer->dtable, (size_t) sel->sel_id);
return (res != 0);
}
/* This is the lookup function. All entries in the table are either a
valid method *or* zero. If zero then either the dispatch table
needs to be installed or it doesn't exist and forwarding is attempted. */
__inline__
IMP
objc_msg_lookup(id receiver, SEL op)
{
IMP result;
if(receiver)
{
result = sarray_get_safe (receiver->class_pointer->dtable,
(sidx)op->sel_id);
if (result == 0)
{
/* Not a valid method */
if(receiver->class_pointer->dtable == __objc_uninstalled_dtable)
{
/* The dispatch table needs to be installed.
This happens on the very first method call to the class. */
__objc_init_install_dtable(receiver, op);
/* Get real method for this in newly installed dtable */
result = get_imp(receiver->class_pointer, op);
}
else
{
/* The dispatch table has been installed so the
method just doesn't exist for the class.
Attempt to forward the method. */
result = __objc_get_forward_imp(op);
}
}
return result;
}
else
return nil_method;
}
IMP
objc_msg_lookup_super (Super_t super, SEL sel)
{
if (super->self)
return get_imp (super->class, sel);
else
return nil_method;
}
int method_get_sizeof_arguments (Method*);
retval_t
objc_msg_sendv(id object, SEL op, arglist_t arg_frame)
{
Method* m = class_get_instance_method(object->class_pointer, op);
const char *type;
*((id*)method_get_first_argument (m, arg_frame, &type)) = object;
*((SEL*)method_get_next_argument (arg_frame, &type)) = op;
return __builtin_apply((apply_t)m->method_imp,
arg_frame,
method_get_sizeof_arguments (m));
}
void
__objc_init_dispatch_tables()
{
__objc_uninstalled_dtable
= sarray_new(200, 0);
}
/* This function is called by objc_msg_lookup when the
dispatch table needs to be installed; thus it is called once
for each class, namely when the very first message is sent to it. */
static void
__objc_init_install_dtable(id receiver, SEL op)
{
/* This may happen, if the programmer has taken the address of a
method before the dtable was initialized... too bad for him! */
if(receiver->class_pointer->dtable != __objc_uninstalled_dtable)
return;
objc_mutex_lock(__objc_runtime_mutex);
if(CLS_ISCLASS(receiver->class_pointer))
{
/* receiver is an ordinary object */
assert(CLS_ISCLASS(receiver->class_pointer));
/* install instance methods table */
__objc_install_dispatch_table_for_class (receiver->class_pointer);
/* call +initialize -- this will in turn install the factory
dispatch table if not already done :-) */
__objc_send_initialize(receiver->class_pointer);
}
else
{
/* receiver is a class object */
assert(CLS_ISCLASS((Class)receiver));
assert(CLS_ISMETA(receiver->class_pointer));
/* Install real dtable for factory methods */
__objc_install_dispatch_table_for_class (receiver->class_pointer);
if (strcmp (sel_get_name (op), "initialize"))
__objc_send_initialize((Class)receiver);
else
CLS_SETINITIALIZED((Class)receiver);
}
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Install dummy table for class which causes the first message to
that class (or instances hereof) to be initialized properly */
void
__objc_install_premature_dtable(Class class)
{
assert(__objc_uninstalled_dtable);
class->dtable = __objc_uninstalled_dtable;
}
/* Send +initialize to class if not already done */
static void
__objc_send_initialize(Class class)
{
/* This *must* be a class object */
assert(CLS_ISCLASS(class));
assert(!CLS_ISMETA(class));
if (!CLS_ISINITIALIZED(class))
{
CLS_SETINITIALIZED(class);
CLS_SETINITIALIZED(class->class_pointer);
if(class->super_class)
__objc_send_initialize(class->super_class);
{
SEL op = sel_register_name ("initialize");
Class tmpclass = class;
IMP imp = 0;
while (!imp && tmpclass) {
MethodList_t method_list = tmpclass->class_pointer->methods;
while(!imp && method_list) {
int i;
Method_t method;
for (i=0;i<method_list->method_count;i++) {
method = &(method_list->method_list[i]);
if (method->method_name
&& method->method_name->sel_id == op->sel_id) {
imp = method->method_imp;
break;
}
}
method_list = method_list->method_next;
}
tmpclass = tmpclass->super_class;
}
if (imp)
(*imp)((id)class, op);
}
}
}
/* Walk on the methods list of class and install the methods in the reverse
order of the lists. Since methods added by categories are before the methods
of class in the methods list, this allows categories to substitute methods
declared in class. However if more than one category replaces the same
method nothing is guaranteed about what method will be used.
Assumes that __objc_runtime_mutex is locked down. */
static void
__objc_install_methods_in_dtable (Class class, MethodList_t method_list)
{
int i;
if (!method_list)
return;
if (method_list->method_next)
__objc_install_methods_in_dtable (class, method_list->method_next);
for (i = 0; i < method_list->method_count; i++)
{
Method_t method = &(method_list->method_list[i]);
sarray_at_put_safe (class->dtable,
(sidx) method->method_name->sel_id,
method->method_imp);
}
}
/* Assumes that __objc_runtime_mutex is locked down. */
static void
__objc_install_dispatch_table_for_class (Class class)
{
Class super;
/* If the class has not yet had its class links resolved, we must
re-compute all class links */
if(!CLS_ISRESOLV(class))
__objc_resolve_class_links();
super = class->super_class;
if (super != 0 && (super->dtable == __objc_uninstalled_dtable))
__objc_install_dispatch_table_for_class (super);
/* Allocate dtable if necessary */
if (super == 0)
{
objc_mutex_lock(__objc_runtime_mutex);
class->dtable = sarray_new (__objc_selector_max_index, 0);
objc_mutex_unlock(__objc_runtime_mutex);
}
else
class->dtable = sarray_lazy_copy (super->dtable);
__objc_install_methods_in_dtable (class, class->methods);
}
void
__objc_update_dispatch_table_for_class (Class class)
{
Class next;
struct sarray *arr;
/* not yet installed -- skip it */
if (class->dtable == __objc_uninstalled_dtable)
return;
objc_mutex_lock(__objc_runtime_mutex);
arr = class->dtable;
__objc_install_premature_dtable (class); /* someone might require it... */
sarray_free (arr); /* release memory */
/* could have been lazy... */
__objc_install_dispatch_table_for_class (class);
if (class->subclass_list) /* Traverse subclasses */
for (next = class->subclass_list; next; next = next->sibling_class)
__objc_update_dispatch_table_for_class (next);
objc_mutex_unlock(__objc_runtime_mutex);
}
/* This function adds a method list to a class. This function is
typically called by another function specific to the run-time. As
such this function does not worry about thread safe issues.
This one is only called for categories. Class objects have their
methods installed right away, and their selectors are made into
SEL's by the function __objc_register_selectors_from_class. */
void
class_add_method_list (Class class, MethodList_t list)
{
int i;
/* Passing of a linked list is not allowed. Do multiple calls. */
assert (!list->method_next);
/* Check for duplicates. */
for (i = 0; i < list->method_count; ++i)
{
Method_t method = &list->method_list[i];
if (method->method_name) /* Sometimes these are NULL */
{
/* This is where selector names are transmogrified to SEL's */
method->method_name =
sel_register_typed_name ((const char*)method->method_name,
method->method_types);
}
}
/* Add the methods to the class's method list. */
list->method_next = class->methods;
class->methods = list;
/* Update the dispatch table of class */
__objc_update_dispatch_table_for_class (class);
}
Method_t
class_get_instance_method(Class class, SEL op)
{
return search_for_method_in_hierarchy(class, op);
}
Method_t
class_get_class_method(MetaClass class, SEL op)
{
return search_for_method_in_hierarchy(class, op);
}
/* Search for a method starting from the current class up its hierarchy.
Return a pointer to the method's method structure if found. NULL
otherwise. */
static Method_t
search_for_method_in_hierarchy (Class cls, SEL sel)
{
Method_t method = NULL;
Class class;
if (! sel_is_mapped (sel))
return NULL;
/* Scan the method list of the class. If the method isn't found in the
list then step to its super class. */
for (class = cls; ((! method) && class); class = class->super_class)
method = search_for_method_in_list (class->methods, sel);
return method;
}
/* Given a linked list of method and a method's name. Search for the named
method's method structure. Return a pointer to the method's method
structure if found. NULL otherwise. */
Method_t
search_for_method_in_list (MethodList_t list, SEL op)
{
MethodList_t method_list = list;
if (! sel_is_mapped (op))
return NULL;
/* If not found then we'll search the list. */
while (method_list)
{
int i;
/* Search the method list. */
for (i = 0; i < method_list->method_count; ++i)
{
Method_t method = &method_list->method_list[i];
if (method->method_name)
if (method->method_name->sel_id == op->sel_id)
return method;
}
/* The method wasn't found. Follow the link to the next list of
methods. */
method_list = method_list->method_next;
}
return NULL;
}
static retval_t __objc_forward (id object, SEL sel, arglist_t args);
/* Forwarding pointers/integers through the normal registers */
static id
__objc_word_forward (id rcv, SEL op, ...)
{
void *args, *res;
args = __builtin_apply_args ();
res = __objc_forward (rcv, op, args);
if (res)
__builtin_return (res);
else
return res;
}
/* Specific routine for forwarding floats/double because of
architectural differences on some processors. i386s for
example which uses a floating point stack versus general
registers for floating point numbers. This forward routine
makes sure that GCC restores the proper return values */
static double
__objc_double_forward (id rcv, SEL op, ...)
{
void *args, *res;
args = __builtin_apply_args ();
res = __objc_forward (rcv, op, args);
__builtin_return (res);
}
#if INVISIBLE_STRUCT_RETURN
static __big
#else
static id
#endif
__objc_block_forward (id rcv, SEL op, ...)
{
void *args, *res;
args = __builtin_apply_args ();
res = __objc_forward (rcv, op, args);
if (res)
__builtin_return (res);
else
#if INVISIBLE_STRUCT_RETURN
return (__big) {{0, 0, 0, 0, 0, 0, 0, 0}};
#else
return nil;
#endif
}
/* This function is installed in the dispatch table for all methods which are
not implemented. Thus, it is called when a selector is not recognized. */
static retval_t
__objc_forward (id object, SEL sel, arglist_t args)
{
IMP imp;
static SEL frwd_sel = 0; /* !T:SAFE2 */
SEL err_sel;
/* first try if the object understands forward:: */
if (!frwd_sel)
frwd_sel = sel_get_any_uid("forward::");
if (__objc_responds_to (object, frwd_sel))
{
imp = get_imp(object->class_pointer, frwd_sel);
return (*imp)(object, frwd_sel, sel, args);
}
/* If the object recognizes the doesNotRecognize: method then we're going
to send it. */
err_sel = sel_get_any_uid ("doesNotRecognize:");
if (__objc_responds_to (object, err_sel))
{
imp = get_imp (object->class_pointer, err_sel);
return (*imp) (object, err_sel, sel);
}
/* The object doesn't recognize the method. Check for responding to
error:. If it does then sent it. */
{
size_t strlen (const char*);
char msg[256 + strlen ((const char*)sel_get_name (sel))
+ strlen ((const char*)object->class_pointer->name)];
sprintf (msg, "(%s) %s does not recognize %s",
(CLS_ISMETA(object->class_pointer)
? "class"
: "instance" ),
object->class_pointer->name, sel_get_name (sel));
err_sel = sel_get_any_uid ("error:");
if (__objc_responds_to (object, err_sel))
{
imp = get_imp (object->class_pointer, err_sel);
return (*imp) (object, sel_get_any_uid ("error:"), msg);
}
/* The object doesn't respond to doesNotRecognize: or error:; Therefore,
a default action is taken. */
objc_error (object, OBJC_ERR_UNIMPLEMENTED, "%s\n", msg);
return 0;
}
}
void
__objc_print_dtable_stats()
{
int total = 0;
objc_mutex_lock(__objc_runtime_mutex);
printf("memory usage: (%s)\n",
#ifdef OBJC_SPARSE2
"2-level sparse arrays"
#else
"3-level sparse arrays"
#endif
);
printf("arrays: %d = %ld bytes\n", narrays,
(long)narrays*sizeof(struct sarray));
total += narrays*sizeof(struct sarray);
printf("buckets: %d = %ld bytes\n", nbuckets,
(long)nbuckets*sizeof(struct sbucket));
total += nbuckets*sizeof(struct sbucket);
printf("idxtables: %d = %ld bytes\n", idxsize, (long)idxsize*sizeof(void*));
total += idxsize*sizeof(void*);
printf("-----------------------------------\n");
printf("total: %d bytes\n", total);
printf("===================================\n");
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Returns the uninstalled dispatch table indicator.
If a class' dispatch table points to __objc_uninstalled_dtable
then that means it needs its dispatch table to be installed. */
__inline__
struct sarray*
objc_get_uninstalled_dtable()
{
return __objc_uninstalled_dtable;
}