diff options
| author | svn2git <svn2git@FreeBSD.org> | 1993-11-01 08:00:00 +0000 |
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1993-11-01 08:00:00 +0000 |
| commit | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (patch) | |
| tree | c5b2ce776438e0a52b492a2ab6ab41360b8ba1f6 /gnu/gcc2/cc | |
Release FreeBSD 1.0upstream/1.0.0_cvsrelease/1.0.0_cvs
This commit was manufactured to restore the state of the 1.0-RELEASE image.
Releases prior to 5.3-RELEASE are omitting the secure/ and crypto/ subdirs.
Diffstat (limited to 'gnu/gcc2/cc')
| -rw-r--r-- | gnu/gcc2/cc/Makefile | 16 | ||||
| -rw-r--r-- | gnu/gcc2/cc/g++.1 | 635 | ||||
| -rw-r--r-- | gnu/gcc2/cc/g++.script | 111 | ||||
| -rw-r--r-- | gnu/gcc2/cc/gcc.1 | 4222 | ||||
| -rw-r--r-- | gnu/gcc2/cc/gcc.c | 4242 |
5 files changed, 9226 insertions, 0 deletions
diff --git a/gnu/gcc2/cc/Makefile b/gnu/gcc2/cc/Makefile new file mode 100644 index 000000000000..d5c31592a183 --- /dev/null +++ b/gnu/gcc2/cc/Makefile @@ -0,0 +1,16 @@ +# @(#)Makefile 6.2 (Berkeley) 3/25/91 + +PROG= gcc +SRCS= gcc.c version.c obstack.c +MAN1= gcc.1 g++.1 +BINDIR= /usr/bin +CFLAGS+= -I$(.CURDIR) -I$(.CURDIR)/../lib +.PATH: $(.CURDIR)/../lib + +afterinstall: + install -c -o $(BINOWN) -g $(BINGRP) -m $(BINMODE) \ + $(.CURDIR)/g++.script $(DESTDIR)/usr/bin/g++ + rm -f $(DESTDIR)$(BINDIR)/cc + cd $(DESTDIR)$(BINDIR); ln -s gcc cc + +.include <bsd.prog.mk> diff --git a/gnu/gcc2/cc/g++.1 b/gnu/gcc2/cc/g++.1 new file mode 100644 index 000000000000..38d4410f8000 --- /dev/null +++ b/gnu/gcc2/cc/g++.1 @@ -0,0 +1,635 @@ +.\" Copyright (c) 1991, 1992 Free Software Foundation -*-Text-*- +.\" See section COPYING for conditions for redistribution +.\" FIXME: no info here on predefines. Should there be? extra for C++... +.TH G++ 1 "30apr1993" "GNU Tools" "GNU Tools" +.de BP +.sp +.ti \-.2i +\(** +.. +.SH NAME +g++ \- GNU project C++ Compiler (v2.4) +.SH SYNOPSIS +.RB g++ " [" \c +.IR option " | " filename " ].\|.\|. +.SH DESCRIPTION +The C and C++ compilers are integrated; +.B g++ +is a script to call +.B gcc with options to recognize C++. +.B gcc +processes input files +through one or more of four stages: preprocessing, compilation, +assembly, and linking. This man page contains full descriptions for +.I only +C++ specific aspects of the compiler, though it also contains +summaries of some general-purpose options. For a fuller explanation +of the compiler, see +.BR gcc ( 1 ). + +C++ source files use one of the suffixes `\|\c +.B .C\c +\&\|', `\|\c +.B .cc\c +\&\|', or `\|\c +.B .cxx\c +\&\|'; preprocessed C++ files use the suffix `\|\c +.B .ii\c +\&\|'. +.SH OPTIONS +There are many command-line options, including options to control +details of optimization, warnings, and code generation, which are +common to both +.B gcc +and +.B g++\c +\&. For full information on all options, see +.BR gcc ( 1 ). + +Options must be separate: `\|\c +.B \-dr\c +\&\|' is quite different from `\|\c +.B \-d \-r +\&\|'. + +Most `\|\c +.B \-f\c +\&\|' and `\|\c +.B \-W\c +\&\|' options have two contrary forms: +.BI \-f name +and +.BI \-fno\- name\c +\& (or +.BI \-W name +and +.BI \-Wno\- name\c +\&). Only the non-default forms are shown here. + +.TP +.B \-c +Compile or assemble the source files, but do not link. The compiler +output is an object file corresponding to each source file. +.TP +.BI \-D macro +Define macro \c +.I macro\c +\& with the string `\|\c +.B 1\c +\&\|' as its definition. +.TP +.BI \-D macro = defn +Define macro \c +.I macro\c +\& as \c +.I defn\c +\&. +.TP +.B \-E +Stop after the preprocessing stage; do not run the compiler proper. The +output is preprocessed source code, which is sent to the +standard output. +.TP +.B \-fall\-virtual +Treat all possible member functions as virtual, implicitly. All +member functions (except for constructor functions and +.B new +or +.B delete +member operators) are treated as virtual functions of the class where +they appear. + +This does not mean that all calls to these member functions will be +made through the internal table of virtual functions. Under some +circumstances, the compiler can determine that a call to a given +virtual function can be made directly; in these cases the calls are +direct in any case. +.TP +.B \-fdollars\-in\-identifiers +Permit the use of `\|\c +.B $\c +\&\|' in identifiers. +Traditional C allowed the character `\|\c +.B $\c +\&\|' to form part of identifiers; by default, GNU C also +allows this. However, ANSI C forbids `\|\c +.B $\c +\&\|' in identifiers, and GNU C++ also forbids it by default on most +platforms (though on some platforms it's enabled by default for GNU +C++ as well). +.TP +.B \-felide\-constructors +Use this option to instruct the compiler to be smarter about when it can +elide constructors. Without this flag, GNU C++ and cfront both +generate effectively the same code for: +.sp +.br +A\ foo\ (); +.br +A\ x\ (foo\ ());\ \ \ //\ x\ initialized\ by\ `foo\ ()',\ no\ ctor\ called +.br +A\ y\ =\ foo\ ();\ \ \ //\ call\ to\ `foo\ ()'\ heads\ to\ temporary, +.br +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ y\ is\ initialized\ from\ the\ temporary. +.br +.sp +Note the difference! With this flag, GNU C++ initializes `\|\c +.B y\c +\&\|' directly +from the call to +.B foo () +without going through a temporary. +.TP +.B \-fenum\-int\-equiv +Normally GNU C++ allows conversion of +.B enum +to +.B int\c +\&, but not the other way around. Use this option if you want GNU C++ +to allow conversion of +.B int +to +.B enum +as well. +.TP +.B \-fno\-gnu\-linker +Do not output global initializations (such as C++ constructors and +destructors) in the form used by the GNU linker (on systems where the GNU +linker is the standard method of handling them). Use this option when +you want to use a non-GNU linker, which also requires using the +.B collect2 +program to make sure the system linker includes +constructors and destructors. (\c +.B collect2 +is included in the GNU CC distribution.) For systems which +.I must +use +.B collect2\c +\&, the compiler driver +.B gcc +is configured to do this automatically. +.TP +.B \-fmemoize\-lookups +.TP +.B \-fsave\-memoized +These flags are used to get the compiler to compile programs faster +using heuristics. They are not on by default since they are only effective +about half the time. The other half of the time programs compile more +slowly (and take more memory). + +The first time the compiler must build a call to a member function (or +reference to a data member), it must (1) determine whether the class +implements member functions of that name; (2) resolve which member +function to call (which involves figuring out what sorts of type +conversions need to be made); and (3) check the visibility of the member +function to the caller. All of this adds up to slower compilation. +Normally, the second time a call is made to that member function (or +reference to that data member), it must go through the same lengthy +process again. This means that code like this +.sp +.br +\ \ cout\ <<\ "This\ "\ <<\ p\ <<\ "\ has\ "\ <<\ n\ <<\ "\ legs.\en"; +.br +.sp +makes six passes through all three steps. By using a software cache, +a ``hit'' significantly reduces this cost. Unfortunately, using the +cache introduces another layer of mechanisms which must be implemented, +and so incurs its own overhead. `\|\c +.B \-fmemoize\-lookups\c +\&\|' enables +the software cache. + +Because access privileges (visibility) to members and member functions +may differ from one function context to the next, +.B g++ +may need to flush the cache. With the `\|\c +.B \-fmemoize\-lookups\c +\&\|' flag, the cache is flushed after every +function that is compiled. The `\|\c +\-fsave\-memoized\c +\&\|' flag enables the same software cache, but when the compiler +determines that the context of the last function compiled would yield +the same access privileges of the next function to compile, it +preserves the cache. +This is most helpful when defining many member functions for the same +class: with the exception of member functions which are friends of +other classes, each member function has exactly the same access +privileges as every other, and the cache need not be flushed. +.TP +.B \-fno\-default\-inline +Do not make member functions inline by default merely because they are +defined inside the class scope. Otherwise, when you specify +.B \-O\c +\&, member functions defined inside class scope are compiled +inline by default; i.e., you don't need to add `\|\c +.B inline\c +\&\|' in front of +the member function name. +.TP +.B \-fno\-strict\-prototype +Consider the declaration \c +.B int foo ();\c +\&. In C++, this means that the +function \c +.B foo\c +\& takes no arguments. In ANSI C, this is declared +.B int foo(void);\c +\&. With the flag `\|\c +.B \-fno\-strict\-prototype\c +\&\|', +declaring functions with no arguments is equivalent to declaring its +argument list to be untyped, i.e., \c +.B int foo ();\c +\& is equivalent to +saying \c +.B int foo (...);\c +\&. +.TP +.B \-fnonnull\-objects +Normally, GNU C++ makes conservative assumptions about objects reached +through references. For example, the compiler must check that `\|\c +.B a\c +\&\|' is not null in code like the following: +.br +\ \ \ \ obj\ &a\ =\ g\ (); +.br +\ \ \ \ a.f\ (2); +.br +Checking that references of this sort have non-null values requires +extra code, however, and it is unnecessary for many programs. You can +use `\|\c +.B \-fnonnull\-objects\c +\&\|' to omit the checks for null, if your program doesn't require the +default checking. +.TP +.B \-fthis\-is\-variable +The incorporation of user-defined free store management into C++ has +made assignment to \c +.B this\c +\& an anachronism. Therefore, by default GNU +C++ treats the type of \c +.B this\c +\& in a member function of \c +.B class X\c +\& +to be \c +.B X *const\c +\&. In other words, it is illegal to assign to +\c +.B this\c +\& within a class member function. However, for backwards +compatibility, you can invoke the old behavior by using +\&`\|\c +.B \-fthis\-is\-variable\c +\&\|'. +.TP +.B \-g +Produce debugging information in the operating system's native format +(for DBX or SDB or DWARF). GDB also can work with this debugging +information. On most systems that use DBX format, `\|\c +.B \-g\c +\&\|' enables use +of extra debugging information that only GDB can use. + +Unlike most other C compilers, GNU CC allows you to use `\|\c +.B \-g\c +\&\|' with +`\|\c +.B \-O\c +\&\|'. The shortcuts taken by optimized code may occasionally +produce surprising results: some variables you declared may not exist +at all; flow of control may briefly move where you did not expect it; +some statements may not be executed because they compute constant +results or their values were already at hand; some statements may +execute in different places because they were moved out of loops. + +Nevertheless it proves possible to debug optimized output. This makes +it reasonable to use the optimizer for programs that might have bugs. +.TP +.BI "\-I" "dir"\c +\& +Append directory \c +.I dir\c +\& to the list of directories searched for include files. +.TP +.BI "\-L" "dir"\c +\& +Add directory \c +.I dir\c +\& to the list of directories to be searched +for `\|\c +.B \-l\c +\&\|'. +.TP +.BI \-l library\c +\& +Use the library named \c +.I library\c +\& when linking. (C++ programs often require `\|\c +\-lg++\c +\&\|' for successful linking.) +.TP +.B \-nostdinc +Do not search the standard system directories for header files. Only +the directories you have specified with +.B \-I +options (and the current directory, if appropriate) are searched. +.TP +.B \-nostdinc++ +Do not search for header files in the standard directories specific to +C++, but do still search the other standard directories. (This option +is used when building libg++.) +.TP +.B \-O +Optimize. Optimizing compilation takes somewhat more time, and a lot +more memory for a large function. +.TP +.BI "\-o " file\c +\& +Place output in file \c +.I file\c +\&. +.TP +.B \-S +Stop after the stage of compilation proper; do not assemble. The output +is an assembler code file for each non-assembler input +file specified. +.TP +.B \-traditional +Attempt to support some aspects of traditional C compilers. + +Specifically, for both C and C++ programs: +.TP +\ \ \ \(bu +In the preprocessor, comments convert to nothing at all, rather than +to a space. This allows traditional token concatenation. +.TP +\ \ \ \(bu +In the preprocessor, macro arguments are recognized within string +constants in a macro definition (and their values are stringified, +though without additional quote marks, when they appear in such a +context). The preprocessor always considers a string constant to end +at a newline. +.TP +\ \ \ \(bu +The preprocessor does not predefine the macro \c +.B __STDC__\c +\& when you use +`\|\c +.B \-traditional\c +\&\|', but still predefines\c +.B __GNUC__\c +\& (since the GNU extensions indicated by +.B __GNUC__\c +\& are not affected by +`\|\c +.B \-traditional\c +\&\|'). If you need to write header files that work +differently depending on whether `\|\c +.B \-traditional\c +\&\|' is in use, by +testing both of these predefined macros you can distinguish four +situations: GNU C, traditional GNU C, other ANSI C compilers, and +other old C compilers. +.TP +\ \ \ \(bu +In the preprocessor, comments convert to nothing at all, rather than +to a space. This allows traditional token concatenation. +.TP +\ \ \ \(bu +In the preprocessor, macro arguments are recognized within string +constants in a macro definition (and their values are stringified, +though without additional quote marks, when they appear in such a +context). The preprocessor always considers a string constant to end +at a newline. +.TP +\ \ \ \(bu +The preprocessor does not predefine the macro \c +.B __STDC__\c +\& when you use +`\|\c +.B \-traditional\c +\&\|', but still predefines\c +.B __GNUC__\c +\& (since the GNU extensions indicated by +.B __GNUC__\c +\& are not affected by +`\|\c +.B \-traditional\c +\&\|'). If you need to write header files that work +differently depending on whether `\|\c +.B \-traditional\c +\&\|' is in use, by +testing both of these predefined macros you can distinguish four +situations: GNU C, traditional GNU C, other ANSI C compilers, and +other old C compilers. +.PP +.TP +\ \ \ \(bu +String ``constants'' are not necessarily constant; they are stored in +writable space, and identical looking constants are allocated +separately. + +For C++ programs only (not C), `\|\c +.B \-traditional\c +\&\|' has one additional effect: assignment to +.B this +is permitted. This is the same as the effect of `\|\c +.B \-fthis\-is\-variable\c +\&\|'. +.TP +.BI \-U macro +Undefine macro \c +.I macro\c +\&. +.TP +.B \-Wall +Issue warnings for conditions which pertain to usage that we recommend +avoiding and that we believe is easy to avoid, even in conjunction +with macros. +.TP +.B \-Wenum\-clash +Warn when converting between different enumeration types. +.TP +.B \-Woverloaded\-virtual +In a derived class, the definitions of virtual functions must match +the type signature of a virtual function declared in the base class. +Use this option to request warnings when a derived class declares a +function that may be an erroneous attempt to define a virtual +function: that is, warn when a function with the same name as a +virtual function in the base class, but with a type signature that +doesn't match any virtual functions from the base class. +.TP +.B \-Wtemplate\-debugging +When using templates in a C++ program, warn if debugging is not yet +fully available. +.TP +.B \-w +Inhibit all warning messages. +.TP +.BI +e N +Control how virtual function definitions are used, in a fashion +compatible with +.B cfront +1.x. +.PP + +.SH PRAGMAS +Two `\|\c +.B #pragma\c +\&\|' directives are supported for GNU C++, to permit using the same +header file for two purposes: as a definition of interfaces to a given +object class, and as the full definition of the contents of that object class. +.TP +.B #pragma interface +Use this directive in header files that define object classes, to save +space in most of the object files that use those classes. Normally, +local copies of certain information (backup copies of inline member +functions, debugging information, and the internal tables that +implement virtual functions) must be kept in each object file that +includes class definitions. You can use this pragma to avoid such +duplication. When a header file containing `\|\c +.B #pragma interface\c +\&\|' is included in a compilation, this auxiliary information +will not be generated (unless the main input source file itself uses +`\|\c +.B #pragma implementation\c +\&\|'). Instead, the object files will contain references to be +resolved at link time. +.tr !" +.TP +.B #pragma implementation +.TP +.BI "#pragma implementation !" objects .h! +Use this pragma in a main input file, when you want full output from +included header files to be generated (and made globally visible). +The included header file, in turn, should use `\|\c +.B #pragma interface\c +\&\|'. +Backup copies of inline member functions, debugging information, and +the internal tables used to implement virtual functions are all +generated in implementation files. + +If you use `\|\c +.B #pragma implementation\c +\&\|' with no argument, it applies to an include file with the same +basename as your source file; for example, in `\|\c +.B allclass.cc\c +\&\|', `\|\c +.B #pragma implementation\c +\&\|' by itself is equivalent to `\|\c +.B +#pragma implementation "allclass.h"\c +\&\|'. Use the string argument if you want a single implementation +file to include code from multiple header files. + +There is no way to split up the contents of a single header file into +multiple implementation files. +.SH FILES +.ta \w'LIBDIR/g++\-include 'u +file.h C header (preprocessor) file +.br +file.i preprocessed C source file +.br +file.C C++ source file +.br +file.cc C++ source file +.br +file.cxx C++ source file +.br +file.s assembly language file +.br +file.o object file +.br +a.out link edited output +.br +\fITMPDIR\fR/cc\(** temporary files +.br +\fILIBDIR\fR/cpp preprocessor +.br +\fILIBDIR\fR/cc1plus compiler +.br +\fILIBDIR\fR/collect linker front end needed on some machines +.br +\fILIBDIR\fR/libgcc.a GCC subroutine library +.br +/lib/crt[01n].o start-up routine +.br +\fILIBDIR\fR/ccrt0 additional start-up routine for C++ +.br +/lib/libc.a standard C library, see +.IR intro (3) +.br +/usr/include standard directory for +.B #include +files +.br +\fILIBDIR\fR/include standard gcc directory for +.B #include +files +.br +\fILIBDIR\fR/g++\-include additional g++ directory for +.B #include +.sp +.I LIBDIR +is usually +.B /usr/local/lib/\c +.IR machine / version . +.br +.I TMPDIR +comes from the environment variable +.B TMPDIR +(default +.B /usr/tmp +if available, else +.B /tmp\c +\&). +.SH "SEE ALSO" +gcc(1), cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). +.br +.RB "`\|" gcc "\|', `\|" cpp \|', +.RB `\| as \|', `\| ld \|', +and +.RB `\| gdb \|' +entries in +.B info\c +\&. +.br +.I +Using and Porting GNU CC (for version 2.0)\c +, Richard M. Stallman; +.I +The C Preprocessor\c +, Richard M. Stallman; +.I +Debugging with GDB: the GNU Source-Level Debugger\c +, Richard M. Stallman and Roland H. Pesch; +.I +Using as: the GNU Assembler\c +, Dean Elsner, Jay Fenlason & friends; +.I +gld: the GNU linker\c +, Steve Chamberlain and Roland Pesch. + +.SH BUGS +For instructions on how to report bugs, see the GCC manual. + +.SH COPYING +Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc. +.PP +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. +.PP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.PP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.SH AUTHORS +See the GNU CC Manual for the contributors to GNU CC. diff --git a/gnu/gcc2/cc/g++.script b/gnu/gcc2/cc/g++.script new file mode 100644 index 000000000000..d633e1c459ad --- /dev/null +++ b/gnu/gcc2/cc/g++.script @@ -0,0 +1,111 @@ +#!/bin/sh +# Compile programs, treating .c files as C++. +: || exec /bin/sh -f $0 $argv:q + +# The compiler name might be different when doing cross-compilation +# (this should be configured) +gcc_name=gcc +speclang=-xnone + +# replace the command name by the name of the new command +progname=`basename $0` +case "$0" in + */*) + gcc=`echo $0 | sed -e "s;/[^/]*$;;"`/$gcc_name + ;; + *) + gcc=$gcc_name + ;; +esac + +# $first is yes for first arg, no afterwards. +first=yes +# If next arg is the argument of an option, $quote is non-empty. +# More precisely, it is the option that wants an argument. +quote= +# $library is made empty to disable use of libg++. +library=-lg++ +numargs=$# + +# ash requires the newline before `do'. +for arg +do + if [ $first = yes ] + then + # Need some 1st arg to `set' which does not begin with `-'. + # We get rid of it after the loop ends. + set gcc + first=no + fi + # If you have to ask what this does, you should not edit this file. :-) + # The ``S'' at the start is so that echo -nostdinc does not eat the + # -nostdinc. + arg=`echo "S$arg" | sed "s/^S//; s/'/'\\\\\\\\''/g"` + if [ x$quote != x ] + then + quote= + else + quote= + case $arg in + -nostdlib) + # Inhibit linking with -lg++. + library= + ;; + -lm | -lmath) + # Because libg++ uses things from the math library, make sure it + # always comes before the math library. We recognize both -lm + # and -lmath, since on some systems (e.g. m88k SVR3), it + # doesn't call it libm.a for some reason. + set "$@" $library + library="" + ;; + -[bBVDUoeTuIYmLiA] | -Tdata) + # these switches take following word as argument, + # so don't treat it as a file name. + quote=$arg + ;; + -[cSEM] | -MM) + # Don't specify libraries if we won't link, + # since that would cause a warning. + library= + ;; + -x*) + speclang=$arg + ;; + -v) + # catch `g++ -v' + if [ $numargs = 1 ] ; then library="" ; fi + ;; + -*) + # Pass other options through; they don't need -x and aren't inputs. + ;; + *) + # If file ends in .c or .i, put options around it. + # But not if a specified -x option is currently active. + case "$speclang $arg" in -xnone\ *.[ci]) + set "$@" -xc++ "'$arg'" -xnone + continue + esac + ;; + esac + fi + set "$@" "'$arg'" +done + +# Get rid of that initial 1st arg +if [ $first = no ]; then + shift +else + echo "$0: No input files specified." + exit 1 +fi + +if [ x$quote != x ] +then + echo "$0: argument to \`$quote' missing" + exit 1 +fi + +eval $gcc "$@" $library + + diff --git a/gnu/gcc2/cc/gcc.1 b/gnu/gcc2/cc/gcc.1 new file mode 100644 index 000000000000..07755f17073b --- /dev/null +++ b/gnu/gcc2/cc/gcc.1 @@ -0,0 +1,4222 @@ +.\" Copyright (c) 1991, 1992, 1993 Free Software Foundation -*-Text-*- +.\" See section COPYING for conditions for redistribution +.TH GCC 1 "30apr1993" "GNU Tools" "GNU Tools" +.de BP +.sp +.ti \-.2i +\(** +.. +.SH NAME +gcc, g++ \- GNU project C and C++ Compiler (v2.4) +.SH SYNOPSIS +.RB gcc " [" \c +.IR option " | " filename " ].\|.\|. +.br +.RB g++ " [" \c +.IR option " | " filename " ].\|.\|. +.SH WARNING +The information in this man page is an extract from the full +documentation of the GNU C compiler, and is limited to the meaning of +the options. This man page is not kept up to date except when +volunteers want to maintain it. + +For complete and current documentation, refer to the Info file `\|\c +.B gcc\c +\&\|' or the manual +.I +Using and Porting GNU CC (for version 2.0)\c +\&. Both are made from the Texinfo source file +.BR gcc.texinfo . +.SH DESCRIPTION +The C and C++ compilers are integrated. Both process input files +through one or more of four stages: preprocessing, compilation, +assembly, and linking. Source filename suffixes identify the source +language, but which name you use for the compiler governs default +assumptions: +.TP +.B gcc +assumes preprocessed (\c +.B .i\c +\&) files are C and assumes C style linking. +.TP +.B g++ +assumes preprocessed (\c +.B .i\c +\&) files are C++ and assumes C++ style linking. +.PP +Suffixes of source file names indicate the language and kind of +processing to be done: + +.ta \w'.cxx 'u +.B .c\c +\& C source; preprocess, compile, assemble +.br +.B .C\c +\& C++ source; preprocess, compile, assemble +.br +.B .cc\c +\& C++ source; preprocess, compile, assemble +.br +.B .cxx\c +\& C++ source; preprocess, compile, assemble +.br +.B .m\c +\& Objective-C source; preprocess, compile, assemble +.br +.B .i\c +\& preprocessed C; compile, assemble +.br +.B .ii\c +\& preprocessed C++; compile, assemble +.br +.B .s\c +\& Assembler source; assemble +.br +.B .S\c +\& Assembler source; preprocess, assemble +.br +.B .h\c +\& Preprocessor file; not usually named on command line + +.I ??\c +\& Other (unrecognized) files passed to linker. +.br +\& Common cases: +.br +.B .o\c +\& Object file +.br +.B .a\c +\& Archive file + +Linking is always the last stage unless you use one of the +.BR \-c , +.BR \-S , +or +.B \-E +options to avoid it (or unless compilation errors stop the whole +process). For the link stage, all +.B .o +files corresponding to source files, +.B \-l +libraries, unrecognized filenames (including named +.B .o +object files and +.B .a +archives) +are passed to the linker in command-line order. + +.SH OPTIONS +Options must be separate: `\|\c +.B \-dr\c +\&\|' is quite different from `\|\c +.B \-d \-r +\&\|'. + +Most `\|\c +.B \-f\c +\&\|' and `\|\c +.B \-W\c +\&\|' options have two contrary forms: +.BI \-f name +and +.BI \-fno\- name\c +\& (or +.BI \-W name +and +.BI \-Wno\- name\c +\&). Only the non-default forms are shown here. + +Here is a summary of all the options, grouped by type. Explanations are +in the following sections. + +.hy 0 +.na +.TP +.B Overall Options +.br +\-c +\-S +\-E +.RI "\-o " file +\-pipe +\-v +.RI "\-x " language + +.TP +.B Language Options +\-ansi +\-fall\-virtual +\-fcond\-mismatch +\-fdollars\-in\-identifiers +\-fenum\-int\-equiv +\-fno\-asm +\-fno\-builtin +\-fno\-strict\-prototype +\-fsigned\-bitfields +\-fsigned\-char +\-fthis\-is\-variable +\-funsigned\-bitfields +\-funsigned\-char +\-fwritable\-strings +\-traditional +\-traditional\-cpp +\-trigraphs + +.TP +.B Warning Options +\-fsyntax\-only +\-pedantic +\-pedantic\-errors +\-w +\-W +\-Wall +\-Waggregate\-return +\-Wcast\-align +\-Wcast\-qual +\-Wchar\-subscript +\-Wcomment +\-Wconversion +\-Wenum\-clash +\-Werror +\-Wformat +.RI \-Wid\-clash\- len +\-Wimplicit +\-Winline +\-Wmissing\-prototypes +\-Wnested\-externs +\-Wno\-import +\-Wparentheses +\-Wpointer\-arith +\-Wredundant\-decls +\-Wreturn\-type +\-Wshadow +\-Wstrict\-prototypes +\-Wswitch +\-Wtemplate\-debugging +\-Wtraditional +\-Wtrigraphs +\-Wuninitialized +\-Wunused +\-Wwrite\-strings + +.TP +.B Debugging Options +\-a +.RI \-d letters +\-fpretend\-float +\-g +.RI \-g level +\-gcoff +\-gxcoff +\-gxcoff+ +\-gdwarf +\-gdwarf+ +\-gstabs +\-gstabs+ +\-ggdb +\-p +\-pg +\-save\-temps +\-print\-libgcc\-file\-name + +.TP +.B Optimization Options +\-fcaller\-saves +\-fcse\-follow\-jumps +\-fcse\-skip\-blocks +\-fdelayed\-branch +\-felide\-constructors +\-fexpensive\-optimizations +\-ffast-\math +\-ffloat\-store +\-fforce\-addr +\-fforce\-mem +\-finline\-functions +\-fkeep\-inline\-functions +\-fmemoize\-lookups +\-fno\-default\-inline +\-fno\-defer\-pop +\-fno\-function\-cse +\-fno\-inline +\-fno\-peephole +\-fomit\-frame\-pointer +\-frerun\-cse\-after\-loop +\-fschedule\-insns +\-fschedule\-insns2 +\-fstrength\-reduce +\-fthread\-jumps +\-funroll\-all\-loops +\-funroll\-loops +\-O +\-O2 + +.TP +.B Preprocessor Options +.RI \-A assertion +\-C +\-dD +\-dM +\-dN +.RI \-D macro [\|= defn \|] +\-E +\-H +.RI "\-idirafter " dir +.RI "\-include " file +.RI "\-imacros " file +.RI "\-iprefix " file +.RI "\-iwithprefix " dir +\-M +\-MD +\-MM +\-MMD +\-nostdinc +\-P +.RI \-U macro +\-undef + +.TP +.B Assembler Option +.RI \-Wa, option + +.TP +.B Linker Options +.RI \-l library +\-nostartfiles +\-nostdlib +\-static +\-shared +\-symbolic +.RI "\-Xlinker\ " option +.RI \-Wl, option +.RI "\-u " symbol + +.TP +.B Directory Options +.RI \-B prefix +.RI \-I dir +\-I\- +.RI \-L dir + +.TP +.B Target Options +.RI "\-b " machine +.RI "\-V " version + +.TP +.B Configuration Dependent Options +.I M680x0\ Options +.br +\-m68000 +\-m68020 +\-m68020\-40 +\-m68030 +\-m68040 +\-m68881 +\-mbitfield +\-mc68000 +\-mc68020 +\-mfpa +\-mnobitfield +\-mrtd +\-mshort +\-msoft\-float + +.I VAX Options +.br +\-mg +\-mgnu +\-munix + +.I SPARC Options +.br +\-mepilogue +\-mfpu +\-mhard\-float +\-mno\-fpu +\-mno\-epilogue +\-msoft\-float +\-msparclite +\-mv8 + +.I Convex Options +.br +\-margcount +\-mc1 +\-mc2 +\-mnoargcount + +.I AMD29K Options +.br +\-m29000 +\-m29050 +\-mbw +\-mdw +\-mkernel\-registers +\-mlarge +\-mnbw +\-mnodw +\-msmall +\-mstack\-check +\-muser\-registers + +.I M88K Options +.br +\-m88000 +\-m88100 +\-m88110 +\-mbig\-pic +\-mcheck\-zero\-division +\-mhandle\-large\-shift +\-midentify\-revision +\-mno\-check\-zero\-division +\-mno\-ocs\-debug\-info +\-mno\-ocs\-frame\-position +\-mno\-optimize\-arg\-area +\-mno\-seriazlize\-volatile +\-mno\-underscores +\-mocs\-debug\-info +\-mocs\-frame\-position +\-moptimize\-arg\-area +\-mserialize\-volatile +.RI \-mshort\-data\- num +\-msvr3 +\-msvr4 +\-mtrap\-large\-shift +\-muse\-div\-instruction +\-mversion\-03.00 +\-mwarn\-passed\-structs + +.I RS6000 Options +.br +\-mfp\-in\-toc +\-mno\-fop\-in\-toc + +.I RT Options +.br +\-mcall\-lib\-mul +\-mfp\-arg\-in\-fpregs +\-mfp\-arg\-in\-gregs +\-mfull\-fp\-blocks +\-mhc\-struct\-return +\-min\-line\-mul +\-mminimum\-fp\-blocks +\-mnohc\-struct\-return + +.I MIPS Options +.br +\-mcpu=\fIcpu type\fP +\-mips2 +\-mips3 +\-mint64 +\-mlong64 +\-mlonglong128 +\-mmips\-as +\-mgas +\-mrnames +\-mno\-rnames +\-mgpopt +\-mno\-gpopt +\-mstats +\-mno\-stats +\-mmemcpy +\-mno\-memcpy +\-mno\-mips\-tfile +\-mmips\-tfile +\-msoft\-float +\-mhard\-float +\-mabicalls +\-mno\-abicalls +\-mhalf\-pic +\-mno\-half\-pic +\-G \fInum\fP +\-nocpp + +.I i386 Options +.br +\-m486 +\-mno\-486 +\-msoft\-float +\-mno\-fp\-ret\-in\-387 + +.I HPPA Options +.br +\-mpa\-risc\-1\-0 +\-mpa\-risc\-1\-1 +\-mkernel +\-mshared\-libs +\-mno\-shared\-libs +\-mlong\-calls +\-mdisable\-fpregs +\-mdisable\-indexing +\-mtrailing\-colon + +.I i960 Options +.br +\-m\fIcpu-type\fP +\-mnumerics +\-msoft\-float +\-mleaf\-procedures +\-mno\-leaf\-procedures +\-mtail\-call +\-mno\-tail\-call +\-mcomplex\-addr +\-mno\-complex\-addr +\-mcode\-align +\-mno\-code\-align +\-mic\-compat +\-mic2.0\-compat +\-mic3.0\-compat +\-masm\-compat +\-mintel\-asm +\-mstrict\-align +\-mno\-strict\-align +\-mold\-align +\-mno\-old\-align + +.I DEC Alpha Options +.br +\-mfp\-regs +\-mno\-fp\-regs +\-mno\-soft\-float +\-msoft\-float + +.I System V Options +.br +\-G +\-Qy +\-Qn +.RI \-YP, paths +.RI \-Ym, dir + +.TP +.B Code Generation Options +.RI \-fcall\-saved\- reg +.RI \-fcall\-used\- reg +.RI \-ffixed\- reg +\-finhibit\-size\-directive +\-fnonnull\-objects +\-fno\-common +\-fno\-ident +\-fno\-gnu\-linker +\-fpcc\-struct\-return +\-fpic +\-fPIC +\-freg\-struct\-returno +\-fshared\-data +\-fshort\-enums +\-fshort\-double +\-fvolatile +\-fvolatile\-global +\-fverbose\-asm +.ad b +.hy 1 + +.SH OVERALL OPTIONS +.TP +.BI "\-x " "language" +Specify explicitly the +.I language\c +\& for the following input files (rather than choosing a default based +on the file name suffix) . This option applies to all following input +files until the next `\|\c +.B \-x\c +\&\|' option. Possible values of \c +.I language\c +\& are +`\|\c +.B c\c +\&\|', `\|\c +.B objective\-c\c +\&\|', `\|\c +.B c\-header\c +\&\|', `\|\c +.B c++\c +\&\|', +`\|\c +.B cpp\-output\c +\&\|', `\|\c +.B assembler\c +\&\|', and `\|\c +.B assembler\-with\-cpp\c +\&\|'. +.TP +.B \-x none +Turn off any specification of a language, so that subsequent files are +handled according to their file name suffixes (as they are if `\|\c +.B \-x\c +\&\|' +has not been used at all). +.PP + +If you want only some of the four stages (preprocess, compile, +assemble, link), you can use +`\|\c +.B \-x\c +\&\|' (or filename suffixes) to tell \c +.B gcc\c +\& where to start, and +one of the options `\|\c +.B \-c\c +\&\|', `\|\c +.B \-S\c +\&\|', or `\|\c +.B \-E\c +\&\|' to say where +\c +.B gcc\c +\& is to stop. Note that some combinations (for example, +`\|\c +.B \-x cpp\-output \-E\c +\&\|') instruct \c +.B gcc\c +\& to do nothing at all. +.TP +.B \-c +Compile or assemble the source files, but do not link. The compiler +output is an object file corresponding to each source file. + +By default, GCC makes the object file name for a source file by replacing +the suffix `\|\c +.B .c\c +\&\|', `\|\c +.B .i\c +\&\|', `\|\c +.B .s\c +\&\|', etc., with `\|\c +.B .o\c +\&\|'. Use +.B \-o\c +\& to select another name. + +GCC ignores any unrecognized input files (those that do not require +compilation or assembly) with the +.B \-c +option. +.TP +.B \-S +Stop after the stage of compilation proper; do not assemble. The output +is an assembler code file for each non-assembler input +file specified. + +By default, GCC makes the assembler file name for a source file by +replacing the suffix `\|\c +.B .c\c +\&\|', `\|\c +.B .i\c +\&\|', etc., with `\|\c +.B .s\c +\&\|'. Use +.B \-o\c +\& to select another name. + + +GCC ignores any input files that don't require compilation. +.TP +.B \-E +Stop after the preprocessing stage; do not run the compiler proper. The +output is preprocessed source code, which is sent to the +standard output. + +GCC ignores input files which don't require preprocessing. +.TP +.BI "\-o " file\c +\& +Place output in file \c +.I file\c +\&. This applies regardless to whatever +sort of output GCC is producing, whether it be an executable file, +an object file, an assembler file or preprocessed C code. + +Since only one output file can be specified, it does not make sense to +use `\|\c +.B \-o\c +\&\|' when compiling more than one input file, unless you are +producing an executable file as output. + +If you do not specify `\|\c +.B \-o\c +\&\|', the default is to put an executable file +in `\|\c +.B a.out\c +\&\|', the object file for `\|\c +.B \c +.I source\c +\&.\c +.I suffix\c +\&\c +\&\|' in +`\|\c +.B \c +.I source\c +\&.o\c +\&\|', its assembler file in `\|\c +.B \c +.I source\c +\&.s\c +\&\|', and +all preprocessed C source on standard output. +.TP +.B \-v +Print (on standard error output) the commands executed to run the stages +of compilation. Also print the version number of the compiler driver +program and of the preprocessor and the compiler proper. +.TP +.B \-pipe +Use pipes rather than temporary files for communication between the +various stages of compilation. This fails to work on some systems where +the assembler cannot read from a pipe; but the GNU assembler has +no trouble. +.PP + +.SH LANGUAGE OPTIONS +The following options control the dialect of C that the compiler +accepts: +.TP +.B \-ansi +Support all ANSI standard C programs. + +This turns off certain features of GNU C that are incompatible with +ANSI C, such as the \c +.B asm\c +\&, \c +.B inline\c +\& and \c +.B typeof\c +\& +keywords, and predefined macros such as \c +.B unix\c +\& and \c +.B vax\c +\& +that identify the type of system you are using. It also enables the +undesirable and rarely used ANSI trigraph feature, and disallows `\|\c +.B $\c +\&\|' as part of identifiers. + +The alternate keywords \c +.B __asm__\c +\&, \c +.B __extension__\c +\&, +\c +.B __inline__\c +\& and \c +.B __typeof__\c +\& continue to work despite +`\|\c +.B \-ansi\c +\&\|'. You would not want to use them in an ANSI C program, of +course, but it is useful to put them in header files that might be included +in compilations done with `\|\c +.B \-ansi\c +\&\|'. Alternate predefined macros +such as \c +.B __unix__\c +\& and \c +.B __vax__\c +\& are also available, with or +without `\|\c +.B \-ansi\c +\&\|'. + +The `\|\c +.B \-ansi\c +\&\|' option does not cause non-ANSI programs to be +rejected gratuitously. For that, `\|\c +.B \-pedantic\c +\&\|' is required in +addition to `\|\c +.B \-ansi\c +\&\|'. + +The preprocessor predefines a macro \c +.B __STRICT_ANSI__\c +\& when you use the `\|\c +.B \-ansi\c +\&\|' +option. Some header files may notice this macro and refrain +from declaring certain functions or defining certain macros that the +ANSI standard doesn't call for; this is to avoid interfering with any +programs that might use these names for other things. +.TP +.B \-fno\-asm +Do not recognize \c +.B asm\c +\&, \c +.B inline\c +\& or \c +.B typeof\c +\& as a +keyword. These words may then be used as identifiers. You can +use \c +.B __asm__\c +\&, \c +.B __inline__\c +\& and \c +.B __typeof__\c +\& instead. +`\|\c +.B \-ansi\c +\&\|' implies `\|\c +.B \-fno\-asm\c +\&\|'. +.TP +.B \-fno\-builtin +Don't recognize built-in functions that do not begin with two leading +underscores. Currently, the functions affected include \c +.B _exit\c +\&, +\c +.B abort\c +\&, \c +.B abs\c +\&, \c +.B alloca\c +\&, \c +.B cos\c +\&, \c +.B exit\c +\&, +\c +.B fabs\c +\&, \c +.B labs\c +\&, \c +.B memcmp\c +\&, \c +.B memcpy\c +\&, \c +.B sin\c +\&, +\c +.B sqrt\c +\&, \c +.B strcmp\c +\&, \c +.B strcpy\c +\&, and \c +.B strlen\c +\&. + +The `\|\c +.B \-ansi\c +\&\|' option prevents \c +.B alloca\c +\& and \c +.B _exit\c +\& from +being builtin functions. +.TP +.B \-fno\-strict\-prototype +Treat a function declaration with no arguments, such as `\|\c +.B int foo +();\c +\&\|', as C would treat it\(em\&as saying nothing about the number of +arguments or their types (C++ only). Normally, such a declaration in +C++ means that the function \c +.B foo\c +\& takes no arguments. +.TP +.B \-trigraphs +Support ANSI C trigraphs. The `\|\c +.B \-ansi\c +\&\|' option implies `\|\c +.B \-trigraphs\c +\&\|'. +.TP +.B \-traditional +Attempt to support some aspects of traditional C compilers. +For details, see the GNU C Manual; the duplicate list here +has been deleted so that we won't get complaints when it +is out of date. + +But one note about C++ programs only (not C). `\|\c +.B \-traditional\c +\&\|' has one additional effect for C++: assignment to +.B this +is permitted. This is the same as the effect of `\|\c +.B \-fthis\-is\-variable\c +\&\|'. +.TP +.B \-traditional\-cpp +Attempt to support some aspects of traditional C preprocessors. +This includes the items that specifically mention the preprocessor above, +but none of the other effects of `\|\c +.B \-traditional\c +\&\|'. +.TP +.B \-fdollars\-in\-identifiers +Permit the use of `\|\c +.B $\c +\&\|' in identifiers (C++ only). You can also use +`\|\c +.B \-fno\-dollars\-in\-identifiers\c +\&\|' to explicitly prohibit use of +`\|\c +.B $\c +\&\|'. (GNU C++ allows `\|\c +.B $\c +\&\|' by default on some target systems +but not others.) +.TP +.B \-fenum\-int\-equiv +Permit implicit conversion of \c +.B int\c +\& to enumeration types (C++ +only). Normally GNU C++ allows conversion of \c +.B enum\c +\& to \c +.B int\c +\&, +but not the other way around. +.TP +.B \-fall\-virtual +Treat all possible member functions as virtual, implicitly. All +member functions (except for constructor functions and +.B new +or +.B delete +member operators) are treated as virtual functions of the class where +they appear. + +This does not mean that all calls to these member functions will be +made through the internal table of virtual functions. Under some +circumstances, the compiler can determine that a call to a given +virtual function can be made directly; in these cases the calls are +direct in any case. +.TP +.B \-fcond\-mismatch +Allow conditional expressions with mismatched types in the second and +third arguments. The value of such an expression is void. +.TP +.B \-fthis\-is\-variable +Permit assignment to \c +.B this\c +\& (C++ only). The incorporation of +user-defined free store management into C++ has made assignment to +`\|\c +.B this\c +\&\|' an anachronism. Therefore, by default it is invalid to +assign to \c +.B this\c +\& within a class member function. However, for +backwards compatibility, you can make it valid with +`\|\c +.B \-fthis-is-variable\c +\&\|'. +.TP +.B \-funsigned\-char +Let the type \c +.B char\c +\& be unsigned, like \c +.B unsigned char\c +\&. + +Each kind of machine has a default for what \c +.B char\c +\& should +be. It is either like \c +.B unsigned char\c +\& by default or like +\c +.B signed char\c +\& by default. + +Ideally, a portable program should always use \c +.B signed char\c +\& or +\c +.B unsigned char\c +\& when it depends on the signedness of an object. +But many programs have been written to use plain \c +.B char\c +\& and +expect it to be signed, or expect it to be unsigned, depending on the +machines they were written for. This option, and its inverse, let you +make such a program work with the opposite default. + +The type \c +.B char\c +\& is always a distinct type from each of +\c +.B signed char\c +\& and \c +.B unsigned char\c +\&, even though its behavior +is always just like one of those two. + +.TP +.B \-fsigned\-char +Let the type \c +.B char\c +\& be signed, like \c +.B signed char\c +\&. + +Note that this is equivalent to `\|\c +.B \-fno\-unsigned\-char\c +\&\|', which is +the negative form of `\|\c +.B \-funsigned\-char\c +\&\|'. Likewise, +`\|\c +.B \-fno\-signed\-char\c +\&\|' is equivalent to `\|\c +.B \-funsigned\-char\c +\&\|'. +.TP +.B \-fsigned\-bitfields +.TP +.B \-funsigned\-bitfields +.TP +.B \-fno\-signed\-bitfields +.TP +.B \-fno\-unsigned\-bitfields +These options control whether a bitfield is +signed or unsigned, when declared with no explicit `\|\c +.B signed\c +\&\|' or `\|\c +.B unsigned\c +\&\|' qualifier. By default, such a bitfield is +signed, because this is consistent: the basic integer types such as +\c +.B int\c +\& are signed types. + +However, when you specify `\|\c +.B \-traditional\c +\&\|', bitfields are all unsigned +no matter what. +.TP +.B \-fwritable\-strings +Store string constants in the writable data segment and don't uniquize +them. This is for compatibility with old programs which assume they +can write into string constants. `\|\c +.B \-traditional\c +\&\|' also has this +effect. + +Writing into string constants is a very bad idea; ``constants'' should +be constant. +.PP + +.SH PREPROCESSOR OPTIONS +These options control the C preprocessor, which is run on each C source +file before actual compilation. + +If you use the `\|\c +.B \-E\c +\&\|' option, GCC does nothing except preprocessing. +Some of these options make sense only together with `\|\c +.B \-E\c +\&\|' because +they cause the preprocessor output to be unsuitable for actual +compilation. +.TP +.BI "\-include " "file" +Process \c +.I file\c +\& as input before processing the regular input file. +In effect, the contents of \c +.I file\c +\& are compiled first. Any `\|\c +.B \-D\c +\&\|' +and `\|\c +.B \-U\c +\&\|' options on the command line are always processed before +`\|\c +.B \-include \c +.I file\c +\&\c +\&\|', regardless of the order in which they are +written. All the `\|\c +.B \-include\c +\&\|' and `\|\c +.B \-imacros\c +\&\|' options are +processed in the order in which they are written. +.TP +.BI "\-imacros " file +Process \c +.I file\c +\& as input, discarding the resulting output, before +processing the regular input file. Because the output generated from +\c +.I file\c +\& is discarded, the only effect of `\|\c +.B \-imacros \c +.I file\c +\&\c +\&\|' is to +make the macros defined in \c +.I file\c +\& available for use in the main +input. The preprocessor evaluates any `\|\c +.B \-D\c +\&\|' and `\|\c +.B \-U\c +\&\|' options +on the command line before processing `\|\c +.B \-imacros\c +.I file\c +\&\|', regardless of the order in +which they are written. All the `\|\c +.B \-include\c +\&\|' and `\|\c +.B \-imacros\c +\&\|' +options are processed in the order in which they are written. +.TP +.BI "-idirafter " "dir"\c +\& +Add the directory \c +.I dir\c +\& to the second include path. The directories +on the second include path are searched when a header file is not found +in any of the directories in the main include path (the one that +`\|\c +.B \-I\c +\&\|' adds to). +.TP +.BI "-iprefix " "prefix"\c +\& +Specify \c +.I prefix\c +\& as the prefix for subsequent `\|\c +.B \-iwithprefix\c +\&\|' +options. +.TP +.BI "-iwithprefix " "dir"\c +\& +Add a directory to the second include path. The directory's name is +made by concatenating \c +.I prefix\c +\& and \c +.I dir\c +\&, where \c +.I prefix\c +\& +was specified previously with `\|\c +.B \-iprefix\c +\&\|'. +.TP +.B \-nostdinc +Do not search the standard system directories for header files. Only +the directories you have specified with `\|\c +.B \-I\c +\&\|' options (and the +current directory, if appropriate) are searched. + +By using both `\|\c +.B \-nostdinc\c +\&\|' and `\|\c +.B \-I\-\c +\&\|', you can limit the include-file search file to only those +directories you specify explicitly. +.TP +.B \-nostdinc++ +Do not search for header files in the C++-specific standard directories, +but do still search the other standard directories. +(This option is used when building `\|\c +.B libg++\c +\&\|'.) +.TP +.B \-undef +Do not predefine any nonstandard macros. (Including architecture flags). +.TP +.B \-E +Run only the C preprocessor. Preprocess all the C source files +specified and output the results to standard output or to the +specified output file. +.TP +.B \-C +Tell the preprocessor not to discard comments. Used with the +`\|\c +.B \-E\c +\&\|' option. +.TP +.B \-P +Tell the preprocessor not to generate `\|\c +.B #line\c +\&\|' commands. +Used with the `\|\c +.B \-E\c +\&\|' option. +.TP +.B \-M +Tell the preprocessor to output a rule suitable for \c +.B make\c +\& +describing the dependencies of each object file. For each source file, +the preprocessor outputs one \c +.B make\c +\&-rule whose target is the object +file name for that source file and whose dependencies are all the files +`\|\c +.B #include\c +\&\|'d in it. This rule may be a single line or may be +continued with `\|\c +.B \e\c +\&\|'-newline if it is long. The list of rules is +printed on standard output instead of the preprocessed C program. + +`\|\c +.B \-M\c +\&\|' implies `\|\c +.B \-E\c +\&\|'. +.TP +.B \-MM +Like `\|\c +.B \-M\c +\&\|' but the output mentions only the user header files +included with `\|\c +.B #include "\c +.I file\c +\&"\c +\&\|'. System header files +included with `\|\c +.B #include <\c +.I file\c +\&>\c +\&\|' are omitted. +.TP +.B \-MD +Like `\|\c +.B \-M\c +\&\|' but the dependency information is written to files with +names made by replacing `\|\c +.B .o\c +\&\|' with `\|\c +.B .d\c +\&\|' at the end of the +output file names. This is in addition to compiling the file as +specified\(em\&`\|\c +.B \-MD\c +\&\|' does not inhibit ordinary compilation the way +`\|\c +.B \-M\c +\&\|' does. + +The Mach utility `\|\c +.B md\c +\&\|' can be used to merge the `\|\c +.B .d\c +\&\|' files +into a single dependency file suitable for using with the `\|\c +.B make\c +\&\|' +command. +.TP +.B \-MMD +Like `\|\c +.B \-MD\c +\&\|' except mention only user header files, not system +header files. +.TP +.B \-H +Print the name of each header file used, in addition to other normal +activities. +.TP +.BI "-A" "question" ( answer ) +Assert the answer +.I answer +for +.I question\c +\&, in case it is tested +with a preprocessor conditional such as `\|\c +.BI "#if #" question ( answer )\c +\&\|'. `\|\c +.B \-A\-\c +\&\|' disables the standard +assertions that normally describe the target machine. +.TP +.BI "-A" "question"\c +\&(\c +.I answer\c +\&) +Assert the answer \c +.I answer\c +\& for \c +.I question\c +\&, in case it is tested +with a preprocessor conditional such as `\|\c +.B #if +#\c +.I question\c +\&(\c +.I answer\c +\&)\c +\&\|'. `\|\c +.B \-A-\c +\&\|' disables the standard +assertions that normally describe the target machine. +.TP +.BI \-D macro +Define macro \c +.I macro\c +\& with the string `\|\c +.B 1\c +\&\|' as its definition. +.TP +.BI \-D macro = defn +Define macro \c +.I macro\c +\& as \c +.I defn\c +\&. All instances of `\|\c +.B \-D\c +\&\|' on +the command line are processed before any `\|\c +.B \-U\c +\&\|' options. +.TP +.BI \-U macro +Undefine macro \c +.I macro\c +\&. `\|\c +.B \-U\c +\&\|' options are evaluated after all `\|\c +.B \-D\c +\&\|' options, but before any `\|\c +.B \-include\c +\&\|' and `\|\c +.B \-imacros\c +\&\|' options. +.TP +.B \-dM +Tell the preprocessor to output only a list of the macro definitions +that are in effect at the end of preprocessing. Used with the `\|\c +.B \-E\c +\&\|' +option. +.TP +.B \-dD +Tell the preprocessor to pass all macro definitions into the output, in +their proper sequence in the rest of the output. +.TP +.B \-dN +Like `\|\c +.B \-dD\c +\&\|' except that the macro arguments and contents are omitted. +Only `\|\c +.B #define \c +.I name\c +\&\c +\&\|' is included in the output. +.PP + +.SH ASSEMBLER OPTION +.TP +.BI "-Wa," "option"\c +\& +Pass \c +.I option\c +\& as an option to the assembler. If \c +.I option\c +\& +contains commas, it is split into multiple options at the commas. +.PP + +.SH LINKER OPTIONS +These options come into play when the compiler links object files into +an executable output file. They are meaningless if the compiler is +not doing a link step. +.TP +.I object-file-name +A file name that does not end in a special recognized suffix is +considered to name an object file or library. (Object files are +distinguished from libraries by the linker according to the file +contents.) If GCC does a link step, these object files are used as input +to the linker. +.TP +.BI \-l library\c +\& +Use the library named \c +.I library\c +\& when linking. + +The linker searches a standard list of directories for the library, +which is actually a file named `\|\c +.B lib\c +.I library\c +\&.a\c +\&\|'. The linker +then uses this file as if it had been specified precisely by name. + +The directories searched include several standard system directories +plus any that you specify with `\|\c +.B \-L\c +\&\|'. + +Normally the files found this way are library files\(em\&archive files +whose members are object files. The linker handles an archive file by +scanning through it for members which define symbols that have so far +been referenced but not defined. However, if the linker finds an +ordinary object file rather than a library, the object file is linked +in the usual fashion. The only difference between using an `\|\c +.B \-l\c +\&\|' option and specifying a file +name is that `\|\c +.B \-l\c +\&\|' surrounds +.I library +with `\|\c +.B lib\c +\&\|' and `\|\c +.B .a\c +\&\|' and searches several directories. +.TP +.B \-lobjc +You need this special case of the +.B \-l +option in order to link an Objective C program. +.TP +.B \-nostartfiles +Do not use the standard system startup files when linking. +The standard libraries are used normally. +.TP +.B \-nostdlib +Don't use the standard system libraries and startup files when linking. +Only the files you specify will be passed to the linker. +.TP +.B \-static +On systems that support dynamic linking, this prevents linking with the shared +libraries. On other systems, this option has no effect. +.TP +.B \-shared +Produce a shared object which can then be linked with other objects to +form an executable. Only a few systems support this option. +.TP +.B \-symbolic +Bind references to global symbols when building a shared object. Warn +about any unresolved references (unless overridden by the link editor +option `\|\c +.B +\-Xlinker \-z \-Xlinker defs\c +\&\|'). Only a few systems support +this option. +.TP +.BI "-Xlinker " "option" +Pass \c +.I option +as an option to the linker. You can use this to +supply system-specific linker options which GNU CC does not know how to +recognize. + +If you want to pass an option that takes an argument, you must use +`\|\c +.B \-Xlinker\c +\&\|' twice, once for the option and once for the argument. +For example, to pass `\|\c +.B +\-assert definitions\c +\&\|', you must write +`\|\c +.B +\-Xlinker \-assert \-Xlinker definitions\c +\&\|'. It does not work to write +`\|\c +.B +\-Xlinker "-assert definitions"\c +\&\|', because this passes the entire +string as a single argument, which is not what the linker expects. +.TP +.BI "-Wl," "option"\c +\& +Pass \c +.I option\c +\& as an option to the linker. If \c +.I option\c +\& contains +commas, it is split into multiple options at the commas. +.TP +.BI "-u " "symbol" +Pretend the symbol +.I symbol +is undefined, to force linking of +library modules to define it. You can use `\|\c +.B \-u\c +\&\|' multiple times with +different symbols to force loading of additional library modules. +.PP + +.SH DIRECTORY OPTIONS +These options specify directories to search for header files, for +libraries and for parts of the compiler: +.TP +.BI "\-I" "dir"\c +\& +Append directory \c +.I dir\c +\& to the list of directories searched for include files. +.TP +.B \-I\- +Any directories you specify with `\|\c +.B \-I\c +\&\|' options before the `\|\c +.B \-I\-\c +\&\|' +option are searched only for the case of `\|\c +.B +#include "\c +.I file\c +.B +\&"\c +\&\|'; +they are not searched for `\|\c +.B #include <\c +.I file\c +\&>\c +\&\|'. + +If additional directories are specified with `\|\c +.B \-I\c +\&\|' options after +the `\|\c +.B \-I\-\c +\&\|', these directories are searched for all `\|\c +.B #include\c +\&\|' +directives. (Ordinarily \c +.I all\c +\& `\|\c +.B \-I\c +\&\|' directories are used +this way.) + +In addition, the `\|\c +.B \-I\-\c +\&\|' option inhibits the use of the current +directory (where the current input file came from) as the first search +directory for `\|\c +.B +#include "\c +.I file\c +.B +\&"\c +\&\|'. There is no way to +override this effect of `\|\c +.B \-I\-\c +\&\|'. With `\|\c +.B \-I.\c +\&\|' you can specify +searching the directory which was current when the compiler was +invoked. That is not exactly the same as what the preprocessor does +by default, but it is often satisfactory. + +`\|\c +.B \-I\-\c +\&\|' does not inhibit the use of the standard system directories +for header files. Thus, `\|\c +.B \-I\-\c +\&\|' and `\|\c +.B \-nostdinc\c +\&\|' are +independent. +.TP +.BI "\-L" "dir"\c +\& +Add directory \c +.I dir\c +\& to the list of directories to be searched +for `\|\c +.B \-l\c +\&\|'. +.TP +.BI "\-B" "prefix"\c +\& +This option specifies where to find the executables, libraries and +data files of the compiler itself. + +The compiler driver program runs one or more of the subprograms +`\|\c +.B cpp\c +\&\|', `\|\c +.B cc1\c +\&\|' (or, for C++, `\|\c +.B cc1plus\c +\&\|'), `\|\c +.B as\c +\&\|' and `\|\c +.B ld\c +\&\|'. It tries +\c +.I prefix\c +\& as a prefix for each program it tries to run, both with and +without `\|\c +.B \c +.I machine\c +\&/\c +.I version\c +\&/\c +\&\|'. + +For each subprogram to be run, the compiler driver first tries the +`\|\c +.B \-B\c +\&\|' prefix, if any. If that name is not found, or if `\|\c +.B \-B\c +\&\|' +was not specified, the driver tries two standard prefixes, which are +`\|\c +.B /usr/lib/gcc/\c +\&\|' and `\|\c +.B /usr/local/lib/gcc-lib/\c +\&\|'. If neither of +those results in a file name that is found, the compiler driver +searches for the unmodified program +name, using the directories specified in your +`\|\c +.B PATH\c +\&\|' environment variable. + +The run-time support file `\|\c +.B libgcc.a\c +\&\|' is also searched for using the +`\|\c +.B \-B\c +\&\|' prefix, if needed. If it is not found there, the two +standard prefixes above are tried, and that is all. The file is left +out of the link if it is not found by those means. Most of the time, +on most machines, `\|\c +.B libgcc.a\c +\&\|' is not actually necessary. + +You can get a similar result from the environment variable +\c +.B GCC_EXEC_PREFIX\c +\&; if it is defined, its value is used as a prefix +in the same way. If both the `\|\c +.B \-B\c +\&\|' option and the +\c +.B GCC_EXEC_PREFIX\c +\& variable are present, the `\|\c +.B \-B\c +\&\|' option is +used first and the environment variable value second. +.PP + +.SH WARNING OPTIONS +Warnings are diagnostic messages that report constructions which +are not inherently erroneous but which are risky or suggest there +may have been an error. + +These options control the amount and kinds of warnings produced by GNU +CC: +.TP +.B \-fsyntax\-only +Check the code for syntax errors, but don't emit any output. +.TP +.B \-w +Inhibit all warning messages. +.TP +.B \-Wno\-import +Inhibit warning messages about the use of +.BR #import . +.TP +.B \-pedantic +Issue all the warnings demanded by strict ANSI standard C; reject +all programs that use forbidden extensions. + +Valid ANSI standard C programs should compile properly with or without +this option (though a rare few will require `\|\c +.B \-ansi\c +\&\|'). However, +without this option, certain GNU extensions and traditional C features +are supported as well. With this option, they are rejected. There is +no reason to \c +.I use\c +\& this option; it exists only to satisfy pedants. + +`\|\c +.B \-pedantic\c +\&\|' does not cause warning messages for use of the +alternate keywords whose names begin and end with `\|\c +.B __\c +\&\|'. Pedantic +warnings are also disabled in the expression that follows +\c +.B __extension__\c +\&. However, only system header files should use +these escape routes; application programs should avoid them. +.TP +.B \-pedantic\-errors +Like `\|\c +.B \-pedantic\c +\&\|', except that errors are produced rather than +warnings. +.TP +.B \-W +Print extra warning messages for these events: +.TP +\ \ \ \(bu +A nonvolatile automatic variable might be changed by a call to +\c +.B longjmp\c +\&. These warnings are possible only in +optimizing compilation. + +The compiler sees only the calls to \c +.B setjmp\c +\&. It cannot know +where \c +.B longjmp\c +\& will be called; in fact, a signal handler could +call it at any point in the code. As a result, you may get a warning +even when there is in fact no problem because \c +.B longjmp\c +\& cannot +in fact be called at the place which would cause a problem. +.TP +\ \ \ \(bu +A function can return either with or without a value. (Falling +off the end of the function body is considered returning without +a value.) For example, this function would evoke such a +warning: +.sp +.br +foo\ (a) +.br +{ +.br +\ \ if\ (a\ >\ 0) +.br +\ \ \ \ return\ a; +.br +} +.br +.sp + +Spurious warnings can occur because GNU CC does not realize that +certain functions (including \c +.B abort\c +\& and \c +.B longjmp\c +\&) +will never return. +.TP +\ \ \ \(bu +An expression-statement contains no side effects. +.TP +\ \ \ \(bu +An unsigned value is compared against zero with `\|\c +.B >\c +\&\|' or `\|\c +.B <=\c +\&\|'. +.PP +.TP +.B \-Wimplicit +Warn whenever a function or parameter is implicitly declared. +.TP +.B \-Wreturn\-type +Warn whenever a function is defined with a return-type that defaults +to \c +.B int\c +\&. Also warn about any \c +.B return\c +\& statement with no +return-value in a function whose return-type is not \c +.B void\c +\&. +.TP +.B \-Wunused +Warn whenever a local variable is unused aside from its declaration, +whenever a function is declared static but never defined, and whenever +a statement computes a result that is explicitly not used. +.TP +.B \-Wswitch +Warn whenever a \c +.B switch\c +\& statement has an index of enumeral type +and lacks a \c +.B case\c +\& for one or more of the named codes of that +enumeration. (The presence of a \c +.B default\c +\& label prevents this +warning.) \c +.B case\c +\& labels outside the enumeration range also +provoke warnings when this option is used. +.TP +.B \-Wcomment +Warn whenever a comment-start sequence `\|\c +.B /*\c +\&\|' appears in a comment. +.TP +.B \-Wtrigraphs +Warn if any trigraphs are encountered (assuming they are enabled). +.TP +.B \-Wformat +Check calls to \c +.B printf\c +\& and \c +.B scanf\c +\&, etc., to make sure that +the arguments supplied have types appropriate to the format string +specified. +.TP +.B \-Wchar\-subscripts +Warn if an array subscript has type +.BR char . +This is a common cause of error, as programmers often forget that this +type is signed on some machines. +.TP +.B \-Wuninitialized +An automatic variable is used without first being initialized. + +These warnings are possible only in optimizing compilation, +because they require data flow information that is computed only +when optimizing. If you don't specify `\|\c +.B \-O\c +\&\|', you simply won't +get these warnings. + +These warnings occur only for variables that are candidates for +register allocation. Therefore, they do not occur for a variable that +is declared \c +.B volatile\c +\&, or whose address is taken, or whose size +is other than 1, 2, 4 or 8 bytes. Also, they do not occur for +structures, unions or arrays, even when they are in registers. + +Note that there may be no warning about a variable that is used only +to compute a value that itself is never used, because such +computations may be deleted by data flow analysis before the warnings +are printed. + +These warnings are made optional because GNU CC is not smart +enough to see all the reasons why the code might be correct +despite appearing to have an error. Here is one example of how +this can happen: + +.sp +.br +{ +.br +\ \ int\ x; +.br +\ \ switch\ (y) +.br +\ \ \ \ { +.br +\ \ \ \ case\ 1:\ x\ =\ 1; +.br +\ \ \ \ \ \ break; +.br +\ \ \ \ case\ 2:\ x\ =\ 4; +.br +\ \ \ \ \ \ break; +.br +\ \ \ \ case\ 3:\ x\ =\ 5; +.br +\ \ \ \ } +.br +\ \ foo\ (x); +.br +} +.br +.sp + + +If the value of \c +.B y\c +\& is always 1, 2 or 3, then \c +.B x\c +\& is +always initialized, but GNU CC doesn't know this. Here is +another common case: + +.sp +.br +{ +.br +\ \ int\ save_y; +.br +\ \ if\ (change_y)\ save_y\ =\ y,\ y\ =\ new_y; +.br +\ \ .\|.\|. +.br +\ \ if\ (change_y)\ y\ =\ save_y; +.br +} +.br +.sp + + +This has no bug because \c +.B save_y\c +\& is used only if it is set. + +Some spurious warnings can be avoided if you declare as +\c +.B volatile\c +\& all the functions you use that never return. +.TP +.B \-Wparentheses +Warn if parentheses are omitted in certain contexts. +.TP +.B \-Wtemplate\-debugging +When using templates in a C++ program, warn if debugging is not yet +fully available (C++ only). +.TP +.B \-Wall +All of the above `\|\c +.B \-W\c +\&\|' options combined. These are all the +options which pertain to usage that we recommend avoiding and that we +believe is easy to avoid, even in conjunction with macros. +.PP + +The remaining `\|\c +.B \-W.\|.\|.\c +\&\|' options are not implied by `\|\c +.B \-Wall\c +\&\|' +because they warn about constructions that we consider reasonable to +use, on occasion, in clean programs. +.TP +.B \-Wtraditional +Warn about certain constructs that behave differently in traditional and +ANSI C. +.TP +\ \ \ \(bu +Macro arguments occurring within string constants in the macro body. +These would substitute the argument in traditional C, but are part of +the constant in ANSI C. +.TP +\ \ \ \(bu +A function declared external in one block and then used after the end of +the block. +.TP +\ \ \ \(bu +A \c +.B switch\c +\& statement has an operand of type \c +.B long\c +\&. +.PP +.TP +.B \-Wshadow +Warn whenever a local variable shadows another local variable. +.TP +.BI "\-Wid\-clash\-" "len"\c +\& +Warn whenever two distinct identifiers match in the first \c +.I len\c +\& +characters. This may help you prepare a program that will compile +with certain obsolete, brain-damaged compilers. +.TP +.B \-Wpointer\-arith +Warn about anything that depends on the ``size of'' a function type or +of \c +.B void\c +\&. GNU C assigns these types a size of 1, for +convenience in calculations with \c +.B void *\c +\& pointers and pointers +to functions. +.TP +.B \-Wcast\-qual +Warn whenever a pointer is cast so as to remove a type qualifier from +the target type. For example, warn if a \c +.B const char *\c +\& is cast +to an ordinary \c +.B char *\c +\&. +.TP +.B \-Wcast\-align +Warn whenever a pointer is cast such that the required alignment of the +target is increased. For example, warn if a \c +.B char *\c +\& is cast to +an \c +.B int *\c +\& on machines where integers can only be accessed at +two- or four-byte boundaries. +.TP +.B \-Wwrite\-strings +Give string constants the type \c +.B const char[\c +.I length\c +\&]\c +\& so that +copying the address of one into a non-\c +.B const\c +\& \c +.B char *\c +\& +pointer will get a warning. These warnings will help you find at +compile time code that can try to write into a string constant, but +only if you have been very careful about using \c +.B const\c +\& in +declarations and prototypes. Otherwise, it will just be a nuisance; +this is why we did not make `\|\c +.B \-Wall\c +\&\|' request these warnings. +.TP +.B \-Wconversion +Warn if a prototype causes a type conversion that is different from what +would happen to the same argument in the absence of a prototype. This +includes conversions of fixed point to floating and vice versa, and +conversions changing the width or signedness of a fixed point argument +except when the same as the default promotion. +.TP +.B \-Waggregate\-return +Warn if any functions that return structures or unions are defined or +called. (In languages where you can return an array, this also elicits +a warning.) +.TP +.B \-Wstrict\-prototypes +Warn if a function is declared or defined without specifying the +argument types. (An old-style function definition is permitted without +a warning if preceded by a declaration which specifies the argument +types.) +.TP +.B \-Wmissing\-prototypes +Warn if a global function is defined without a previous prototype +declaration. This warning is issued even if the definition itself +provides a prototype. The aim is to detect global functions that fail +to be declared in header files. +.TP +.B \-Wredundant-decls +Warn if anything is declared more than once in the same scope, even in +cases where multiple declaration is valid and changes nothing. +.TP +.B \-Wnested-externs +Warn if an \c +.B extern\c +\& declaration is encountered within an function. +.TP +.B \-Wenum\-clash +Warn about conversion between different enumeration types (C++ only). +.TP +.B \-Woverloaded\-virtual +(C++ only.) +In a derived class, the definitions of virtual functions must match +the type signature of a virtual function declared in the base class. +Use this option to request warnings when a derived class declares a +function that may be an erroneous attempt to define a virtual +function: that is, warn when a function with the same name as a +virtual function in the base class, but with a type signature that +doesn't match any virtual functions from the base class. +.TP +.B \-Winline +Warn if a function can not be inlined, and either it was declared as inline, +or else the +.B \-finline\-functions +option was given. +.TP +.B \-Werror +Treat warnings as errors; abort compilation after any warning. +.PP + +.SH DEBUGGING OPTIONS +GNU CC has various special options that are used for debugging +either your program or GCC: +.TP +.B \-g +Produce debugging information in the operating system's native format +(stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging +information. + +On most systems that use stabs format, `\|\c +.B \-g\c +\&\|' enables use of extra +debugging information that only GDB can use; this extra information +makes debugging work better in GDB but will probably make other debuggers +crash or +refuse to read the program. If you want to control for certain whether +to generate the extra information, use `\|\c +.B \-gstabs+\c +\&\|', `\|\c +.B \-gstabs\c +\&\|', +`\|\c +.B \-gxcoff+\c +\&\|', `\|\c +.B \-gxcoff\c +\&\|', `\|\c +.B \-gdwarf+\c +\&\|', or `\|\c +.B \-gdwarf\c +\&\|' +(see below). + +Unlike most other C compilers, GNU CC allows you to use `\|\c +.B \-g\c +\&\|' with +`\|\c +.B \-O\c +\&\|'. The shortcuts taken by optimized code may occasionally +produce surprising results: some variables you declared may not exist +at all; flow of control may briefly move where you did not expect it; +some statements may not be executed because they compute constant +results or their values were already at hand; some statements may +execute in different places because they were moved out of loops. + +Nevertheless it proves possible to debug optimized output. This makes +it reasonable to use the optimizer for programs that might have bugs. + +The following options are useful when GNU CC is generated with the +capability for more than one debugging format. +.TP +.B \-ggdb +Produce debugging information in the native format (if that is supported), +including GDB extensions if at all possible. +.TP +.B \-gstabs +Produce debugging information in stabs format (if that is supported), +without GDB extensions. This is the format used by DBX on most BSD +systems. +.TP +.B \-gstabs+ +Produce debugging information in stabs format (if that is supported), +using GNU extensions understood only by the GNU debugger (GDB). The +use of these extensions is likely to make other debuggers crash or +refuse to read the program. +.TP +.B \-gcoff +Produce debugging information in COFF format (if that is supported). +This is the format used by SDB on most System V systems prior to +System V Release 4. +.TP +.B \-gxcoff +Produce debugging information in XCOFF format (if that is supported). +This is the format used by the DBX debugger on IBM RS/6000 systems. +.TP +.B \-gxcoff+ +Produce debugging information in XCOFF format (if that is supported), +using GNU extensions understood only by the GNU debugger (GDB). The +use of these extensions is likely to make other debuggers crash or +refuse to read the program. +.TP +.B \-gdwarf +Produce debugging information in DWARF format (if that is supported). +This is the format used by SDB on most System V Release 4 systems. +.TP +.B \-gdwarf+ +Produce debugging information in DWARF format (if that is supported), +using GNU extensions understood only by the GNU debugger (GDB). The +use of these extensions is likely to make other debuggers crash or +refuse to read the program. +.PP +.BI "\-g" "level" +.br +.BI "\-ggdb" "level" +.br +.BI "\-gstabs" "level" +.br +.BI "\-gcoff" "level" +.BI "\-gxcoff" "level" +.TP +.BI "\-gdwarf" "level" +Request debugging information and also use \c +.I level\c +\& to specify how +much information. The default level is 2. + +Level 1 produces minimal information, enough for making backtraces in +parts of the program that you don't plan to debug. This includes +descriptions of functions and external variables, but no information +about local variables and no line numbers. + +Level 3 includes extra information, such as all the macro definitions +present in the program. Some debuggers support macro expansion when +you use `\|\c +.B \-g3\c +\&\|'. +.TP +.B \-p +Generate extra code to write profile information suitable for the +analysis program \c +.B prof\c +\&. +.TP +.B \-pg +Generate extra code to write profile information suitable for the +analysis program \c +.B gprof\c +\&. +.TP +.B \-a +Generate extra code to write profile information for basic blocks, +which will record the number of times each basic block is executed. +This data could be analyzed by a program like \c +.B tcov\c +\&. Note, +however, that the format of the data is not what \c +.B tcov\c +\& expects. +Eventually GNU \c +.B gprof\c +\& should be extended to process this data. +.TP +.BI "\-d" "letters"\c +\& +Says to make debugging dumps during compilation at times specified by +\c +.I letters\c +\&. This is used for debugging the compiler. The file names +for most of the dumps are made by appending a word to the source file +name (e.g. `\|\c +.B foo.c.rtl\c +\&\|' or `\|\c +.B foo.c.jump\c +\&\|'). +.TP +.B \-dM +Dump all macro definitions, at the end of preprocessing, and write no +output. +.TP +.B \-dN +Dump all macro names, at the end of preprocessing. +.TP +.B \-dD +Dump all macro definitions, at the end of preprocessing, in addition to +normal output. +.TP +.B \-dy +Dump debugging information during parsing, to standard error. +.TP +.B \-dr +Dump after RTL generation, to `\|\c +.B \c +.I file\c +\&.rtl\c +\&\|'. +.TP +.B \-dx +Just generate RTL for a function instead of compiling it. Usually used +with `\|\c +.B r\c +\&\|'. +.TP +.B \-dj +Dump after first jump optimization, to `\|\c +.B \c +.I file\c +\&.jump\c +\&\|'. +.TP +.B \-ds +Dump after CSE (including the jump optimization that sometimes +follows CSE), to `\|\c +.B \c +.I file\c +\&.cse\c +\&\|'. +.TP +.B \-dL +Dump after loop optimization, to `\|\c +.B \c +.I file\c +\&.loop\c +\&\|'. +.TP +.B \-dt +Dump after the second CSE pass (including the jump optimization that +sometimes follows CSE), to `\|\c +.B \c +.I file\c +\&.cse2\c +\&\|'. +.TP +.B \-df +Dump after flow analysis, to `\|\c +.B \c +.I file\c +\&.flow\c +\&\|'. +.TP +.B \-dc +Dump after instruction combination, to `\|\c +.B \c +.I file\c +\&.combine\c +\&\|'. +.TP +.B \-dS +Dump after the first instruction scheduling pass, to +`\|\c +.B \c +.I file\c +\&.sched\c +\&\|'. +.TP +.B \-dl +Dump after local register allocation, to `\|\c +.B \c +.I file\c +\&.lreg\c +\&\|'. +.TP +.B \-dg +Dump after global register allocation, to `\|\c +.B \c +.I file\c +\&.greg\c +\&\|'. +.TP +.B \-dR +Dump after the second instruction scheduling pass, to +`\|\c +.B \c +.I file\c +\&.sched2\c +\&\|'. +.TP +.B \-dJ +Dump after last jump optimization, to `\|\c +.B \c +.I file\c +\&.jump2\c +\&\|'. +.TP +.B \-dd +Dump after delayed branch scheduling, to `\|\c +.B \c +.I file\c +\&.dbr\c +\&\|'. +.TP +.B \-dk +Dump after conversion from registers to stack, to `\|\c +.B \c +.I file\c +\&.stack\c +\&\|'. +.TP +.B \-da +Produce all the dumps listed above. +.TP +.B \-dm +Print statistics on memory usage, at the end of the run, to +standard error. +.TP +.B \-dp +Annotate the assembler output with a comment indicating which +pattern and alternative was used. +.TP +.B \-fpretend\-float +When running a cross-compiler, pretend that the target machine uses the +same floating point format as the host machine. This causes incorrect +output of the actual floating constants, but the actual instruction +sequence will probably be the same as GNU CC would make when running on +the target machine. +.TP +.B \-save\-temps +Store the usual ``temporary'' intermediate files permanently; place them +in the current directory and name them based on the source file. Thus, +compiling `\|\c +.B foo.c\c +\&\|' with `\|\c +.B \-c \-save\-temps\c +\&\|' would produce files +`\|\c +.B foo.cpp\c +\&\|' and `\|\c +.B foo.s\c +\&\|', as well as `\|\c +.B foo.o\c +\&\|'. +.TP +.B \-print\-libgcc\-file\-name +Print the full absolute name of the library file `\|\c +.B libgcc.a\c +\&\|' that +would be used when linking\(em\&and do not do anything else. With this +option, GNU CC does not compile or link anything; it just prints the +file name. +.PP + +.SH OPTIMIZATION OPTIONS +These options control various sorts of optimizations: +.PP +.B \-O +.TP +.B \-O1 +Optimize. Optimizing compilation takes somewhat more time, and a lot +more memory for a large function. + +Without `\|\c +.B \-O\c +\&\|', the compiler's goal is to reduce the cost of +compilation and to make debugging produce the expected results. +Statements are independent: if you stop the program with a breakpoint +between statements, you can then assign a new value to any variable or +change the program counter to any other statement in the function and +get exactly the results you would expect from the source code. + +Without `\|\c +.B \-O\c +\&\|', only variables declared \c +.B register\c +\& are +allocated in registers. The resulting compiled code is a little worse +than produced by PCC without `\|\c +.B \-O\c +\&\|'. + +With `\|\c +.B \-O\c +\&\|', the compiler tries to reduce code size and execution +time. + +When you specify `\|\c +.B \-O\c +\&\|', `\|\c +.B \-fthread\-jumps\c +\&\|' and +`\|\c +.B \-fdelayed\-branch\c +\&\|' are turned on. On some machines other +flags may also be turned on. +.TP +.B \-O2 +Optimize even more. Nearly all supported optimizations that do not +involve a space-speed tradeoff are performed. As compared to +.B \-O\c +\&, +this option increases both compilation time and the performance of the +generated code. + +.B \-O2 +turns on all +.BI \-f flag +options that enable more optimization, except for +.B \-funroll\-loops\c +\&, +.B \-funroll\-all\-loops +and +.BR \-fomit\-frame\-pointer . +.TP +.B \-O0 +Do not optimize. + +If you use multiple +.B \-O +options, with or without level numbers, the last such option is the +one that is effective. +.PP + +Options of the form `\|\c +.B \-f\c +.I flag\c +\&\c +\&\|' specify machine-independent +flags. Most flags have both positive and negative forms; the negative +form of `\|\c +.B \-ffoo\c +\&\|' would be `\|\c +.B \-fno\-foo\c +\&\|'. The following list shows +only one form\(em\&the one which is not the default. +You can figure out the other form by either removing `\|\c +.B no\-\c +\&\|' or +adding it. +.TP +.B \-ffloat\-store +Do not store floating point variables in registers. This +prevents undesirable excess precision on machines such as the +68000 where the floating registers (of the 68881) keep more +precision than a \c +.B double\c +\& is supposed to have. + +For most programs, the excess precision does only good, but a few +programs rely on the precise definition of IEEE floating point. +Use `\|\c +.B \-ffloat\-store\c +\&\|' for such programs. +.TP +.B \-fmemoize\-lookups +.TP +.B \-fsave\-memoized +Use heuristics to compile faster (C++ only). These heuristics are not +enabled by default, since they are only effective for certain input +files. Other input files compile more slowly. + +The first time the compiler must build a call to a member function (or +reference to a data member), it must (1) determine whether the class +implements member functions of that name; (2) resolve which member +function to call (which involves figuring out what sorts of type +conversions need to be made); and (3) check the visibility of the member +function to the caller. All of this adds up to slower compilation. +Normally, the second time a call is made to that member function (or +reference to that data member), it must go through the same lengthy +process again. This means that code like this +.sp +.br +cout\ <<\ "This\ "\ <<\ p\ <<\ "\ has\ "\ <<\ n\ <<\ "\ legs.\en"; +.br +.sp +makes six passes through all three steps. By using a software cache, +a ``hit'' significantly reduces this cost. Unfortunately, using the +cache introduces another layer of mechanisms which must be implemented, +and so incurs its own overhead. `\|\c +.B \-fmemoize\-lookups\c +\&\|' enables +the software cache. + +Because access privileges (visibility) to members and member functions +may differ from one function context to the next, +.B g++ +may need to flush the cache. With the `\|\c +.B \-fmemoize\-lookups\c +\&\|' flag, the cache is flushed after every +function that is compiled. The `\|\c +\-fsave\-memoized\c +\&\|' flag enables the same software cache, but when the compiler +determines that the context of the last function compiled would yield +the same access privileges of the next function to compile, it +preserves the cache. +This is most helpful when defining many member functions for the same +class: with the exception of member functions which are friends of +other classes, each member function has exactly the same access +privileges as every other, and the cache need not be flushed. +.TP +.B \-fno\-default\-inline +Don't make member functions inline by default merely because they are +defined inside the class scope (C++ only). +.TP +.B \-fno\-defer\-pop +Always pop the arguments to each function call as soon as that +function returns. For machines which must pop arguments after a +function call, the compiler normally lets arguments accumulate on the +stack for several function calls and pops them all at once. +.TP +.B \-fforce\-mem +Force memory operands to be copied into registers before doing +arithmetic on them. This may produce better code by making all +memory references potential common subexpressions. When they are +not common subexpressions, instruction combination should +eliminate the separate register-load. I am interested in hearing +about the difference this makes. +.TP +.B \-fforce\-addr +Force memory address constants to be copied into registers before +doing arithmetic on them. This may produce better code just as +`\|\c +.B \-fforce\-mem\c +\&\|' may. I am interested in hearing about the +difference this makes. +.TP +.B \-fomit\-frame\-pointer +Don't keep the frame pointer in a register for functions that +don't need one. This avoids the instructions to save, set up and +restore frame pointers; it also makes an extra register available +in many functions. \c +.I It also makes debugging impossible on +most machines.\c +\& + +On some machines, such as the Vax, this flag has no effect, because +the standard calling sequence automatically handles the frame pointer +and nothing is saved by pretending it doesn't exist. The +machine-description macro \c +.B FRAME_POINTER_REQUIRED\c +\& controls +whether a target machine supports this flag. +.TP +.B \-finline\-functions +Integrate all simple functions into their callers. The compiler +heuristically decides which functions are simple enough to be worth +integrating in this way. + +If all calls to a given function are integrated, and the function is +declared \c +.B static\c +\&, then GCC normally does not output the function as +assembler code in its own right. +.TP +.B \-fcaller\-saves +Enable values to be allocated in registers that will be clobbered by +function calls, by emitting extra instructions to save and restore the +registers around such calls. Such allocation is done only when it +seems to result in better code than would otherwise be produced. + +This option is enabled by default on certain machines, usually those +which have no call-preserved registers to use instead. +.TP +.B \-fkeep\-inline\-functions +Even if all calls to a given function are integrated, and the function +is declared \c +.B static\c +\&, nevertheless output a separate run-time +callable version of the function. +.TP +.B \-fno\-function\-cse +Do not put function addresses in registers; make each instruction that +calls a constant function contain the function's address explicitly. + +This option results in less efficient code, but some strange hacks +that alter the assembler output may be confused by the optimizations +performed when this option is not used. +.TP +.B \-fno\-peephole +Disable any machine-specific peephole optimizations. +.TP +.B \-ffast-math +This option allows GCC to violate some ANSI or IEEE rules/specifications +in the interest of optimizing code for speed. For example, it allows +the compiler to assume arguments to the \c +.B sqrt\c +\& function are +non-negative numbers. + +This option should never be turned on by any `\|\c +.B \-O\c +\&\|' option since +it can result in incorrect output for programs which depend on +an exact implementation of IEEE or ANSI rules/specifications for +math functions. +.PP + +The following options control specific optimizations. The `\|\c +.B \-O2\c +\&\|' +option turns on all of these optimizations except `\|\c +.B \-funroll\-loops\c +\&\|' +and `\|\c +.B \-funroll\-all\-loops\c +\&\|'. + +The `\|\c +.B \-O\c +\&\|' option usually turns on +the `\|\c +.B \-fthread\-jumps\c +\&\|' and `\|\c +.B \-fdelayed\-branch\c +\&\|' options, but +specific machines may change the default optimizations. + +You can use the following flags in the rare cases when ``fine-tuning'' +of optimizations to be performed is desired. +.TP +.B \-fstrength\-reduce +Perform the optimizations of loop strength reduction and +elimination of iteration variables. +.TP +.B \-fthread\-jumps +Perform optimizations where we check to see if a jump branches to a +location where another comparison subsumed by the first is found. If +so, the first branch is redirected to either the destination of the +second branch or a point immediately following it, depending on whether +the condition is known to be true or false. +.TP +.B \-funroll\-loops +Perform the optimization of loop unrolling. This is only done for loops +whose number of iterations can be determined at compile time or run time. +.TP +.B \-funroll\-all\-loops +Perform the optimization of loop unrolling. This is done for all loops. +This usually makes programs run more slowly. +.TP +.B \-fcse\-follow\-jumps +In common subexpression elimination, scan through jump instructions +when the target of the jump is not reached by any other path. For +example, when CSE encounters an \c +.B if\c +\& statement with an +\c +.B else\c +\& clause, CSE will follow the jump when the condition +tested is false. +.TP +.B \-fcse\-skip\-blocks +This is similar to `\|\c +.B \-fcse\-follow\-jumps\c +\&\|', but causes CSE to +follow jumps which conditionally skip over blocks. When CSE +encounters a simple \c +.B if\c +\& statement with no else clause, +`\|\c +.B \-fcse\-skip\-blocks\c +\&\|' causes CSE to follow the jump around the +body of the \c +.B if\c +\&. +.TP +.B \-frerun\-cse\-after\-loop +Re-run common subexpression elimination after loop optimizations has been +performed. +.TP +.B \-felide\-constructors +Elide constructors when this seems plausible (C++ only). With this +flag, GNU C++ initializes \c +.B y\c +\& directly from the call to \c +.B foo\c +\& +without going through a temporary in the following code: + +.sp +.br +A\ foo\ (); +.br +A\ y\ =\ foo\ (); +.br +.sp + +Without this option, GNU C++ first initializes \c +.B y\c +\& by calling the +appropriate constructor for type \c +.B A\c +\&; then assigns the result of +\c +.B foo\c +\& to a temporary; and, finally, replaces the initial valyue of +`\|\c +.B y\c +\&\|' with the temporary. + +The default behavior (`\|\c +.B \-fno\-elide\-constructors\c +\&\|') is specified by +the draft ANSI C++ standard. If your program's constructors have side +effects, using `\|\c +.B \-felide-constructors\c +\&\|' can make your program act +differently, since some constructor calls may be omitted. +.TP +.B \-fexpensive\-optimizations +Perform a number of minor optimizations that are relatively expensive. +.TP +.B \-fdelayed\-branch +If supported for the target machine, attempt to reorder instructions +to exploit instruction slots available after delayed branch +instructions. +.TP +.B \-fschedule\-insns +If supported for the target machine, attempt to reorder instructions to +eliminate execution stalls due to required data being unavailable. This +helps machines that have slow floating point or memory load instructions +by allowing other instructions to be issued until the result of the load +or floating point instruction is required. +.TP +.B \-fschedule\-insns2 +Similar to `\|\c +.B \-fschedule\-insns\c +\&\|', but requests an additional pass of +instruction scheduling after register allocation has been done. This is +especially useful on machines with a relatively small number of +registers and where memory load instructions take more than one cycle. +.PP + +.SH TARGET OPTIONS +By default, GNU CC compiles code for the same type of machine that you +are using. However, it can also be installed as a cross-compiler, to +compile for some other type of machine. In fact, several different +configurations of GNU CC, for different target machines, can be +installed side by side. Then you specify which one to use with the +`\|\c +.B \-b\c +\&\|' option. + +In addition, older and newer versions of GNU CC can be installed side +by side. One of them (probably the newest) will be the default, but +you may sometimes wish to use another. +.TP +.BI "\-b " "machine"\c +\& +The argument \c +.I machine\c +\& specifies the target machine for compilation. +This is useful when you have installed GNU CC as a cross-compiler. + +The value to use for \c +.I machine\c +\& is the same as was specified as the +machine type when configuring GNU CC as a cross-compiler. For +example, if a cross-compiler was configured with `\|\c +.B configure +i386v\c +\&\|', meaning to compile for an 80386 running System V, then you +would specify `\|\c +.B \-b i386v\c +\&\|' to run that cross compiler. + +When you do not specify `\|\c +.B \-b\c +\&\|', it normally means to compile for +the same type of machine that you are using. +.TP +.BI "\-V " "version"\c +\& +The argument \c +.I version\c +\& specifies which version of GNU CC to run. +This is useful when multiple versions are installed. For example, +\c +.I version\c +\& might be `\|\c +.B 2.0\c +\&\|', meaning to run GNU CC version 2.0. + +The default version, when you do not specify `\|\c +.B \-V\c +\&\|', is controlled +by the way GNU CC is installed. Normally, it will be a version that +is recommended for general use. +.PP + +.SH MACHINE DEPENDENT OPTIONS +Each of the target machine types can have its own special options, +starting with `\|\c +.B \-m\c +\&\|', to choose among various hardware models or +configurations\(em\&for example, 68010 vs 68020, floating coprocessor or +none. A single installed version of the compiler can compile for any +model or configuration, according to the options specified. + +Some configurations of the compiler also support additional special +options, usually for command-line compatibility with other compilers on +the same platform. + +These are the `\|\c +.B \-m\c +\&\|' options defined for the 68000 series: +.TP +.B \-m68000 +.TP +.B \-mc68000 +Generate output for a 68000. This is the default when the compiler is +configured for 68000-based systems. +.TP +.B \-m68020 +.TP +.B \-mc68020 +Generate output for a 68020 (rather than a 68000). This is the +default when the compiler is configured for 68020-based systems. +.TP +.B \-m68881 +Generate output containing 68881 instructions for floating point. +This is the default for most 68020-based systems unless +.B \-nfp +was specified when the compiler was configured. +.TP +.B \-m68030 +Generate output for a 68030. This is the default when the compiler is +configured for 68030-based systems. +.TP +.B \-m68040 +Generate output for a 68040. This is the default when the compiler is +configured for 68040-based systems. +.TP +.B \-m68020\-40 +Generate output for a 68040, without using any of the new instructions. +This results in code which can run relatively efficiently on either a +68020/68881 or a 68030 or a 68040. +.TP +.B \-mfpa +Generate output containing Sun FPA instructions for floating point. +.TP +.B \-msoft\-float +Generate output containing library calls for floating point. +.I +WARNING: +the requisite libraries are not part of GNU CC. Normally the +facilities of the machine's usual C compiler are used, but this can't +be done directly in cross-compilation. You must make your own +arrangements to provide suitable library functions for cross-compilation. +.TP +.B \-mshort +Consider type \c +.B int\c +\& to be 16 bits wide, like \c +.B short int\c +\&. +.TP +.B \-mnobitfield +Do not use the bit-field instructions. `\|\c +.B \-m68000\c +\&\|' implies +`\|\c +.B \-mnobitfield\c +\&\|'. +.TP +.B \-mbitfield +Do use the bit-field instructions. `\|\c +.B \-m68020\c +\&\|' implies +`\|\c +.B \-mbitfield\c +\&\|'. This is the default if you use the unmodified +sources. +.TP +.B \-mrtd +Use a different function-calling convention, in which functions +that take a fixed number of arguments return with the \c +.B rtd\c +\& +instruction, which pops their arguments while returning. This +saves one instruction in the caller since there is no need to pop +the arguments there. + +This calling convention is incompatible with the one normally +used on Unix, so you cannot use it if you need to call libraries +compiled with the Unix compiler. + +Also, you must provide function prototypes for all functions that +take variable numbers of arguments (including \c +.B printf\c +\&); +otherwise incorrect code will be generated for calls to those +functions. + +In addition, seriously incorrect code will result if you call a +function with too many arguments. (Normally, extra arguments are +harmlessly ignored.) + +The \c +.B rtd\c +\& instruction is supported by the 68010 and 68020 +processors, but not by the 68000. +.PP + +These `\|\c +.B \-m\c +\&\|' options are defined for the Vax: +.TP +.B \-munix +Do not output certain jump instructions (\c +.B aobleq\c +\& and so on) +that the Unix assembler for the Vax cannot handle across long +ranges. +.TP +.B \-mgnu +Do output those jump instructions, on the assumption that you +will assemble with the GNU assembler. +.TP +.B \-mg +Output code for g-format floating point numbers instead of d-format. +.PP + +These `\|\c +.B \-m\c +\&\|' switches are supported on the SPARC: + +.PP +.B \-mfpu +.TP +.B \-mhard\-float +Generate output containing floating point instructions. This is the +default. +.PP +.B \-mno\-fpu +.TP +.B \-msoft\-float +Generate output containing library calls for floating point. +.I Warning: +there is no GNU floating-point library for SPARC. +Normally the facilities of the machine's usual C compiler are used, but +this cannot be done directly in cross-compilation. You must make your +own arrangements to provide suitable library functions for +cross-compilation. + +.B \-msoft\-float +changes the calling convention in the output file; +therefore, it is only useful if you compile +.I all +of a program with this option. +.PP +.B \-mno\-epilogue +.TP +.B \-mepilogue +With +.B \-mepilogue +(the default), the compiler always emits code for +function exit at the end of each function. Any function exit in +the middle of the function (such as a return statement in C) will +generate a jump to the exit code at the end of the function. + +With +.BR \-mno\-epilogue , +the compiler tries to emit exit code inline at every function exit. +.PP +.B \-mv8 +.TP +.B \-msparclite +These two options select variations on the SPARC architecture. + +By default (unless specifically configured for the Fujitsu SPARClite), +GCC generates code for the v7 variant of the SPARC architecture. + +.B \-mv8 +will give you SPARC v8 code. The only difference from v7 +code is that the compiler emits the integer multiply and integer +divide instructions which exist in SPARC v8 but not in SPARC v7. + +.B \-msparclite +will give you SPARClite code. This adds the integer +multiply, integer divide step and scan (ffs) instructions which +exist in SPARClite but not in SPARC v7. +.PP + +These `\|\c +.B \-m\c +\&\|' options are defined for the Convex: +.TP +.B \-mc1 +Generate output for a C1. This is the default when the compiler is +configured for a C1. +.TP +.B \-mc2 +Generate output for a C2. This is the default when the compiler is +configured for a C2. +.TP +.B \-margcount +Generate code which puts an argument count in the word preceding each +argument list. Some nonportable Convex and Vax programs need this word. +(Debuggers don't, except for functions with variable-length argument +lists; this info is in the symbol table.) +.TP +.B \-mnoargcount +Omit the argument count word. This is the default if you use the +unmodified sources. +.PP + +These `\|\c +.B \-m\c +\&\|' options are defined for the AMD Am29000: +.TP +.B \-mdw +Generate code that assumes the DW bit is set, i.e., that byte and +halfword operations are directly supported by the hardware. This is the +default. +.TP +.B \-mnodw +Generate code that assumes the DW bit is not set. +.TP +.B \-mbw +Generate code that assumes the system supports byte and halfword write +operations. This is the default. +.TP +.B \-mnbw +Generate code that assumes the systems does not support byte and +halfword write operations. This implies `\|\c +.B \-mnodw\c +\&\|'. +.TP +.B \-msmall +Use a small memory model that assumes that all function addresses are +either within a single 256 KB segment or at an absolute address of less +than 256K. This allows the \c +.B call\c +\& instruction to be used instead +of a \c +.B const\c +\&, \c +.B consth\c +\&, \c +.B calli\c +\& sequence. +.TP +.B \-mlarge +Do not assume that the \c +.B call\c +\& instruction can be used; this is the +default. +.TP +.B \-m29050 +Generate code for the Am29050. +.TP +.B \-m29000 +Generate code for the Am29000. This is the default. +.TP +.B \-mkernel\-registers +Generate references to registers \c +.B gr64-gr95\c +\& instead of +\c +.B gr96-gr127\c +\&. This option can be used when compiling kernel code +that wants a set of global registers disjoint from that used by +user-mode code. + +Note that when this option is used, register names in `\|\c +.B \-f\c +\&\|' flags +must use the normal, user-mode, names. +.TP +.B \-muser\-registers +Use the normal set of global registers, \c +.B gr96-gr127\c +\&. This is the +default. +.TP +.B \-mstack\-check +Insert a call to \c +.B __msp_check\c +\& after each stack adjustment. This +is often used for kernel code. +.PP + +These `\|\c +.B \-m\c +\&\|' options are defined for Motorola 88K architectures: +.TP +.B \-m88000 +Generate code that works well on both the m88100 and the +m88110. +.TP +.B \-m88100 +Generate code that works best for the m88100, but that also +runs on the m88110. +.TP +.B \-m88110 +Generate code that works best for the m88110, and may not run +on the m88100. +.TP +.B \-midentify\-revision +Include an \c +.B ident\c +\& directive in the assembler output recording the +source file name, compiler name and version, timestamp, and compilation +flags used. +.TP +.B \-mno\-underscores +In assembler output, emit symbol names without adding an underscore +character at the beginning of each name. The default is to use an +underscore as prefix on each name. +.TP +.B \-mno\-check\-zero\-division +.TP +.B \-mcheck\-zero\-division +Early models of the 88K architecture had problems with division by zero; +in particular, many of them didn't trap. Use these options to avoid +including (or to include explicitly) additional code to detect division +by zero and signal an exception. All GCC configurations for the 88K use +`\|\c +.B \-mcheck\-zero\-division\c +\&\|' by default. +.TP +.B \-mocs\-debug\-info +.TP +.B \-mno\-ocs\-debug\-info +Include (or omit) additional debugging information (about +registers used in each stack frame) as specified in the 88Open Object +Compatibility Standard, ``OCS''. This extra information is not needed +by GDB. The default for DG/UX, SVr4, and Delta 88 SVr3.2 is to +include this information; other 88k configurations omit this information +by default. +.TP +.B \-mocs\-frame\-position +.TP +.B \-mno\-ocs\-frame\-position +Force (or do not require) register values to be stored in a particular +place in stack frames, as specified in OCS. The DG/UX, Delta88 SVr3.2, +and BCS configurations use `\|\c +.B \-mocs\-frame\-position\c +\&\|'; other 88k +configurations have the default `\|\c +.B \-mno\-ocs\-frame\-position\c +\&\|'. +.TP +.B \-moptimize\-arg\-area +.TP +.B \-mno\-optimize\-arg\-area +Control how to store function arguments in stack frames. +`\|\c +.B \-moptimize\-arg\-area\c +\&\|' saves space, but may break some +debuggers (not GDB). `\|\c +.B \-mno\-optimize\-arg\-area\c +\&\|' conforms better to +standards. By default GCC does not optimize the argument area. +.TP +.BI "\-mshort\-data\-" "num"\c +\& +.I num\c +\& +Generate smaller data references by making them relative to \c +.B r0\c +\&, +which allows loading a value using a single instruction (rather than the +usual two). You control which data references are affected by +specifying \c +.I num\c +\& with this option. For example, if you specify +`\|\c +.B \-mshort\-data\-512\c +\&\|', then the data references affected are those +involving displacements of less than 512 bytes. +`\|\c +.B \-mshort\-data\-\c +.I num\c +\&\c +\&\|' is not effective for \c +.I num\c +\& greater +than 64K. +.PP +.B \-mserialize-volatile +.TP +.B \-mno-serialize-volatile +Do, or do not, generate code to guarantee sequential consistency of +volatile memory references. + +GNU CC always guarantees consistency by default, for the preferred +processor submodel. How this is done depends on the submodel. + +The m88100 processor does not reorder memory references and so always +provides sequential consistency. If you use `\|\c +.B \-m88100\c +\&\|', GNU CC does +not generate any special instructions for sequential consistency. + +The order of memory references made by the m88110 processor does not +always match the order of the instructions requesting those references. +In particular, a load instruction may execute before a preceding store +instruction. Such reordering violates sequential consistency of +volatile memory references, when there are multiple processors. When +you use `\|\c +.B \-m88000\c +\&\|' or `\|\c +.B \-m88110\c +\&\|', GNU CC generates special +instructions when appropriate, to force execution in the proper order. + +The extra code generated to guarantee consistency may affect the +performance of your application. If you know that you can safely forgo +this guarantee, you may use the option `\|\c +.B \-mno-serialize-volatile\c +\&\|'. + +If you use the `\|\c +.B \-m88100\c +\&\|' option but require sequential consistency +when running on the m88110 processor, you should use +`\|\c +.B \-mserialize-volatile\c +\&\|'. +.PP +.B \-msvr4 +.TP +.B \-msvr3 +Turn on (`\|\c +.B \-msvr4\c +\&\|') or off (`\|\c +.B \-msvr3\c +\&\|') compiler extensions +related to System V release 4 (SVr4). This controls the following: +.TP +\ \ \ \(bu +Which variant of the assembler syntax to emit (which you can select +independently using `\|\c +.B \-mversion\-03.00\c +\&\|'). +.TP +\ \ \ \(bu +`\|\c +.B \-msvr4\c +\&\|' makes the C preprocessor recognize `\|\c +.B #pragma weak\c +\&\|' +.TP +\ \ \ \(bu +`\|\c +.B \-msvr4\c +\&\|' makes GCC issue additional declaration directives used in +SVr4. +.PP +`\|\c +.B \-msvr3\c +\&\|' is the default for all m88K configurations except +the SVr4 configuration. +.TP +.B \-mtrap\-large\-shift +.TP +.B \-mhandle\-large\-shift +Include code to detect bit-shifts of more than 31 bits; respectively, +trap such shifts or emit code to handle them properly. By default GCC +makes no special provision for large bit shifts. +.TP +.B \-muse\-div\-instruction +Very early models of the 88K architecture didn't have a divide +instruction, so GCC avoids that instruction by default. Use this option +to specify that it's safe to use the divide instruction. +.TP +.B \-mversion\-03.00 +In the DG/UX configuration, there are two flavors of SVr4. This option +modifies +.B \-msvr4 +to select whether the hybrid-COFF or real-ELF +flavor is used. All other configurations ignore this option. +.TP +.B \-mwarn\-passed\-structs +Warn when a function passes a struct as an argument or result. +Structure-passing conventions have changed during the evolution of the C +language, and are often the source of portability problems. By default, +GCC issues no such warning. +.PP +These options are defined for the IBM RS6000: + +.PP +.B \-mfp\-in\-toc +.TP +.B \-mno\-fp\-in\-toc +Control whether or not floating-point constants go in the Table of +Contents (TOC), a table of all global variable and function addresses. By +default GCC puts floating-point constants there; if the TOC overflows, +`\|\c +.B \-mno\-fp\-in\-toc\c +\&\|' will reduce the size of the TOC, which may avoid +the overflow. + +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the IBM RT PC: +.TP +.B \-min\-line\-mul +Use an in-line code sequence for integer multiplies. This is the +default. +.TP +.B \-mcall\-lib\-mul +Call \c +.B lmul$$\c +\& for integer multiples. +.TP +.B \-mfull\-fp\-blocks +Generate full-size floating point data blocks, including the minimum +amount of scratch space recommended by IBM. This is the default. +.TP +.B \-mminimum\-fp\-blocks +Do not include extra scratch space in floating point data blocks. This +results in smaller code, but slower execution, since scratch space must +be allocated dynamically. +.TP +.B \-mfp\-arg\-in\-fpregs +Use a calling sequence incompatible with the IBM calling convention in +which floating point arguments are passed in floating point registers. +Note that \c +.B varargs.h\c +\& and \c +.B stdargs.h\c +\& will not work with +floating point operands if this option is specified. +.TP +.B \-mfp\-arg\-in\-gregs +Use the normal calling convention for floating point arguments. This is +the default. +.TP +.B \-mhc\-struct\-return +Return structures of more than one word in memory, rather than in a +register. This provides compatibility with the MetaWare HighC (hc) +compiler. Use `\|\c +.B \-fpcc\-struct\-return\c +\&\|' for compatibility with the +Portable C Compiler (pcc). +.TP +.B \-mnohc\-struct\-return +Return some structures of more than one word in registers, when +convenient. This is the default. For compatibility with the +IBM-supplied compilers, use either `\|\c +.B \-fpcc\-struct\-return\c +\&\|' or +`\|\c +.B \-mhc\-struct\-return\c +\&\|'. +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the MIPS family of computers: +.TP +.BI "\-mcpu=" "cpu-type" +Assume the defaults for the machine type +.I cpu-type +when +scheduling instructions. The default +.I cpu-type +is +.BR default , +which picks the longest cycles times for any of the machines, in order +that the code run at reasonable rates on all MIPS cpu's. Other +choices for +.I cpu-type +are +.BR r2000 , +.BR r3000 , +.BR r4000 , +and +.BR r6000 . +While picking a specific +.I cpu-type +will schedule things appropriately for that particular chip, the +compiler will not generate any code that does not meet level 1 of the +MIPS ISA (instruction set architecture) without the +.B \-mips2 +or +.B \-mips3 +switches being used. +.TP +.B \-mips2 +Issue instructions from level 2 of the MIPS ISA (branch likely, square +root instructions). The +.B \-mcpu=r4000 +or +.B \-mcpu=r6000 +switch must be used in conjunction with +.BR \-mips2 . +.TP +.B \-mips3 +Issue instructions from level 3 of the MIPS ISA (64 bit instructions). +The +.B \-mcpu=r4000 +switch must be used in conjunction with +.BR \-mips2 . +.TP +.B \-mint64 +.TP +.B \-mlong64 +.TP +.B \-mlonglong128 +These options don't work at present. +.TP +.B \-mmips\-as +Generate code for the MIPS assembler, and invoke +.B mips\-tfile +to add normal debug information. This is the default for all +platforms except for the OSF/1 reference platform, using the OSF/rose +object format. If any of the +.BR \-ggdb , +.BR \-gstabs , +or +.B \-gstabs+ +switches are used, the +.B mips\-tfile +program will encapsulate the stabs within MIPS ECOFF. +.TP +.B \-mgas +Generate code for the GNU assembler. This is the default on the OSF/1 +reference platform, using the OSF/rose object format. +.TP +.B \-mrnames +.TP +.B \-mno\-rnames +The +.B \-mrnames +switch says to output code using the MIPS software names for the +registers, instead of the hardware names (ie, +.B a0 +instead of +.BR $4 ). +The GNU assembler does not support the +.B \-mrnames +switch, and the MIPS assembler will be instructed to run the MIPS C +preprocessor over the source file. The +.B \-mno\-rnames +switch is default. +.TP +.B \-mgpopt +.TP +.B \-mno\-gpopt +The +.B \-mgpopt +switch says to write all of the data declarations before the +instructions in the text section, to all the MIPS assembler to +generate one word memory references instead of using two words for +short global or static data items. This is on by default if +optimization is selected. +.TP +.B \-mstats +.TP +.B \-mno\-stats +For each non-inline function processed, the +.B \-mstats +switch causes the compiler to emit one line to the standard error file +to print statistics about the program (number of registers saved, +stack size, etc.). +.TP +.B \-mmemcpy +.TP +.B \-mno\-memcpy +The +.B \-mmemcpy +switch makes all block moves call the appropriate string function +.RB ( memcpy +or +.BR bcopy ) +instead of possibly generating inline code. +.TP +.B \-mmips\-tfile +.TP +.B \-mno\-mips\-tfile +The +.B \-mno\-mips\-tfile +switch causes the compiler not postprocess the object file with the +.B mips\-tfile +program, after the MIPS assembler has generated it to add debug +support. If +.B mips\-tfile +is not run, then no local variables will be available to the debugger. +In addition, +.B stage2 +and +.B stage3 +objects will have the temporary file names passed to the assembler +embedded in the object file, which means the objects will not compare +the same. +.TP +.B \-msoft\-float +Generate output containing library calls for floating point. +.I +WARNING: +the requisite libraries are not part of GNU CC. Normally the +facilities of the machine's usual C compiler are used, but this can't +be done directly in cross-compilation. You must make your own +arrangements to provide suitable library functions for cross-compilation. +.TP +.B \-mhard\-float +Generate output containing floating point instructions. This is the +default if you use the unmodified sources. +.TP +.B \-mfp64 +Assume that the +.B FR +bit in the status word is on, and that there are 32 64-bit floating +point registers, instead of 32 32-bit floating point registers. You +must also specify the +.B \-mcpu=r4000 +and +.B \-mips3 +switches. +.TP +.B \-mfp32 +Assume that there are 32 32-bit floating point registers. This is the +default. +.PP +.B \-mabicalls +.TP +.B \-mno\-abicalls +Emit (or do not emit) the +.BR \&.abicalls , +.BR \&.cpload , +and +.B \&.cprestore +pseudo operations that some System V.4 ports use for position +independent code. +.TP +.B \-mhalf\-pic +.TP +.B \-mno\-half\-pic +The +.B \-mhalf\-pic +switch says to put pointers to extern references into the data section +and load them up, rather than put the references in the text section. +This option does not work at present. +.B +.BI \-G num +Put global and static items less than or equal to +.I num +bytes into the small data or bss sections instead of the normal data +or bss section. This allows the assembler to emit one word memory +reference instructions based on the global pointer +.RB ( gp +or +.BR $28 ), +instead of the normal two words used. By default, +.I num +is 8 when the MIPS assembler is used, and 0 when the GNU +assembler is used. The +.BI \-G num +switch is also passed to the assembler and linker. All modules should +be compiled with the same +.BI \-G num +value. +.TP +.B \-nocpp +Tell the MIPS assembler to not run it's preprocessor over user +assembler files (with a `\|\c +.B .s\c +\&\|' suffix) when assembling them. +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the Intel 80386 family of computers: + +.B \-m486 +.TP +.B \-mno\-486 +Control whether or not code is optimized for a 486 instead of an +386. Code generated for a 486 will run on a 386 and vice versa. +.TP +.B \-msoft\-float +Generate output containing library calls for floating point. +.I Warning: +the requisite libraries are not part of GNU CC. +Normally the facilities of the machine's usual C compiler are used, but +this can't be done directly in cross-compilation. You must make your +own arrangements to provide suitable library functions for +cross-compilation. + +On machines where a function returns floating point results in the 80387 +register stack, some floating point opcodes may be emitted even if +`\|\c +.B \-msoft-float\c +\&\|' is used. +.TP +.B \-mno-fp-ret-in-387 +Do not use the FPU registers for return values of functions. + +The usual calling convention has functions return values of types +\c +.B float\c +\& and \c +.B double\c +\& in an FPU register, even if there +is no FPU. The idea is that the operating system should emulate +an FPU. + +The option `\|\c +.B \-mno-fp-ret-in-387\c +\&\|' causes such values to be returned +in ordinary CPU registers instead. +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the HPPA family of computers: +.TP +.B \-mpa-risc-1-0 +Generate code for a PA 1.0 processor. +.TP +.B \-mpa-risc-1-1 +Generate code for a PA 1.1 processor. +.TP +.B \-mkernel +Generate code which is suitable for use in kernels. Specifically, avoid +\c +.B add\c +\& instructions in which one of the arguments is the DP register; +generate \c +.B addil\c +\& instructions instead. This avoids a rather serious +bug in the HP-UX linker. +.TP +.B \-mshared-libs +Generate code that can be linked against HP-UX shared libraries. This option +is not fully function yet, and is not on by default for any PA target. Using +this option can cause incorrect code to be generated by the compiler. +.TP +.B \-mno-shared-libs +Don't generate code that will be linked against shared libraries. This is +the default for all PA targets. +.TP +.B \-mlong-calls +Generate code which allows calls to functions greater than 256K away from +the caller when the caller and callee are in the same source file. Do +not turn this option on unless code refuses to link with "branch out of +range errors" from the linker. +.TP +.B \-mdisable-fpregs +Prevent floating point registers from being used in any manner. This is +necessary for compiling kernels which perform lazy context switching of +floating point registers. If you use this option and attempt to perform +floating point operations, the compiler will abort. +.TP +.B \-mdisable-indexing +Prevent the compiler from using indexing address modes. This avoids some +rather obscure problems when compiling MIG generated code under MACH. +.TP +.B \-mtrailing-colon +Add a colon to the end of label definitions (for ELF assemblers). +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the Intel 80960 family of computers: +.TP +.BI "\-m" "cpu-type" +Assume the defaults for the machine type +.I cpu-type +for instruction and addressing-mode availability and alignment. +The default +.I cpu-type +is +.BR kb ; +other choices are +.BR ka , +.BR mc , +.BR ca , +.BR cf , +.BR sa , +and +.BR sb . +.TP +.B \-mnumerics +.TP +.B \-msoft\-float +The +.B \-mnumerics +option indicates that the processor does support +floating-point instructions. The +.B \-msoft\-float +option indicates +that floating-point support should not be assumed. +.TP +.B \-mleaf\-procedures +.TP +.B \-mno\-leaf\-procedures +Do (or do not) attempt to alter leaf procedures to be callable with the +.I bal +instruction as well as +.IR call . +This will result in more +efficient code for explicit calls when the +.I bal +instruction can be +substituted by the assembler or linker, but less efficient code in other +cases, such as calls via function pointers, or using a linker that doesn't +support this optimization. +.TP +.B \-mtail\-call +.TP +.B \-mno\-tail\-call +Do (or do not) make additional attempts (beyond those of the +machine-independent portions of the compiler) to optimize tail-recursive +calls into branches. You may not want to do this because the detection of +cases where this is not valid is not totally complete. The default is +.BR \-mno\-tail\-call . +.TP +.B \-mcomplex\-addr +.TP +.B \-mno\-complex\-addr +Assume (or do not assume) that the use of a complex addressing mode is a +win on this implementation of the i960. Complex addressing modes may not +be worthwhile on the K-series, but they definitely are on the C-series. +The default is currently +.B \-mcomplex\-addr +for all processors except +the CB and CC. +.TP +.B \-mcode\-align +.TP +.B \-mno\-code\-align +Align code to 8-byte boundaries for faster fetching (or don't bother). +Currently turned on by default for C-series implementations only. +.TP +.B \-mic\-compat +.TP +.B \-mic2.0\-compat +.TP +.B \-mic3.0\-compat +Enable compatibility with iC960 v2.0 or v3.0. +.TP +.B \-masm\-compat +.TP +.B \-mintel\-asm +Enable compatibility with the iC960 assembler. +.TP +.B \-mstrict\-align +.TP +.B \-mno\-strict\-align +Do not permit (do permit) unaligned accesses. +.TP +.B \-mold\-align +Enable structure-alignment compatibility with Intel's gcc release version +1.3 (based on gcc 1.37). Currently this is buggy in that +.B #pragma align 1 +is always assumed as well, and cannot be turned off. +.PP +These `\|\c +.B \-m\c +\&\|' options are defined for the DEC Alpha implementations: +.TP +.B \-mno-soft-float +.TP +.B \-msoft-float +Use (do not use) the hardware floating-point instructions for +floating-point operations. When \c +.B \-msoft-float\c +\& is specified, +functions in `\|\c +.B libgcc1.c\c +\&\|' will be used to perform floating-point +operations. Unless they are replaced by routines that emulate the +floating-point operations, or compiled in such a way as to call such +emulations routines, these routines will issue floating-point +operations. If you are compiling for an Alpha without floating-point +operations, you must ensure that the library is built so as not to call +them. + +Note that Alpha implementations without floating-point operations are +required to have floating-point registers. +.TP +.B \-mfp-reg +.TP +.B \-mno-fp-regs +Generate code that uses (does not use) the floating-point register set. +.B \-mno-fp-regs\c +\& implies \c +.B \-msoft-float\c +\&. If the floating-point +register set is not used, floating point operands are passed in integer +registers as if they were integers and floating-point results are passed +in $0 instead of $f0. This is a non-standard calling sequence, so any +function with a floating-point argument or return value called by code +compiled with \c +.B \-mno-fp-regs\c +\& must also be compiled with that +option. + +A typical use of this option is building a kernel that does not use, +and hence need not save and restore, any floating-point registers. +.PP +These additional options are available on System V Release 4 for +compatibility with other compilers on those systems: +.TP +.B \-G +On SVr4 systems, \c +.B gcc\c +\& accepts the option `\|\c +.B \-G\c +\&\|' (and passes +it to the system linker), for compatibility with other compilers. +However, we suggest you use `\|\c +.B \-symbolic\c +\&\|' or `\|\c +.B \-shared\c +\&\|' as +appropriate, instead of supplying linker options on the \c +.B gcc\c +\& +command line. +.TP +.B \-Qy +Identify the versions of each tool used by the compiler, in a +\c +.B .ident\c +\& assembler directive in the output. +.TP +.B \-Qn +Refrain from adding \c +.B .ident\c +\& directives to the output file (this is +the default). +.TP +.BI "-YP," "dirs"\c +\& +Search the directories \c +.I dirs\c +\&, and no others, for libraries +specified with `\|\c +.B \-l\c +\&\|'. You can separate directory entries in +\c +.I dirs\c +\& from one another with colons. +.TP +.BI "-Ym," "dir"\c +\& +Look in the directory \c +.I dir\c +\& to find the M4 preprocessor. +The assembler uses this option. +.PP + +.SH CODE GENERATION OPTIONS +These machine-independent options control the interface conventions +used in code generation. + +Most of them begin with `\|\c +\-f\c +\&\|'. These options have both positive and negative forms; the negative form +of `\|\c +.B \-ffoo\c +\&\|' would be `\|\c +.B \-fno\-foo\c +\&\|'. In the table below, only +one of the forms is listed\(em\&the one which is not the default. You +can figure out the other form by either removing `\|\c +.B no\-\c +\&\|' or adding +it. +.TP +.B \-fnonnull\-objects +Assume that objects reached through references are not null +(C++ only). + +Normally, GNU C++ makes conservative assumptions about objects reached +through references. For example, the compiler must check that \c +.B a\c +\& +is not null in code like the following: + +.sp +.br +obj\ &a\ =\ g\ (); +.br +a.f\ (2); +.br +.sp + +Checking that references of this sort have non-null values requires +extra code, however, and it is unnecessary for many programs. You can +use `\|\c +.B \-fnonnull-objects\c +\&\|' to omit the checks for null, if your +program doesn't require checking. +.TP +.B \-fpcc\-struct\-return +Use the same convention for returning \c +.B struct\c +\& and \c +.B union\c +\& +values that is used by the usual C compiler on your system. This +convention is less efficient for small structures, and on many +machines it fails to be reentrant; but it has the advantage of +allowing intercallability between GCC-compiled code and PCC-compiled +code. +.TP +.B \-freg\-struct\-return +Use the convention that +.B struct +and +.B union +values are returned in registers when possible. This is more +efficient for small structures than +.BR \-fpcc\-struct\-return . + +If you specify neither +.B \-fpcc\-struct\-return +nor +.BR \-freg\-struct\-return , +GNU CC defaults to whichever convention is standard for the target. +If there is no standard convention, GNU CC defaults to +.BR \-fpcc\-struct\-return . +.TP +.B \-fshort\-enums +Allocate to an \c +.B enum\c +\& type only as many bytes as it needs for the +declared range of possible values. Specifically, the \c +.B enum\c +\& type +will be equivalent to the smallest integer type which has enough room. +.TP +.B \-fshort\-double +Use the same size for +.B double +as for +.B float +\&. +.TP +.B \-fshared\-data +Requests that the data and non-\c +.B const\c +\& variables of this +compilation be shared data rather than private data. The distinction +makes sense only on certain operating systems, where shared data is +shared between processes running the same program, while private data +exists in one copy per process. +.TP +.B \-fno\-common +Allocate even uninitialized global variables in the bss section of the +object file, rather than generating them as common blocks. This has the +effect that if the same variable is declared (without \c +.B extern\c +\&) in +two different compilations, you will get an error when you link them. +The only reason this might be useful is if you wish to verify that the +program will work on other systems which always work this way. +.TP +.B \-fno\-ident +Ignore the `\|\c +.B #ident\c +\&\|' directive. +.TP +.B \-fno\-gnu\-linker +Do not output global initializations (such as C++ constructors and +destructors) in the form used by the GNU linker (on systems where the GNU +linker is the standard method of handling them). Use this option when +you want to use a non-GNU linker, which also requires using the +\c +.B collect2\c +\& program to make sure the system linker includes +constructors and destructors. (\c +.B collect2\c +\& is included in the GNU CC +distribution.) For systems which \c +.I must\c +\& use \c +.B collect2\c +\&, the +compiler driver \c +.B gcc\c +\& is configured to do this automatically. +.TP +.B \-finhibit-size-directive +Don't output a \c +.B .size\c +\& assembler directive, or anything else that +would cause trouble if the function is split in the middle, and the +two halves are placed at locations far apart in memory. This option is +used when compiling `\|\c +.B crtstuff.c\c +\&\|'; you should not need to use it +for anything else. +.TP +.B \-fverbose-asm +Put extra commentary information in the generated assembly code to +make it more readable. This option is generally only of use to those +who actually need to read the generated assembly code (perhaps while +debugging the compiler itself). +.TP +.B \-fvolatile +Consider all memory references through pointers to be volatile. +.TP +.B \-fvolatile\-global +Consider all memory references to extern and global data items to +be volatile. +.TP +.B \-fpic +If supported for the target machines, generate position-independent code, +suitable for use in a shared library. +.TP +.B \-fPIC +If supported for the target machine, emit position-independent code, +suitable for dynamic linking, even if branches need large displacements. +.TP +.BI "\-ffixed\-" "reg"\c +\& +Treat the register named \c +.I reg\c +\& as a fixed register; generated code +should never refer to it (except perhaps as a stack pointer, frame +pointer or in some other fixed role). + +\c +.I reg\c +\& must be the name of a register. The register names accepted +are machine-specific and are defined in the \c +.B REGISTER_NAMES\c +\& +macro in the machine description macro file. + +This flag does not have a negative form, because it specifies a +three-way choice. +.TP +.BI "\-fcall\-used\-" "reg"\c +\& +Treat the register named \c +.I reg\c +\& as an allocatable register that is +clobbered by function calls. It may be allocated for temporaries or +variables that do not live across a call. Functions compiled this way +will not save and restore the register \c +.I reg\c +\&. + +Use of this flag for a register that has a fixed pervasive role in the +machine's execution model, such as the stack pointer or frame pointer, +will produce disastrous results. + +This flag does not have a negative form, because it specifies a +three-way choice. +.TP +.BI "\-fcall\-saved\-" "reg"\c +\& +Treat the register named \c +.I reg\c +\& as an allocatable register saved by +functions. It may be allocated even for temporaries or variables that +live across a call. Functions compiled this way will save and restore +the register \c +.I reg\c +\& if they use it. + +Use of this flag for a register that has a fixed pervasive role in the +machine's execution model, such as the stack pointer or frame pointer, +will produce disastrous results. + +A different sort of disaster will result from the use of this flag for +a register in which function values may be returned. + +This flag does not have a negative form, because it specifies a +three-way choice. +.PP + +.SH PRAGMAS +Two `\|\c +.B #pragma\c +\&\|' directives are supported for GNU C++, to permit using the same +header file for two purposes: as a definition of interfaces to a given +object class, and as the full definition of the contents of that object class. +.TP +.B #pragma interface +(C++ only.) +Use this directive in header files that define object classes, to save +space in most of the object files that use those classes. Normally, +local copies of certain information (backup copies of inline member +functions, debugging information, and the internal tables that +implement virtual functions) must be kept in each object file that +includes class definitions. You can use this pragma to avoid such +duplication. When a header file containing `\|\c +.B #pragma interface\c +\&\|' is included in a compilation, this auxiliary information +will not be generated (unless the main input source file itself uses +`\|\c +.B #pragma implementation\c +\&\|'). Instead, the object files will contain references to be +resolved at link time. +.tr !" +.TP +.B #pragma implementation +.TP +.BI "#pragma implementation !" objects .h! +(C++ only.) +Use this pragma in a main input file, when you want full output from +included header files to be generated (and made globally visible). +The included header file, in turn, should use `\|\c +.B #pragma interface\c +\&\|'. +Backup copies of inline member functions, debugging information, and +the internal tables used to implement virtual functions are all +generated in implementation files. + +If you use `\|\c +.B #pragma implementation\c +\&\|' with no argument, it applies to an include file with the same +basename as your source file; for example, in `\|\c +.B allclass.cc\c +\&\|', `\|\c +.B #pragma implementation\c +\&\|' by itself is equivalent to `\|\c +.B +#pragma implementation "allclass.h"\c +\&\|'. Use the string argument if you want a single implementation +file to include code from multiple header files. + +There is no way to split up the contents of a single header file into +multiple implementation files. +.SH FILES +.ta \w'LIBDIR/g++\-include 'u +file.c C source file +.br +file.h C header (preprocessor) file +.br +file.i preprocessed C source file +.br +file.C C++ source file +.br +file.cc C++ source file +.br +file.cxx C++ source file +.br +file.m Objective-C source file +.br +file.s assembly language file +.br +file.o object file +.br +a.out link edited output +.br +\fITMPDIR\fR/cc\(** temporary files +.br +\fILIBDIR\fR/cpp preprocessor +.br +\fILIBDIR\fR/cc1 compiler for C +.br +\fILIBDIR\fR/cc1plus compiler for C++ +.br +\fILIBDIR\fR/collect linker front end needed on some machines +.br +\fILIBDIR\fR/libgcc.a GCC subroutine library +.br +/lib/crt[01n].o start-up routine +.br +\fILIBDIR\fR/ccrt0 additional start-up routine for C++ +.br +/lib/libc.a standard C library, see +.IR intro (3) +.br +/usr/include standard directory for +.B #include +files +.br +\fILIBDIR\fR/include standard gcc directory for +.B #include +files +.br +\fILIBDIR\fR/g++\-include additional g++ directory for +.B #include +.sp +.I LIBDIR +is usually +.B /usr/local/lib/\c +.IR machine / version . +.br +.I TMPDIR +comes from the environment variable +.B TMPDIR +(default +.B /usr/tmp +if available, else +.B /tmp\c +\&). +.SH "SEE ALSO" +cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). +.br +.RB "`\|" gcc "\|', `\|" cpp \|', +.RB `\| as \|', `\| ld \|', +and +.RB `\| gdb \|' +entries in +.B info\c +\&. +.br +.I +Using and Porting GNU CC (for version 2.0)\c +, Richard M. Stallman; +.I +The C Preprocessor\c +, Richard M. Stallman; +.I +Debugging with GDB: the GNU Source-Level Debugger\c +, Richard M. Stallman and Roland H. Pesch; +.I +Using as: the GNU Assembler\c +, Dean Elsner, Jay Fenlason & friends; +.I +ld: the GNU linker\c +, Steve Chamberlain and Roland Pesch. + +.SH BUGS +For instructions on reporting bugs, see the GCC manual. + +.SH COPYING +Copyright (c) 1991, 1992, 1993 Free Software Foundation, Inc. +.PP +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. +.PP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.PP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.SH AUTHORS +See the GNU CC Manual for the contributors to GNU CC. diff --git a/gnu/gcc2/cc/gcc.c b/gnu/gcc2/cc/gcc.c new file mode 100644 index 000000000000..5470d9e7f739 --- /dev/null +++ b/gnu/gcc2/cc/gcc.c @@ -0,0 +1,4242 @@ +/* Compiler driver program that can handle many languages. + Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. + +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, 675 Mass Ave, Cambridge, MA 02139, USA. + +This paragraph is here to try to keep Sun CC from dying. +The number of chars here seems crucial!!!! */ + +/* This program is the user interface to the C compiler and possibly to +other compilers. It is used because compilation is a complicated procedure +which involves running several programs and passing temporary files between +them, forwarding the users switches to those programs selectively, +and deleting the temporary files at the end. + +CC recognizes how to compile each input file by suffixes in the file names. +Once it knows which kind of compilation to perform, the procedure for +compilation is specified by a string called a "spec". */ + +#include <sys/types.h> +#include <ctype.h> +#include <signal.h> +#include <sys/stat.h> +#include <sys/file.h> /* May get R_OK, etc. on some systems. */ + +#include "config.h" +#include "obstack.h" +#include "gvarargs.h" +#include <stdio.h> + +#ifndef R_OK +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#endif + +/* Define a generic NULL if one hasn't already been defined. */ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef GENERIC_PTR +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define GENERIC_PTR void * +#else +#define GENERIC_PTR char * +#endif +#endif + +#ifndef NULL_PTR +#define NULL_PTR ((GENERIC_PTR)0) +#endif + +#ifdef USG +#define vfork fork +#endif /* USG */ + +/* On MSDOS, write temp files in current dir + because there's no place else we can expect to use. */ +#if __MSDOS__ +#ifndef P_tmpdir +#define P_tmpdir "./" +#endif +#endif + +/* Test if something is a normal file. */ +#ifndef S_ISREG +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif + +/* Test if something is a directory. */ +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +/* By default there is no special suffix for executables. */ +#ifndef EXECUTABLE_SUFFIX +#define EXECUTABLE_SUFFIX "" +#endif + +/* By default, colon separates directories in a path. */ +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR ':' +#endif + +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +extern void free (); +extern char *getenv (); + +extern int errno, sys_nerr; +extern char *sys_errlist[]; + +extern int execv (), execvp (); + +/* If a stage of compilation returns an exit status >= 1, + compilation of that file ceases. */ + +#define MIN_FATAL_STATUS 1 + +/* Flag saying to print the full filename of libgcc.a + as found through our usual search mechanism. */ + +static int print_libgcc_file_name; + +/* Flag indicating whether we should print the command and arguments */ + +static int verbose_flag; + +/* Nonzero means write "temp" files in source directory + and use the source file's name in them, and don't delete them. */ + +static int save_temps_flag; + +/* The compiler version specified with -V */ + +static char *spec_version; + +/* The target machine specified with -b. */ + +static char *spec_machine = ""; + +/* Nonzero if cross-compiling. + When -b is used, the value comes from the `specs' file. */ + +#ifdef CROSS_COMPILE +static int cross_compile = 1; +#else +static int cross_compile = 0; +#endif + +/* The number of errors that have occurred; the link phase will not be + run if this is non-zero. */ +static int error_count = 0; + +/* This is the obstack which we use to allocate many strings. */ + +static struct obstack obstack; + +/* This is the obstack to build an environment variable to pass to + collect2 that describes all of the relevant switches of what to + pass the compiler in building the list of pointers to constructors + and destructors. */ + +static struct obstack collect_obstack; + +extern char *version_string; + +static void set_spec (); +static struct compiler *lookup_compiler (); +static char *find_a_file (); +static void add_prefix (); +static char *skip_whitespace (); +static void record_temp_file (); +static char *handle_braces (); +static char *save_string (); +static char *concat (); +static int do_spec (); +static int do_spec_1 (); +static char *find_file (); +static int is_directory (); +static void validate_switches (); +static void validate_all_switches (); +static void give_switch (); +static void pfatal_with_name (); +static void perror_with_name (); +static void perror_exec (); +static void fatal (); +static void error (); +void fancy_abort (); +char *xmalloc (); +char *xrealloc (); + +/* Specs are strings containing lines, each of which (if not blank) +is made up of a program name, and arguments separated by spaces. +The program name must be exact and start from root, since no path +is searched and it is unreliable to depend on the current working directory. +Redirection of input or output is not supported; the subprograms must +accept filenames saying what files to read and write. + +In addition, the specs can contain %-sequences to substitute variable text +or for conditional text. Here is a table of all defined %-sequences. +Note that spaces are not generated automatically around the results of +expanding these sequences; therefore, you can concatenate them together +or with constant text in a single argument. + + %% substitute one % into the program name or argument. + %i substitute the name of the input file being processed. + %b substitute the basename of the input file being processed. + This is the substring up to (and not including) the last period + and not including the directory. + %g substitute the temporary-file-name-base. This is a string chosen + once per compilation. Different temporary file names are made by + concatenation of constant strings on the end, as in `%g.s'. + %g also has the same effect of %d. + %u like %g, but make the temporary file name unique. + %U returns the last file name generated with %u. + %d marks the argument containing or following the %d as a + temporary file name, so that that file will be deleted if CC exits + successfully. Unlike %g, this contributes no text to the argument. + %w marks the argument containing or following the %w as the + "output file" of this compilation. This puts the argument + into the sequence of arguments that %o will substitute later. + %W{...} + like %{...} but mark last argument supplied within + as a file to be deleted on failure. + %o substitutes the names of all the output files, with spaces + automatically placed around them. You should write spaces + around the %o as well or the results are undefined. + %o is for use in the specs for running the linker. + Input files whose names have no recognized suffix are not compiled + at all, but they are included among the output files, so they will + be linked. + %p substitutes the standard macro predefinitions for the + current target machine. Use this when running cpp. + %P like %p, but puts `__' before and after the name of each macro. + (Except macros that already have __.) + This is for ANSI C. + %I Substitute a -iprefix option made from GCC_EXEC_PREFIX. + %s current argument is the name of a library or startup file of some sort. + Search for that file in a standard list of directories + and substitute the full name found. + %eSTR Print STR as an error message. STR is terminated by a newline. + Use this when inconsistent options are detected. + %x{OPTION} Accumulate an option for %X. + %X Output the accumulated linker options specified by compilations. + %Y Output the accumulated assembler options specified by compilations. + %a process ASM_SPEC as a spec. + This allows config.h to specify part of the spec for running as. + %A process ASM_FINAL_SPEC as a spec. A capital A is actually + used here. This can be used to run a post-processor after the + assembler has done it's job. + %D Dump out a -L option for each directory in startfile_prefix. + %l process LINK_SPEC as a spec. + %L process LIB_SPEC as a spec. + %S process STARTFILE_SPEC as a spec. A capital S is actually used here. + %E process ENDFILE_SPEC as a spec. A capital E is actually used here. + %c process SIGNED_CHAR_SPEC as a spec. + %C process CPP_SPEC as a spec. A capital C is actually used here. + %1 process CC1_SPEC as a spec. + %2 process CC1PLUS_SPEC as a spec. + %| output "-" if the input for the current command is coming from a pipe. + %* substitute the variable part of a matched option. (See below.) + Note that each comma in the substituted string is replaced by + a single space. + %{S} substitutes the -S switch, if that switch was given to CC. + If that switch was not specified, this substitutes nothing. + Here S is a metasyntactic variable. + %{S*} substitutes all the switches specified to CC whose names start + with -S. This is used for -o, -D, -I, etc; switches that take + arguments. CC considers `-o foo' as being one switch whose + name starts with `o'. %{o*} would substitute this text, + including the space; thus, two arguments would be generated. + %{S*:X} substitutes X if one or more switches whose names start with -S are + specified to CC. Note that the tail part of the -S option + (i.e. the part matched by the `*') will be substituted for each + occurrence of %* within X. + %{S:X} substitutes X, but only if the -S switch was given to CC. + %{!S:X} substitutes X, but only if the -S switch was NOT given to CC. + %{|S:X} like %{S:X}, but if no S switch, substitute `-'. + %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'. + %{.S:X} substitutes X, but only if processing a file with suffix S. + %{!.S:X} substitutes X, but only if NOT processing a file with suffix S. + %(Spec) processes a specification defined in a specs file as *Spec: + %[Spec] as above, but put __ around -D arguments + +The conditional text X in a %{S:X} or %{!S:X} construct may contain +other nested % constructs or spaces, or even newlines. They are +processed as usual, as described above. + +The character | is used to indicate that a command should be piped to +the following command, but only if -pipe is specified. + +Note that it is built into CC which switches take arguments and which +do not. You might think it would be useful to generalize this to +allow each compiler's spec to say which switches take arguments. But +this cannot be done in a consistent fashion. CC cannot even decide +which input files have been specified without knowing which switches +take arguments, and it must know which input files to compile in order +to tell which compilers to run. + +CC also knows implicitly that arguments starting in `-l' are to be +treated as compiler output files, and passed to the linker in their +proper position among the other output files. */ + +/* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1. */ + +/* config.h can define ASM_SPEC to provide extra args to the assembler + or extra switch-translations. */ +#ifndef ASM_SPEC +#define ASM_SPEC "" +#endif + +/* config.h can define ASM_FINAL_SPEC to run a post processor after + the assembler has run. */ +#ifndef ASM_FINAL_SPEC +#define ASM_FINAL_SPEC "" +#endif + +/* config.h can define CPP_SPEC to provide extra args to the C preprocessor + or extra switch-translations. */ +#ifndef CPP_SPEC +#define CPP_SPEC "" +#endif + +/* config.h can define CC1_SPEC to provide extra args to cc1 and cc1plus + or extra switch-translations. */ +#ifndef CC1_SPEC +#define CC1_SPEC "" +#endif + +/* config.h can define CC1PLUS_SPEC to provide extra args to cc1plus + or extra switch-translations. */ +#ifndef CC1PLUS_SPEC +#define CC1PLUS_SPEC "" +#endif + +/* config.h can define LINK_SPEC to provide extra args to the linker + or extra switch-translations. */ +#ifndef LINK_SPEC +#define LINK_SPEC "" +#endif + +/* config.h can define LIB_SPEC to override the default libraries. */ +#ifndef LIB_SPEC +#define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" +#endif + +/* config.h can define STARTFILE_SPEC to override the default crt0 files. */ +#ifndef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" +#endif + +/* config.h can define SWITCHES_NEED_SPACES to control passing -o and -L. + Make the string nonempty to require spaces there. */ +#ifndef SWITCHES_NEED_SPACES +#define SWITCHES_NEED_SPACES "" +#endif + +/* config.h can define ENDFILE_SPEC to override the default crtn files. */ +#ifndef ENDFILE_SPEC +#define ENDFILE_SPEC "" +#endif + +/* This spec is used for telling cpp whether char is signed or not. */ +#ifndef SIGNED_CHAR_SPEC +/* Use #if rather than ?: + because MIPS C compiler rejects like ?: in initializers. */ +#if DEFAULT_SIGNED_CHAR +#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}" +#else +#define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}" +#endif +#endif + +static char *cpp_spec = CPP_SPEC; +static char *cpp_predefines = CPP_PREDEFINES; +static char *cc1_spec = CC1_SPEC; +static char *cc1plus_spec = CC1PLUS_SPEC; +static char *signed_char_spec = SIGNED_CHAR_SPEC; +static char *asm_spec = ASM_SPEC; +static char *asm_final_spec = ASM_FINAL_SPEC; +static char *link_spec = LINK_SPEC; +static char *lib_spec = LIB_SPEC; +static char *endfile_spec = ENDFILE_SPEC; +static char *startfile_spec = STARTFILE_SPEC; +static char *switches_need_spaces = SWITCHES_NEED_SPACES; + +/* This defines which switch letters take arguments. */ + +#ifndef SWITCH_TAKES_ARG +#define SWITCH_TAKES_ARG(CHAR) \ + ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ + || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ + || (CHAR) == 'I' || (CHAR) == 'm' \ + || (CHAR) == 'L' || (CHAR) == 'A') +#endif + +/* This defines which multi-letter switches take arguments. */ + +#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ + (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ + || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ + || !strcmp (STR, "iwithprefix")) + +#ifndef WORD_SWITCH_TAKES_ARG +#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) +#endif + +/* Record the mapping from file suffixes for compilation specs. */ + +struct compiler +{ + char *suffix; /* Use this compiler for input files + whose names end in this suffix. */ + + char *spec[4]; /* To use this compiler, concatenate these + specs and pass to do_spec. */ +}; + +/* Pointer to a vector of `struct compiler' that gives the spec for + compiling a file, based on its suffix. + A file that does not end in any of these suffixes will be passed + unchanged to the loader and nothing else will be done to it. + + An entry containing two 0s is used to terminate the vector. + + If multiple entries match a file, the last matching one is used. */ + +static struct compiler *compilers; + +/* Number of entries in `compilers', not counting the null terminator. */ + +static int n_compilers; + +/* The default list of file name suffixes and their compilation specs. */ + +static struct compiler default_compilers[] = +{ + {".c", "@c"}, + {"@c", + "gcpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ + -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs} \ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", + "%{!M:%{!MM:%{!E:gcc1 %{!pipe:%g.i} %1 \ + %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ + %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\ + %{aux-info*}\ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ + %{!pipe:%g.s} %A\n }}}}"}, + {"-", + "%{E:gcpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ + -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs}\ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %W{o*}}\ + %{!E:%e-E required when input is from standard input}"}, + {".m", "@objective-c"}, + {"@objective-c", + "gcpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d}\ + -undef -D__OBJC__ -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs}\ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", + "%{!M:%{!MM:%{!E:gcc1obj %{!pipe:%g.i} %1 \ + %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ + %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ + -lang-objc %{gen-decls} \ + %{aux-info*}\ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ + %{!pipe:%g.s} %A\n }}}}"}, + {".h", "@c-header"}, + {"@c-header", + "%{!E:%eCompilation of header file requested} \ + gcpp %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \ + -undef -D__GNUC__=2 %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!undef:%{!ansi:%p} %P} %{trigraphs}\ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %W{o*}"}, + {".cc", "@c++"}, + {".cxx", "@c++"}, + {".C", "@c++"}, + {"@c++", + "gcpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} \ + -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus \ + %{ansi:-trigraphs -$ -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional} %{trigraphs}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", + "%{!M:%{!MM:%{!E:gcc1plus %{!pipe:%g.i} %1 %2\ + %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ + %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\ + %{aux-info*}\ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ + %{!pipe:%g.s} %A\n }}}}"}, + {".i", "@cpp-output"}, + {"@cpp-output", + "gcc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ + %{v:-version} %{pg:-p} %{p} %{f*}\ + %{aux-info*}\ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %{!pipe:%g.s} %A\n }"}, + {".ii", "@c++-cpp-output"}, + {"@c++-cpp-output", + "gcc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ + %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\ + %{v:-version} %{pg:-p} %{p} %{f*} %{+e*}\ + %{aux-info*}\ + %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ + %{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ + %{!pipe:%g.s} %A\n }"}, + {".s", "@assembler"}, + {"@assembler", + "%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o} %i %A\n }"}, + {".S", "@assembler-with-cpp"}, + {"@assembler-with-cpp", + "gcpp -lang-asm %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + %{C:%{!E:%eGNU C does not support -C without using -E}}\ + %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{trigraphs} \ + -undef -$ %{!undef:%p %P} -D__ASSEMBLER__ \ + %c %{O*:%{!O0:-D__OPTIMIZE__}} %{traditional} %{ftraditional:-traditional}\ + %{traditional-cpp:-traditional}\ + %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*}\ + %i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", + "%{!M:%{!MM:%{!E:%{!S:as %{R} %{j} %{J} %{h} %{d2} %a %Y\ + %{c:%W{o*}%{!o*:-o %w%b.o}}%{!c:-o %d%w%u.o}\ + %{!pipe:%g.s} %A\n }}}}"}, + /* Mark end of table */ + {0, 0} +}; + +/* Number of elements in default_compilers, not counting the terminator. */ + +static int n_default_compilers + = (sizeof default_compilers / sizeof (struct compiler)) - 1; + +/* Here is the spec for running the linker, after compiling all files. */ + +/* -u* was put back because both BSD and SysV seem to support it. */ +/* %{static:} simply prevents an error message if the target machine + doesn't handle -static. */ +#ifdef LINK_LIBGCC_SPECIAL_1 +/* Have gcc do the search for libgcc.a, but generate -L options as usual. */ +static char *link_command_spec = "\ +%{!fsyntax-only: \ + %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ + %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ + %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ + %{L*} %D %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}"; +#else +#ifdef LINK_LIBGCC_SPECIAL +/* Have gcc do the search for libgcc.a, and don't generate -L options. */ +static char *link_command_spec = "\ +%{!fsyntax-only: \ + %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ + %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ + %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ + %{L*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}"; +#else +/* Use -L and have the linker do the search for -lgcc. */ +static char *link_command_spec = "\ +%{!fsyntax-only: \ + %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ + %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\ + %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\ + %{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}"; +#endif +#endif + +/* A vector of options to give to the linker. + These options are accumulated by -Xlinker and -Wl, + and substituted into the linker command with %X. */ +static int n_linker_options; +static char **linker_options; + +/* A vector of options to give to the assembler. + These options are accumulated by -Wa, + and substituted into the assembler command with %X. */ +static int n_assembler_options; +static char **assembler_options; + +/* Define how to map long options into short ones. */ + +/* This structure describes one mapping. */ +struct option_map +{ + /* The long option's name. */ + char *name; + /* The equivalent short option. */ + char *equivalent; + /* Argument info. A string of flag chars; NULL equals no options. + a => argument required. + o => argument optional. + j => join argument to equivalent, making one word. + * => allow other text after NAME as an argument. */ + char *arg_info; +}; + +/* This is the table of mappings. Mappings are tried sequentially + for each option encountered; the first one that matches, wins. */ + +struct option_map option_map[] = + { + {"--profile-blocks", "-a", 0}, + {"--target", "-b", "a"}, + {"--compile", "-c", 0}, + {"--dump", "-d", "a"}, + {"--entry", "-e", 0}, + {"--debug", "-g", "oj"}, + {"--include", "-include", "a"}, + {"--imacros", "-imacros", "a"}, + {"--include-prefix", "-iprefix", "a"}, + {"--include-directory-after", "-idirafter", "a"}, + {"--include-with-prefix", "-iwithprefix", "a"}, + {"--machine-", "-m", "*j"}, + {"--machine", "-m", "aj"}, + {"--no-standard-includes", "-nostdinc", 0}, + {"--no-standard-libraries", "-nostdlib", 0}, + {"--no-precompiled-includes", "-noprecomp", 0}, + {"--output", "-o", "a"}, + {"--profile", "-p", 0}, + {"--quiet", "-q", 0}, + {"--silent", "-q", 0}, + {"--force-link", "-u", "a"}, + {"--verbose", "-v", 0}, + {"--no-warnings", "-w", 0}, + {"--language", "-x", "a"}, + + {"--assert", "-A", "a"}, + {"--prefix", "-B", "a"}, + {"--comments", "-C", 0}, + {"--define-macro", "-D", "a"}, + {"--preprocess", "-E", 0}, + {"--trace-includes", "-H", 0}, + {"--include-directory", "-I", "a"}, + {"--include-barrier", "-I-", 0}, + {"--library-directory", "-L", "a"}, + {"--dependencies", "-M", 0}, + {"--user-dependencies", "-MM", 0}, + {"--write-dependencies", "-MD", 0}, + {"--write-user-dependencies", "-MMD", 0}, + {"--optimize", "-O", "oj"}, + {"--no-line-commands", "-P", 0}, + {"--assemble", "-S", 0}, + {"--undefine-macro", "-U", "a"}, + {"--use-version", "-V", "a"}, + {"--for-assembler", "-Wa", "a"}, + {"--extra-warnings", "-W", 0}, + {"--all-warnings", "-Wall", 0}, + {"--warn-", "-W", "*j"}, + {"--for-linker", "-Xlinker", "a"}, + + {"--ansi", "-ansi", 0}, + {"--traditional", "-traditional", 0}, + {"--traditional-cpp", "-traditional-cpp", 0}, + {"--trigraphs", "-trigraphs", 0}, + {"--pipe", "-pipe", 0}, + {"--dumpbase", "-dumpbase", "a"}, + {"--pedantic", "-pedantic", 0}, + {"--pedantic-errors", "-pedantic-errors", 0}, + {"--save-temps", "-save-temps", 0}, + {"--print-libgcc-file-name", "-print-libgcc-file-name", 0}, + {"--static", "-static", 0}, + {"--shared", "-shared", 0}, + {"--symbolic", "-symbolic", 0}, + {"--", "-f", "*j"} + }; + +/* Translate the options described by *ARGCP and *ARGVP. + Make a new vector and store it back in *ARGVP, + and store its length in *ARGVC. */ + +static void +translate_options (argcp, argvp) + int *argcp; + char ***argvp; +{ + int i, j; + int argc = *argcp; + char **argv = *argvp; + char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *)); + int newindex = 0; + + i = 0; + newv[newindex++] = argv[i++]; + + while (i < argc) + { + /* Translate -- options. */ + if (argv[i][0] == '-' && argv[i][1] == '-') + { + /* Find a mapping that applies to this option. */ + for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++) + { + int optlen = strlen (option_map[j].name); + int complen = strlen (argv[i]); + char *arginfo = option_map[j].arg_info; + + if (arginfo == 0) + arginfo = ""; + if (complen > optlen) + complen = optlen; + if (!strncmp (argv[i], option_map[j].name, complen)) + { + int extra = strlen (argv[i]) > optlen; + char *arg = 0; + + if (extra) + { + /* If the option has an argument, accept that. */ + if (argv[i][optlen] == '=') + arg = argv[i] + optlen + 1; + /* If this mapping allows extra text at end of name, + accept that as "argument". */ + else if (index (arginfo, '*') != 0) + arg = argv[i] + optlen; + /* Otherwise, extra text at end means mismatch. + Try other mappings. */ + else + continue; + } + else if (index (arginfo, '*') != 0) + error ("Incomplete `%s' option", option_map[j].name); + + /* Handle arguments. */ + if (index (arginfo, 'o') != 0) + { + if (arg == 0) + { + if (i + 1 == argc) + error ("Missing argument to `%s' option", + option_map[j].name); + arg = argv[++i]; + } + } + else if (index (arginfo, 'a') == 0) + { + if (arg != 0) + error ("Extraneous argument to `%s' option", + option_map[j].name); + arg = 0; + } + + /* Store the translation as one argv elt or as two. */ + if (arg != 0 && index (arginfo, 'j') != 0) + newv[newindex++] = concat (option_map[j].equivalent, + arg, ""); + else if (arg != 0) + { + newv[newindex++] = option_map[j].equivalent; + newv[newindex++] = arg; + } + else + newv[newindex++] = option_map[j].equivalent; + + break; + } + } + i++; + } + /* Handle old-fashioned options--just copy them through, + with their arguments. */ + else if (argv[i][0] == '-') + { + char *p = argv[i] + 1; + int c = *p; + int nskip = 1; + + if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) + nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0); + else if (WORD_SWITCH_TAKES_ARG (p)) + nskip += WORD_SWITCH_TAKES_ARG (p); + + while (nskip > 0) + { + newv[newindex++] = argv[i++]; + nskip--; + } + } + else + /* Ordinary operands, or +e options. */ + newv[newindex++] = argv[i++]; + } + + newv[newindex] = 0; + + *argvp = newv; + *argcp = newindex; +} + +/* Read compilation specs from a file named FILENAME, + replacing the default ones. + + A suffix which starts with `*' is a definition for + one of the machine-specific sub-specs. The "suffix" should be + *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc. + The corresponding spec is stored in asm_spec, etc., + rather than in the `compilers' vector. + + Anything invalid in the file is a fatal error. */ + +static void +read_specs (filename) + char *filename; +{ + int desc; + struct stat statbuf; + char *buffer; + register char *p; + + if (verbose_flag) + fprintf (stderr, "Reading specs from %s\n", filename); + + /* Open and stat the file. */ + desc = open (filename, 0, 0); + if (desc < 0) + pfatal_with_name (filename); + if (stat (filename, &statbuf) < 0) + pfatal_with_name (filename); + + /* Read contents of file into BUFFER. */ + buffer = xmalloc ((unsigned) statbuf.st_size + 1); + read (desc, buffer, (unsigned) statbuf.st_size); + buffer[statbuf.st_size] = 0; + close (desc); + + /* Scan BUFFER for specs, putting them in the vector. */ + p = buffer; + while (1) + { + char *suffix; + char *spec; + char *in, *out, *p1, *p2; + + /* Advance P in BUFFER to the next nonblank nocomment line. */ + p = skip_whitespace (p); + if (*p == 0) + break; + + /* Find the colon that should end the suffix. */ + p1 = p; + while (*p1 && *p1 != ':' && *p1 != '\n') p1++; + /* The colon shouldn't be missing. */ + if (*p1 != ':') + fatal ("specs file malformed after %d characters", p1 - buffer); + /* Skip back over trailing whitespace. */ + p2 = p1; + while (p2 > buffer && (p2[-1] == ' ' || p2[-1] == '\t')) p2--; + /* Copy the suffix to a string. */ + suffix = save_string (p, p2 - p); + /* Find the next line. */ + p = skip_whitespace (p1 + 1); + if (p[1] == 0) + fatal ("specs file malformed after %d characters", p - buffer); + p1 = p; + /* Find next blank line. */ + while (*p1 && !(*p1 == '\n' && p1[1] == '\n')) p1++; + /* Specs end at the blank line and do not include the newline. */ + spec = save_string (p, p1 - p); + p = p1; + + /* Delete backslash-newline sequences from the spec. */ + in = spec; + out = spec; + while (*in != 0) + { + if (in[0] == '\\' && in[1] == '\n') + in += 2; + else if (in[0] == '#') + { + while (*in && *in != '\n') in++; + } + else + *out++ = *in++; + } + *out = 0; + + if (suffix[0] == '*') + { + if (! strcmp (suffix, "*link_command")) + link_command_spec = spec; + else + set_spec (suffix + 1, spec); + } + else + { + /* Add this pair to the vector. */ + compilers + = ((struct compiler *) + xrealloc (compilers, (n_compilers + 2) * sizeof (struct compiler))); + compilers[n_compilers].suffix = suffix; + bzero (compilers[n_compilers].spec, + sizeof compilers[n_compilers].spec); + compilers[n_compilers].spec[0] = spec; + n_compilers++; + } + + if (*suffix == 0) + link_command_spec = spec; + } + + if (link_command_spec == 0) + fatal ("spec file has no spec for linking"); +} + +static char * +skip_whitespace (p) + char *p; +{ + while (1) + { + /* A fully-blank line is a delimiter in the SPEC file and shouldn't + be considered whitespace. */ + if (p[0] == '\n' && p[1] == '\n' && p[2] == '\n') + return p + 1; + else if (*p == '\n' || *p == ' ' || *p == '\t') + p++; + else if (*p == '#') + { + while (*p != '\n') p++; + p++; + } + else + break; + } + + return p; +} + +/* Structure to keep track of the specs that have been defined so far. These + are accessed using %(specname) or %[specname] in a compiler or link spec. */ + +struct spec_list +{ + char *name; /* Name of the spec. */ + char *spec; /* The spec itself. */ + struct spec_list *next; /* Next spec in linked list. */ +}; + +/* List of specs that have been defined so far. */ + +static struct spec_list *specs = (struct spec_list *) 0; + +/* Change the value of spec NAME to SPEC. If SPEC is empty, then the spec is + removed; If the spec starts with a + then SPEC is added to the end of the + current spec. */ + +static void +set_spec (name, spec) + char *name; + char *spec; +{ + struct spec_list *sl; + char *old_spec; + + /* See if the spec already exists */ + for (sl = specs; sl; sl = sl->next) + if (strcmp (sl->name, name) == 0) + break; + + if (!sl) + { + /* Not found - make it */ + sl = (struct spec_list *) xmalloc (sizeof (struct spec_list)); + sl->name = save_string (name, strlen (name)); + sl->spec = save_string ("", 0); + sl->next = specs; + specs = sl; + } + + old_spec = sl->spec; + if (name && spec[0] == '+' && isspace (spec[1])) + sl->spec = concat (old_spec, spec + 1, ""); + else + sl->spec = save_string (spec, strlen (spec)); + + if (! strcmp (name, "asm")) + asm_spec = sl->spec; + else if (! strcmp (name, "asm_final")) + asm_final_spec = sl->spec; + else if (! strcmp (name, "cc1")) + cc1_spec = sl->spec; + else if (! strcmp (name, "cc1plus")) + cc1plus_spec = sl->spec; + else if (! strcmp (name, "cpp")) + cpp_spec = sl->spec; + else if (! strcmp (name, "endfile")) + endfile_spec = sl->spec; + else if (! strcmp (name, "lib")) + lib_spec = sl->spec; + else if (! strcmp (name, "link")) + link_spec = sl->spec; + else if (! strcmp (name, "predefines")) + cpp_predefines = sl->spec; + else if (! strcmp (name, "signed_char")) + signed_char_spec = sl->spec; + else if (! strcmp (name, "startfile")) + startfile_spec = sl->spec; + else if (! strcmp (name, "switches_need_spaces")) + switches_need_spaces = sl->spec; + else if (! strcmp (name, "cross_compile")) + cross_compile = atoi (sl->spec); + /* Free the old spec */ + if (old_spec) + free (old_spec); +} + +/* Accumulate a command (program name and args), and run it. */ + +/* Vector of pointers to arguments in the current line of specifications. */ + +static char **argbuf; + +/* Number of elements allocated in argbuf. */ + +static int argbuf_length; + +/* Number of elements in argbuf currently in use (containing args). */ + +static int argbuf_index; + +/* This is the list of suffixes and codes (%g/%u/%U) and the associated + temp file. Used only if MKTEMP_EACH_FILE. */ + +static struct temp_name { + char *suffix; /* suffix associated with the code. */ + int length; /* strlen (suffix). */ + int unique; /* Indicates whether %g or %u/%U was used. */ + char *filename; /* associated filename. */ + int filename_length; /* strlen (filename). */ + struct temp_name *next; +} *temp_names; + +/* Number of commands executed so far. */ + +static int execution_count; + +/* Number of commands that exited with a signal. */ + +static int signal_count; + +/* Name with which this program was invoked. */ + +static char *programname; + +/* Structures to keep track of prefixes to try when looking for files. */ + +struct prefix_list +{ + char *prefix; /* String to prepend to the path. */ + struct prefix_list *next; /* Next in linked list. */ + int require_machine_suffix; /* Don't use without machine_suffix. */ + /* 2 means try both machine_suffix and just_machine_suffix. */ + int *used_flag_ptr; /* 1 if a file was found with this prefix. */ +}; + +struct path_prefix +{ + struct prefix_list *plist; /* List of prefixes to try */ + int max_len; /* Max length of a prefix in PLIST */ + char *name; /* Name of this list (used in config stuff) */ +}; + +/* List of prefixes to try when looking for executables. */ + +static struct path_prefix exec_prefix = { 0, 0, "exec" }; + +/* List of prefixes to try when looking for startup (crt0) files. */ + +static struct path_prefix startfile_prefix = { 0, 0, "startfile" }; + +/* Suffix to attach to directories searched for commands. + This looks like `MACHINE/VERSION/'. */ + +static char *machine_suffix = 0; + +/* Suffix to attach to directories searched for commands. + This is just `MACHINE/'. */ + +static char *just_machine_suffix = 0; + +/* Adjusted value of GCC_EXEC_PREFIX envvar. */ + +static char *gcc_exec_prefix; + +/* Default prefixes to attach to command names. */ + +#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */ +#undef MD_EXEC_PREFIX +#undef MD_STARTFILE_PREFIX +#undef MD_STARTFILE_PREFIX_1 +#endif + +#ifndef STANDARD_EXEC_PREFIX +#define STANDARD_EXEC_PREFIX "/usr/libexec/" +#endif /* !defined STANDARD_EXEC_PREFIX */ + +static char *standard_exec_prefix = STANDARD_EXEC_PREFIX; +static char *standard_exec_prefix_1 = ""; +#ifdef MD_EXEC_PREFIX +static char *md_exec_prefix = MD_EXEC_PREFIX; +#endif + +#ifndef STANDARD_STARTFILE_PREFIX +#define STANDARD_STARTFILE_PREFIX "/usr/lib/" +#endif /* !defined STANDARD_STARTFILE_PREFIX */ + +#ifdef MD_STARTFILE_PREFIX +static char *md_startfile_prefix = MD_STARTFILE_PREFIX; +#endif +#ifdef MD_STARTFILE_PREFIX_1 +static char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1; +#endif +static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX; +static char *standard_startfile_prefix_1 = "/lib/"; +static char *standard_startfile_prefix_2 = "/usr/lib/"; + +#ifndef TOOLDIR_BASE_PREFIX +#define TOOLDIR_BASE_PREFIX "/usr/local/" +#endif +static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX; +static char *tooldir_prefix; + +/* Clear out the vector of arguments (after a command is executed). */ + +static void +clear_args () +{ + argbuf_index = 0; +} + +/* Add one argument to the vector at the end. + This is done when a space is seen or at the end of the line. + If DELETE_ALWAYS is nonzero, the arg is a filename + and the file should be deleted eventually. + If DELETE_FAILURE is nonzero, the arg is a filename + and the file should be deleted if this compilation fails. */ + +static void +store_arg (arg, delete_always, delete_failure) + char *arg; + int delete_always, delete_failure; +{ + if (argbuf_index + 1 == argbuf_length) + { + argbuf = (char **) xrealloc (argbuf, (argbuf_length *= 2) * sizeof (char *)); + } + + argbuf[argbuf_index++] = arg; + argbuf[argbuf_index] = 0; + + if (delete_always || delete_failure) + record_temp_file (arg, delete_always, delete_failure); +} + +/* Record the names of temporary files we tell compilers to write, + and delete them at the end of the run. */ + +/* This is the common prefix we use to make temp file names. + It is chosen once for each run of this program. + It is substituted into a spec by %g. + Thus, all temp file names contain this prefix. + In practice, all temp file names start with this prefix. + + This prefix comes from the envvar TMPDIR if it is defined; + otherwise, from the P_tmpdir macro if that is defined; + otherwise, in /usr/tmp or /tmp. */ + +static char *temp_filename; + +/* Length of the prefix. */ + +static int temp_filename_length; + +/* Define the list of temporary files to delete. */ + +struct temp_file +{ + char *name; + struct temp_file *next; +}; + +/* Queue of files to delete on success or failure of compilation. */ +static struct temp_file *always_delete_queue; +/* Queue of files to delete on failure of compilation. */ +static struct temp_file *failure_delete_queue; + +/* Record FILENAME as a file to be deleted automatically. + ALWAYS_DELETE nonzero means delete it if all compilation succeeds; + otherwise delete it in any case. + FAIL_DELETE nonzero means delete it if a compilation step fails; + otherwise delete it in any case. */ + +static void +record_temp_file (filename, always_delete, fail_delete) + char *filename; + int always_delete; + int fail_delete; +{ + register char *name; + name = xmalloc (strlen (filename) + 1); + strcpy (name, filename); + + if (always_delete) + { + register struct temp_file *temp; + for (temp = always_delete_queue; temp; temp = temp->next) + if (! strcmp (name, temp->name)) + goto already1; + temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); + temp->next = always_delete_queue; + temp->name = name; + always_delete_queue = temp; + already1:; + } + + if (fail_delete) + { + register struct temp_file *temp; + for (temp = failure_delete_queue; temp; temp = temp->next) + if (! strcmp (name, temp->name)) + goto already2; + temp = (struct temp_file *) xmalloc (sizeof (struct temp_file)); + temp->next = failure_delete_queue; + temp->name = name; + failure_delete_queue = temp; + already2:; + } +} + +/* Delete all the temporary files whose names we previously recorded. */ + +static void +delete_temp_files () +{ + register struct temp_file *temp; + + for (temp = always_delete_queue; temp; temp = temp->next) + { +#ifdef DEBUG + int i; + printf ("Delete %s? (y or n) ", temp->name); + fflush (stdout); + i = getchar (); + if (i != '\n') + while (getchar () != '\n') ; + if (i == 'y' || i == 'Y') +#endif /* DEBUG */ + { + struct stat st; + if (stat (temp->name, &st) >= 0) + { + /* Delete only ordinary files. */ + if (S_ISREG (st.st_mode)) + if (unlink (temp->name) < 0) + if (verbose_flag) + perror_with_name (temp->name); + } + } + } + + always_delete_queue = 0; +} + +/* Delete all the files to be deleted on error. */ + +static void +delete_failure_queue () +{ + register struct temp_file *temp; + + for (temp = failure_delete_queue; temp; temp = temp->next) + { +#ifdef DEBUG + int i; + printf ("Delete %s? (y or n) ", temp->name); + fflush (stdout); + i = getchar (); + if (i != '\n') + while (getchar () != '\n') ; + if (i == 'y' || i == 'Y') +#endif /* DEBUG */ + { + if (unlink (temp->name) < 0) + if (verbose_flag) + perror_with_name (temp->name); + } + } +} + +static void +clear_failure_queue () +{ + failure_delete_queue = 0; +} + +/* Compute a string to use as the base of all temporary file names. + It is substituted for %g. */ + +static void +choose_temp_base () +{ + char *base = getenv ("TMPDIR"); + int len; + + if (base == (char *)0) + { +#ifdef P_tmpdir + if (access (P_tmpdir, R_OK | W_OK) == 0) + base = P_tmpdir; +#endif + if (base == (char *)0) + { + if (access ("/usr/tmp", R_OK | W_OK) == 0) + base = "/usr/tmp/"; + else + base = "/tmp/"; + } + } + + 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 (); +} + + +/* Routine to add variables to the environment. We do this to pass + the pathname of the gcc driver, and the directories search to the + collect2 program, which is being run as ld. This way, we can be + sure of executing the right compiler when collect2 wants to build + constructors and destructors. Since the environment variables we + use come from an obstack, we don't have to worry about allocating + space for them. */ + +#ifndef HAVE_PUTENV + +void +putenv (str) + char *str; +{ +#ifndef VMS /* nor about VMS */ + + extern char **environ; + char **old_environ = environ; + char **envp; + int num_envs = 0; + int name_len = 1; + int str_len = strlen (str); + char *p = str; + int ch; + + while ((ch = *p++) != '\0' && ch != '=') + name_len++; + + if (!ch) + abort (); + + /* Search for replacing an existing environment variable, and + count the number of total environment variables. */ + for (envp = old_environ; *envp; envp++) + { + num_envs++; + if (!strncmp (str, *envp, name_len)) + { + *envp = str; + return; + } + } + + /* Add a new environment variable */ + environ = (char **) xmalloc (sizeof (char *) * (num_envs+2)); + *environ = str; + bcopy (old_environ, environ+1, sizeof (char *) * (num_envs+1)); + +#endif /* VMS */ +} + +#endif /* HAVE_PUTENV */ + + +/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */ + +static void +putenv_from_prefixes (paths, env_var) + struct path_prefix *paths; + char *env_var; +{ + int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0; + int just_suffix_len + = (just_machine_suffix) ? strlen (just_machine_suffix) : 0; + int first_time = TRUE; + struct prefix_list *pprefix; + + obstack_grow (&collect_obstack, env_var, strlen (env_var)); + + for (pprefix = paths->plist; pprefix != 0; pprefix = pprefix->next) + { + int len = strlen (pprefix->prefix); + + if (machine_suffix + && is_directory (pprefix->prefix, machine_suffix, 0)) + { + if (!first_time) + obstack_1grow (&collect_obstack, PATH_SEPARATOR); + + first_time = FALSE; + obstack_grow (&collect_obstack, pprefix->prefix, len); + obstack_grow (&collect_obstack, machine_suffix, suffix_len); + } + + if (just_machine_suffix + && pprefix->require_machine_suffix == 2 + && is_directory (pprefix->prefix, just_machine_suffix, 0)) + { + if (!first_time) + obstack_1grow (&collect_obstack, PATH_SEPARATOR); + + first_time = FALSE; + obstack_grow (&collect_obstack, pprefix->prefix, len); + obstack_grow (&collect_obstack, just_machine_suffix, + just_suffix_len); + } + + if (!pprefix->require_machine_suffix) + { + if (!first_time) + obstack_1grow (&collect_obstack, PATH_SEPARATOR); + + first_time = FALSE; + obstack_grow (&collect_obstack, pprefix->prefix, len); + } + } + obstack_1grow (&collect_obstack, '\0'); + putenv (obstack_finish (&collect_obstack)); +} + + +/* Search for NAME using the prefix list PREFIXES. MODE is passed to + access to check permissions. + Return 0 if not found, otherwise return its name, allocated with malloc. */ + +static char * +find_a_file (pprefix, name, mode) + struct path_prefix *pprefix; + char *name; + int mode; +{ + char *temp; + char *file_suffix = ((mode & X_OK) != 0 ? EXECUTABLE_SUFFIX : ""); + struct prefix_list *pl; + int len = pprefix->max_len + strlen (name) + strlen (file_suffix) + 1; + + if (machine_suffix) + len += strlen (machine_suffix); + + temp = xmalloc (len); + + /* Determine the filename to execute (special case for absolute paths). */ + + if (*name == '/') + { + if (access (name, mode)) + { + strcpy (temp, name); + return temp; + } + } + else + for (pl = pprefix->plist; pl; pl = pl->next) + { + if (machine_suffix) + { + strcpy (temp, pl->prefix); + strcat (temp, machine_suffix); + strcat (temp, name); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + /* Some systems have a suffix for executable files. + So try appending that. */ + if (file_suffix[0] != 0) + { + strcat (temp, file_suffix); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + } + } + /* Certain prefixes are tried with just the machine type, + not the version. This is used for finding as, ld, etc. */ + if (just_machine_suffix && pl->require_machine_suffix == 2) + { + strcpy (temp, pl->prefix); + strcat (temp, just_machine_suffix); + strcat (temp, name); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + /* Some systems have a suffix for executable files. + So try appending that. */ + if (file_suffix[0] != 0) + { + strcat (temp, file_suffix); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + } + } + /* Certain prefixes can't be used without the machine suffix + when the machine or version is explicitly specified. */ + if (!pl->require_machine_suffix) + { + strcpy (temp, pl->prefix); + strcat (temp, name); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + /* Some systems have a suffix for executable files. + So try appending that. */ + if (file_suffix[0] != 0) + { + strcat (temp, file_suffix); + if (access (temp, mode) == 0) + { + if (pl->used_flag_ptr != 0) + *pl->used_flag_ptr = 1; + return temp; + } + } + } + } + + free (temp); + return 0; +} + +/* Add an entry for PREFIX in PLIST. If FIRST is set, it goes + at the start of the list, otherwise it goes at the end. + + If WARN is nonzero, we will warn if no file is found + through this prefix. WARN should point to an int + which will be set to 1 if this entry is used. + + REQUIRE_MACHINE_SUFFIX is 1 if this prefix can't be used without + the complete value of machine_suffix. + 2 means try both machine_suffix and just_machine_suffix. */ + +static void +add_prefix (pprefix, prefix, first, require_machine_suffix, warn) + struct path_prefix *pprefix; + char *prefix; + int first; + int require_machine_suffix; + int *warn; +{ + struct prefix_list *pl, **prev; + int len; + + if (!first && pprefix->plist) + { + for (pl = pprefix->plist; pl->next; pl = pl->next) + ; + prev = &pl->next; + } + else + prev = &pprefix->plist; + + /* Keep track of the longest prefix */ + + len = strlen (prefix); + if (len > pprefix->max_len) + pprefix->max_len = len; + + pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); + pl->prefix = save_string (prefix, len); + pl->require_machine_suffix = require_machine_suffix; + pl->used_flag_ptr = warn; + if (warn) + *warn = 0; + + if (*prev) + pl->next = *prev; + else + pl->next = (struct prefix_list *) 0; + *prev = pl; +} + +/* Print warnings for any prefixes in the list PPREFIX that were not used. */ + +static void +unused_prefix_warnings (pprefix) + struct path_prefix *pprefix; +{ + struct prefix_list *pl = pprefix->plist; + + while (pl) + { + if (pl->used_flag_ptr != 0 && !*pl->used_flag_ptr) + { + error ("file path prefix `%s' never used", + pl->prefix); + /* Prevent duplicate warnings. */ + *pl->used_flag_ptr = 1; + } + pl = pl->next; + } +} + +/* Get rid of all prefixes built up so far in *PLISTP. */ + +static void +free_path_prefix (pprefix) + struct path_prefix *pprefix; +{ + struct prefix_list *pl = pprefix->plist; + struct prefix_list *temp; + + while (pl) + { + temp = pl; + pl = pl->next; + free (temp->prefix); + free ((char *) temp); + } + pprefix->plist = (struct prefix_list *) 0; +} + +/* stdin file number. */ +#define STDIN_FILE_NO 0 + +/* stdout file number. */ +#define STDOUT_FILE_NO 1 + +/* value of `pipe': port index for reading. */ +#define READ_PORT 0 + +/* value of `pipe': port index for writing. */ +#define WRITE_PORT 1 + +/* Pipe waiting from last process, to be used as input for the next one. + Value is STDIN_FILE_NO if no pipe is waiting + (i.e. the next command is the first of a group). */ + +static int last_pipe_input; + +/* Fork one piped subcommand. FUNC is the system call to use + (either execv or execvp). ARGV is the arg vector to use. + NOT_LAST is nonzero if this is not the last subcommand + (i.e. its output should be piped to the next one.) */ + +#ifndef OS2 +#ifdef __MSDOS__ + +/* Declare these to avoid compilation error. They won't be called. */ +int execv(const char *a, const char **b){} +int execvp(const char *a, const char **b){} + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + char *scmd; + FILE *argfile; + int i; + + scmd = (char *)malloc (strlen (program) + strlen (temp_filename) + 6); + sprintf (scmd, "%s @%s.gp", program, temp_filename); + argfile = fopen (scmd+strlen (program) + 2, "w"); + if (argfile == 0) + pfatal_with_name (scmd + strlen (program) + 2); + + 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 (scmd + strlen (program) + 2); + return i << 8; +} + +#else /* not __MSDOS__ */ + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + int (*func)() = (search_flag ? execv : execvp); + int pid; + int pdes[2]; + int input_desc = last_pipe_input; + int output_desc = STDOUT_FILE_NO; + int retries, sleep_interval; + + /* If this isn't the last process, make a pipe for its output, + and record it as waiting to be the input to the next process. */ + + if (not_last) + { + if (pipe (pdes) < 0) + pfatal_with_name ("pipe"); + output_desc = pdes[WRITE_PORT]; + last_pipe_input = pdes[READ_PORT]; + } + else + last_pipe_input = STDIN_FILE_NO; + + /* Fork a subprocess; wait and retry if it fails. */ + sleep_interval = 1; + for (retries = 0; retries < 4; retries++) + { + pid = vfork (); + if (pid >= 0) + break; + sleep (sleep_interval); + sleep_interval *= 2; + } + + switch (pid) + { + case -1: +#ifdef vfork + pfatal_with_name ("fork"); +#else + pfatal_with_name ("vfork"); +#endif + /* NOTREACHED */ + return 0; + + case 0: /* child */ + /* Move the input and output pipes into place, if nec. */ + if (input_desc != STDIN_FILE_NO) + { + close (STDIN_FILE_NO); + dup (input_desc); + close (input_desc); + } + if (output_desc != STDOUT_FILE_NO) + { + close (STDOUT_FILE_NO); + dup (output_desc); + close (output_desc); + } + + /* Close the parent's descs that aren't wanted here. */ + if (last_pipe_input != STDIN_FILE_NO) + close (last_pipe_input); + + /* Exec the program. */ + (*func) (program, argv); + perror_exec (program); + exit (-1); + /* NOTREACHED */ + return 0; + + default: + /* In the parent, after forking. + Close the descriptors that we made for this child. */ + if (input_desc != STDIN_FILE_NO) + close (input_desc); + if (output_desc != STDOUT_FILE_NO) + close (output_desc); + + /* Return child's process number. */ + return pid; + } +} + +#endif /* not __MSDOS__ */ +#else /* not OS2 */ + +static int +pexecute (search_flag, program, argv, not_last) + int search_flag; + char *program; + char *argv[]; + int not_last; +{ + return (search_flag ? spawnv : spawnvp) (1, program, argv); +} +#endif /* not OS2 */ + +/* Execute the command specified by the arguments on the current line of spec. + When using pipes, this includes several piped-together commands + with `|' between them. + + Return 0 if successful, -1 if failed. */ + +static int +execute () +{ + int i; + int n_commands; /* # of command. */ + char *string; + struct command + { + char *prog; /* program name. */ + char **argv; /* vector of args. */ + int pid; /* pid of process for this command. */ + }; + + struct command *commands; /* each command buffer with above info. */ + + /* Count # of piped commands. */ + for (n_commands = 1, i = 0; i < argbuf_index; i++) + if (strcmp (argbuf[i], "|") == 0) + n_commands++; + + /* Get storage for each command. */ + commands + = (struct command *) alloca (n_commands * sizeof (struct command)); + + /* Split argbuf into its separate piped processes, + and record info about each one. + Also search for the programs that are to be run. */ + + commands[0].prog = argbuf[0]; /* first command. */ + commands[0].argv = &argbuf[0]; + string = find_a_file (&exec_prefix, commands[0].prog, X_OK); + if (string) + commands[0].argv[0] = string; + + for (n_commands = 1, i = 0; i < argbuf_index; i++) + if (strcmp (argbuf[i], "|") == 0) + { /* each command. */ +#ifdef __MSDOS__ + fatal ("-pipe not supported under MS-DOS"); +#endif + argbuf[i] = 0; /* termination of command args. */ + commands[n_commands].prog = argbuf[i + 1]; + commands[n_commands].argv = &argbuf[i + 1]; + string = find_a_file (&exec_prefix, commands[n_commands].prog, X_OK); + if (string) + commands[n_commands].argv[0] = string; + n_commands++; + } + + argbuf[argbuf_index] = 0; + + /* If -v, print what we are about to do, and maybe query. */ + + if (verbose_flag) + { + /* Print each piped command as a separate line. */ + for (i = 0; i < n_commands ; i++) + { + char **j; + + for (j = commands[i].argv; *j; j++) + fprintf (stderr, " %s", *j); + + /* Print a pipe symbol after all but the last command. */ + if (i + 1 != n_commands) + fprintf (stderr, " |"); + fprintf (stderr, "\n"); + } + fflush (stderr); +#ifdef DEBUG + fprintf (stderr, "\nGo ahead? (y or n) "); + fflush (stderr); + i = getchar (); + if (i != '\n') + while (getchar () != '\n') ; + if (i != 'y' && i != 'Y') + return 0; +#endif /* DEBUG */ + } + + /* Run each piped subprocess. */ + + last_pipe_input = STDIN_FILE_NO; + for (i = 0; i < n_commands; i++) + { + char *string = commands[i].argv[0]; + + commands[i].pid = pexecute (string != commands[i].prog, + string, commands[i].argv, + i + 1 < n_commands); + + if (string != commands[i].prog) + free (string); + } + + execution_count++; + + /* Wait for all the subprocesses to finish. + We don't care what order they finish in; + we know that N_COMMANDS waits will get them all. */ + + { + int ret_code = 0; + + for (i = 0; i < n_commands; i++) + { + int status; + int pid; + char *prog; + +#ifdef __MSDOS__ + status = pid = commands[i].pid; +#else + pid = wait (&status); +#endif + if (pid < 0) + abort (); + + if (status != 0) + { + int j; + for (j = 0; j < n_commands; j++) + if (commands[j].pid == pid) + prog = commands[j].prog; + + if ((status & 0x7F) != 0) + { + fatal ("Internal compiler error: program %s got fatal signal %d", + prog, (status & 0x7F)); + signal_count++; + } + if (((status & 0xFF00) >> 8) >= MIN_FATAL_STATUS) + ret_code = -1; + } + } + return ret_code; + } +} + +/* Find all the switches given to us + and make a vector describing them. + The elements of the vector are strings, one per switch given. + If a switch uses following arguments, then the `part1' field + is the switch itself and the `args' field + is a null-terminated vector containing the following arguments. + The `valid' field is nonzero if any spec has looked at this switch; + if it remains zero at the end of the run, it must be meaningless. */ + +struct switchstr +{ + char *part1; + char **args; + int valid; +}; + +static struct switchstr *switches; + +static int n_switches; + +struct infile +{ + char *name; + char *language; +}; + +/* Also a vector of input files specified. */ + +static struct infile *infiles; + +static int n_infiles; + +/* And a vector of corresponding output files is made up later. */ + +static char **outfiles; + +/* Create the vector `switches' and its contents. + Store its length in `n_switches'. */ + +static void +process_command (argc, argv) + int argc; + char **argv; +{ + register int i; + char *temp; + char *spec_lang = 0; + int last_language_n_infiles; + + gcc_exec_prefix = getenv ("GCC_EXEC_PREFIX"); + + n_switches = 0; + n_infiles = 0; + + /* Default for -V is our version number, ending at first space. */ + spec_version = save_string (version_string, strlen (version_string)); + for (temp = spec_version; *temp && *temp != ' '; temp++); + if (*temp) *temp = '\0'; + + /* Set up the default search paths. */ + + if (gcc_exec_prefix) + { + add_prefix (&exec_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); + add_prefix (&startfile_prefix, gcc_exec_prefix, 0, 0, NULL_PTR); + } + + /* COMPILER_PATH and LIBRARY_PATH have values + that are lists of directory names with colons. */ + + temp = getenv ("COMPILER_PATH"); + if (temp) + { + char *startp, *endp; + char *nstore = (char *) alloca (strlen (temp) + 3); + + startp = endp = temp; + while (1) + { + if (*endp == PATH_SEPARATOR || *endp == 0) + { + strncpy (nstore, startp, endp-startp); + if (endp == startp) + { + strcpy (nstore, "./"); + } + else if (endp[-1] != '/') + { + nstore[endp-startp] = '/'; + nstore[endp-startp+1] = 0; + } + else + nstore[endp-startp] = 0; + add_prefix (&exec_prefix, nstore, 0, 0, NULL_PTR); + if (*endp == 0) + break; + endp = startp = endp + 1; + } + else + endp++; + } + } + + temp = getenv ("LIBRARY_PATH"); + if (temp) + { + char *startp, *endp; + char *nstore = (char *) alloca (strlen (temp) + 3); + + startp = endp = temp; + while (1) + { + if (*endp == PATH_SEPARATOR || *endp == 0) + { + strncpy (nstore, startp, endp-startp); + if (endp == startp) + { + strcpy (nstore, "./"); + } + else if (endp[-1] != '/') + { + nstore[endp-startp] = '/'; + nstore[endp-startp+1] = 0; + } + else + nstore[endp-startp] = 0; + add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); + if (*endp == 0) + break; + endp = startp = endp + 1; + } + else + endp++; + } + } + + /* Use LPATH like LIBRARY_PATH (for the CMU build program). */ + temp = getenv ("LPATH"); + if (temp) + { + char *startp, *endp; + char *nstore = (char *) alloca (strlen (temp) + 3); + + startp = endp = temp; + while (1) + { + if (*endp == PATH_SEPARATOR || *endp == 0) + { + strncpy (nstore, startp, endp-startp); + if (endp == startp) + { + strcpy (nstore, "./"); + } + else if (endp[-1] != '/') + { + nstore[endp-startp] = '/'; + nstore[endp-startp+1] = 0; + } + else + nstore[endp-startp] = 0; + add_prefix (&startfile_prefix, nstore, 0, 0, NULL_PTR); + if (*endp == 0) + break; + endp = startp = endp + 1; + } + else + endp++; + } + } + + /* Convert new-style -- options to old-style. */ + translate_options (&argc, &argv); + + /* Scan argv twice. Here, the first time, just count how many switches + there will be in their vector, and how many input files in theirs. + Here we also parse the switches that cc itself uses (e.g. -v). */ + + for (i = 1; i < argc; i++) + { + if (! strcmp (argv[i], "-dumpspecs")) + { + printf ("*asm:\n%s\n\n", asm_spec); + printf ("*asm_final:\n%s\n\n", asm_final_spec); + printf ("*cpp:\n%s\n\n", cpp_spec); + printf ("*cc1:\n%s\n\n", cc1_spec); + printf ("*cc1plus:\n%s\n\n", cc1plus_spec); + printf ("*endfile:\n%s\n\n", endfile_spec); + printf ("*link:\n%s\n\n", link_spec); + printf ("*lib:\n%s\n\n", lib_spec); + printf ("*startfile:\n%s\n\n", startfile_spec); + printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces); + printf ("*signed_char:\n%s\n\n", signed_char_spec); + printf ("*predefines:\n%s\n\n", cpp_predefines); + printf ("*cross_compile:\n%d\n\n", cross_compile); + + exit (0); + } + else if (! strcmp (argv[i], "-dumpversion")) + { + printf ("%s\n", version_string); + exit (0); + } + else if (! strcmp (argv[i], "-print-libgcc-file-name")) + { + print_libgcc_file_name = 1; + } + else if (! strcmp (argv[i], "-Xlinker")) + { + /* Pass the argument of this option to the linker when we link. */ + + if (i + 1 == argc) + fatal ("argument to `-Xlinker' is missing"); + + n_linker_options++; + if (!linker_options) + linker_options + = (char **) xmalloc (n_linker_options * sizeof (char **)); + else + linker_options + = (char **) xrealloc (linker_options, + n_linker_options * sizeof (char **)); + + linker_options[n_linker_options - 1] = argv[++i]; + } + else if (! strncmp (argv[i], "-Wl,", 4)) + { + int prev, j; + /* Pass the rest of this option to the linker when we link. */ + + n_linker_options++; + if (!linker_options) + linker_options + = (char **) xmalloc (n_linker_options * sizeof (char **)); + else + linker_options + = (char **) xrealloc (linker_options, + n_linker_options * sizeof (char **)); + + /* Split the argument at commas. */ + prev = 4; + for (j = 4; argv[i][j]; j++) + if (argv[i][j] == ',') + { + linker_options[n_linker_options - 1] + = save_string (argv[i] + prev, j - prev); + n_linker_options++; + linker_options + = (char **) xrealloc (linker_options, + n_linker_options * sizeof (char **)); + prev = j + 1; + } + /* Record the part after the last comma. */ + linker_options[n_linker_options - 1] = argv[i] + prev; + } + else if (! strncmp (argv[i], "-Wa,", 4)) + { + int prev, j; + /* Pass the rest of this option to the assembler. */ + + n_assembler_options++; + if (!assembler_options) + assembler_options + = (char **) xmalloc (n_assembler_options * sizeof (char **)); + else + assembler_options + = (char **) xrealloc (assembler_options, + n_assembler_options * sizeof (char **)); + + /* Split the argument at commas. */ + prev = 4; + for (j = 4; argv[i][j]; j++) + if (argv[i][j] == ',') + { + assembler_options[n_assembler_options - 1] + = save_string (argv[i] + prev, j - prev); + n_assembler_options++; + assembler_options + = (char **) xrealloc (assembler_options, + n_assembler_options * sizeof (char **)); + prev = j + 1; + } + /* Record the part after the last comma. */ + assembler_options[n_assembler_options - 1] = argv[i] + prev; + } + else if (argv[i][0] == '+' && argv[i][1] == 'e') + /* The +e options to the C++ front-end. */ + n_switches++; + else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') + { + register char *p = &argv[i][1]; + register int c = *p; + + switch (c) + { + case 'b': + if (p[1] == 0 && i + 1 == argc) + fatal ("argument to `-b' is missing"); + if (p[1] == 0) + spec_machine = argv[++i]; + else + spec_machine = p + 1; + break; + + case 'B': + { + int *temp = (int *) xmalloc (sizeof (int)); + char *value; + if (p[1] == 0 && i + 1 == argc) + fatal ("argument to `-B' is missing"); + if (p[1] == 0) + value = argv[++i]; + else + value = p + 1; + add_prefix (&exec_prefix, value, 1, 0, temp); + add_prefix (&startfile_prefix, value, 1, 0, temp); + } + break; + + case 'v': /* Print our subcommands and print versions. */ + n_switches++; + /* If they do anything other than exactly `-v', don't set + verbose_flag; rather, continue on to give the error. */ + if (p[1] != 0) + break; + verbose_flag++; + break; + + case 'V': + if (p[1] == 0 && i + 1 == argc) + fatal ("argument to `-V' is missing"); + if (p[1] == 0) + spec_version = argv[++i]; + else + spec_version = p + 1; + break; + + case 's': + if (!strcmp (p, "save-temps")) + { + save_temps_flag = 1; + n_switches++; + break; + } + default: + n_switches++; + + if (SWITCH_TAKES_ARG (c) > (p[1] != 0)) + i += SWITCH_TAKES_ARG (c) - (p[1] != 0); + else if (WORD_SWITCH_TAKES_ARG (p)) + i += WORD_SWITCH_TAKES_ARG (p); + } + } + else + n_infiles++; + } + + /* Set up the search paths before we go looking for config files. */ + + /* These come before the md prefixes so that we will find gcc's subcommands + (such as cpp) rather than those of the host system. */ + /* Use 2 as fourth arg meaning try just the machine as a suffix, + as well as trying the machine and the version. */ + add_prefix (&exec_prefix, standard_exec_prefix, 0, 2, NULL_PTR); + add_prefix (&exec_prefix, standard_exec_prefix_1, 0, 2, NULL_PTR); + + add_prefix (&startfile_prefix, standard_exec_prefix, 0, 1, NULL_PTR); + add_prefix (&startfile_prefix, standard_exec_prefix_1, 0, 1, NULL_PTR); + + tooldir_prefix = concat (tooldir_base_prefix, spec_machine, "/"); + + /* If tooldir is relative, base it on exec_prefix. A relative + tooldir lets us move the installed tree as a unit. + + If GCC_EXEC_PREFIX is defined, then we want to add two relative + directories, so that we can search both the user specified directory + and the standard place. */ + + if (*tooldir_prefix != '/') + { + if (gcc_exec_prefix) + { + char *gcc_exec_tooldir_prefix + = concat (concat (gcc_exec_prefix, spec_machine, "/"), + concat (spec_version, "/", tooldir_prefix), + ""); + + add_prefix (&exec_prefix, concat (gcc_exec_tooldir_prefix, "bin", "/"), + 0, 0, NULL_PTR); + add_prefix (&startfile_prefix, concat (gcc_exec_tooldir_prefix, "lib", "/"), + 0, 0, NULL_PTR); + } + + tooldir_prefix = concat (concat (standard_exec_prefix, spec_machine, "/"), + concat (spec_version, "/", tooldir_prefix), + ""); + } + + add_prefix (&exec_prefix, concat (tooldir_prefix, "bin", "/"), + 0, 0, NULL_PTR); + add_prefix (&startfile_prefix, concat (tooldir_prefix, "lib", "/"), + 0, 0, NULL_PTR); + + /* More prefixes are enabled in main, after we read the specs file + and determine whether this is cross-compilation or not. */ + + + /* Then create the space for the vectors and scan again. */ + + switches = ((struct switchstr *) + xmalloc ((n_switches + 1) * sizeof (struct switchstr))); + infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile)); + n_switches = 0; + n_infiles = 0; + last_language_n_infiles = -1; + + /* This, time, copy the text of each switch and store a pointer + to the copy in the vector of switches. + Store all the infiles in their vector. */ + + for (i = 1; i < argc; i++) + { + /* Just skip the switches that were handled by the preceding loop. */ + if (!strcmp (argv[i], "-Xlinker")) + i++; + else if (! strncmp (argv[i], "-Wl,", 4)) + ; + else if (! strncmp (argv[i], "-Wa,", 4)) + ; + else if (! strcmp (argv[i], "-print-libgcc-file-name")) + ; + else if (argv[i][0] == '+' && argv[i][1] == 'e') + { + /* Compensate for the +e options to the C++ front-end; + they're there simply for cfront call-compatibility. We do + some magic in default_compilers to pass them down properly. + Note we deliberately start at the `+' here, to avoid passing + -e0 or -e1 down into the linker. */ + switches[n_switches].part1 = &argv[i][0]; + switches[n_switches].args = 0; + switches[n_switches].valid = 0; + n_switches++; + } + else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l') + { + register char *p = &argv[i][1]; + register int c = *p; + + if (c == 'B' || c == 'b' || c == 'V') + { + /* Skip a separate arg, if any. */ + if (p[1] == 0) + i++; + continue; + } + if (c == 'x') + { + if (p[1] == 0 && i + 1 == argc) + fatal ("argument to `-x' is missing"); + if (p[1] == 0) + spec_lang = argv[++i]; + else + spec_lang = p + 1; + if (! strcmp (spec_lang, "none")) + /* Suppress the warning if -xnone comes after the last input file, + because alternate command interfaces like g++ might find it + useful to place -xnone after each input file. */ + spec_lang = 0; + else + last_language_n_infiles = n_infiles; + continue; + } + switches[n_switches].part1 = p; + /* Deal with option arguments in separate argv elements. */ + if ((SWITCH_TAKES_ARG (c) > (p[1] != 0)) + || WORD_SWITCH_TAKES_ARG (p)) { + int j = 0; + int n_args = WORD_SWITCH_TAKES_ARG (p); + + if (n_args == 0) { + /* Count only the option arguments in separate argv elements. */ + n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); + } + if (i + n_args >= argc) + fatal ("argument to `-%s' is missing", p); + switches[n_switches].args + = (char **) xmalloc ((n_args + 1) * sizeof (char *)); + while (j < n_args) + switches[n_switches].args[j++] = argv[++i]; + /* Null-terminate the vector. */ + switches[n_switches].args[j] = 0; + } else if (*switches_need_spaces != 0 && (c == 'o' || c == 'L')) { + /* On some systems, ld cannot handle -o or -L without space. + So split the -o or -L from its argument. */ + switches[n_switches].part1 = (c == 'o' ? "o" : "L"); + switches[n_switches].args = (char **) xmalloc (2 * sizeof (char *)); + switches[n_switches].args[0] = xmalloc (strlen (p)); + strcpy (switches[n_switches].args[0], &p[1]); + switches[n_switches].args[1] = 0; + } else + switches[n_switches].args = 0; + switches[n_switches].valid = 0; + /* This is always valid, since gcc.c itself understands it. */ + if (!strcmp (p, "save-temps")) + switches[n_switches].valid = 1; + n_switches++; + } + else + { + if ((argv[i][0] != '-' || argv[i][1] != 'l') + && access (argv[i], R_OK) < 0) + { + perror_with_name (argv[i]); + error_count++; + } + else + { + infiles[n_infiles].language = spec_lang; + infiles[n_infiles++].name = argv[i]; + } + } + } + + if (n_infiles == last_language_n_infiles) + error ("Warning: `-x %s' after last input file has no effect", spec_lang); + + switches[n_switches].part1 = 0; + infiles[n_infiles].name = 0; + + /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake. */ + if (gcc_exec_prefix) + { + temp = (char *) xmalloc (strlen (gcc_exec_prefix) + strlen (spec_version) + + strlen (spec_machine) + 3); + strcpy (temp, gcc_exec_prefix); + strcat (temp, spec_machine); + strcat (temp, "/"); + strcat (temp, spec_version); + strcat (temp, "/"); + gcc_exec_prefix = temp; + } +} + +/* Process a spec string, accumulating and running commands. */ + +/* These variables describe the input file name. + input_file_number is the index on outfiles of this file, + so that the output file name can be stored for later use by %o. + input_basename is the start of the part of the input file + sans all directory names, and basename_length is the number + of characters starting there excluding the suffix .c or whatever. */ + +static char *input_filename; +static int input_file_number; +static int input_filename_length; +static int basename_length; +static char *input_basename; +static char *input_suffix; + +/* These are variables used within do_spec and do_spec_1. */ + +/* Nonzero if an arg has been started and not yet terminated + (with space, tab or newline). */ +static int arg_going; + +/* Nonzero means %d or %g has been seen; the next arg to be terminated + is a temporary file name. */ +static int delete_this_arg; + +/* Nonzero means %w has been seen; the next arg to be terminated + is the output file name of this compilation. */ +static int this_is_output_file; + +/* Nonzero means %s has been seen; the next arg to be terminated + is the name of a library file and we should try the standard + search dirs for it. */ +static int this_is_library_file; + +/* Nonzero means that the input of this command is coming from a pipe. */ +static int input_from_pipe; + +/* Process the spec SPEC and run the commands specified therein. + Returns 0 if the spec is successfully processed; -1 if failed. */ + +static int +do_spec (spec) + char *spec; +{ + int value; + + clear_args (); + arg_going = 0; + delete_this_arg = 0; + this_is_output_file = 0; + this_is_library_file = 0; + input_from_pipe = 0; + + value = do_spec_1 (spec, 0, NULL_PTR); + + /* Force out any unfinished command. + If -pipe, this forces out the last command if it ended in `|'. */ + if (value == 0) + { + if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|")) + argbuf_index--; + + if (argbuf_index > 0) + value = execute (); + } + + return value; +} + +/* Process the sub-spec SPEC as a portion of a larger spec. + This is like processing a whole spec except that we do + not initialize at the beginning and we do not supply a + newline by default at the end. + INSWITCH nonzero means don't process %-sequences in SPEC; + in this case, % is treated as an ordinary character. + This is used while substituting switches. + INSWITCH nonzero also causes SPC not to terminate an argument. + + Value is zero unless a line was finished + and the command on that line reported an error. */ + +static int +do_spec_1 (spec, inswitch, soft_matched_part) + char *spec; + int inswitch; + char *soft_matched_part; +{ + register char *p = spec; + register int c; + int i; + char *string; + int value; + + while (c = *p++) + /* If substituting a switch, treat all chars like letters. + Otherwise, NL, SPC, TAB and % are special. */ + switch (inswitch ? 'a' : c) + { + case '\n': + /* End of line: finish any pending argument, + then run the pending command if one has been started. */ + if (arg_going) + { + obstack_1grow (&obstack, 0); + string = obstack_finish (&obstack); + if (this_is_library_file) + string = find_file (string); + store_arg (string, delete_this_arg, this_is_output_file); + if (this_is_output_file) + outfiles[input_file_number] = string; + } + arg_going = 0; + + if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|")) + { + int i; + for (i = 0; i < n_switches; i++) + if (!strcmp (switches[i].part1, "pipe")) + break; + + /* A `|' before the newline means use a pipe here, + but only if -pipe was specified. + Otherwise, execute now and don't pass the `|' as an arg. */ + if (i < n_switches) + { + input_from_pipe = 1; + switches[i].valid = 1; + break; + } + else + argbuf_index--; + } + + if (argbuf_index > 0) + { + value = execute (); + if (value) + return value; + } + /* Reinitialize for a new command, and for a new argument. */ + clear_args (); + arg_going = 0; + delete_this_arg = 0; + this_is_output_file = 0; + this_is_library_file = 0; + input_from_pipe = 0; + break; + + case '|': + /* End any pending argument. */ + if (arg_going) + { + obstack_1grow (&obstack, 0); + string = obstack_finish (&obstack); + if (this_is_library_file) + string = find_file (string); + store_arg (string, delete_this_arg, this_is_output_file); + if (this_is_output_file) + outfiles[input_file_number] = string; + } + + /* Use pipe */ + obstack_1grow (&obstack, c); + arg_going = 1; + break; + + case '\t': + case ' ': + /* Space or tab ends an argument if one is pending. */ + if (arg_going) + { + obstack_1grow (&obstack, 0); + string = obstack_finish (&obstack); + if (this_is_library_file) + string = find_file (string); + store_arg (string, delete_this_arg, this_is_output_file); + if (this_is_output_file) + outfiles[input_file_number] = string; + } + /* Reinitialize for a new argument. */ + arg_going = 0; + delete_this_arg = 0; + this_is_output_file = 0; + this_is_library_file = 0; + break; + + case '%': + switch (c = *p++) + { + case 0: + fatal ("Invalid specification! Bug in cc."); + + case 'b': + obstack_grow (&obstack, input_basename, basename_length); + arg_going = 1; + break; + + case 'd': + delete_this_arg = 2; + break; + + /* Dump out the directories specified with LIBRARY_PATH, + followed by the absolute directories + that we search for startfiles. */ + case 'D': + { + struct prefix_list *pl = startfile_prefix.plist; + int bufsize = 100; + char *buffer = (char *) xmalloc (bufsize); + int idx; + + for (; pl; pl = pl->next) + { +#ifdef RELATIVE_PREFIX_NOT_LINKDIR + /* Used on systems which record the specified -L dirs + and use them to search for dynamic linking. */ + /* Relative directories always come from -B, + and it is better not to use them for searching + at run time. In particular, stage1 loses */ + if (pl->prefix[0] != '/') + continue; +#endif + if (machine_suffix) + { + if (is_directory (pl->prefix, machine_suffix, 1)) + { + do_spec_1 ("-L", 0, NULL_PTR); +#ifdef SPACE_AFTER_L_OPTION + do_spec_1 (" ", 0, NULL_PTR); +#endif + do_spec_1 (pl->prefix, 1, NULL_PTR); + /* Remove slash from machine_suffix. */ + if (strlen (machine_suffix) >= bufsize) + bufsize = strlen (machine_suffix) * 2 + 1; + buffer = (char *) xrealloc (buffer, bufsize); + strcpy (buffer, machine_suffix); + idx = strlen (buffer); + if (buffer[idx - 1] == '/') + buffer[idx - 1] = 0; + do_spec_1 (buffer, 1, NULL_PTR); + /* Make this a separate argument. */ + do_spec_1 (" ", 0, NULL_PTR); + } + } + if (!pl->require_machine_suffix) + { + if (is_directory (pl->prefix, "", 1)) + { + do_spec_1 ("-L", 0, NULL_PTR); +#ifdef SPACE_AFTER_L_OPTION + do_spec_1 (" ", 0, NULL_PTR); +#endif + /* Remove slash from pl->prefix. */ + if (strlen (pl->prefix) >= bufsize) + bufsize = strlen (pl->prefix) * 2 + 1; + buffer = (char *) xrealloc (buffer, bufsize); + strcpy (buffer, pl->prefix); + idx = strlen (buffer); + if (buffer[idx - 1] == '/') + buffer[idx - 1] = 0; + do_spec_1 (buffer, 1, NULL_PTR); + /* Make this a separate argument. */ + do_spec_1 (" ", 0, NULL_PTR); + } + } + } + free (buffer); + } + break; + + case 'e': + /* {...:%efoo} means report an error with `foo' as error message + and don't execute any more commands for this file. */ + { + char *q = p; + char *buf; + while (*p != 0 && *p != '\n') p++; + buf = (char *) alloca (p - q + 1); + strncpy (buf, q, p - q); + buf[p - q] = 0; + error ("%s", buf); + return -1; + } + break; + + case 'g': + case 'u': + case 'U': + if (save_temps_flag) + obstack_grow (&obstack, input_basename, basename_length); + else + { +#ifdef MKTEMP_EACH_FILE + /* ??? This has a problem: the total number of + values mktemp can return is limited. + That matters for the names of object files. + In 2.4, do something about that. */ + struct temp_name *t; + char *suffix = p; + while (*p == '.' || isalpha (*p)) + p++; + + /* See if we already have an association of %g/%u/%U and + suffix. */ + for (t = temp_names; t; t = t->next) + if (t->length == p - suffix + && strncmp (t->suffix, suffix, p - suffix) == 0 + && t->unique == (c != 'g')) + break; + + /* Make a new association if needed. %u requires one. */ + if (t == 0 || c == 'u') + { + if (t == 0) + { + t = (struct temp_name *) xmalloc (sizeof (struct temp_name)); + t->next = temp_names; + temp_names = t; + } + t->length = p - suffix; + t->suffix = save_string (suffix, p - suffix); + t->unique = (c != 'g'); + choose_temp_base (); + t->filename = temp_filename; + t->filename_length = temp_filename_length; + } + + obstack_grow (&obstack, t->filename, t->filename_length); + delete_this_arg = 1; +#else + obstack_grow (&obstack, temp_filename, temp_filename_length); + if (c == 'u' || c == 'U') + { + static int unique; + char buff[9]; + if (c == 'u') + unique++; + sprintf (buff, "%d", unique); + obstack_grow (&obstack, buff, strlen (buff)); + } +#endif + delete_this_arg = 1; + } + arg_going = 1; + break; + + case 'i': + obstack_grow (&obstack, input_filename, input_filename_length); + arg_going = 1; + break; + + case 'I': + if (gcc_exec_prefix) + { + do_spec_1 ("-iprefix", 1, NULL_PTR); + /* Make this a separate argument. */ + do_spec_1 (" ", 0, NULL_PTR); + do_spec_1 (gcc_exec_prefix, 1, NULL_PTR); + do_spec_1 (" ", 0, NULL_PTR); + } + break; + + case 'o': + { + register int f; + for (f = 0; f < n_infiles; f++) + store_arg (outfiles[f], 0, 0); + } + break; + + case 's': + this_is_library_file = 1; + break; + + case 'w': + this_is_output_file = 1; + break; + + case 'W': + { + int index = argbuf_index; + /* Handle the {...} following the %W. */ + if (*p != '{') + abort (); + p = handle_braces (p + 1); + if (p == 0) + return -1; + /* If any args were output, mark the last one for deletion + on failure. */ + if (argbuf_index != index) + record_temp_file (argbuf[argbuf_index - 1], 0, 1); + break; + } + + /* %x{OPTION} records OPTION for %X to output. */ + case 'x': + { + char *p1 = p; + char *string; + + /* Skip past the option value and make a copy. */ + if (*p != '{') + abort (); + while (*p++ != '}') + ; + string = save_string (p1 + 1, p - p1 - 2); + + /* See if we already recorded this option. */ + for (i = 0; i < n_linker_options; i++) + if (! strcmp (string, linker_options[i])) + { + free (string); + return 0; + } + + /* This option is new; add it. */ + n_linker_options++; + if (!linker_options) + linker_options + = (char **) xmalloc (n_linker_options * sizeof (char **)); + else + linker_options + = (char **) xrealloc (linker_options, + n_linker_options * sizeof (char **)); + + linker_options[n_linker_options - 1] = string; + } + break; + + /* Dump out the options accumulated previously using %x, + -Xlinker and -Wl,. */ + case 'X': + for (i = 0; i < n_linker_options; i++) + { + do_spec_1 (linker_options[i], 1, NULL_PTR); + /* Make each accumulated option a separate argument. */ + do_spec_1 (" ", 0, NULL_PTR); + } + break; + + /* Dump out the options accumulated previously using -Wa,. */ + case 'Y': + for (i = 0; i < n_assembler_options; i++) + { + do_spec_1 (assembler_options[i], 1, NULL_PTR); + /* Make each accumulated option a separate argument. */ + do_spec_1 (" ", 0, NULL_PTR); + } + break; + + /* Here are digits and numbers that just process + a certain constant string as a spec. */ + + case '1': + value = do_spec_1 (cc1_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case '2': + value = do_spec_1 (cc1plus_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'a': + value = do_spec_1 (asm_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'A': + value = do_spec_1 (asm_final_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'c': + value = do_spec_1 (signed_char_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'C': + value = do_spec_1 (cpp_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'E': + value = do_spec_1 (endfile_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'l': + value = do_spec_1 (link_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'L': + value = do_spec_1 (lib_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + case 'p': + { + char *x = (char *) alloca (strlen (cpp_predefines) + 1); + char *buf = x; + char *y; + + /* Copy all of the -D options in CPP_PREDEFINES into BUF. */ + y = cpp_predefines; + while (*y != 0) + { + if (! strncmp (y, "-D", 2)) + /* Copy the whole option. */ + while (*y && *y != ' ' && *y != '\t') + *x++ = *y++; + else if (*y == ' ' || *y == '\t') + /* Copy whitespace to the result. */ + *x++ = *y++; + /* Don't copy other options. */ + else + y++; + } + + *x = 0; + + value = do_spec_1 (buf, 0, NULL_PTR); + if (value != 0) + return value; + } + break; + + case 'P': + { + char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1); + char *buf = x; + char *y; + + /* Copy all of CPP_PREDEFINES into BUF, + but put __ after every -D and at the end of each arg. */ + y = cpp_predefines; + while (*y != 0) + { + if (! strncmp (y, "-D", 2)) + { + int flag = 0; + + *x++ = *y++; + *x++ = *y++; + + if (strncmp (y, "__", 2)) + { + /* Stick __ at front of macro name. */ + *x++ = '_'; + *x++ = '_'; + /* Arrange to stick __ at the end as well. */ + flag = 1; + } + + /* Copy the macro name. */ + while (*y && *y != '=' && *y != ' ' && *y != '\t') + *x++ = *y++; + + if (flag) + { + *x++ = '_'; + *x++ = '_'; + } + + /* Copy the value given, if any. */ + while (*y && *y != ' ' && *y != '\t') + *x++ = *y++; + } + else if (*y == ' ' || *y == '\t') + /* Copy whitespace to the result. */ + *x++ = *y++; + /* Don't copy -A options */ + else + y++; + } + *x++ = ' '; + + /* Copy all of CPP_PREDEFINES into BUF, + but put __ after every -D. */ + y = cpp_predefines; + while (*y != 0) + { + if (! strncmp (y, "-D", 2)) + { + *x++ = *y++; + *x++ = *y++; + + if (strncmp (y, "__", 2)) + { + /* Stick __ at front of macro name. */ + *x++ = '_'; + *x++ = '_'; + } + + /* Copy the macro name. */ + while (*y && *y != '=' && *y != ' ' && *y != '\t') + *x++ = *y++; + + /* Copy the value given, if any. */ + while (*y && *y != ' ' && *y != '\t') + *x++ = *y++; + } + else if (*y == ' ' || *y == '\t') + /* Copy whitespace to the result. */ + *x++ = *y++; + /* Don't copy -A options */ + else + y++; + } + *x++ = ' '; + + /* Copy all of the -A options in CPP_PREDEFINES into BUF. */ + y = cpp_predefines; + while (*y != 0) + { + if (! strncmp (y, "-A", 2)) + /* Copy the whole option. */ + while (*y && *y != ' ' && *y != '\t') + *x++ = *y++; + else if (*y == ' ' || *y == '\t') + /* Copy whitespace to the result. */ + *x++ = *y++; + /* Don't copy other options. */ + else + y++; + } + + *x = 0; + + value = do_spec_1 (buf, 0, NULL_PTR); + if (value != 0) + return value; + } + break; + + case 'S': + value = do_spec_1 (startfile_spec, 0, NULL_PTR); + if (value != 0) + return value; + break; + + /* Here we define characters other than letters and digits. */ + + case '{': + p = handle_braces (p); + if (p == 0) + return -1; + break; + + case '%': + obstack_1grow (&obstack, '%'); + break; + + case '*': + do_spec_1 (soft_matched_part, 1, NULL_PTR); + do_spec_1 (" ", 0, NULL_PTR); + break; + + /* Process a string found as the value of a spec given by name. + This feature allows individual machine descriptions + to add and use their own specs. + %[...] modifies -D options the way %P does; + %(...) uses the spec unmodified. */ + case '(': + case '[': + { + char *name = p; + struct spec_list *sl; + int len; + + /* The string after the S/P is the name of a spec that is to be + processed. */ + while (*p && *p != ')' && *p != ']') + p++; + + /* See if it's in the list */ + for (len = p - name, sl = specs; sl; sl = sl->next) + if (strncmp (sl->name, name, len) == 0 && !sl->name[len]) + { + name = sl->spec; + break; + } + + if (sl) + { + if (c == '(') + { + value = do_spec_1 (name, 0, NULL_PTR); + if (value != 0) + return value; + } + else + { + char *x = (char *) alloca (strlen (name) * 2 + 1); + char *buf = x; + char *y = name; + + /* Copy all of NAME into BUF, but put __ after + every -D and at the end of each arg, */ + while (1) + { + if (! strncmp (y, "-D", 2)) + { + *x++ = '-'; + *x++ = 'D'; + *x++ = '_'; + *x++ = '_'; + y += 2; + } + else if (*y == ' ' || *y == 0) + { + *x++ = '_'; + *x++ = '_'; + if (*y == 0) + break; + else + *x++ = *y++; + } + else + *x++ = *y++; + } + *x = 0; + + value = do_spec_1 (buf, 0, NULL_PTR); + if (value != 0) + return value; + } + } + + /* Discard the closing paren or bracket. */ + if (*p) + p++; + } + break; + + case '|': + if (input_from_pipe) + do_spec_1 ("-", 0, NULL_PTR); + break; + + default: + abort (); + } + break; + + case '\\': + /* Backslash: treat next character as ordinary. */ + c = *p++; + + /* fall through */ + default: + /* Ordinary character: put it into the current argument. */ + obstack_1grow (&obstack, c); + arg_going = 1; + } + + return 0; /* End of string */ +} + +/* Return 0 if we call do_spec_1 and that returns -1. */ + +static char * +handle_braces (p) + register char *p; +{ + register char *q; + char *filter; + int pipe = 0; + int negate = 0; + int suffix = 0; + + if (*p == '|') + /* A `|' after the open-brace means, + if the test fails, output a single minus sign rather than nothing. + This is used in %{|!pipe:...}. */ + pipe = 1, ++p; + + if (*p == '!') + /* A `!' after the open-brace negates the condition: + succeed if the specified switch is not present. */ + negate = 1, ++p; + + if (*p == '.') + /* A `.' after the open-brace means test against the current suffix. */ + { + if (pipe) + abort (); + + suffix = 1; + ++p; + } + + filter = p; + while (*p != ':' && *p != '}') p++; + if (*p != '}') + { + register int count = 1; + q = p + 1; + while (count > 0) + { + if (*q == '{') + count++; + else if (*q == '}') + count--; + else if (*q == 0) + abort (); + q++; + } + } + else + q = p + 1; + + if (suffix) + { + int found = (input_suffix != 0 + && strlen (input_suffix) == p - filter + && strncmp (input_suffix, filter, p - filter) == 0); + + if (p[0] == '}') + abort (); + + if (negate != found + && do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) + return 0; + + return q; + } + else if (p[-1] == '*' && p[0] == '}') + { + /* Substitute all matching switches as separate args. */ + register int i; + --p; + for (i = 0; i < n_switches; i++) + if (!strncmp (switches[i].part1, filter, p - filter)) + give_switch (i, 0); + } + else + { + /* Test for presence of the specified switch. */ + register int i; + int present = 0; + + /* If name specified ends in *, as in {x*:...}, + check for %* and handle that case. */ + if (p[-1] == '*' && !negate) + { + int substitution; + char *r = p; + + /* First see whether we have %*. */ + substitution = 0; + while (r < q) + { + if (*r == '%' && r[1] == '*') + substitution = 1; + r++; + } + /* If we do, handle that case. */ + if (substitution) + { + /* Substitute all matching switches as separate args. + But do this by substituting for %* + in the text that follows the colon. */ + + unsigned hard_match_len = p - filter - 1; + char *string = save_string (p + 1, q - p - 2); + + for (i = 0; i < n_switches; i++) + if (!strncmp (switches[i].part1, filter, hard_match_len)) + { + do_spec_1 (string, 0, &switches[i].part1[hard_match_len]); + /* Pass any arguments this switch has. */ + give_switch (i, 1); + } + + return q; + } + } + + /* If name specified ends in *, as in {x*:...}, + check for presence of any switch name starting with x. */ + if (p[-1] == '*') + { + for (i = 0; i < n_switches; i++) + { + unsigned hard_match_len = p - filter - 1; + + if (!strncmp (switches[i].part1, filter, hard_match_len)) + { + switches[i].valid = 1; + present = 1; + } + } + } + /* Otherwise, check for presence of exact name specified. */ + else + { + for (i = 0; i < n_switches; i++) + { + if (!strncmp (switches[i].part1, filter, p - filter) + && switches[i].part1[p - filter] == 0) + { + switches[i].valid = 1; + present = 1; + break; + } + } + } + + /* If it is as desired (present for %{s...}, absent for %{-s...}) + then substitute either the switch or the specified + conditional text. */ + if (present != negate) + { + if (*p == '}') + { + give_switch (i, 0); + } + else + { + if (do_spec_1 (save_string (p + 1, q - p - 2), 0, NULL_PTR) < 0) + return 0; + } + } + else if (pipe) + { + /* Here if a %{|...} conditional fails: output a minus sign, + which means "standard output" or "standard input". */ + do_spec_1 ("-", 0, NULL_PTR); + } + } + + return q; +} + +/* Pass a switch to the current accumulating command + in the same form that we received it. + SWITCHNUM identifies the switch; it is an index into + the vector of switches gcc received, which is `switches'. + This cannot fail since it never finishes a command line. + + If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */ + +static void +give_switch (switchnum, omit_first_word) + int switchnum; + int omit_first_word; +{ + if (!omit_first_word) + { + do_spec_1 ("-", 0, NULL_PTR); + do_spec_1 (switches[switchnum].part1, 1, NULL_PTR); + } + do_spec_1 (" ", 0, NULL_PTR); + if (switches[switchnum].args != 0) + { + char **p; + for (p = switches[switchnum].args; *p; p++) + { + do_spec_1 (*p, 1, NULL_PTR); + do_spec_1 (" ", 0, NULL_PTR); + } + } + switches[switchnum].valid = 1; +} + +/* Search for a file named NAME trying various prefixes including the + user's -B prefix and some standard ones. + Return the absolute file name found. If nothing is found, return NAME. */ + +static char * +find_file (name) + char *name; +{ + char *newname; + + newname = find_a_file (&startfile_prefix, name, R_OK); + return newname ? newname : name; +} + +/* Determine whether a directory exists. If LINKER, return 0 for + certain fixed names not needed by the linker. If not LINKER, it is + only important to return 0 if the host machine has a small ARG_MAX + limit. */ + +static int +is_directory (path1, path2, linker) + char *path1; + char *path2; + int linker; +{ + int len1 = strlen (path1); + int len2 = strlen (path2); + char *path = (char *) alloca (3 + len1 + len2); + char *cp; + struct stat st; + +#ifndef SMALL_ARG_MAX + if (! linker) + return 1; +#endif + + /* Construct the path from the two parts. Ensure the string ends with "/.". + The resulting path will be a directory even if the given path is a + symbolic link. */ + bcopy (path1, path, len1); + bcopy (path2, path + len1, len2); + cp = path + len1 + len2; + if (cp[-1] != '/') + *cp++ = '/'; + *cp++ = '.'; + *cp = '\0'; + + /* Exclude directories that the linker is known to search. */ + if (linker + && ((cp - path == 6 && strcmp (path, "/lib/.") == 0) + || (cp - path == 10 && strcmp (path, "/usr/lib/.") == 0))) + return 0; + + return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode)); +} + +/* On fatal signals, delete all the temporary files. */ + +static void +fatal_error (signum) + int signum; +{ + signal (signum, SIG_DFL); + delete_failure_queue (); + delete_temp_files (); + /* Get the same signal again, this time not handled, + so its normal effect occurs. */ + kill (getpid (), signum); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + register int i; + int j; + int value; + int linker_was_run = 0; + char *explicit_link_files; + char *specs_file; + char *p; + + p = argv[0] + strlen (argv[0]); + while (p != argv[0] && p[-1] != '/') --p; + programname = p; + + if (signal (SIGINT, SIG_IGN) != SIG_IGN) + signal (SIGINT, fatal_error); +#ifdef SIGHUP + if (signal (SIGHUP, SIG_IGN) != SIG_IGN) + signal (SIGHUP, fatal_error); +#endif + if (signal (SIGTERM, SIG_IGN) != SIG_IGN) + signal (SIGTERM, fatal_error); +#ifdef SIGPIPE + if (signal (SIGPIPE, SIG_IGN) != SIG_IGN) + signal (SIGPIPE, fatal_error); +#endif + + argbuf_length = 10; + argbuf = (char **) xmalloc (argbuf_length * sizeof (char *)); + + obstack_init (&obstack); + + /* Set up to remember the pathname of gcc and any options + needed for collect. We use argv[0] instead of programname because + we need the complete pathname. */ + obstack_init (&collect_obstack); + obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1); + obstack_grow (&collect_obstack, argv[0], strlen (argv[0])+1); + putenv (obstack_finish (&collect_obstack)); + + /* Choose directory for temp files. */ + + choose_temp_base (); + + /* Make a table of what switches there are (switches, n_switches). + Make a table of specified input files (infiles, n_infiles). + Decode switches that are handled locally. */ + + process_command (argc, argv); + + /* Initialize the vector of specs to just the default. + This means one element containing 0s, as a terminator. */ + + compilers = (struct compiler *) xmalloc (sizeof default_compilers); + bcopy (default_compilers, compilers, sizeof default_compilers); + n_compilers = n_default_compilers; + + /* Read specs from a file if there is one. */ + + machine_suffix = concat (spec_machine, "/", concat (spec_version, "/", "")); + just_machine_suffix = concat (spec_machine, "/", ""); + + specs_file = find_a_file (&startfile_prefix, "specs", R_OK); + /* Read the specs file unless it is a default one. */ + if (specs_file != 0 && strcmp (specs_file, "specs")) + read_specs (specs_file); + + /* If not cross-compiling, look for startfiles in the standard places. */ + /* The fact that these are done here, after reading the specs file, + means that it cannot be found in these directories. + But that's okay. It should never be there anyway. */ + if (!cross_compile) + { +#ifdef MD_EXEC_PREFIX + add_prefix (&exec_prefix, md_exec_prefix, 0, 0, NULL_PTR); + add_prefix (&startfile_prefix, md_exec_prefix, 0, 0, NULL_PTR); +#endif + +#ifdef MD_STARTFILE_PREFIX + add_prefix (&startfile_prefix, md_startfile_prefix, 0, 0, NULL_PTR); +#endif + +#ifdef MD_STARTFILE_PREFIX_1 + add_prefix (&startfile_prefix, md_startfile_prefix_1, 0, 0, NULL_PTR); +#endif + + add_prefix (&startfile_prefix, standard_startfile_prefix, 0, 0, + NULL_PTR); + add_prefix (&startfile_prefix, standard_startfile_prefix_1, 0, 0, + NULL_PTR); + add_prefix (&startfile_prefix, standard_startfile_prefix_2, 0, 0, + NULL_PTR); +#if 0 /* Can cause surprises, and one can use -B./ instead. */ + add_prefix (&startfile_prefix, "./", 0, 1, NULL_PTR); +#endif + } + + /* Now we have the specs. + Set the `valid' bits for switches that match anything in any spec. */ + + validate_all_switches (); + + /* Warn about any switches that no pass was interested in. */ + + for (i = 0; i < n_switches; i++) + if (! switches[i].valid) + error ("unrecognized option `-%s'", switches[i].part1); + + if (print_libgcc_file_name) + { + printf ("%s\n", find_file ("libgcc.a")); + exit (0); + } + + /* Obey some of the options. */ + + if (verbose_flag) + { + fprintf (stderr, "gcc version %s\n", version_string); + if (n_infiles == 0) + exit (0); + } + + if (n_infiles == 0) + fatal ("No input files specified."); + + /* Make a place to record the compiler output file names + that correspond to the input files. */ + + outfiles = (char **) xmalloc (n_infiles * sizeof (char *)); + bzero (outfiles, n_infiles * sizeof (char *)); + + /* Record which files were specified explicitly as link input. */ + + explicit_link_files = xmalloc (n_infiles); + bzero (explicit_link_files, n_infiles); + + for (i = 0; i < n_infiles; i++) + { + register struct compiler *cp = 0; + int this_file_error = 0; + + /* Tell do_spec what to substitute for %i. */ + + input_filename = infiles[i].name; + input_filename_length = strlen (input_filename); + input_file_number = i; + + /* Use the same thing in %o, unless cp->spec says otherwise. */ + + outfiles[i] = input_filename; + + /* Figure out which compiler from the file's suffix. */ + + cp = lookup_compiler (infiles[i].name, input_filename_length, + infiles[i].language); + + if (cp) + { + /* Ok, we found an applicable compiler. Run its spec. */ + /* First say how much of input_filename to substitute for %b */ + register char *p; + int len; + + input_basename = input_filename; + for (p = input_filename; *p; p++) + if (*p == '/') + input_basename = p + 1; + + /* Find a suffix starting with the last period, + and set basename_length to exclude that suffix. */ + basename_length = strlen (input_basename); + p = input_basename + basename_length; + while (p != input_basename && *p != '.') --p; + if (*p == '.' && p != input_basename) + { + basename_length = p - input_basename; + input_suffix = p + 1; + } + else + input_suffix = ""; + + len = 0; + for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++) + if (cp->spec[j]) + len += strlen (cp->spec[j]); + + p = (char *) xmalloc (len + 1); + + len = 0; + for (j = 0; j < sizeof cp->spec / sizeof cp->spec[0]; j++) + if (cp->spec[j]) + { + strcpy (p + len, cp->spec[j]); + len += strlen (cp->spec[j]); + } + + value = do_spec (p); + free (p); + if (value < 0) + this_file_error = 1; + } + + /* If this file's name does not contain a recognized suffix, + record it as explicit linker input. */ + + else + explicit_link_files[i] = 1; + + /* Clear the delete-on-failure queue, deleting the files in it + if this compilation failed. */ + + if (this_file_error) + { + delete_failure_queue (); + error_count++; + } + /* If this compilation succeeded, don't delete those files later. */ + clear_failure_queue (); + } + + /* Run ld to link all the compiler output files. */ + + if (error_count == 0) + { + int tmp = execution_count; + int i; + int first_time; + + /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables + for collect. */ + putenv_from_prefixes (&exec_prefix, "COMPILER_PATH="); + putenv_from_prefixes (&startfile_prefix, "LIBRARY_PATH="); + + /* Build COLLECT_GCC_OPTIONS to have all of the options specified to + the compiler. */ + obstack_grow (&collect_obstack, "COLLECT_GCC_OPTIONS=", + sizeof ("COLLECT_GCC_OPTIONS=")-1); + + first_time = TRUE; + for (i = 0; i < n_switches; i++) + { + char **args; + if (!first_time) + obstack_grow (&collect_obstack, " ", 1); + + first_time = FALSE; + obstack_grow (&collect_obstack, "-", 1); + obstack_grow (&collect_obstack, switches[i].part1, + strlen (switches[i].part1)); + + for (args = switches[i].args; args && *args; args++) + { + obstack_grow (&collect_obstack, " ", 1); + obstack_grow (&collect_obstack, *args, strlen (*args)); + } + } + obstack_grow (&collect_obstack, "\0", 1); + putenv (obstack_finish (&collect_obstack)); + + value = do_spec (link_command_spec); + if (value < 0) + error_count = 1; + linker_was_run = (tmp != execution_count); + } + + /* Warn if a -B option was specified but the prefix was never used. */ + unused_prefix_warnings (&exec_prefix); + unused_prefix_warnings (&startfile_prefix); + + /* If options said don't run linker, + complain about input files to be given to the linker. */ + + if (! linker_was_run && error_count == 0) + for (i = 0; i < n_infiles; i++) + if (explicit_link_files[i]) + error ("%s: linker input file unused since linking not done", + outfiles[i]); + + /* Delete some or all of the temporary files we made. */ + + if (error_count) + delete_failure_queue (); + delete_temp_files (); + + exit (error_count > 0 ? (signal_count ? 2 : 1) : 0); + /* NOTREACHED */ + return 0; +} + +/* Find the proper compilation spec for the file name NAME, + whose length is LENGTH. LANGUAGE is the specified language, + or 0 if none specified. */ + +static struct compiler * +lookup_compiler (name, length, language) + char *name; + int length; + char *language; +{ + struct compiler *cp; + + /* Look for the language, if one is spec'd. */ + if (language != 0) + { + for (cp = compilers + n_compilers - 1; cp >= compilers; cp--) + { + if (language != 0) + { + if (cp->suffix[0] == '@' + && !strcmp (cp->suffix + 1, language)) + return cp; + } + } + error ("language %s not recognized", language); + } + + /* Look for a suffix. */ + for (cp = compilers + n_compilers - 1; cp >= compilers; cp--) + { + if (/* The suffix `-' matches only the file name `-'. */ + (!strcmp (cp->suffix, "-") && !strcmp (name, "-")) + || + (strlen (cp->suffix) < length + /* See if the suffix matches the end of NAME. */ + && !strcmp (cp->suffix, + name + length - strlen (cp->suffix)))) + { + if (cp->spec[0][0] == '@') + { + struct compiler *new; + /* An alias entry maps a suffix to a language. + Search for the language; pass 0 for NAME and LENGTH + to avoid infinite recursion if language not found. + Construct the new compiler spec. */ + language = cp->spec[0] + 1; + new = (struct compiler *) xmalloc (sizeof (struct compiler)); + new->suffix = cp->suffix; + bcopy (lookup_compiler (NULL_PTR, 0, language)->spec, + new->spec, sizeof new->spec); + return new; + } + /* A non-alias entry: return it. */ + return cp; + } + } + + return 0; +} + +char * +xmalloc (size) + unsigned size; +{ + register char *value = (char *) malloc (size); + if (value == 0) + fatal ("virtual memory exhausted"); + return value; +} + +char * +xrealloc (ptr, size) + char *ptr; + unsigned size; +{ + register char *value = (char *) realloc (ptr, 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 char * +save_string (s, len) + char *s; + int len; +{ + register char *result = xmalloc (len + 1); + + bcopy (s, result, len); + result[len] = 0; + return result; +} + +static void +pfatal_with_name (name) + char *name; +{ + char *s; + + if (errno < sys_nerr) + s = concat ("%s: ", sys_errlist[errno], ""); + else + s = "cannot open %s"; + fatal (s, name); +} + +static void +perror_with_name (name) + char *name; +{ + char *s; + + if (errno < sys_nerr) + s = concat ("%s: ", sys_errlist[errno], ""); + else + s = "cannot open %s"; + error (s, name); +} + +static void +perror_exec (name) + char *name; +{ + char *s; + + if (errno < sys_nerr) + s = concat ("installation problem, cannot exec %s: ", + sys_errlist[errno], ""); + else + s = "installation problem, cannot exec %s"; + error (s, name); +} + +/* 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 gcc abort."); +} + +#ifdef HAVE_VPRINTF + +/* Output an error message and exit */ + +static void +fatal (va_alist) + va_dcl +{ + va_list ap; + char *format; + + va_start (ap); + format = va_arg (ap, char *); + fprintf (stderr, "%s: ", programname); + vfprintf (stderr, format, ap); + va_end (ap); + fprintf (stderr, "\n"); + delete_temp_files (); + exit (1); +} + +static void +error (va_alist) + va_dcl +{ + va_list ap; + char *format; + + va_start (ap); + format = va_arg (ap, char *); + fprintf (stderr, "%s: ", programname); + vfprintf (stderr, format, ap); + va_end (ap); + + fprintf (stderr, "\n"); +} + +#else /* not HAVE_VPRINTF */ + +static void +fatal (msg, arg1, arg2) + char *msg, *arg1, *arg2; +{ + error (msg, arg1, arg2); + delete_temp_files (); + exit (1); +} + +static void +error (msg, arg1, arg2) + char *msg, *arg1, *arg2; +{ + fprintf (stderr, "%s: ", programname); + fprintf (stderr, msg, arg1, arg2); + fprintf (stderr, "\n"); +} + +#endif /* not HAVE_VPRINTF */ + + +static void +validate_all_switches () +{ + struct compiler *comp; + register char *p; + register char c; + struct spec_list *spec; + + for (comp = compilers; comp->spec[0]; comp++) + { + int i; + for (i = 0; i < sizeof comp->spec / sizeof comp->spec[0] && comp->spec[i]; i++) + { + p = comp->spec[i]; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + } + } + + /* look through the linked list of extra specs read from the specs file */ + for (spec = specs; spec ; spec = spec->next) + { + p = spec->spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + } + + p = link_command_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + /* Now notice switches mentioned in the machine-specific specs. */ + + p = asm_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = asm_final_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = cpp_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = signed_char_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = cc1_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = cc1plus_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = link_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = lib_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); + + p = startfile_spec; + while (c = *p++) + if (c == '%' && *p == '{') + /* We have a switch spec. */ + validate_switches (p + 1); +} + +/* Look at the switch-name that comes after START + and mark as valid all supplied switches that match it. */ + +static void +validate_switches (start) + char *start; +{ + register char *p = start; + char *filter; + register int i; + int suffix = 0; + + if (*p == '|') + ++p; + + if (*p == '!') + ++p; + + if (*p == '.') + suffix = 1, ++p; + + filter = p; + while (*p != ':' && *p != '}') p++; + + if (suffix) + ; + else if (p[-1] == '*') + { + /* Mark all matching switches as valid. */ + --p; + for (i = 0; i < n_switches; i++) + if (!strncmp (switches[i].part1, filter, p - filter)) + switches[i].valid = 1; + } + else + { + /* Mark an exact matching switch as valid. */ + for (i = 0; i < n_switches; i++) + { + if (!strncmp (switches[i].part1, filter, p - filter) + && switches[i].part1[p - filter] == 0) + switches[i].valid = 1; + } + } +} |
