diff options
45 files changed, 1896 insertions, 294 deletions
diff --git a/gnu/egcs/ChangeLog b/gnu/egcs/ChangeLog index 77d5478404f..d7319f7cfaa 100644 --- a/gnu/egcs/ChangeLog +++ b/gnu/egcs/ChangeLog @@ -1,3 +1,7 @@ +Tue Mar 7 21:48:55 2000 Jeffrey A Law (law@cygnus.com) + + * config.guess: Fix detection of ReliantUNIX. + Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. diff --git a/gnu/egcs/INSTALL/README b/gnu/egcs/INSTALL/README index 7c888f53a8c..8afbd068f4f 100644 --- a/gnu/egcs/INSTALL/README +++ b/gnu/egcs/INSTALL/README @@ -1,10 +1,9 @@ -The installation instructions are no longer in this directory. Instead -they can be found in the "install" directory at the toplevel of the GCC -distribution (ie gcc-2.95/install). For HTML browsing start with -install/index.html, for plaintext, start with install/INDEX. +This directory has been obsoleted for egcs snapshots and CVS access. -Moving the installation instructions in this manner makes it significantly -easier to share code between the distribution and the web pages. +Instead check out the toplevel "wwwdocs" as a sibling of your egcs +tree or read these files via the egcs web site +http://www.gnu.org/software/gcc/ -This directory (INSTALL) will be completely removed in the next major -GCC release. + +Copies of the relevant files will be copied into this directory for +releases. diff --git a/gnu/egcs/configure b/gnu/egcs/configure index ebc654e9150..cd6791b94e1 100644 --- a/gnu/egcs/configure +++ b/gnu/egcs/configure @@ -86,7 +86,7 @@ subdirs= target_alias=NOTARGET target_makefile_frag= undefs=NOUNDEFS -version="$Revision: 1.1.1.2 $" +version="$Revision: 1.1.1.3 $" x11=default bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' diff --git a/gnu/egcs/etc/ChangeLog b/gnu/egcs/etc/ChangeLog index a1f9b964bd2..76a6628ab5a 100644 --- a/gnu/egcs/etc/ChangeLog +++ b/gnu/egcs/etc/ChangeLog @@ -1,3 +1,7 @@ +2000-05-18 Martin von Loewis <loewis@informatik.hu-berlin.de> + + * standards.texi, make-stds.texi: Update to FSF version of May 13. + Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. diff --git a/gnu/egcs/etc/make-stds.texi b/gnu/egcs/etc/make-stds.texi index b8e0bbed4f1..b655ea58750 100644 --- a/gnu/egcs/etc/make-stds.texi +++ b/gnu/egcs/etc/make-stds.texi @@ -21,6 +21,8 @@ chapter @end ifclear @end iftex describes conventions for writing the Makefiles for GNU programs. +Using Automake will help you write a Makefile that follows these +conventions. @menu * Makefile Basics:: General Conventions for Makefiles @@ -280,8 +282,8 @@ installed. Installation directories should always be named by variables, so it is easy to install in a nonstandard place. The standard names for these variables are described below. They are based on a standard filesystem -layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and -other modern operating systems. +layout; variants of it are used in SVR4, 4.4BSD, GNU/Linux, Ultrix v4, +and other modern operating systems. These two variables set the root for the installation. All the other installation directories should be subdirectories of one of these two, diff --git a/gnu/egcs/etc/standards.texi b/gnu/egcs/etc/standards.texi index 93fddcb0e21..8970dad7dfd 100644 --- a/gnu/egcs/etc/standards.texi +++ b/gnu/egcs/etc/standards.texi @@ -3,7 +3,7 @@ @setfilename standards.info @settitle GNU Coding Standards @c This date is automagically updated when you save this file: -@set lastupdate March 13, 1998 +@set lastupdate May 13, 2000 @c %**end of header @ifinfo @@ -28,7 +28,7 @@ END-INFO-DIR-ENTRY @ifinfo GNU Coding Standards -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -84,13 +84,14 @@ Last updated @value{lastupdate}. @end ifinfo @menu -* Preface:: About the GNU Coding Standards -* Intellectual Property:: Keeping Free Software Free -* Design Advice:: General Program Design -* Program Behavior:: Program Behavior for All Programs -* Writing C:: Making The Best Use of C -* Documentation:: Documenting Programs -* Managing Releases:: The Release Process +* Preface:: About the GNU Coding Standards +* Legal Issues:: Keeping Free Software Free +* Design Advice:: General Program Design +* Program Behavior:: Program Behavior for All Programs +* Writing C:: Making The Best Use of C +* Documentation:: Documenting Programs +* Managing Releases:: The Release Process +* References:: References to Non-Free Software or Documentation @end menu @node Preface @@ -113,15 +114,16 @@ you don't have those files, please mail your suggestion anyway. This release of the GNU Coding Standards was last updated @value{lastupdate}. -@node Intellectual Property +@node Legal Issues @chapter Keeping Free Software Free This @value{CHAPTER} discusses how you can make sure that GNU software -remains unencumbered. +avoids legal difficulties, and other related issues. @menu * Reading Non-Free Code:: Referring to Proprietary Programs * Contributions:: Accepting Contributions +* Trademarks:: How We Deal with Trademark Issues @end menu @node Reading Non-Free Code @@ -157,15 +159,15 @@ Or turn some parts of the program into independently usable libraries. Or use a simple garbage collector instead of tracking precisely when to free memory, or use a new GNU facility such as obstacks. - @node Contributions @section Accepting Contributions -If someone else sends you a piece of code to add to the program you are -working on, we need legal papers to use it---the same sort of legal -papers we will need to get from you. @emph{Each} significant -contributor to a program must sign some sort of legal papers in order -for us to have clear title to the program. The main author alone is not +If the program you are working on is copyrighted by the Free Software +Foundation, then when someone else sends you a piece of code to add to +the program, we need legal papers to use it---just as we asked you to +sign papers initially. @emph{Each} person who makes a nontrivial +contribution to a program must sign some sort of legal papers in order +for us to have clear title to the program; the main author alone is not enough. So, before adding in any contributions from other people, please tell @@ -181,16 +183,17 @@ This also applies to comments and documentation files. For copyright law, comments and code are just text. Copyright applies to all kinds of text, so we need legal papers for all kinds. +We know it is frustrating to ask for legal papers; it's frustrating for +us as well. But if you don't wait, you are going out on a limb---for +example, what if the contributor's employer won't sign a disclaimer? +You might have to take that code out again! + You don't need papers for changes of a few lines here or there, since they are not significant for copyright purposes. Also, you don't need papers if all you get from the suggestion is some ideas, not actual code -which you use. For example, if you write a different solution to the -problem, you don't need to get papers. - -We know this is frustrating; it's frustrating for us as well. But if -you don't wait, you are going out on a limb---for example, what if the -contributor's employer won't sign a disclaimer? You might have to take -that code out again! +which you use. For example, if someone send you one implementation, but +you write a different implementation of the same idea, you don't need to +get papers. The very worst thing is if you forget to tell us about the other contributor. We could be very embarrassed in court some day as a @@ -200,39 +203,113 @@ We have more detailed advice for maintainers of programs; if you have reached the stage of actually maintaining a program for GNU (whether released or not), please ask us for a copy. +@node Trademarks +@section Trademarks + +Please do not include any trademark acknowledgements in GNU software +packages or documentation. + +Trademark acknowledgements are the statements that such-and-such is a +trademark of so-and-so. The GNU Project has no objection to the basic +idea of trademarks, but these acknowledgements feel like kowtowing, so +we don't use them. There is no legal requirement for them. + +What is legally required, as regards other people's trademarks, is to +avoid using them in ways which a reader might read as naming or labeling +our own programs or activities. For example, since ``Objective C'' is +(or at least was) a trademark, we made sure to say that we provide a +``compiler for the Objective C language'' rather than an ``Objective C +compiler''. The latter is meant to be short for the former, but it does +not explicitly state the relationship, so it could be misinterpreted as +using ``Objective C'' as a label for the compiler rather than for the +language. + @node Design Advice @chapter General Program Design This @value{CHAPTER} discusses some of the issues you should take into account when designing your program. +@c Standard or ANSI C +@c +@c In 1989 the American National Standards Institute (ANSI) standardized +@c C as standard X3.159-1989. In December of that year the +@c International Standards Organization ISO adopted the ANSI C standard +@c making minor changes. In 1990 ANSI then re-adopted ISO standard +@c C. This version of C is known as either ANSI C or Standard C. + @menu +* Source Language:: Which languges to use. * Compatibility:: Compatibility with other implementations * Using Extensions:: Using non-standard features -* ANSI C:: Using ANSI C features -* Source Language:: Using languages other than C +* Standard C:: Using Standard (ANSI 1989) C features @end menu +@node Source Language +@section Which Languages to Use + +When you want to use a language that gets compiled and runs at high +speed, the best language to use is C. Using another language is like +using a non-standard feature: it will cause trouble for users. Even if +GCC supports the other language, users may find it inconvenient to have +to install the compiler for that other language in order to build your +program. For example, if you write your program in C++, people will +have to install the GNU C++ compiler in order to compile your program. + +C has one other advantage over C++ and other compiled languages: more +people know C, so more people will find it easy to read and modify the +program if it is written in C. + +So in general it is much better to use use C, rather than the +comparable alternatives. + +But there are two exceptions to that conclusion: + +@itemize @bullet +@item +It is no problem to use another language to write a tool specifically +intended for use with that language. That is because the only people +who want to build the tool will be those who have installed the other +language anyway. + +@item +If an application is of interest only to a narrow part of the community, +then the question of which language it is written in has less effect on +other people, so you may as well please yourself. +@end itemize + +Many programs are designed to be extensible: they include an interpreter +for a language that is higher level than C. Often much of the program +is written in that language, too. The Emacs editor pioneered this +technique. + +The standard extensibility interpreter for GNU software is GUILE, which +implements the language Scheme (an especially clean and simple dialect +of Lisp). @uref{http://www.gnu.org/software/guile/}. We don't reject +programs written in other ``scripting languages'' such as Perl and +Python, but using GUILE is very important for the overall consistency of +the GNU system. + @node Compatibility @section Compatibility with Other Implementations With occasional exceptions, utility programs and libraries for GNU should be upward compatible with those in Berkeley Unix, and upward -compatible with @sc{ansi} C if @sc{ansi} C specifies their behavior, and -upward compatible with @sc{POSIX} if @sc{POSIX} specifies their -behavior. +compatible with 1989 Standard C if 1989 Standard C specifies their +behavior, and upward compatible with @sc{posix} if @sc{posix} specifies +their behavior. When these standards conflict, it is useful to offer compatibility modes for each of them. -@sc{ansi} C and @sc{POSIX} prohibit many kinds of extensions. Feel free -to make the extensions anyway, and include a @samp{--ansi}, +1989 Standard C and @sc{posix} prohibit many kinds of extensions. Feel +free to make the extensions anyway, and include a @samp{--ansi}, @samp{--posix}, or @samp{--compatible} option to turn them off. However, if the extension has a significant chance of breaking any real -programs or scripts, then it is not really upward compatible. Try to -redesign its interface. +programs or scripts, then it is not really upward compatible. So you +should try to redesign its interface to make it upward compatible. -Many GNU programs suppress extensions that conflict with POSIX if the +Many GNU programs suppress extensions that conflict with @sc{posix} if the environment variable @code{POSIXLY_CORRECT} is defined (even if it is defined with a null value). Please make your program recognize this variable if appropriate. @@ -243,7 +320,8 @@ completely with something totally different and better. (For example, @code{vi} is replaced with Emacs.) But it is nice to offer a compatible feature as well. (There is a free @code{vi} clone, so we offer it.) -Additional useful features not in Berkeley Unix are welcome. +Additional useful features are welcome regardless of whether +there is any precedent for them. @node Using Extensions @section Using Non-standard Features @@ -267,29 +345,28 @@ straightforwardly do without them, but to use the extensions if they are a big improvement. An exception to this rule are the large, established programs (such as -Emacs) which run on a great variety of systems. Such programs would -be broken by use of GNU extensions. +Emacs) which run on a great variety of systems. Using GNU extensions in +such programs would make many users unhappy, so we don't do that. -Another exception is for programs that are used as part of -compilation: anything that must be compiled with other compilers in -order to bootstrap the GNU compilation facilities. If these require -the GNU compiler, then no one can compile them without having them -installed already. That would be no good. +Another exception is for programs that are used as part of compilation: +anything that must be compiled with other compilers in order to +bootstrap the GNU compilation facilities. If these require the GNU +compiler, then no one can compile them without having them installed +already. That would be extremely troublesome in certain cases. -@node ANSI C -@section @sc{ansi} C and pre-@sc{ansi} C +@node Standard C +@section 1989 Standard C and Pre-Standard C -Do not ever use the ``trigraph'' feature of @sc{ansi} C. +1989 Standard C is widespread enough now that it is ok to use its +features in new programs. There is one exception: do not ever use the +``trigraph'' feature of 1989 Standard C. -@sc{ansi} C is widespread enough now that it is ok to write new programs -that use @sc{ansi} C features (and therefore will not work in -non-@sc{ansi} compilers). And if a program is already written in -@sc{ansi} C, there's no need to convert it to support non-@sc{ansi} -compilers. +However, it is easy to support pre-standard compilers in most programs, +so if you know how to do that, feel free. If a program you are +maintaining has such support, you should try to keep it working. -However, it is easy to support non-@sc{ansi} compilers in most programs, -so you might still consider doing so when you write a program. Instead -of writing function definitions in @sc{ansi} prototype form, +To support pre-standard C, instead of writing function definitions in +standard prototype form, @example int @@ -298,7 +375,7 @@ foo (int x, int y) @end example @noindent -write the definition in pre-@sc{ansi} style like this, +write the definition in pre-standard style like this, @example int @@ -315,56 +392,42 @@ int foo (int, int); @end example You need such a declaration anyway, in a header file, to get the benefit -of @sc{ansi} C prototypes in all the files where the function is called. -And once you have it, you lose nothing by writing the function -definition in the pre-@sc{ansi} style. - -If you don't know non-@sc{ansi} C, there's no need to learn it; just -write in @sc{ansi} C. - -@node Source Language -@section Using Languages Other Than C - -Using a language other than C is like using a non-standard feature: it -will cause trouble for users. Even if GCC supports the other language, -users may find it inconvenient to have to install the compiler for that -other language in order to build your program. For example, if you -write your program in C++, people will have to install the C++ compiler -in order to compile your program. Thus, it is better if you write in C. - -But there are three situations when there is no disadvantage in using -some other language: - -@itemize @bullet -@item -It is okay to use another language if your program contains an -interpreter for that language. - -For example, if your program links with GUILE, it is ok to write part of -the program in Scheme or another language supported by GUILE. - -@item -It is okay to use another language in a tool specifically intended for -use with that language. - -This is okay because the only people who want to build the tool will be -those who have installed the other language anyway. - -@item -If an application is of interest to a narrow community, then perhaps -it's not important if the application is inconvenient to install. -@end itemize +of prototypes in all the files where the function is called. And once +you have the declaration, you normally lose nothing by writing the +function definition in the pre-standard style. + +This technique does not work for integer types narrower than @code{int}. +If you think of an argument as being of a type narrower than @code{int}, +declare it as @code{int} instead. + +There are a few special cases where this technique is hard to use. For +example, if a function argument needs to hold the system type +@code{dev_t}, you run into trouble, because @code{dev_t} is shorter than +@code{int} on some machines; but you cannot use @code{int} instead, +because @code{dev_t} is wider than @code{int} on some machines. There +is no type you can safely use on all machines in a non-standard +definition. The only way to support non-standard C and pass such an +argument is to check the width of @code{dev_t} using Autoconf and choose +the argument type accordingly. This may not be worth the trouble. + +In order to support pre-standard compilers that do not recognize +prototypes, you may want to use a preprocessor macro like this: -C has one other advantage over C++ and other compiled languages: more -people know C, so more people will find it easy to read and modify the -program if it is written in C. +@example +/* Declare the prototype for a general external function. */ +#if defined (__STDC__) || defined (WINDOWSNT) +#define P_(proto) proto +#else +#define P_(proto) () +#endif +@end example @node Program Behavior @chapter Program Behavior for All Programs -This @value{CHAPTER} describes how to write robust software. It also -describes general standards for error messages, the command line interface, -and how libraries should behave. +This @value{CHAPTER} describes conventions for writing robust +software. It also describes general standards for error messages, the +command line interface, and how libraries should behave. @menu * Semantics:: Writing robust programs @@ -384,9 +447,13 @@ all data structures dynamically. In most Unix utilities, ``long lines are silently truncated''. This is not acceptable in a GNU utility. Utilities reading files should not drop NUL characters, or any other -nonprinting characters @emph{including those with codes above 0177}. The -only sensible exceptions would be utilities specifically intended for -interface to certain types of printers that can't handle those characters. +nonprinting characters @emph{including those with codes above 0177}. +The only sensible exceptions would be utilities specifically intended +for interface to certain types of terminals or printers +that can't handle those characters. +Whenever possible, try to make programs work properly with +sequences of bytes that represent multibyte characters, using encodings +such as UTF-8 and others. Check every system call for an error return, unless you know you wish to ignore errors. Include the system error text (from @code{perror} or @@ -428,11 +495,18 @@ Try to avoid low-level interfaces to obscure Unix data structures (such as file directories, utmp, or the layout of kernel memory), since these are less likely to work compatibly. If you need to find all the files in a directory, use @code{readdir} or some other high-level interface. -These will be supported compatibly by GNU. +These are supported compatibly by GNU. + +The preferred signal handling facilities are the BSD variant of +@code{signal}, and the @sc{posix} @code{sigaction} function; the +alternative USG @code{signal} interface is an inferior design. -By default, the GNU system will provide the signal handling functions of -@sc{BSD} and of @sc{POSIX}. So GNU software should be written to use -these. +Nowadays, using the @sc{posix} signal functions may be the easiest way +to make a program portable. If you use @code{signal}, then on GNU/Linux +systems running GNU libc version 1, you should include +@file{bsd/signal.h} instead of @file{signal.h}, so as to get BSD +behavior. It is up to you whether to support systems where +@code{signal} has only the USG behavior, or give up on them. In error checks that detect ``impossible'' conditions, just abort. There is usually no point in printing any message. These checks @@ -452,6 +526,20 @@ If you make temporary files, check the @code{TMPDIR} environment variable; if that variable is defined, use the specified directory instead of @file{/tmp}. +In addition, be aware that there is a possible security problem when +creating temporary files in directories world-writable directories. In +C, you can avoid this problem by creating temporary files in this +manner: + +@example +fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600); +@end example + +@noindent +or by using the @code{mkstemps} function from libiberty. + +In bash, use @code{set -C} to avoid this problem. + @node Libraries @section Library Behavior @@ -490,6 +578,20 @@ Error messages from compilers should look like this: @var{source-file-name}:@var{lineno}: @var{message} @end example +@noindent +If you want to mention the column number, use this format: + +@example +@var{source-file-name}:@var{lineno}:@var{column}: @var{message} +@end example + +@noindent +Line numbers should start from 1 at the beginning of the file, and +column numbers should start from 1 at the beginning of the line. (Both +of these conventions are chosen for compatibility.) Calculate column +numbers assuming that space and all ASCII printing characters have +equal width, and assuming tab stops every 8 columns. + Error messages from other noninteractive programs should look like this: @example @@ -506,6 +608,12 @@ when there is an appropriate source file, or like this: @noindent when there is no relevant source file. +If you want to mention the column number, use this format: + +@example +@var{program}:@var{source-file-name}:@var{lineno}:@var{column}: @var{message} +@end example + In an interactive program (one that is reading commands from a terminal), it is better not to include the program name in an error message. The place to indicate which program is running is in the @@ -533,8 +641,10 @@ to select among the alternate behaviors. Likewise, please don't make the behavior of the program depend on the type of output device it is used with. Device independence is an -important principle of the system's design; do not compromise it -merely to save someone from typing an option now and then. +important principle of the system's design; do not compromise it merely +to save someone from typing an option now and then. (Variation in error +message syntax when using a terminal is ok, because that is a side issue +that people do not depend on.) If you think one behavior is most useful when the output is to a terminal, and another is most useful when the output is a file or a @@ -550,11 +660,11 @@ output device type. For example, we provide a @code{dir} program much like @code{ls} except that its default output format is always multi-column format. -It is a good idea to follow the @sc{POSIX} guidelines for the +It is a good idea to follow the @sc{posix} guidelines for the command-line options of a program. The easiest way to do this is to use @code{getopt} to parse them. Note that the GNU version of @code{getopt} will normally permit options anywhere among the arguments unless the -special argument @samp{--} is used. This is not what @sc{POSIX} +special argument @samp{--} is used. This is not what @sc{posix} specifies; it is a GNU extension. Please define long-named options that are equivalent to the @@ -581,7 +691,7 @@ and @samp{--help}. @table @code @item --version -This option should direct the program to information about its name, +This option should direct the program to print information about its name, version, origin and legal status, all on standard output, and then exit successfully. Other options and arguments should be ignored once this is seen, and the program should not perform its normal function. @@ -738,6 +848,9 @@ and @code{unexpand}. @item avoid-wraps @samp{-n} in @code{wdiff}. +@item background +For server programs, run in the background. + @item backward-search @samp{-B} in @code{ctags}. @@ -862,6 +975,9 @@ Used in @code{tar} and @code{cpio}. @item dereference-args @samp{-D} in @code{du}. +@item device +Specify an I/O device (special file name). + @item diacritics @samp{-d} in @code{recode}. @@ -994,6 +1110,11 @@ Used in @code{makeinfo}. @item force-prefix @samp{-F} in @code{shar}. +@item foreground +For server programs, run in the foreground; +in other words, don't do anything special to run the server +in the background. + @item format Used in @code{ls}, @code{time}, and @code{ptx}. @@ -1039,6 +1160,9 @@ Used to ask for brief usage information. @item hide-control-chars @samp{-q} in @code{ls}. +@item html +In @code{makeinfo}, output HTML. + @item idle @samp{-u} in @code{who}. @@ -1099,6 +1223,10 @@ Used to ask for brief usage information. @item info @samp{-i}, @samp{-l}, and @samp{-m} in Finger. +@item init-file +In some programs, specify the name of the file to read as the user's +init file. + @item initial @samp{-i} in @code{expand}. @@ -1117,6 +1245,9 @@ Used to ask for brief usage information. @item intermix-type @samp{-p} in @code{shar}. +@item iso-8601 +Used in @code{date} + @item jobs @samp{-j} in Make. @@ -1352,6 +1483,10 @@ Used in GDB. @item only-time @samp{-F} in @code{gprof}. +@item options +@samp{-o} in @code{getopt}, @code{fdlist}, @code{fdmount}, +@code{fdmountd}, and @code{fdumount}. + @item output In various programs, specify the output file name. @@ -1436,6 +1571,9 @@ Used in @code{tar} and @code{cp}. @item prompt @samp{-p} in @code{ed}. +@item proxy +Specify an HTTP proxy. + @item query-user @samp{-X} in @code{shar}. @@ -1564,6 +1702,12 @@ Used in many programs to inhibit the usual output. @item size @samp{-s} in @code{ls}. +@item socket +Specify a file descriptor for a network server to use for its socket, +instead of opening and binding a new socket. This provides a way to +run, in a nonpriveledged process, a server that normally needs a +reserved port number. + @item sort Used in @code{ls}. @@ -1662,6 +1806,9 @@ Used in GDB and @code{objdump}. @item time Used in @code{ls} and @code{touch}. +@item timeout +Specify how long to wait before giving up on some operation. + @item to-stdout @samp{-O} in @code{tar}. @@ -1813,7 +1960,8 @@ concat (s1, s2) /* Name starts in column zero here */ @end example @noindent -or, if you want to use @sc{ansi} C, format the definition like this: +or, if you want to use Standard C syntax, format the definition like +this: @example static char * @@ -1823,7 +1971,7 @@ concat (char *s1, char *s2) @} @end example -In @sc{ansi} C, if the arguments don't fit nicely on one line, +In Standard C, if the arguments don't fit nicely on one line, split it like this: @example @@ -1833,7 +1981,17 @@ lots_of_args (int an_integer, long a_long, short a_short, @dots{} @end example -For the body of the function, we prefer code formatted like this: +The rest of this section gives our recommendations for other aspects of +C formatting style. We don't think of them as requirements, because it +causes no problems for users if two different programs have different +formatting styles. + +But whatever style you use, please use it consistently, since a mixture +of styles within one program tends to look ugly. If you are +contributing changes to an existing program, please follow the style of +that program. + +For the body of the function, our recommended style looks like this: @example if (x < foo (y, z)) @@ -1879,14 +2037,15 @@ mode = ((inmode[j] == VOIDmode Insert extra parentheses so that Emacs will indent the code properly. For example, the following indentation looks nice if you do it by hand, -but Emacs would mess it up: @example v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000 + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000; @end example -But adding a set of parentheses solves the problem: +@noindent +but Emacs would alter it. Adding a set of parentheses produces +something that looks equally nice, and which Emacs will preserve: @example v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000 @@ -1908,7 +2067,6 @@ pages at logical places (but not within a function). It does not matter just how long the pages are, since they do not have to fit on a printed page. The formfeeds should appear alone on lines by themselves. - @node Comments @section Commenting Your Work @@ -2007,6 +2165,13 @@ but, by contrast, write the comments this way for a @samp{#ifndef}: Please explicitly declare all arguments to functions. Don't omit them just because they are @code{int}s. +Some programmers like to use the GCC @samp{-Wall} option, and change the +code whenever it issues a warning. If you want to do this, then do. +Other programmers prefer not to use @samp{-Wall}, because it gives +warnings for valid and legitimate code which they do not want to change. +If you want to do this, then do. The compiler should be your servant, +not your master. + Declarations of external functions and functions to appear later in the source file should all go in one place near the beginning of the file (somewhere before the first function definition in the file), or else @@ -2128,7 +2293,7 @@ Don't make the program ugly to placate @code{lint}. Please don't insert any casts to @code{void}. Zero without a cast is perfectly fine as a null pointer constant, except when calling a varargs function. -@node Names +@node Names @section Naming Variables and Functions The names of global variables and functions in a program serve as @@ -2140,6 +2305,10 @@ comments. Local variable names can be shorter, because they are used only within one context, where (presumably) comments explain their purpose. +Try to limit your use of abbreviations in symbol names. It is ok to +make a few abbreviations, explain what they mean, and then use them +frequently, but don't use lots of obscure abbreviations. + Please use underscores to separate words in a name, so that the Emacs word commands can be useful within them. Stick to lower case; reserve upper case for macros and @code{enum} constants, and for name-prefixes @@ -2198,14 +2367,22 @@ Avoid using the format of semi-internal data bases (e.g., directories) when there is a higher-level alternative (@code{readdir}). As for systems that are not like Unix, such as MSDOS, Windows, the -Macintosh, VMS, and MVS, supporting them is usually so much work that it -is better if you don't. - -The planned GNU kernel is not finished yet, but you can tell which -facilities it will provide by looking at the GNU C Library Manual. The -GNU kernel is based on Mach, so the features of Mach will also be -available. However, if you use Mach features, you'll probably have -trouble debugging your program today. +Macintosh, VMS, and MVS, supporting them is often a lot of work. When +that is the case, it is better to spend your time adding features that +will be useful on GNU and GNU/Linux, rather than on supporting other +incompatible systems. + +It is a good idea to define the ``feature test macro'' +@code{_GNU_SOURCE} when compiling your C files. When you compile on GNU +or GNU/Linux, this will enable the declarations of GNU library extension +functions, and that will usually give you a compiler error message if +you define the same function names in some other way in your program. +(You don't have to actually @emph{use} these functions, if you prefer +to make the program more portable to other systems.) + +But whether or not you use these GNU extensions, you should avoid +using their names for any other meanings. Doing so would make it hard +to move your code into other GNU programs. @node CPU Portability @section Portability between @sc{cpu}s @@ -2231,9 +2408,9 @@ while ((c = getchar()) != EOF) When calling functions, you need not worry about the difference between pointers of various types, or between pointers and integers. On most machines, there's no difference anyway. As for the few machines where -there is a difference, all of them support @sc{ansi} C, so you can use -prototypes (conditionalized to be active only in @sc{ansi} C) to make -the code work on those systems. +there is a difference, all of them support 1989 Standard C, so you can +use prototypes (perhaps conditionalized to be active only in Standard C) +to make the code work on those systems. In certain cases, it is ok to pass integer and pointer arguments indiscriminately to the same function, and use no prototype on any @@ -2243,7 +2420,7 @@ that pass their arguments along to @code{printf} and friends: @example error (s, a1, a2, a3) char *s; - int a1, a2, a3; + char *a1, *a2, *a3; @{ fprintf (stderr, "error: "); fprintf (stderr, s, a1, a2, a3); @@ -2251,32 +2428,42 @@ error (s, a1, a2, a3) @end example @noindent -In practice, this works on all machines, and it is much simpler than any -``correct'' alternative. Be sure @emph{not} to use a prototype -for such functions. +In practice, this works on all machines, since a pointer is generally +the widest possible kind of argument; it is much simpler than any +``correct'' alternative. Be sure @emph{not} to use a prototype for such +functions. + +If you have decided to use 1989 Standard C, then you can instead define +@code{error} using @file{stdarg.h}, and pass the arguments along to +@code{vfprintf}. -However, avoid casting pointers to integers unless you really need to. -These assumptions really reduce portability, and in most programs they -are easy to avoid. In the cases where casting pointers to integers is -essential---such as, a Lisp interpreter which stores type information as -well as an address in one word---it is ok to do so, but you'll have to -make explicit provisions to handle different word sizes. +Avoid casting pointers to integers if you can. Such casts greatly +reduce portability, and in most programs they are easy to avoid. In the +cases where casting pointers to integers is essential---such as, a Lisp +interpreter which stores type information as well as an address in one +word---you'll have to make explicit provisions to handle different word +sizes. You will also need to make provision for systems in which the +normal range of addresses you can get from @code{malloc} starts far away +from zero. @node System Functions @section Calling System Functions -C implementations differ substantially. @sc{ansi} C reduces but does not -eliminate the incompatibilities; meanwhile, many users wish to compile -GNU software with pre-@sc{ansi} compilers. This chapter gives -recommendations for how to use the more or less standard C library -functions to avoid unnecessary loss of portability. +C implementations differ substantially. 1989 Standard C reduces but does +not eliminate the incompatibilities; meanwhile, many GNU packages still +support pre-standard compilers because this is not hard to do. This +chapter gives recommendations for how to use the more-or-less standard C +library functions to avoid unnecessary loss of portability. @itemize @bullet @item -Don't use the value of @code{sprintf}. It returns the number of +Don't use the return value of @code{sprintf}. It returns the number of characters written on some systems, but not on all systems. @item +Be aware that @code{vfprintf} is not always available. + +@item @code{main} should be declared to return type @code{int}. It should terminate either by calling @code{exit} or by returning the integer status code; make sure it cannot ever return an undefined value. @@ -2297,7 +2484,7 @@ actual conflicts. @item If you must declare a system function, don't specify the argument types. -Use an old-style declaration, not an @sc{ansi} prototype. The more you +Use an old-style declaration, not a Standard C prototype. The more you specify about the function, the more likely a conflict. @item @@ -2329,7 +2516,7 @@ figure out which file to include, or don't include either file. If you don't include either strings file, you can't get declarations for the string functions from the header file in the usual way. -That causes less of a problem than you might think. The newer @sc{ansi} +That causes less of a problem than you might think. The newer standard string functions should be avoided anyway because many systems still don't support them. The string functions you can use are these: @@ -2359,7 +2546,7 @@ names, but neither pair works on all systems. You should pick a single pair of names and use it throughout your program. (Nowadays, it is better to choose @code{strchr} and -@code{strrchr} for new programs, since those are the standard @sc{ansi} +@code{strrchr} for new programs, since those are the standard names.) Declare both of those names as functions returning @code{char *}. On systems which don't support those names, define them as macros in terms of the other pair. For example, here is what to put at the @@ -2503,6 +2690,7 @@ all these kinds of files. @menu * GNU Manuals:: Writing proper manuals. * Manual Structure Details:: Specific structure conventions. +* License for Manuals:: Writing the distribution terms for a manual. * NEWS File:: NEWS files supplement manuals. * Change Logs:: Recording Changes * Man Pages:: Man pages are secondary. @@ -2514,9 +2702,12 @@ all these kinds of files. @section GNU Manuals The preferred way to document part of the GNU system is to write a -manual in the Texinfo formatting language. See the Texinfo manual, -either the hardcopy, or the on-line version available through -@code{info} or the Emacs Info subsystem (@kbd{C-h i}). +manual in the Texinfo formatting language. This makes it possible to +produce a good quality formatted book, using @TeX{}, and to generate an +Info file. It is also possible to generate HTML output from Texinfo +source. See the Texinfo manual, either the hardcopy, or the on-line +version available through @code{info} or the Emacs Info subsystem +(@kbd{C-h i}). Programmers often find it most natural to structure the documentation following the structure of the implementation, which they know. But @@ -2557,6 +2748,8 @@ It should be set up for convenient access to each topic through Info, and for reading straight through (appendixes aside). A GNU manual should give a good introduction to a beginner reading through from the start, and should also provide all the details that hackers want. +The Bison manual is a good example of this---please take a look at it +to see what we mean. That is not as hard as it first sounds. Arrange each chapter as a logical breakdown of its topic, but order the sections, and write their @@ -2576,9 +2769,12 @@ explanation of the underlying concepts. (There are, of course exceptions.) Also Unix man pages use a particular format which is different from what we use in GNU manuals. +Please include an email address in the manual for where to report +bugs @emph{in the manual}. + Please do not use the term ``pathname'' that is used in Unix documentation; use ``file name'' (two words) instead. We use the term -``path'' only for search paths, which are lists of file names. +``path'' only for search paths, which are lists of directory names. Please do not use the term ``illegal'' to refer to erroneous input to a computer program. Please use ``invalid'' for this, and reserve the term @@ -2611,6 +2807,18 @@ quickly reading just this part of its manual. If one manual describes several programs, it should have such a node for each program described. +@node License for Manuals +@section License for Manuals + +If the manual contains a copy of the GNU GPL or GNU LGPL, or if it +contains chapters that make political or personal statements, please +copy the distribution terms of the GNU Emacs Manual, and adapt it by +modifying appropriately the list of special chapters that may not be +modified or deleted. + +If the manual does not contain any such chapters, then imitate the +simpler distribution terms of the Texinfo manual. + @node NEWS File @section The NEWS File @@ -2659,7 +2867,8 @@ you. Another alternative is to record change log information with a version control system such as RCS or CVS. This can be converted automatically -to a @file{ChangeLog} file. +to a @file{ChangeLog} file using @code{rcs2log}; in Emacs, the command +@kbd{C-x v a} (@code{vc-update-change-log}) does the job. There's no need to describe the full purpose of the changes or how they work together. If you think that a change calls for explanation, you're @@ -3030,6 +3239,21 @@ files} and @dfn{non-source files}. Source files are written by humans and never changed automatically; non-source files are produced from source files by programs under the control of the Makefile. +The distribution should contain a file named @file{README} which gives +the name of the package, and a general description of what it does. It +is also good to explain the purpose of each of the first-level +subdirectories in the package, if there are any. The @file{README} file +should either state the version number of the package, or refer to where +in the package it can be found. + +The @file{README} file should refer to the file @file{INSTALL}, which +should contain an explanation of the installation procedure. + +The @file{README} file should also refer to the file which contains the +copying conditions. The GNU GPL, if used, should be in a file called +@file{COPYING}. If the GNU LGPL is used, it should be in a file called +@file{COPYING.LIB}. + Naturally, all the source files must be in the distribution. It is okay to include non-source files in the distribution, provided they are up-to-date and machine-independent, so that building the distribution @@ -3054,7 +3278,7 @@ Make sure that all the files in the distribution are world-readable. Make sure that no file name in the distribution is more than 14 characters long. Likewise, no file created by building the program should have a name longer than 14 characters. The reason for this is -that some systems adhere to a foolish interpretation of the POSIX +that some systems adhere to a foolish interpretation of the @sc{posix} standard, and refuse to open a longer name, rather than truncating as they did in the past. @@ -3082,6 +3306,31 @@ Leaving them out would make the distribution file a little smaller at the expense of possible inconvenience to a user who doesn't know what other files to get. +@node References +@chapter References to Non-Free Software and Documentation + +A GNU program should not recommend use of any non-free program. We +can't stop some people from writing proprietary programs, or stop other +people from using them. But we can and should avoid helping to +advertise them to new customers. + +Sometimes it is important to mention how to build your package on top of +some non-free operating system or other non-free base package. In such +cases, please mention the name of the non-free package or system in the +briefest possible way. Don't include any references for where to find +more information about the proprietary program. The goal should be that +people already using the proprietary program will get the advice they +need about how to use your free program, while people who don't already +use the proprietary program will not see anything to encourage them to +take an interest in it. + +Likewise, a GNU package should not refer the user to any non-free +documentation for free software. The need for free documentation to go +with free software is now a major focus of the GNU project; to show that +we are serious about the need for free documentation, we must not +undermine our position by recommending use of documentation that isn't +free. + @contents @bye diff --git a/gnu/egcs/gcc/config/alpha/linux-elf.h b/gnu/egcs/gcc/config/alpha/linux-elf.h index fc07127d757..50bf2307d5b 100644 --- a/gnu/egcs/gcc/config/alpha/linux-elf.h +++ b/gnu/egcs/gcc/config/alpha/linux-elf.h @@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */ #ifndef USE_GNULIBC_1 #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 #endif #ifndef USE_GNULIBC_1 diff --git a/gnu/egcs/gcc/config/arm/arm.md b/gnu/egcs/gcc/config/arm/arm.md index 16e66181ead..7ccbb5cb2d1 100644 --- a/gnu/egcs/gcc/config/arm/arm.md +++ b/gnu/egcs/gcc/config/arm/arm.md @@ -1837,7 +1837,8 @@ (define_insn "negdi2" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] + (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0"))) + (clobber (reg:CC 24))] "" "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0" [(set_attr "conds" "clob") diff --git a/gnu/egcs/gcc/config/arm/linux-elf.h b/gnu/egcs/gcc/config/arm/linux-elf.h index e5b4de1c13b..956ecba5348 100644 --- a/gnu/egcs/gcc/config/arm/linux-elf.h +++ b/gnu/egcs/gcc/config/arm/linux-elf.h @@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA. */ /* This was defined in linux.h. Define it here also. */ #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 /* Handle #pragma weak and #pragma pack. */ #define HANDLE_SYSV_PRAGMA diff --git a/gnu/egcs/gcc/config/elfos.h b/gnu/egcs/gcc/config/elfos.h index 6c107311fd7..d4826159198 100644 --- a/gnu/egcs/gcc/config/elfos.h +++ b/gnu/egcs/gcc/config/elfos.h @@ -1,6 +1,6 @@ /* elfos.h -- operating system specific defines to be used when targeting GCC for some generic ELF system - Copyright (C) 1991, 1994, 1995, 1999 Free Software Foundation, Inc. + Copyright (C) 1991, 1994, 1995, 1999, 2000 Free Software Foundation, Inc. Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com). This file is part of GNU CC. @@ -426,7 +426,8 @@ do { \ else \ data_section (); \ } \ - else if (TREE_CODE (DECL) == VAR_DECL) \ + else if (TREE_CODE (DECL) == VAR_DECL \ + || TREE_CODE (DECL) == CONSTRUCTOR) \ { \ if ((flag_pic && RELOC) \ || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ diff --git a/gnu/egcs/gcc/config/h8300/h8300.md b/gnu/egcs/gcc/config/h8300/h8300.md index 7e49af5ef75..da6519300e9 100644 --- a/gnu/egcs/gcc/config/h8300/h8300.md +++ b/gnu/egcs/gcc/config/h8300/h8300.md @@ -2292,7 +2292,7 @@ (define_peephole [(set (match_operand:HI 1 "register_operand" "") - (plus:HI (match_dup 1) (const_int -1))) + (plus:HI (match_dup 1) (const_int -2))) (set (mem:HI (match_dup 1)) (match_operand:HI 0 "register_operand" ""))] "REGNO(operands[1]) != REGNO(operands[0])" diff --git a/gnu/egcs/gcc/config/i386/freebsd-elf.h b/gnu/egcs/gcc/config/i386/freebsd-elf.h index e97d4ca07bb..8c907bf9d1e 100644 --- a/gnu/egcs/gcc/config/i386/freebsd-elf.h +++ b/gnu/egcs/gcc/config/i386/freebsd-elf.h @@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */ /* Use more efficient ``thunks'' to implement C++ vtables. */ #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 /* Override the default comment-starter of "/". */ #undef ASM_COMMENT_START diff --git a/gnu/egcs/gcc/config/i386/sol2gas.h b/gnu/egcs/gcc/config/i386/sol2gas.h index 7f2c9629d7c..558183aecd5 100644 --- a/gnu/egcs/gcc/config/i386/sol2gas.h +++ b/gnu/egcs/gcc/config/i386/sol2gas.h @@ -4,8 +4,6 @@ Copyright (C) 1999 Free Software Foundation, Inc. */ -#ifndef GAS_DOES_NOT_SUPPORT_MINUS_S -#define GAS_DOES_NOT_SUPPORT_MINUS_S 1 +#ifndef GAS_REJECTS_MINUS_S +#define GAS_REJECTS_MINUS_S 1 #endif - -#include "i386/sol2.h" diff --git a/gnu/egcs/gcc/config/linux.h b/gnu/egcs/gcc/config/linux.h index b619d01cdf5..46ce8988223 100644 --- a/gnu/egcs/gcc/config/linux.h +++ b/gnu/egcs/gcc/config/linux.h @@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */ #ifndef USE_GNULIBC_1 #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 #endif #undef LIB_SPEC diff --git a/gnu/egcs/gcc/config/m68k/mot3300-crt0.S b/gnu/egcs/gcc/config/m68k/mot3300-crt0.S index 489261421b1..8a46993c615 100644 --- a/gnu/egcs/gcc/config/m68k/mot3300-crt0.S +++ b/gnu/egcs/gcc/config/m68k/mot3300-crt0.S @@ -93,6 +93,6 @@ __stop_monitor: COMM splimit%,4 COMM environ,4 - IDENT ("$Id: mot3300-crt0.S,v 1.1.1.2 1999/08/23 20:30:20 espie Exp $") + IDENT ("$Id: mot3300-crt0.S,v 1.1.1.3 2000/06/05 22:17:14 espie Exp $") IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)") IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)") diff --git a/gnu/egcs/gcc/config/m68k/mot3300Mcrt0.S b/gnu/egcs/gcc/config/m68k/mot3300Mcrt0.S index 0d24fbf4b66..fb81a14318c 100644 --- a/gnu/egcs/gcc/config/m68k/mot3300Mcrt0.S +++ b/gnu/egcs/gcc/config/m68k/mot3300Mcrt0.S @@ -137,6 +137,6 @@ LOCAL_LABEL(endofstart): COMM environ,4 COMM _countbase,4 - IDENT ("$Id: mot3300Mcrt0.S,v 1.1.1.2 1999/08/23 20:30:20 espie Exp $") + IDENT ("$Id: mot3300Mcrt0.S,v 1.1.1.3 2000/06/05 22:17:14 espie Exp $") IDENT ("Contributed by Manfred Hollstein (manfred@lts.sel.alcatel.de)") IDENT ("Corrections by Philippe De Muyter (phdm@macqel.be)") diff --git a/gnu/egcs/gcc/config/m88k/dgux.h b/gnu/egcs/gcc/config/m88k/dgux.h index de5755d4570..214058ae43a 100644 --- a/gnu/egcs/gcc/config/m88k/dgux.h +++ b/gnu/egcs/gcc/config/m88k/dgux.h @@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA. */ (TARGET_SVR4 ? DWARF_DEBUG : SDB_DEBUG) #ifndef VERSION_INFO2 -#define VERSION_INFO2 "$Revision: 1.1.1.2 $" +#define VERSION_INFO2 "$Revision: 1.1.1.3 $" #endif #ifndef NO_BUGS #define AS_BUG_IMMEDIATE_LABEL diff --git a/gnu/egcs/gcc/config/rs6000/eabi-ctors.c b/gnu/egcs/gcc/config/rs6000/eabi-ctors.c index ebc23ded35c..2ff3c1abc61 100644 --- a/gnu/egcs/gcc/config/rs6000/eabi-ctors.c +++ b/gnu/egcs/gcc/config/rs6000/eabi-ctors.c @@ -58,14 +58,14 @@ void (*__atexit)(func_ptr); void __do_global_ctors (void) { - func_ptr *ptr = &__CTOR_LIST__[0]; - func_ptr *end = &__CTOR_END__[0]; + func_ptr *ptr = &__CTOR_END__[0] - 1; + func_ptr *start = &__CTOR_LIST__[0]; if (__atexit) __atexit (__do_global_dtors); /* Call the constructors collected in the .ctors section. */ - for ( ; ptr != end; ptr++) + for ( ; ptr >= start; ptr--) if (*ptr) (*ptr)(); @@ -77,15 +77,15 @@ __do_global_ctors (void) void __do_global_dtors (void) { - func_ptr *ptr = &__DTOR_END__[0] - 1; - func_ptr *start = &__DTOR_LIST__[0]; + func_ptr *ptr = &__DTOR_LIST__[0]; + func_ptr *end = &__DTOR_END__[0]; /* Call the termination function in the .fini section. */ (*fini_ptr) (); /* Call the destructors collected in the .dtors section. Run the destructors in reverse order. */ - for ( ; ptr >= start; ptr--) + for ( ; ptr < end; ptr++) if (*ptr) (*ptr)(); } diff --git a/gnu/egcs/gcc/config/rs6000/linux.h b/gnu/egcs/gcc/config/rs6000/linux.h index c2a04fa85b1..8210076245a 100644 --- a/gnu/egcs/gcc/config/rs6000/linux.h +++ b/gnu/egcs/gcc/config/rs6000/linux.h @@ -69,7 +69,7 @@ Boston, MA 02111-1307, USA. */ #undef DEFAULT_VTABLE_THUNKS #ifndef USE_GNULIBC_1 -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 #endif #undef JUMP_TABLES_IN_TEXT_SECTION diff --git a/gnu/egcs/gcc/config/rs6000/rs6000.md b/gnu/egcs/gcc/config/rs6000/rs6000.md index 9b3c4306f77..0211728fa19 100644 --- a/gnu/egcs/gcc/config/rs6000/rs6000.md +++ b/gnu/egcs/gcc/config/rs6000/rs6000.md @@ -3042,16 +3042,14 @@ "TARGET_POWER" "@ sle %0,%1,%2 - {sli|slwi} %0,%1,%h2" - [(set_attr "length" "8")]) + {sli|slwi} %0,%1,%h2") (define_insn "ashlsi3_no_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "! TARGET_POWER" - "{sl|slw}%I2 %0,%1,%h2" - [(set_attr "length" "8")]) + "{sl|slw}%I2 %0,%1,%h2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") @@ -5494,12 +5492,12 @@ (define_expand "iordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5510,12 +5508,26 @@ emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_iordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*iordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ or %0,%1,%2 @@ -5549,25 +5561,36 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_expand "xordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5578,12 +5601,26 @@ emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_xordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*xordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ xor %0,%1,%2 @@ -5617,14 +5654,25 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_insn "*eqvdi3_internal1" @@ -6620,13 +6668,14 @@ (set (match_dup 3) (match_dup 1))] " { + HOST_WIDE_INT value = INTVAL (operands[1]); operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0); operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0); #if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx; + operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else - operands[4] = GEN_INT ((HOST_WIDE_INT) INTVAL (operands[1]) >> 32); - operands[1] = GEN_INT (INTVAL (operands[1]) & 0xffffffff); + operands[4] = GEN_INT (value >> 32); + operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); #endif }") @@ -6763,7 +6812,8 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (match_operand:DI 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" + "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 + && num_insns_constant (operands[1], DImode) > 1" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) @@ -6774,29 +6824,40 @@ (match_dup 3)))] " { - HOST_WIDE_INT low; - HOST_WIDE_INT high; - if (GET_CODE (operands[1]) == CONST_DOUBLE) { - low = CONST_DOUBLE_LOW (operands[1]); - high = CONST_DOUBLE_HIGH (operands[1]); + operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]), + 0, DImode); } else -#if HOST_BITS_PER_WIDE_INT == 32 - { - low = INTVAL (operands[1]); - high = (low < 0) ? ~0 : 0; - } -#else { - low = INTVAL (operands[1]) & 0xffffffff; - high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32; + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx; + operands[3] = immed_double_const (value, 0, DImode); } -#endif +}") - operands[2] = GEN_INT (high); - operands[3] = GEN_INT (low); +(define_split + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (match_operand:DI 1 "const_int_operand" ""))] + "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64 + && num_insns_constant (operands[1], DImode) > 1" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 0) + (ashift:DI (match_dup 0) + (const_int 32))) + (set (match_dup 0) + (ior:DI (match_dup 0) + (match_dup 3)))] + " +{ +#if HOST_BITS_PER_WIDE_INT != 32 + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = GEN_INT (value >> 32); + operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); +#endif }") (define_insn "" @@ -7804,7 +7865,8 @@ rs6000_output_load_toc_table (asm_out_file, 30); return \"\"; }" - [(set_attr "type" "load")]) + [(set_attr "type" "load") + (set_attr "length" "24")]) ;; A function pointer under AIX is a pointer to a data area whose first word ;; contains the actual address of the function, whose second word contains a @@ -8784,7 +8846,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:SI 2 "reg_or_u_short_operand" "rK")))] "" "{cmpl%I2|cmplw%I2} %0,%1,%W2" [(set_attr "type" "compare")]) @@ -8792,7 +8854,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:DI 2 "reg_or_u_short_operand" "rK")))] "" "cmpld%I2 %0,%1,%W2" [(set_attr "type" "compare")]) @@ -9161,7 +9223,7 @@ (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (const_int 31))) (clobber (match_scratch:SI 2 "=&r"))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" [(set_attr "length" "8")]) diff --git a/gnu/egcs/gcc/config/sparc/linux.h b/gnu/egcs/gcc/config/sparc/linux.h index d967b01ebe3..40694908b68 100644 --- a/gnu/egcs/gcc/config/sparc/linux.h +++ b/gnu/egcs/gcc/config/sparc/linux.h @@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */ #ifndef USE_GNULIBC_1 #undef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 1 +#define DEFAULT_VTABLE_THUNKS 2 #endif /* Use stabs instead of DWARF debug format. */ diff --git a/gnu/egcs/gcc/config/sparc/sparc.md b/gnu/egcs/gcc/config/sparc/sparc.md index cb008b169b1..aafb7a63ea4 100644 --- a/gnu/egcs/gcc/config/sparc/sparc.md +++ b/gnu/egcs/gcc/config/sparc/sparc.md @@ -7355,7 +7355,7 @@ gen_rtvec (3, gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)), - GEN_INT (INTVAL (operands[3]) & 0xfff), + operands[3], gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); else @@ -7387,7 +7387,7 @@ emit_call_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx), - GEN_INT (INTVAL (operands[3]) & 0xfff), + operands[3], gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15))))); else diff --git a/gnu/egcs/gcc/config/v850/v850.c b/gnu/egcs/gcc/config/v850/v850.c index 15867ac4892..66b52d9580a 100644 --- a/gnu/egcs/gcc/config/v850/v850.c +++ b/gnu/egcs/gcc/config/v850/v850.c @@ -1864,10 +1864,8 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n", else init_stack_free = actual_fsize; - /* Deallocate the rest of the stack if it is > 32K or if extra stack - was allocated for an interrupt handler that makes a call. */ - if (actual_fsize > init_stack_free - || (interrupt_handler && actual_fsize)) + /* Deallocate the rest of the stack if it is > 32K. */ + if (actual_fsize > init_stack_free) { int diff; diff --git a/gnu/egcs/gcc/cp/ChangeLog b/gnu/egcs/gcc/cp/ChangeLog index efa30edcad2..3f005333b88 100644 --- a/gnu/egcs/gcc/cp/ChangeLog +++ b/gnu/egcs/gcc/cp/ChangeLog @@ -1,3 +1,126 @@ +2000-03-08 Nathan Sidwell <nathan@codesourcery.com> + + * exception.cc (__cp_pop_exception): Cleanup the original object. + +1999-11-13 Jason Merrill <jason@yorick.cygnus.com> + + * rtti.c (get_tinfo_fn_unused): Split out from get_tinfo_fn. + * class.c (set_rtti_entry): Use it. + +Wed Apr 12 00:45:49 2000 Jeffrey A Law (law@cygnus.com) + + 2000-02-03 <loewis@informatik.hu-berlin.de> + * call.c (add_function_candidate): Do not add vlist ctor into + candidates in compatibility mode. + (build_user_type_conversion_1): Add LOOKUP_HAS_VLIST when adding + vlist. + (convert_like): Likewise. + (build_over_call): Skip vlist only if it is mentioned in flags. + (build_new_method_call): Do not add vlist in compatibility mode, + except for dtors. + * cp-tree.h (flag_vtable_thunks): Has now four possible values. + (DECL_VLIST_CTOR_WRAPPER_P, DECL_VLIST_CTOR_WRAPPED): New macros. + (in_charge_identifier): Declare external. + * decl.c (xref_basetypes): Check for vtable_thunks >=2. + (finish_dtor): Use bit 2 of in_chrg. + (finish_function): Do not finish vlist ctor wrappers. + * decl2.c (flag_vtable_thunks_compat): New variable. + (lang_decode_option): Set it accordingly. + (maybe_retrofit_in_chrg): Call make_vlist_ctor_wrapper. + * init.c (build_base_dtor_call): Pass 4 in in_chrg. + (no_vlist_base_init): New function. + (expand_default_init): Do not pass vlist in compatibility mode. + Try to call old base ctor if new one was not generated. + (build_new_1): Do not pass vlist in compatibility mode. + * method.c (get_id_2): Do not put _Vlist into dtor name in + compatibility mode. + (make_vlist_ctor_wrapper, emit_vlist_ctor_wrapper): New functions. + (synthesize_method): Call emit_vlist_ctor_wrapper. + * pt.c (instantiate_class_template): Check for vtable_thunks >=2. + + Sat Nov 13 15:48:59 1999 H.J. Lu <hjl@gnu.org> + * init.c (finish_dtor): Call mark_all_temps_used () before + declaring vlist. + + Tue Nov 9 15:01:57 1999 H.J. Lu <hjl@gnu.org> + * init.c (construct_virtual_bases): Update. + (expand_cleanup_for_base): Update. + + Tue Nov 9 08:25:04 1999 H.J. Lu <hjl@gnu.org> + * init.c (construct_virtual_bases): Update. + (expand_cleanup_for_base): Take vlist parameter. + (emit_base_init): Pass vlist to expand_cleanup_for_base. + (construct_virtual_bases): Likewise. + + 1999-05-02 Martin von Löwis <loewis@informatik.hu-berlin.de> + * class.c (prepare_ctor_vtable, finish_one_ctor_vtable, + prepend_ctor_vfields_for_vbase, finish_ctor_vtables_for_vbases, + finish_ctor_vtables_1, prepend_vbase_vfields, + finish_ctor_vtables): New functions. + (finish_struct_1): Call finish_ctor_vtables. + * cp-tree.h (TYPE_USES_PVBASES): New macro. + (constructor_for_vbase_attr): Widen to two bits. + (CONSTRUCTOR_FOR_VBASE, CONSTRUCTOR_FOR_PVBASE, + DESTRUCTOR_FOR_PVBASE): New macros. + (DECL_CONSTRUCTOR_FOR_VBASE_P): Adopt to new enumeration. + (DECL_CONSTRUCTOR_FOR_VBASE): New macro. + (DECL_CONSTRUCTOR_FOR_PVBASE_P, DECL_DESTRUCTOR_FOR_PVBASE_P): New + macros. + (vlist_identifier, vlist_type_node, vlist_zero_node): Declare. + (VCTABLE_NAME, VLIST_NAME_FORMAT, VLIST_NAME, VLIST1_NAME, + VLIST_TYPE_NAME): New macros. + (LOOKUP_HAS_VLIST): New macro. + (build_base_dtor_call, init_vlist): Declare. + (build_destructor_name): Add int argument. + * decl.c (vlist_identifier, vlist_type_node, vlist_zero_node): + Define. + (init_decl_processing): Initialize them. + (grokdeclarator): Handle vlist argument. + (copy_args_p): Likewise. + (grok_ctor_properties): Don't try to skip initial int for + templates. Skip vlist if available. + (xref_basetypes): Set TYPE_USES_PVBASES. + (finish_dtor, finish_ctor): New functions, moved out of ... + (finish_function): ... here. + * decl2.c (lang_decode_option): Set flag_vtable_thunks explicitly. + (maybe_retrofit_in_chrg): Retrofit __vlist parameter. + (grokclassfn): Pass pvbase flag into mangled name. + * init.c (build_base_dtor_call): New function. + (build_partial_cleanup_for): Call it. + (pvbasecount, init_vlist, ): New functions. + (emit_base_init): Process vlist argument. + (expand_aggr_vbase_init_1): Likewise. + (expand_aggr_vbase_init): Likewise. + (expand_default_init): Likewise. + (build_new_1): Pass null vlist argument. + (build_delete): Likewise. Call build_base_dtor_call. + * method.c (process_overload_item): Mangle _Vlist specially. + (build_base_path, get_vlist_vtable_id): New functions. + (build_destructor_name): Potentially mangle _Vlist into it. + (do_build_copy_constructor): Skip vlist argument. + (synthesize_method): Likewise. + * pt.c (has_pvbases_p): New function. + (instantiate_class_template): Call it. + (tsubst_decl): Retrofit before mangling. Pass pvbase_p to + destructor mangling. + * search.c (expand_direct_vtbls_init_thunks): New function. + (expand_indirect_vtbls_init_thunks): New function. + (expand_indirect_vtbls_init): Call it. + * call.c (add_function_candidate): Process vlist argument. + (build_user_type_conversion_1): Add vlist argument. + (convert_like): Likewise. + (build_over_call): Likewise. + (build_new_method_call): Likewise. + +2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de> + + * typeck2.c (my_friendly_abort): Use GCCBUGURL. + +1999-11-01 Jason Merrill <jason@yorick.cygnus.com> + + * decl2.c (maybe_make_one_only): Always make things comdat on + ELF targets, too. + Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. diff --git a/gnu/egcs/gcc/cp/class.c b/gnu/egcs/gcc/cp/class.c index 400c67de41a..74808c56f35 100644 --- a/gnu/egcs/gcc/cp/class.c +++ b/gnu/egcs/gcc/cp/class.c @@ -102,8 +102,15 @@ static tree get_basefndecls PROTO((tree, tree)); static void set_rtti_entry PROTO((tree, tree, tree)); static tree build_vtable PROTO((tree, tree)); static void prepare_fresh_vtable PROTO((tree, tree)); +static tree prepare_ctor_vtable PROTO((tree, tree, tree)); static void fixup_vtable_deltas1 PROTO((tree, tree)); static void fixup_vtable_deltas PROTO((tree, int, tree)); +static tree finish_one_ctor_vtable PROTO((tree, tree, tree, tree)); +static tree prepend_ctor_vfields_for_vbase PROTO((tree, tree, tree, tree, int, tree)); +static tree finish_ctor_vtables_for_vbases PROTO((tree, tree, tree)); +static tree finish_ctor_vtables_1 PROTO((tree, tree)); +static tree prepend_vbase_vfields PROTO((tree, int, tree)); +static void finish_ctor_vtables PROTO((tree)); static void finish_vtbls PROTO((tree, int, tree)); static void modify_vtable_entry PROTO((tree, tree, tree)); static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT)); @@ -673,7 +680,7 @@ set_rtti_entry (virtuals, offset, type) return; if (flag_rtti) - vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type)); + vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn_unused (type)); else vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, size_zero_node); TREE_CONSTANT (vfn) = 1; @@ -922,6 +929,43 @@ prepare_fresh_vtable (binfo, for_type) SET_BINFO_NEW_VTABLE_MARKED (binfo); } +/* Return a new vtable for use in initialization of the BASE subobject + of COMPLETE_TYPE. The vtable there goes into the vfield of the + VBASEBASE virtual subobject. */ + +static tree +prepare_ctor_vtable (complete_type, base, vbasebase) + tree complete_type, base, vbasebase; +{ + tree orig_decl = BINFO_VTABLE (vbasebase); + tree name = get_vlist_vtable_id (base, vbasebase); + tree new_decl; + + new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); + /* Remember which class this vtable is really for. */ + DECL_CONTEXT (new_decl) = complete_type; + + DECL_ARTIFICIAL (new_decl) = 1; + TREE_STATIC (new_decl) = 1; + new_decl = pushdecl_top_level (new_decl); + DECL_VIRTUAL_P (new_decl) = 1; +#ifndef WRITABLE_VTABLES + /* Make them READONLY by default. (mrs) */ + TREE_READONLY (new_decl) = 1; +#endif + DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); + +#ifdef GATHER_STATISTICS + n_vtables += 1; + n_vtable_elems += list_length (BINFO_VIRTUALS (binfo)); +#endif + + /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ + import_export_vtable (new_decl, complete_type, 0); + + return new_decl; +} + #if 0 /* Access the virtual function table entry that logically contains BASE_FNDECL. VIRTUALS is the virtual function table's @@ -1798,6 +1842,7 @@ finish_struct_bits (t, max_has_virtual) TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t); TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t); TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t); + TYPE_USES_PVBASES (variants) = TYPE_USES_PVBASES (t); /* Copy whatever these are holding today. */ TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t); TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t); @@ -2933,6 +2978,309 @@ warn_hidden (t) } } +/* Generate one vtable for use in constructors or destructors of BASE + subobjects of COMPLETE_TYPE objects. The vtable belongs to the + vfield of the VBASEVASE subobject of the VBASE virtual base of + COMPLETE_TYPE (and BASE). */ + +static tree +finish_one_ctor_vtable (complete_type, base, vbase, vbasebase) + tree complete_type, base, vbase, vbasebase; +{ + tree virtuals; + tree newtable; + tree newvirtuals; + tree offset; + tree newvbase = binfo_member (BINFO_TYPE (vbase), + CLASSTYPE_VBASECLASSES (complete_type)); + + newtable = prepare_ctor_vtable (complete_type, base, vbasebase); + newvirtuals = copy_list (BINFO_VIRTUALS (vbasebase)); + + virtuals = newvirtuals; + /* Change the offset entry. First, delta between base an vbase. */ + offset = ssize_binop (MINUS_EXPR, BINFO_OFFSET (newvbase), + BINFO_OFFSET (base)); + /* Add delta between vbase and vbasebase. */ + offset = ssize_binop (PLUS_EXPR, offset, BINFO_OFFSET (vbasebase)); + offset = ssize_binop (MINUS_EXPR, offset, BINFO_OFFSET (vbase)); + /* Finally, negate. */ + offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); + offset = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); + TREE_CONSTANT (offset) = 1; + TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, offset); + virtuals = TREE_CHAIN (virtuals); + + /* Skip the typeinfo function. */ + virtuals = TREE_CHAIN (virtuals); + + /* Iterate over all methods of this virtual base. */ + for (; virtuals; virtuals = TREE_CHAIN (virtuals)) + { + tree fndecl = TREE_VALUE (virtuals); + tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl); + fndecl = TREE_OPERAND (pfn, 0); + if (fndecl) + { + tree delta, newdelta, binfo_context; + tree context = DECL_CLASS_CONTEXT (fndecl); + + /* If this method is implemented in a base of the vbase, the + thunk we have is correct. */ + if (DERIVED_FROM_P (context, vbase)) + continue; + + binfo_context = binfo_value (context, base); + if (TREE_VIA_VIRTUAL (binfo_context)) + binfo_context = binfo_member + (context, CLASSTYPE_VBASECLASSES (complete_type)); + /* This is the delta from a complete C to a B subobject, or + more generally to the base subobject that implements the + virtual function for B. BASE already has the offset to + the complete type. */ + delta = BINFO_OFFSET (binfo_context); + /* This is the delta from the A to the complete C. */ + newdelta = BINFO_OFFSET (newvbase); + /* This is the delta from the A to the B subobject. */ + newdelta = size_binop (MINUS_EXPR, newdelta, delta); + newdelta = ssize_binop (MINUS_EXPR, integer_zero_node, + newdelta); + + modify_vtable_entry (virtuals, + build_vtable_entry (newdelta, pfn), + fndecl); + } + } + DECL_INITIAL (newtable) = build_nt (CONSTRUCTOR, NULL_TREE, + newvirtuals); + DECL_CONTEXT (newtable) = NULL_TREE; + cp_finish_decl (newtable, DECL_INITIAL (newtable), NULL_TREE, 0, 0); + DECL_CONTEXT (newtable) = complete_type; + return newtable; +} + +/* Add all vtables into LIST for the VBASEBASE subobject and its bases + of VBASE virtual BASE of COMPLETE_TYPE for use in BASE + constructors. DO_SELF indicates whether this is the VBASEBASE that + has 'primary' vfield. Return the new LIST. */ + +static tree +prepend_ctor_vfields_for_vbase (complete_type, base, vbase, vbasebase, + do_self, list) + tree complete_type, base, vbase, vbasebase; + int do_self; + tree list; +{ + int i; + tree vtbl; + tree bases = BINFO_BASETYPES (vbasebase); + int vfp = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (vbasebase)); + + if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (vbasebase))) + { + vtbl = finish_one_ctor_vtable (complete_type, base, vbase, vbasebase); + vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl); + TREE_READONLY (vtbl) = 1; + TREE_CONSTANT (vtbl) = 1; + list = tree_cons (NULL_TREE, vtbl, list); + } + + if (!bases) + return list; + + for (i = 0; i < TREE_VEC_LENGTH (bases); i++) + { + tree vbasebase = TREE_VEC_ELT (bases, i); + if (TREE_VIA_VIRTUAL (vbasebase)) + continue; + list = prepend_ctor_vfields_for_vbase + (complete_type, base, vbase, vbasebase, (i != vfp), list); + } + + return list; +} + +/* Iterate over all virtual bases of the BASE subobject of + COMPLETE_TYPE. This list is given in VBASES. Return the list of + vtables generated in the process. */ + +static tree +finish_ctor_vtables_for_vbases (vbases, base, complete_type) + tree vbases, base, complete_type; +{ + tree result = NULL_TREE; + + for (; vbases; vbases = TREE_CHAIN (vbases)) + result = prepend_ctor_vfields_for_vbase + (complete_type, base, vbases, vbases, 1, result); + return result; +} + +/* Generate special vtables for virtual bases for use inside base + class ctors and dtors. Inside this function, we assume the + following scenario: + class A{virtual void foo();}; + class B:virtual A{int member1;} + class C:B{int member2;} + + BINFO is a base subject (e.g. B) of COMPLETE_TYPE. Returns the list + of virtual tables. */ + +static tree +finish_ctor_vtables_1 (binfo, complete_type) + tree binfo; + tree complete_type; +{ + int i; + tree binfos; + tree result = NULL_TREE; + + binfos = BINFO_BASETYPES (binfo); + if (!binfos) + return result; + + /* Iterate over all bases (i.e. B). */ + for (i = 0; i < TREE_VEC_LENGTH (binfos); i++) + { + tree base = TREE_VEC_ELT (binfos, i); + tree vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (base)); + if (!vbases) + /* This base class does not have virtual bases. */ + continue; + if (TREE_VIA_VIRTUAL (base)) + /* A virtual base class is initialized on in the most-derived + constructor. */ + continue; + if (!TYPE_USES_PVBASES (BINFO_TYPE (base))) + /* Class has no polymorphic vbases. */ + continue; + /* Prepend vtable list for base class. */ + result = chainon (finish_ctor_vtables_1 (base, complete_type), + result); + /* Prepend our own vtable list. */ + result = chainon + (finish_ctor_vtables_for_vbases (vbases, base, complete_type), + result); + } + return result; +} + +/* Add the vtables of a virtual base BINFO in front of LIST, returning + the new list. DO_SELF indicates whether we have to return the + vtable of a vfield borrowed in a derived class. */ + +static tree +prepend_vbase_vfields (binfo, do_self, list) + tree binfo; + int do_self; + tree list; +{ + int i; + tree vtbl; + tree bases = BINFO_BASETYPES (binfo); + int vfp = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); + + if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) + { + vtbl = BINFO_VTABLE (binfo); + vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, vtbl); + TREE_READONLY (vtbl) = 1; + TREE_CONSTANT (vtbl) = 1; + list = tree_cons (NULL_TREE, vtbl, list); + } + + if (!bases) + return list; + + for (i = 0; i < TREE_VEC_LENGTH (bases); i++) + { + tree base = TREE_VEC_ELT (bases, i); + if (TREE_VIA_VIRTUAL (base)) + continue; + list = prepend_vbase_vfields (base, (i != vfp), list); + } + + return list; +} + +/* Wrapper around finish_ctor_vtables_1. Compute the vtable list for + type T. */ + +static void +finish_ctor_vtables (t) + tree t; +{ + tree veclist = NULL_TREE; + tree decl, type; + char *name; + tree vbase; + int len; + + /* This is only good for vtable thunks. */ + my_friendly_assert (flag_vtable_thunks, 990307); + + /* Start with the list of most-derived vtables. */ + + for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; + vbase = TREE_CHAIN (vbase)) + veclist = prepend_vbase_vfields (vbase, 1, veclist); + + /* Compute the list of vtables for the bases. */ + veclist = chainon (veclist, finish_ctor_vtables_1 (TYPE_BINFO (t), t)); + + /* Finally, we initialize the virtual bases first. */ + for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; + vbase = TREE_CHAIN (vbase)) + { + tree vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbase)); + if (!vbases) + continue; + veclist = chainon (veclist, + finish_ctor_vtables_for_vbases (vbases, vbase, t)); + veclist = chainon (veclist, + finish_ctor_vtables_1 (vbase, t)); + } + + veclist = nreverse (veclist); + + /* Generate the name for the vtable list. */ + name = alloca (strlen (VLIST_NAME_FORMAT) + + TYPE_ASSEMBLER_NAME_LENGTH (t) + 2); + sprintf (name, VLIST_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (t)); + + /* Build the type of the list. */ + len = list_length (veclist) - 1; + if (len < 0) + /* If this class has virtual bases without virtual methods, make a + single zero-entry in the array. This avoids zero-sized objects. */ + len++; + type = build_cplus_array_type (vtbl_ptr_type_node, + build_index_type (size_int (len))); + + + /* Produce a new decl holding the list. */ + decl = build_lang_decl (VAR_DECL, get_identifier (name), type); + TREE_STATIC (decl) = 1; + TREE_READONLY (decl) = 1; + decl = pushdecl_top_level (decl); + import_export_vtable (decl, t, 0); + DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, veclist); + + DECL_ARTIFICIAL (decl) = 1; + /* This tells finish_file et.al. that this is related to virtual + tables. There is currently no way to distinguish between vtables + and vlists, other than the name of the decl. */ + DECL_VIRTUAL_P (decl) = 1; + + /* Output the array. */ + cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); + + /* Set the class context after finishing, so that finish thinks this + is an unrelated global, and then finish_vtable_vardecl knows what + class this is related to. */ + DECL_CONTEXT (decl) = t; +} + /* Check for things that are invalid. There are probably plenty of other things we should check for also. */ @@ -4069,6 +4417,10 @@ finish_struct_1 (t, warn_anon) /* Make the rtl for any new vtables we have created, and unmark the base types we marked. */ finish_vtbls (TYPE_BINFO (t), 1, t); + /* If we use thunks, and have virtual bases, we might need to emit + additional vtables. */ + if (flag_vtable_thunks && TYPE_USES_PVBASES (t)) + finish_ctor_vtables (t); hack_incomplete_structures (t); #if 0 diff --git a/gnu/egcs/gcc/cp/exception.cc b/gnu/egcs/gcc/cp/exception.cc index 8e8f35f50db..59342c6423e 100644 --- a/gnu/egcs/gcc/cp/exception.cc +++ b/gnu/egcs/gcc/cp/exception.cc @@ -247,10 +247,10 @@ __cp_pop_exception (cp_eh_info *p) if (p->cleanup) /* 2 is a magic value for destructors; see build_delete(). */ - p->cleanup (p->value, 2); + p->cleanup (p->original_value, 2); // value may have been adjusted. if (! __is_pointer (p->type)) - __eh_free (p->original_value); // value may have been co-erced. + __eh_free (p->original_value); // value may have been adjusted. __eh_free (p); } diff --git a/gnu/egcs/gcc/cp/gxxint.texi b/gnu/egcs/gcc/cp/gxxint.texi index 05f1373b252..81bcab86425 100644 --- a/gnu/egcs/gcc/cp/gxxint.texi +++ b/gnu/egcs/gcc/cp/gxxint.texi @@ -26,6 +26,7 @@ Questions and comments to Benjamin Kosnik @code{<bkoz@@cygnus.com>}. * Exception Handling:: * Free Store:: * Mangling:: Function name mangling for C++ and Java +* Vtables:: Two ways to do virtual functions * Concept Index:: @end menu @@ -190,7 +191,9 @@ accessed by the BINFO_ accessor macros. The virtual function table holds information used in virtual function dispatching. In the compiler, they are usually referred to as vtables, or vtbls. The first index is not used in the normal way, I believe it -is probably used for the virtual destructor. +is probably used for the virtual destructor. There are two forms of +virtual tables, one that has offsets in addition to pointers, and one +using thunks. @xref{Vtables}. @item vfield @@ -1455,7 +1458,7 @@ To meet the first goal, we defer emission of inlines and vtables until the end of the translation unit, where we can decide whether or not they are needed, and how to emit them if they are. -@node Mangling, Concept Index, Free Store, Top +@node Mangling, Vtables, Free Store, Top @section Function name mangling for C++ and Java Both C++ and Jave provide overloaded function and methods, @@ -1839,7 +1842,231 @@ Used for template type parameters. The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p} also seem to be used for obscure purposes ... -@node Concept Index, , Mangling, Top +@node Vtables, Concept Index, Mangling, Top +@section Virtual Tables + +In order to invoke virtual functions, GNU C++ uses virtual tables. Each +virtual function gets an index, and the table entry points to the +overridden function to call. Sometimes, and adjustment to the this +pointer has to be made before calling a virtual function: + +@example +struct A@{ + int i; + virtual void foo(); +@}; + +struct B@{ + int j; + virtual void bar(); +@}; + +struct C:A,B@{ + virtual void bar(); +@}; + +void C::bar() +@{ + i++; +@} + +int main() +@{ + C *c = new C; + B *b = c; + c->bar(); +@} +@end example + +Here, casting from @samp{c} to @samp{b} adds an offset. When @samp{bar} +is called, this offset needs to be subtracted, so that @samp{C::bar} can +properly access @samp{i}. One approach of achieving this is to use +@emph{thunks}, which are small half-functions put into the virtual +table. The modify the first argument (the @samp{this} pointer), and then +jump into the real function. + +The other (traditional) approach is to have an additional integer in the +virtual table which is added to this. This is an additional overhead +both at the function call, and in the size of virtual tables: In the +case of single inheritance (or for the first base class), these integers +will always be zero. + +@subsection Virtual Base Classes with Virtual Tables + +In case of virtual bases, the code is even more +complicated. Constructors and destructors need to know whether they are +"in charge" of the virtual bases, and an implicit integer +@samp{__in_chrg} for that purpose. + +@example +struct A@{ + int i; + virtual void bar(); + void call_bar()@{bar();@} +@}; + +struct B:virtual A@{ + B(); + int j; + virtual void bar(); +@}; + +B::B()@{ + call_bar(); +@} + +struct C@{ + int k; +@}; + +struct D:C,B@{ + int l; + virtual void bar(); +@}; + +@end example + +When constructing an instance of B, it will have the following layout: +@samp{vbase pointer to A}, @samp{j}, @samp{A virtual table}, @samp{i}. +On a 32-bit machine, downcasting from @samp{A*} to @samp{B*} would need +to subtract 8, which would be the thunk executed when calling +@samp{B::bar} inside @samp{call_bar}. + +When constructing an instance of D, it will have a different layout: +@samp{k}, @samp{vbase pointer to A}, @samp{j}, @samp{l}, @samp{A virtual +table}, @samp{i}. So, when downcasting from @samp{A*} to @samp{B*} in a +@samp{D} object, the offset would be @samp{12}. + +This means that during construction of the @samp{B} base of a @samp{D} +object, a virtual table is needed which has a @samp{-12} thunk to +@samp{B::bar}. This is @emph{only} needed during construction and +destruction, as the full object will use a @samp{-16} thunk to +@samp{D::bar}. + +In order to implement this, the compiler generates an implicit argument +(in addition to @code{__in_chrg}): the virtual list argument +@code{__vlist}. This is a list of virtual tables needed during +construction and destruction. The virtual pointers are ordered in the +way they are used during construction; the destructors will process the +array in reverse order. The ordering is as follows: +@itemize @bullet +@item +If the class is in charge, the vlist starts with virtual table pointers +for the virtual bases that have virtual bases themselves. Here, only +@emph{polymorphic} virtual bases (pvbases) are interesting: if a vbase +has no virtual functions, it doesn't have a virtual table. + +@item +Next, the vlist has virtual tables for the initialization of the +non-virtual bases. These bases are not in charge, so the layout is +recursive, but ignores virtual bases during recursion. + +@item +Next, there is a number of virtual tables for each virtual base. These +are sorted in the order in which virtual bases are constructed. Each +virtual base may have more than one @code{vfield}, and therefore require +more than one @code{vtable}. The order of vtables is the same as used +when initializing vfields of non-virtual bases in a constructor. +@end itemize + +The compiler emits a virtual table list in a variable mangled as +@code{__vl.classname}. + +Class with virtual bases, but without pvbases, only have the +@code{__in_chrg} argument to their ctors and dtors: they don't have any +vfields in the vbases to initialize. + +A further problem arises with virtual destructors: A destructor +typically has only the @code{__in_chrg} argument, which also indicates +whether the destructor should call @code{operator delete}. A dtor of a +class with pvbases has an additional argument. Unfortunately, a caller +of a virtual dtor might not know whether to pass that argument or not. +Therefore, the dtor processes the @code{__vlist} argument in an +automatic variable, which is initialized from the class' vlist if the +__in_chrg flag has a zero value in bit 2 (bit mask 4), or from the +argument @code{__vlist1} if bit 2 of the __in_chrg parameter is set to +one. + +@subsection Specification of non-thunked vtables + +In the traditional implementation of vtables, each slot contains three +fields: The offset to be added to the this pointer before invoking a +virtual function, an unused field that is always zero, and the pointer +to the virtual function. The first two fields are typically 16 bits +wide. The unused field is called `index'; it may be non-zero in +pointer-to-member-functions, which use the same layout. + +The virtual table then is an array of vtable slots. The first slot is +always the virtual type info function, the other slots are in the order +in which the virtual functions appear in the class declaration. + +If a class has base classes, it may inherit other bases' vfields. Each +class may have a primary vfield; the primary vfield of the derived class +is the primary vfield of the left-most non-virtual base class. If a +class inherits a primary vfield, any new virtual functions in the +derived class are appended to the virtual table of the primary +vfield. If there are new virtual functions in the derived class, and no +primary vfield is inherited, a new vfield is introduced which becomes +primary. The redefined virtual functions fill the vtable slots inherited +from the base; new virtual functions are put into the primary vtable in +the order of declaration. If no new virtual functions are introduced, no +primary vfield is allocated. + +In a base class that has pvbases, virtual tables are needed which are +used only in the constructor (see example above). At run-time, the +virtual tables of the base class are adjusted, to reflect the new offset +of the pvbase. The compiler knows statically what offset the pvbase has +for a complete object. At run-time, the offset of the pvbase can be +extracted from the vbase pointer, which is set in the constructor of the +complete object. These two offsets result in a delta, which is used to +adjust the deltas in the vtable (the adjustment might be different for +different vtable slots). To adjust the vtables, the compiler emits code +that creates a vtable on the stack. This vtable is initialized with the +vtable for the complete base type, and then adjusted. + +In order to call a virtual function, the compiler gets the offset field +from the vtable entry, and adds it to the this pointer. It then +indirectly calls the virtual function pointer, passing the adjusted this +pointer, and any arguments the virtual function may have. + +To implement dynamic casting, the dynamic_cast function needs typeinfos +for the complete type, and the pointer to the complete type. The +typeinfo pointer is obtained by calling the virtual typeinfo function +(which doesn't take a this parameter). The pointer to the complete +object is obtained by adding the offset of the virtual typeinfo vtable +slot, since this virtual function is always implemented in the complete +object. + +@subsection Specification of thunked vtables + +For vtable thunks, each slot only consists of a pointer to the virtual +function, which might be a thunk function. The first slot in the vtable +is an offset of the this pointer to the complete object, which is needed +as a parameter to __dynamic_cast. The second slot is the virtual +typeinfo function. All other slots are allocated with the same procedure +as in the non-thunked case. Allocation of vfields also uses the same +procedure as described above. + +If the virtual function needs an adjusted this pointer, a thunk function +is emitted. If supported by the target architecture, this is only a +half-function. Such a thunk has no stack frame; it merely adjusts the +first argument of the function, and then directly branches into the +implementation of the virtual function. If the architecture does not +support half-functions (i.e. if ASM_OUTPUT_MI_THUNK is not defined), the +compiler emits a wrapper function, which copies all arguments, adjust +the this pointer, and then calls the original function. Since objects of +non-aggregate type are passed by invisible reference, this copies only +POD arguments. The approach fails for virtual functions with a variable +number of arguments. + +In order to support the vtables needed in base constructors with +pvbases, the compiler passes an implicit __vlist argument as described +above, if the version 2 thunks are used. For version 1 thunks, the base +class constructor will fill in the vtables for the complete base class, +which will incorrectly adjust the this pointer, leading to a dynamic +error. + +@node Concept Index, , Vtables, Top @section Concept Index diff --git a/gnu/egcs/gcc/cp/init.c b/gnu/egcs/gcc/cp/init.c index 38bf2487a93..aed1fde6551 100644 --- a/gnu/egcs/gcc/cp/init.c +++ b/gnu/egcs/gcc/cp/init.c @@ -59,7 +59,8 @@ static tree initializing_context PROTO((tree)); static void expand_vec_init_try_block PROTO((tree)); static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree)); static tree build_java_class_ref PROTO((tree)); -static void expand_cleanup_for_base PROTO((tree, tree)); +static void expand_cleanup_for_base PROTO((tree, tree, tree)); +static int pvbasecount PROTO((tree, int)); /* Cache the identifier nodes for the magic field of a new cookie. */ static tree nc_nelts_field_id; @@ -478,6 +479,93 @@ sort_base_init (t, rbase_ptr, vbase_ptr) *vbase_ptr = vbases; } +/* Invoke a base-class destructor. REF is the object being destroyed, + BINFO is the base class, and DTOR_ARG indicates whether the base + class should invoke delete. */ + +tree +build_base_dtor_call (ref, binfo, dtor_arg) + tree ref, binfo, dtor_arg; +{ + tree args = NULL_TREE; + tree vlist = lookup_name (vlist_identifier, 0); + tree call, decr; + + if (TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + { + args = expr_tree_cons (NULL_TREE, vlist, args); + dtor_arg = build (BIT_IOR_EXPR, integer_type_node, + dtor_arg, build_int_2 (4, 0)); + dtor_arg = fold (dtor_arg); + } + args = expr_tree_cons (NULL_TREE, dtor_arg, args); + call = build_scoped_method_call (ref, binfo, dtor_identifier, args); + + if (!TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + /* For plain inheritance, do not try to adjust __vlist. */ + return call; + + /* Now decrement __vlist by the number of slots consumed by the base + dtor. */ + decr = build_int_2 (pvbasecount (BINFO_TYPE (binfo), 0), 0); + decr = build_binary_op (MINUS_EXPR, vlist, decr); + decr = build_modify_expr (vlist, NOP_EXPR, decr); + + return build (COMPOUND_EXPR, void_type_node, call, decr); +} + +/* Return the number of vlist entries needed to initialize TYPE, + depending on whether it is IN_CHARGE. */ + +static int +pvbasecount (type, in_charge) + tree type; + int in_charge; +{ + int i; + int result = 0; + tree vbase; + + for (vbase = (CLASSTYPE_VBASECLASSES (type)); vbase; + vbase = TREE_CHAIN (vbase)) + { + result += list_length (CLASSTYPE_VFIELDS (BINFO_TYPE (vbase))); + if (in_charge) + result += pvbasecount (BINFO_TYPE (vbase), 0); + } + + for (i=0; i < CLASSTYPE_N_BASECLASSES (type); i++) + { + tree base = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i); + if (TREE_VIA_VIRTUAL (base)) + continue; + result += pvbasecount (BINFO_TYPE (base), 0); + } + return result; +} + +void +init_vlist (t) + tree t; +{ + char *name; + tree expr; + tree vlist = lookup_name (vlist_identifier, 0); + + name = alloca (strlen (VLIST_NAME_FORMAT) + + TYPE_ASSEMBLER_NAME_LENGTH (t) + 2); + sprintf (name, VLIST_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (t)); + + expr = get_identifier (name); + expr = lookup_name (expr, 0); + expr = build1 (ADDR_EXPR, TREE_TYPE (vlist), expr); + if (DECL_DESTRUCTOR_FOR_PVBASE_P (current_function_decl)) + /* Move to the end of the vlist. */ + expr = build_binary_op (PLUS_EXPR, expr, + build_int_2 (pvbasecount (t, 1), 0)); + expand_expr_stmt (build_modify_expr (vlist, NOP_EXPR, expr)); +} + /* Perform whatever initializations have yet to be done on the base class of the class variable. These actions are in the global variable CURRENT_BASE_INIT_LIST. Such an action could be @@ -510,6 +598,7 @@ emit_base_init (t, immediately) tree binfos = BINFO_BASETYPES (t_binfo); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; tree expr = NULL_TREE; + tree vlist = lookup_name (vlist_identifier, 0); if (! immediately) { @@ -581,7 +670,7 @@ emit_base_init (t, immediately) free_temp_slots (); } - expand_cleanup_for_base (base_binfo, NULL_TREE); + expand_cleanup_for_base (base_binfo, vlist, NULL_TREE); rbase_init_list = TREE_CHAIN (rbase_init_list); } @@ -750,30 +839,39 @@ expand_virtual_init (binfo, decl) destroyed. */ static void -expand_cleanup_for_base (binfo, flag) +expand_cleanup_for_base (binfo, vlist, flag) tree binfo; + tree vlist; tree flag; { tree expr; - if (!TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) - return; + if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) + { + /* All cleanups must be on the function_obstack. */ + push_obstacks_nochange (); + resume_temporary_allocation (); - /* All cleanups must be on the function_obstack. */ - push_obstacks_nochange (); - resume_temporary_allocation (); + /* Call the destructor. */ + expr = build_base_dtor_call (current_class_ref, binfo, + integer_zero_node); + if (flag) + expr = fold (build (COND_EXPR, void_type_node, + truthvalue_conversion (flag), + expr, integer_zero_node)); - /* Call the destructor. */ - expr = (build_scoped_method_call - (current_class_ref, binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node))); - if (flag) - expr = fold (build (COND_EXPR, void_type_node, - truthvalue_conversion (flag), - expr, integer_zero_node)); + pop_obstacks (); + add_partial_entry (expr); + } - pop_obstacks (); - add_partial_entry (expr); + if (TYPE_USES_PVBASES (BINFO_TYPE (binfo))) + { + /* Increment vlist by number of base's vbase classes. */ + expr = build_int_2 (pvbasecount (BINFO_TYPE (binfo), 0), 0); + expr = build_binary_op (PLUS_EXPR, vlist, expr); + expr = build_modify_expr (vlist, NOP_EXPR, expr); + expand_expr_stmt (expr); + } } /* Subroutine of `expand_aggr_vbase_init'. @@ -813,6 +911,7 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) { tree vbases; tree result; + tree vlist = NULL_TREE; /* If there are no virtual baseclasses, we shouldn't even be here. */ my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621); @@ -820,6 +919,11 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) /* First set the pointers in our object that tell us where to find our virtual baseclasses. */ expand_start_cond (flag, 0); + if (TYPE_USES_PVBASES (type)) + { + init_vlist (type); + vlist = lookup_name (vlist_identifier, 0); + } result = init_vbase_pointers (type, this_ptr); if (result) expand_expr_stmt (build_compound_expr (result)); @@ -851,7 +955,7 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) init_list); expand_end_cond (); - expand_cleanup_for_base (vbases, flag); + expand_cleanup_for_base (vbases, vlist, flag); } } @@ -1146,6 +1250,44 @@ expand_aggr_init (exp, init, flags) TREE_THIS_VOLATILE (exp) = was_volatile; } +static tree +no_vlist_base_init (rval, exp, init, binfo, flags) + tree rval, exp, init, binfo; + int flags; +{ + tree nrval, func, parms; + + /* Obtain the vlist-expecting ctor. */ + func = rval; + my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131); + func = TREE_OPERAND (func, 0); + my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132); + + if (init == NULL_TREE + || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init))) + { + parms = init; + if (parms) + init = TREE_VALUE (parms); + } + else + parms = build_expr_list (NULL_TREE, init); + + flags &= ~LOOKUP_HAS_VLIST; + + parms = expr_tree_cons (NULL_TREE, integer_zero_node, parms); + flags |= LOOKUP_HAS_IN_CHARGE; + + nrval = build_method_call (exp, ctor_identifier, + parms, binfo, flags); + + func = build (NE_EXPR, boolean_type_node, + func, null_pointer_node); + nrval = build (COND_EXPR, void_type_node, + func, rval, nrval); + return nrval; +} + static void expand_default_init (binfo, true_exp, exp, init, flags) tree binfo; @@ -1163,6 +1305,8 @@ expand_default_init (binfo, true_exp, exp, init, flags) out, then look hard. */ tree rval; tree parms; + tree vlist = NULL_TREE; + tree orig_init = init; if (init && TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING)) @@ -1206,6 +1350,21 @@ expand_default_init (binfo, true_exp, exp, init, flags) if (TYPE_USES_VIRTUAL_BASECLASSES (type)) { + if (TYPE_USES_PVBASES (type)) + { + /* In compatibility mode, when not calling a base ctor, + we do not pass the vlist argument. */ + if (true_exp == exp) + vlist = flag_vtable_thunks_compat? NULL_TREE : vlist_zero_node; + else + vlist = lookup_name (vlist_identifier, 0); + + if (vlist) + { + parms = expr_tree_cons (NULL_TREE, vlist, parms); + flags |= LOOKUP_HAS_VLIST; + } + } if (true_exp == exp) parms = expr_tree_cons (NULL_TREE, integer_one_node, parms); else @@ -1215,6 +1374,10 @@ expand_default_init (binfo, true_exp, exp, init, flags) rval = build_method_call (exp, ctor_identifier, parms, binfo, flags); + if (vlist && true_exp != exp && flag_vtable_thunks_compat) + { + rval = no_vlist_base_init (rval, exp, orig_init, binfo, flags); + } if (TREE_SIDE_EFFECTS (rval)) expand_expr_stmt (rval); } @@ -2408,6 +2571,12 @@ build_new_1 (exp) if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type)) { + if (TYPE_USES_PVBASES (true_type) + && !flag_vtable_thunks_compat) + { + init = expr_tree_cons (NULL_TREE, vlist_zero_node, init); + flags |= LOOKUP_HAS_VLIST; + } init = expr_tree_cons (NULL_TREE, integer_one_node, init); flags |= LOOKUP_HAS_IN_CHARGE; } @@ -3123,9 +3292,21 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) else passed_auto_delete = auto_delete; - expr = build_method_call - (ref, dtor_identifier, build_expr_list (NULL_TREE, passed_auto_delete), - NULL_TREE, flags); + /* Maybe pass vlist pointer to destructor. */ + if (TYPE_USES_PVBASES (type)) + { + /* Pass vlist_zero even if in backwards compatibility mode, + as the extra argument should not hurt if it is not used. */ + expr = build_expr_list (NULL_TREE, vlist_zero_node); + flags |= LOOKUP_HAS_VLIST; + } + else + expr = NULL_TREE; + + expr = expr_tree_cons (NULL_TREE, passed_auto_delete, expr); + + expr = build_method_call (ref, dtor_identifier, expr, + NULL_TREE, flags); if (do_delete) expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); @@ -3181,14 +3362,13 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) { tree this_auto_delete; + /* Should the base invoke delete? */ if (BINFO_OFFSET_ZEROP (base_binfo)) this_auto_delete = parent_auto_delete; else this_auto_delete = integer_zero_node; - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, this_auto_delete)); + expr = build_base_dtor_call (ref, base_binfo, this_auto_delete); exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); } @@ -3200,9 +3380,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) || TREE_VIA_VIRTUAL (base_binfo)) continue; - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node)); + expr = build_base_dtor_call (ref, base_binfo, integer_zero_node); exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); } diff --git a/gnu/egcs/gcc/cp/method.c b/gnu/egcs/gcc/cp/method.c index d4a667bdf82..d60bfda5242 100644 --- a/gnu/egcs/gcc/cp/method.c +++ b/gnu/egcs/gcc/cp/method.c @@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */ #include "hard-reg-set.h" #include "flags.h" #include "toplev.h" +#include "decl.h" /* TREE_LIST of the current inline functions that need to be processed. */ @@ -88,6 +89,8 @@ static int is_back_referenceable_type PROTO((tree)); static int check_btype PROTO((tree)); static void build_mangled_name_for_type PROTO((tree)); static void build_mangled_name_for_type_with_Gcode PROTO((tree, int)); +static tree build_base_path PROTO((tree, int)); + # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) @@ -1349,6 +1352,15 @@ process_overload_item (parmtype, extra_Gcode) #endif case POINTER_TYPE: + /* Even though the vlist_type_node is PPPFe (i.e. `int + (***)(...)'), it is different from the any other occurence of + the pointer type, because the underlying function type is + different. */ + if (parmtype == vlist_type_node) + { + OB_PUTS (VLIST_TYPE_NAME); + return; + } OB_PUTC ('P'); more: build_mangled_name_for_type (TREE_TYPE (parmtype)); @@ -1809,14 +1821,64 @@ get_id_2 (name, name2) return get_identifier (obstack_base (&scratch_obstack)); } -/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */ +/* Print a binfo path T, starting with the most derived class. If + OMIT_LAST is set, drop and return the most derived class. */ + +static tree +build_base_path (t, omit_last) + tree t; + int omit_last; +{ + tree ret = NULL_TREE; + if (BINFO_INHERITANCE_CHAIN (t)) + ret = build_base_path (BINFO_INHERITANCE_CHAIN (t), omit_last); + else if (omit_last) + return t; + process_overload_item (BINFO_TYPE (t), 0); + return ret; +} + +/* Return a mangled name for a vlist vtable, using the path of both + BASE and VBASE. */ + +tree +get_vlist_vtable_id (base, vbase) + tree base, vbase; +{ + tree last; + OB_INIT (); + OB_PUTS (VCTABLE_NAME); + build_base_path (base, 0); + OB_PUTC ('_'); + /* Since the base path should end where the vbase path starts, we + can omit the most-derived class in the vbase path. Check below + that this really happens. */ + last = build_base_path (vbase, 1); + my_friendly_assert (BINFO_TYPE (last) == BINFO_TYPE (base), 990402); + OB_FINISH (); + return get_identifier (obstack_base (&scratch_obstack)); +} + +/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. If + HAS_VLIST is set, also add the vlist argument. */ tree -build_destructor_name (type) +build_destructor_name (type, has_vlist) tree type; + int has_vlist; { - return build_overload_with_type (get_identifier (DESTRUCTOR_DECL_PREFIX), - type); + OB_INIT (); + OB_PUTS (DESTRUCTOR_DECL_PREFIX); + start_squangling (); + build_mangled_name_for_type (type); + /* If we need backwards compatibility, we can get aways by + not linking type-safely, as the dtor will check whether + the argument was provided. */ + if (has_vlist && !flag_vtable_thunks_compat) + OB_PUTS (VLIST_TYPE_NAME); + OB_FINISH (); + end_squangling (); + return get_identifier (obstack_base (&scratch_obstack)); } /* Given a tree_code CODE, and some arguments (at least one), @@ -2178,6 +2240,136 @@ emit_thunk (thunk_fndecl) TREE_SET_CODE (thunk_fndecl, THUNK_DECL); } +void +make_vlist_ctor_wrapper (fn) + tree fn; +{ + tree fntype, decl; + tree arg_types, parms, parm, basetype, pbasetype; + tree t, ctors; + + arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); + pbasetype = TREE_VALUE (arg_types); + basetype = TREE_TYPE (pbasetype); + parms = DECL_ARGUMENTS (fn); + + /* Skip this, __in_chrg, and _vlist */ + arg_types = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arg_types))); + + + /* Add __in_charge. */ + arg_types = hash_tree_chain (integer_type_node, arg_types); + + /* Don't add this to arg_types, as build_cplus_method_type does so. */ + + fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), + arg_types); + + decl = build_lang_decl (FUNCTION_DECL, DECL_NAME (fn), fntype); + DECL_LANG_SPECIFIC (decl)->decl_flags = DECL_LANG_SPECIFIC (fn)->decl_flags; + DECL_EXTERNAL (decl) = 0; + TREE_PUBLIC (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; + DECL_CONSTRUCTOR_P (decl) = 1; + DECL_CONSTRUCTOR_FOR_VBASE (decl) = CONSTRUCTOR_FOR_VBASE; + /* Claim that this is never a template instantiation. */ + DECL_USE_TEMPLATE (decl) = 0; + DECL_TEMPLATE_INFO (decl) = NULL_TREE; + + /* Set up clone argument trees for the thunk. */ + parms = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (parms))); + /* Add this */ + t = build_decl (PARM_DECL, this_identifier, pbasetype); + SET_DECL_ARTIFICIAL (t); + DECL_ARG_TYPE (t) = pbasetype; + DECL_REGISTER (t) = 1; + /* Add __in_charge. */ + parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); + SET_DECL_ARTIFICIAL (parm); + DECL_ARG_TYPE (parm) = integer_type_node; + TREE_CHAIN (parm) = t; + t = parm; + + while (parms) + { + tree x = copy_node (parms); + TREE_CHAIN (x) = t; + DECL_CONTEXT (x) = decl; + t = x; + parms = TREE_CHAIN (parms); + } + parms = nreverse (t); + DECL_ARGUMENTS (decl) = parms; + + DECL_ASSEMBLER_NAME (decl) + = build_decl_overload (DECL_NAME (decl), + TYPE_ARG_TYPES (TREE_TYPE (decl)), 2); + + ctors = CLASSTYPE_METHOD_VEC (basetype); + if (ctors) + ctors = TREE_VEC_ELT (ctors, 0); + for ( ; ctors; ctors = OVL_NEXT (ctors)) + if (DECL_ASSEMBLER_NAME (OVL_CURRENT (ctors)) + == DECL_ASSEMBLER_NAME (decl)) + break; + + if (!ctors) + { + add_method (basetype, 0, decl); + cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0, 0); + } + else + decl = OVL_CURRENT (ctors); + + /* Remember the original function. */ + DECL_VLIST_CTOR_WRAPPED (decl) = fn; + + /* When fn is declared, DECL_INITIAL is null. When it is defined, + DECL_INITIAL will be error_mark_node. */ + if (DECL_INITIAL (fn) == error_mark_node) + { + /* Record that the ctor is being defined, so we also emit the + wrapper later. */ + TREE_USED (decl) = 1; + DECL_NOT_REALLY_EXTERN (decl) = 1; + DECL_INITIAL (decl) = NULL_TREE; + mark_inline_for_output (decl); + } +} + +static void +emit_vlist_ctor_wrapper (decl) + tree decl; +{ + tree t, parms, fn; + + current_function_is_thunk = 1; + + parms = DECL_ARGUMENTS (decl); + fn = DECL_VLIST_CTOR_WRAPPED (decl); + mark_used (fn); + + /* Build up the call to the real function. */ + t = NULL_TREE; + /* Push this, __in_charge. */ + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + /* Push 0 as __vlist. */ + t = expr_tree_cons (NULL_TREE, vlist_zero_node, t); + /* Push rest of arguments. */ + while (parms) + { + t = expr_tree_cons (NULL_TREE, parms, t); + parms = TREE_CHAIN (parms); + } + t = nreverse (t); + t = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), t); + expand_expr_stmt (t); +} + + /* Code for synthesizing methods which have default semantics defined. */ /* For the anonymous union in TYPE, return the member that is at least as @@ -2212,6 +2404,8 @@ do_build_copy_constructor (fndecl) if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) parm = TREE_CHAIN (parm); + if (TYPE_USES_PVBASES (current_class_type)) + parm = TREE_CHAIN (parm); parm = convert_from_reference (parm); if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) @@ -2408,6 +2602,16 @@ synthesize_method (fndecl) int nested = (current_function_decl != NULL_TREE); tree context = hack_decl_function_context (fndecl); + /* If this is a wrapper around a undefined vlist ctor, don't emit it + even if it is used. */ + if (DECL_VLIST_CTOR_WRAPPER_P (fndecl)) + { + tree orig_fn = DECL_VLIST_CTOR_WRAPPED (fndecl); + mark_used (orig_fn); + if (DECL_INITIAL (orig_fn) == NULL_TREE) + return; + } + if (at_eof) import_export_decl (fndecl); @@ -2429,7 +2633,11 @@ synthesize_method (fndecl) tree arg_chain = FUNCTION_ARG_CHAIN (fndecl); if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl)) arg_chain = TREE_CHAIN (arg_chain); - if (arg_chain != void_list_node) + else if (DECL_CONSTRUCTOR_FOR_PVBASE_P (fndecl)) + arg_chain = TREE_CHAIN (TREE_CHAIN (arg_chain)); + if (DECL_VLIST_CTOR_WRAPPER_P (fndecl)) + emit_vlist_ctor_wrapper (fndecl); + else if (arg_chain != void_list_node) do_build_copy_constructor (fndecl); else if (TYPE_NEEDS_CONSTRUCTING (current_class_type)) setup_vtbl_ptr (); @@ -2443,3 +2651,6 @@ synthesize_method (fndecl) else if (nested) pop_cp_function_context (context); } + + + diff --git a/gnu/egcs/gcc/cp/rtti.c b/gnu/egcs/gcc/cp/rtti.c index e0ce5cd8666..c8c1ba95255 100644 --- a/gnu/egcs/gcc/cp/rtti.c +++ b/gnu/egcs/gcc/cp/rtti.c @@ -363,8 +363,19 @@ get_tinfo_var (type) return tdecl; } +/* Returns the decl for a function which will return a type_info node for + TYPE. This version does not mark the function used, for use in + set_rtti_entry; for the vtable case, we'll get marked in + finish_vtable_vardecl, when we know that we want to be emitted. + + We do this to avoid emitting the tinfo node itself, since we don't + currently support DECL_DEFER_OUTPUT for variables. Also, we don't + associate constant pools with their functions properly, so we would + emit string constants and such even though we don't emit the actual + function. When those bugs are fixed, this function should go away. */ + tree -get_tinfo_fn (type) +get_tinfo_fn_unused (type) tree type; { tree name; @@ -393,13 +404,23 @@ get_tinfo_fn (type) pushdecl_top_level (d); make_function_rtl (d); - mark_used (d); mark_inline_for_output (d); pop_obstacks (); return d; } +/* Likewise, but also mark it used. Called by various EH and RTTI code. */ + +tree +get_tinfo_fn (type) + tree type; +{ + tree d = get_tinfo_fn_unused (type); + mark_used (d); + return d; +} + tree get_typeid_1 (type) tree type; diff --git a/gnu/egcs/gcc/cp/search.c b/gnu/egcs/gcc/cp/search.c index 8760c6aff7d..fb99f8f8eef 100644 --- a/gnu/egcs/gcc/cp/search.c +++ b/gnu/egcs/gcc/cp/search.c @@ -151,6 +151,9 @@ static int protected_accessible_p PROTO ((tree, tree, tree, tree)); static int friend_accessible_p PROTO ((tree, tree, tree, tree)); static void setup_class_bindings PROTO ((tree, int)); static int template_self_reference_p PROTO ((tree, tree)); +static void expand_direct_vtbls_init_thunks PROTO((tree, tree, int)); +static void expand_indirect_vtbls_init_thunks PROTO((tree, tree, tree)); + /* Allocate a level of searching. */ @@ -2626,6 +2629,117 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori } } +/* Emit initialization of vfields of BASE, where the complete object + is pointed to by decl_ptr. DO_SELF indicates we have to do our own + vfield, otherwise only proceed to our own direct non-virtual bases. */ + +static void +expand_direct_vtbls_init_thunks (base, decl_ptr, do_self) + tree base, decl_ptr; + int do_self; +{ + tree addr, expr; + tree type = BINFO_TYPE (base); + tree binfos = BINFO_BASETYPES (base); + int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; + tree vlist = lookup_name (vlist_identifier, 0); + int in_dtor = DECL_DESTRUCTOR_FOR_PVBASE_P (current_function_decl); + + my_friendly_assert (vlist != NULL_TREE, 990320); + + if (in_dtor) + /* In the destructor, we find the vfield pointers for the bases in + reverse order, before we find our own vfield pointer. */ + for (i = n_baselinks - 1; i >= 0; i--) + { + tree base_binfo = TREE_VEC_ELT (binfos, i); + int is_not_base_vtable + = i != CLASSTYPE_VFIELD_PARENT (type); + if (! TREE_VIA_VIRTUAL (base_binfo)) + expand_direct_vtbls_init_thunks (base_binfo, decl_ptr, + is_not_base_vtable); + } + + if (do_self && CLASSTYPE_VFIELDS (type)) + { + addr = build_vbase_path (PLUS_EXPR, build_pointer_type (type), + decl_ptr, base, 1); + addr = build_indirect_ref (addr, "vptr"); + addr = build_vfield_ref (addr, type); + + /* In a destructor, we decrease the vlist before we retrieve the + value. In a constructor, we increase the vlist after we + retrieve the value. */ + if (in_dtor) + { + expr = build_binary_op (MINUS_EXPR, vlist, integer_one_node); + expr = build_modify_expr (vlist, NOP_EXPR, expr); + expand_expr_stmt (expr); + } + + /* Store the next vptr into the vbase's vptr. */ + expr = build_indirect_ref (vlist, "__vlist"); + expr = convert_force (TREE_TYPE (addr), expr, 0); + expr = build_modify_expr (addr, NOP_EXPR, expr); + expand_expr_stmt (expr); + + /* Advance the vlist. */ + if (!in_dtor) + { + expr = build_binary_op (PLUS_EXPR, vlist, integer_one_node); + expr = build_modify_expr (vlist, NOP_EXPR, expr); + expand_expr_stmt (expr); + } + } + + if (!in_dtor) + for (i = 0; i < n_baselinks; i++) + { + tree base_binfo = TREE_VEC_ELT (binfos, i); + int is_not_base_vtable = i != CLASSTYPE_VFIELD_PARENT (type); + if (! TREE_VIA_VIRTUAL (base_binfo)) + expand_direct_vtbls_init_thunks (base_binfo, decl_ptr, + is_not_base_vtable); + } +} + +/* Like expand_indirect_vtbls_init below, but based on the vtable list + passed to the constructor. */ + +static void +expand_indirect_vtbls_init_thunks (binfo, true_exp, decl_ptr) + tree binfo; + tree true_exp, decl_ptr; +{ + tree type = BINFO_TYPE (binfo); + tree vbases = CLASSTYPE_VBASECLASSES (type); + struct vbase_info vi; + + vi.decl_ptr = (true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) + : decl_ptr); + vi.vbase_types = vbases; + + dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi); + + /* Initialized with vtables of type TYPE. */ + for (; vbases; vbases = TREE_CHAIN (vbases)) + { + tree addr; + + if (!CLASSTYPE_VFIELD (BINFO_TYPE (vbases))) + /* This vbase doesn't have a vptr of its own. */ + /* FIXME: check */ + continue; + + addr = convert_pointer_to_vbase (TREE_TYPE (vbases), decl_ptr); + expand_direct_vtbls_init_thunks (TYPE_BINFO (BINFO_TYPE (vbases)), + addr, 1); + + } + + dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0); +} + /* Build a COMPOUND_EXPR which when expanded will generate the code needed to initialize all the virtual function table slots of all the virtual baseclasses. MAIN_BINFO is the binfo which determines @@ -2657,6 +2771,12 @@ expand_indirect_vtbls_init (binfo, true_exp, decl_ptr) mark_all_temps_used(); + if (TYPE_USES_PVBASES (type)) + { + expand_indirect_vtbls_init_thunks (binfo, true_exp, decl_ptr); + return; + } + if (TYPE_USES_VIRTUAL_BASECLASSES (type)) { rtx fixup_insns = NULL_RTX; diff --git a/gnu/egcs/gcc/cp/typeck2.c b/gnu/egcs/gcc/cp/typeck2.c index 6322157e624..da98203bdc0 100644 --- a/gnu/egcs/gcc/cp/typeck2.c +++ b/gnu/egcs/gcc/cp/typeck2.c @@ -344,7 +344,7 @@ my_friendly_abort (i) else ack ("Internal compiler error %d.", i); ack ("Please submit a full bug report."); - ack ("See <URL:http://www.gnu.org/software/gcc/faq.html#bugreport> for instructions."); + ack ("See %s for instructions.", GCCBUGURL); } else error ("confused by earlier errors, bailing out"); @@ -359,7 +359,7 @@ my_friendly_abort (i) error ("Internal compiler error %d.", i); error ("Please submit a full bug report."); - fatal ("See <URL:http://www.gnu.org/software/gcc/faq.html#bugreport> for instructions."); + fatal ("See %s for instructions.", GCCBUGURL); } void diff --git a/gnu/egcs/gcc/f/ChangeLog b/gnu/egcs/gcc/f/ChangeLog index 2e818152ca1..47a745e70ff 100644 --- a/gnu/egcs/gcc/f/ChangeLog +++ b/gnu/egcs/gcc/f/ChangeLog @@ -1,3 +1,11 @@ +Mon Mar 13 01:00:55 2000 Toon Moene <toon@moene.indiv.nluug.nl> + + * stw.h (struct _ffestw_): Change type of uses_ to int. + +Fri Feb 18 13:36:50 2000 Martin von Loewis <loewis@informatik.hu-berlin.de> + + * g77spec.c (lang_specific_driver): Use GCCBUGURL. + Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) * gcc-2.95.2 Released. diff --git a/gnu/egcs/gcc/f/stw.h b/gnu/egcs/gcc/f/stw.h index 58818a61bf2..554d047e611 100644 --- a/gnu/egcs/gcc/f/stw.h +++ b/gnu/egcs/gcc/f/stw.h @@ -70,7 +70,7 @@ struct _ffestw_ ffewhereLine line_; /* Where first token of statement triggering state */ ffewhereColumn col_; /* was seen in source file. */ - char uses_; /* # uses (new+use-kill calls). */ + int uses_; /* # uses (new+use-kill calls). */ ffestvState state_; int substate_; /* Used on a per-block-state basis. */ #if FFECOM_targetCURRENT == FFECOM_targetGCC diff --git a/gnu/egcs/gcc/f/version.c b/gnu/egcs/gcc/f/version.c index 5e8381f0fc4..1b1cfd2bf96 100644 --- a/gnu/egcs/gcc/f/version.c +++ b/gnu/egcs/gcc/f/version.c @@ -1 +1 @@ -const char *ffe_version_string = "0.5.25 19991024 (release)"; +const char *ffe_version_string = "0.5.25 19991030 (prerelease)"; diff --git a/gnu/egcs/gcc/fixinc/fixincl.sh b/gnu/egcs/gcc/fixinc/fixincl.sh index 56eebd60bc4..05722bdff01 100644 --- a/gnu/egcs/gcc/fixinc/fixincl.sh +++ b/gnu/egcs/gcc/fixinc/fixincl.sh @@ -125,7 +125,12 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || continue +# This originally used cd || continue, however, that does not work with the +# Solaris2 /bin/sh. +if [ ! -d ${INPUT} ]; then + continue +fi +cd ${INPUT} INPUT=`${PWDCMD}` # diff --git a/gnu/egcs/gcc/fixinc/inclhack.sh b/gnu/egcs/gcc/fixinc/inclhack.sh index f6fab88798b..c2d85b1a4bf 100644 --- a/gnu/egcs/gcc/fixinc/inclhack.sh +++ b/gnu/egcs/gcc/fixinc/inclhack.sh @@ -123,7 +123,12 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || continue +# This originally used cd || continue, however, that does not work with the +# Solaris2 /bin/sh. +if [ ! -d ${INPUT} ]; then + continue +fi +cd ${INPUT} INPUT=`${PWDCMD}` # diff --git a/gnu/egcs/gcc/fixinc/inclhack.tpl b/gnu/egcs/gcc/fixinc/inclhack.tpl index 587a8e53143..2c76483ba62 100644 --- a/gnu/egcs/gcc/fixinc/inclhack.tpl +++ b/gnu/egcs/gcc/fixinc/inclhack.tpl @@ -118,7 +118,12 @@ for INPUT in ${INPUTLIST} ; do cd ${ORIGDIR} -cd ${INPUT} || continue +# This originally used cd || continue, however, that does not work with the +# Solaris2 /bin/sh. +if [ ! -d ${INPUT} ]; then + continue +fi +cd ${INPUT} INPUT=`${PWDCMD}` # diff --git a/gnu/egcs/gcc/glimits.h b/gnu/egcs/gcc/glimits.h index 559e712d726..2878051f625 100644 --- a/gnu/egcs/gcc/glimits.h +++ b/gnu/egcs/gcc/glimits.h @@ -64,7 +64,7 @@ /* Minimum and maximum values a `signed long int' can hold. (Same as `int'). */ #ifndef __LONG_MAX__ -#if defined (__alpha__) || defined (__sparc_v9__) || defined (__sparcv9) +#if defined (__alpha__) || (defined (_ARCH_PPC) && defined (__64BIT__)) || defined (__sparc_v9__) || defined (__sparcv9) #define __LONG_MAX__ 9223372036854775807L #else #define __LONG_MAX__ 2147483647L diff --git a/gnu/egcs/gcc/just-fixinc b/gnu/egcs/gcc/just-fixinc index a04028a1ce9..60cb7da36ec 100644 --- a/gnu/egcs/gcc/just-fixinc +++ b/gnu/egcs/gcc/just-fixinc @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: just-fixinc,v 1.1.1.2 1999/08/23 20:28:37 espie Exp $ +# $Id: just-fixinc,v 1.1.1.3 2000/06/05 22:15:48 espie Exp $ # This script exists for use after installing # the GCC binaries from a distribution tape/CD-ROM. # Use it *after* copying the directory of binaries diff --git a/gnu/egcs/gcc/mkinstalldirs b/gnu/egcs/gcc/mkinstalldirs index 5ff7c74965e..ddef74c0b7b 100644 --- a/gnu/egcs/gcc/mkinstalldirs +++ b/gnu/egcs/gcc/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1.1.2 1999/08/23 20:28:41 espie Exp $ +# $Id: mkinstalldirs,v 1.1.1.3 2000/06/05 22:15:52 espie Exp $ errstatus=0 diff --git a/gnu/egcs/gcc/system.h b/gnu/egcs/gcc/system.h index 7d6082ccf29..1b40e6004fc 100644 --- a/gnu/egcs/gcc/system.h +++ b/gnu/egcs/gcc/system.h @@ -22,6 +22,11 @@ Boston, MA 02111-1307, USA. */ #ifndef __GCC_SYSTEM_H__ #define __GCC_SYSTEM_H__ +/* This is the location of the online document giving information how + to report bugs. If you change this string, also check for strings + not under control of the preprocessor. */ +#define GCCBUGURL "<URL:http://www.gnu.org/software/gcc/bugs.html>" + /* We must include stdarg.h/varargs.h before stdio.h. */ #ifdef ANSI_PROTOTYPES #include <stdarg.h> @@ -399,8 +404,8 @@ extern void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORE #else #define abort() fatal ("Internal compiler error in `%s', at %s:%d\n" \ "Please submit a full bug report.\n" \ - "See <URL:http://www.gnu.org/software/gcc/faq.html#bugreport> for instructions.", \ - __PRETTY_FUNCTION__, trim_filename (__FILE__), __LINE__) + "See %s for instructions.", \ + __PRETTY_FUNCTION__, trim_filename (__FILE__), __LINE__, GCCBUGURL) #endif /* recent gcc */ /* trim_filename is in toplev.c. Define a stub macro for files that diff --git a/gnu/egcs/gcc/testsuite/ChangeLog b/gnu/egcs/gcc/testsuite/ChangeLog index b37ee29cc0a..64ec141af16 100644 --- a/gnu/egcs/gcc/testsuite/ChangeLog +++ b/gnu/egcs/gcc/testsuite/ChangeLog @@ -1,3 +1,23 @@ +Sun Oct 24 23:54:10 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95.2 Released. + +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95.1 Released. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 23:40:51 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 21:41:37 1999 Jeffrey A Law (law@cygnus.com) + + * README: More listname related changes. + 1999-06-05 Craig Burley <craig@jcb-sc.com> * g77.f-torture/compile/19990502-0.f: Replace with new, diff --git a/gnu/egcs/gcc/testsuite/README b/gnu/egcs/gcc/testsuite/README index 2b336f5b29d..7d064730daf 100644 --- a/gnu/egcs/gcc/testsuite/README +++ b/gnu/egcs/gcc/testsuite/README @@ -13,8 +13,8 @@ developers. These tests are included "as is". If any of them fails, do not report a bug. Bug reports for DejaGnu can go to bug-dejagnu@prep.ai.mit.edu. Discussion and comments about this testsuite should be sent to -egcs@egcs.cygnus.com; additions and changes to should go to sent to -egcs-patches@egcs.cygnus.com. +gcc@gcc.gnu.org; additions and changes to should go to sent to +gcc-patches@gcc.gnu.org. The entire testsuite is invoked by `make check` at the top level of the EGCS tree. `make check-g++` runs the C++ testsuite only. @@ -41,7 +41,7 @@ the following structure: g++.other g++.pt Tests for templates g++.rfg - g++.robertl Tests from egcs-bugs@egcs.cygnus.com, gathered by Robert Lipe + g++.robertl Tests from gcc-bugs@gcc.gnu.org, gathered by Robert Lipe g++.old-deja uses a fixed driver for all g++ tests based on the old DejaGnu drivers. But just because its old, doesn't mean its redundant! diff --git a/gnu/egcs/gcc/unroll.c b/gnu/egcs/gcc/unroll.c index d6dbcf0fbc1..376bc996678 100644 --- a/gnu/egcs/gcc/unroll.c +++ b/gnu/egcs/gcc/unroll.c @@ -3682,10 +3682,14 @@ loop_iterations (loop_start, loop_end, loop_info) return 0; } - /* The only new registers that care created before loop iterations are - givs made from biv increments, so this should never occur. */ - - if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements) + /* The only new registers that are created before loop iterations + are givs made from biv increments or registers created by + load_mems. In the latter case, it is possible that try_copy_prop + will propagate a new pseudo into the old iteration register but + this will be marked by having the REG_USERVAR_P bit set. */ + + if ((unsigned) REGNO (iteration_var) >= reg_iv_type->num_elements + && ! REG_USERVAR_P (iteration_var)) abort (); iteration_info (iteration_var, &initial_value, &increment, |