[PING2/rfa/testsuite] compiler.exp: rewrite get_compiler_info

Michael Elizabeth Chastain
2004-01-24T07:25:27Z

[Ping ... submitted 2004-01-13 ... submitted 2004-01-06 ...]

This is a new implementation of get_compiler_info.

The current get_compiler_info does not work correctly on HP-UX 11, which
has separate compilers for C++ and Ansi C. get_compiler_info always
uses the Ansi C compiler, even when testing for C++. This works for
unified compilers like gcc but not for separate compilers such as
/opt/ansic/bin/cc and /opt/aCC/bin/aCC.

Also, the current implementation has two strategies:

[gdb_compile -E compiler.c -o foo.ci]
source foo.ci

This is used on all targets except hppa*-*-hpux* and mips*-*-irix*.
This is a gcc extension; Single Unix Spec specifically says that the
behavior of "-E" and "-o" together are not specified. This gcc
extension does not work with HP-UX compilers.

[remote_exec $compiler -E compiler.c > foo.ci]
source foo.ci

This is used on targets hppa*-hp-hpux* and mips*-*-irix*. This
conforms to SuS and is portable. But it does not use
[target_compile] because of the output redirection, so it's really
only suitable for build == host (unless we execute code in dejagnu
that we've never executed before). More immediately, this strategy
makes its own attempt to figure out the language compiler and gets
it wrong. That's screwing me on HP-UX.

Also, the current implementation calls "what $blah" to figure out if the
compiler is HP-UX Ansi C, and it's a mess where $blah really comes from.
Especially when my compiler is actually a shell script named "gcc" that
invokes the real compiler. I killed that and just added more
preprocessor tests to compiler.c and compiler.cc.

To import the preprocessor defines into TCL, I just do this:

set cppout [ gdb_compile "${ifile} "" preprocess [list "$args" quiet] ]
eval "$cppout"

Well, it's more lines than that, but that's the idea. There is no more
foo.ci file. I just capture the standard output and eval it.

The drawback is that the output of "gcc -E ..." winds up in gdb.log.
Twice. (dejagnu turns on output logging, and then sends copies of the
captured output to the log also). I fixed that by toggling the log
file at the expect level.

I also deleted some HP Fortran logic which was completely unused.

"gdb_preprocess" and "get_compiler" went to the dead proc cemetery.

There were some weird "uplevel \#0" qualifiers that don't need to be
qualified. I took some of these out, but I left some of them in (the
ones for "$true" and "$false").

I think this is a lot simpler and more portable than the old code.

Tested on:

native i686-pc-linux-gnu, gcc 2.95.3, 3.2.2, HEAD, dwarf-2 and stabs+
native hppa2.0w-hp-hpux11.11 with HP C B.11.11.28706.GP
native hppa2.0w-hp-hpux11.11 with HP aC++ B3910B A.03.45

I'm particularly interested if Mark K could test this with
a native Solaris compiler (not gcc).

Okay to commit?

Michael C

2004-01-06 Michael Chastain <mec.gnu@mindspring.com>

* lib/compiler.c: Add hp_cc_compiler and hp_aCC_compiler.
* lib/compiler.cc: Likewise.
* lib/gdb.exp (get_compiler_info): Always call gdb_compile to
get the right preprocessor. Eval the output directly. Remove
special tests for hp_cc_compiler and hp_aCC_compiler. Remove
hp_f77_compiler and hp_f90_compiler completely.
(gdb_preprocess): Delete.
(get_compiler): Delete.

Index: lib/compiler.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/compiler.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 compiler.c
*** lib/compiler.c 17 Nov 2003 15:00:20 -0000 1.2
--- lib/compiler.c 6 Jan 2004 20:42:57 -0000
***************
*** 1,6 ****
/* This test file is part of GDB, the GNU debugger.

! Copyright 1995, 1997, 1999, 2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,6 ----
/* This test file is part of GDB, the GNU debugger.

! Copyright 1995, 1997, 1999, 2003, 2004 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
***************
*** 19,54 ****
Please email any bugs, comments, and/or additions to this file to:
bug-gdb@prep.ai.mit.edu */

! /* Often the behavior of any particular test depends upon what compiler was
! used to compile the test. As each test is compiled, this file is
! preprocessed by the same compiler used to compile that specific test
! (different tests might be compiled by different compilers, particularly
! if compiled at different times), and used to generate a *.ci (compiler
! info) file for that test.
!
! I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
! which can then be sourced by callfuncs.exp to give callfuncs.exp access
! to information about the compilation environment.
!
! TODO: It might be a good idea to add expect code that tests each
! definition made with 'set" to see if one already exists, and if so
! warn about conflicts if it is being set to something else. */

! /* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info).
! If this ends up being hairy, we could use a common header file. */

! #if defined (__STDC__) || defined (_AIX)
! set signed_keyword_not_used 0
! #else
! set signed_keyword_not_used 1
! #endif

#if defined (__GNUC__)
- set gcc_compiled __GNUC__
set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -]
#else
set gcc_compiled 0
- set compiler_info ""
#endif

! return 0
--- 19,65 ----
Please email any bugs, comments, and/or additions to this file to:
bug-gdb@prep.ai.mit.edu */

! /* Sometimes the behavior of a test depends upon the compiler used to
! compile the test program. A test script can call get_compiler_info
! to figure out the compiler version and test_compiler_info to test it.

! get_compiler_info runs the preprocessor on this file and then eval's
! the result. This sets various symbols for use by test_compiler_info.

! TODO: make compiler_info a local variable for get_compiler_info and
! test_compiler_info.
!
! TODO: all clients should use test_compiler_info and should not
! use gcc_compiled, hp_cc_compiler, or hp_aCC_compiler.
!
! TODO: purge signed_keyword_not_used. */
!
! set compiler_info ""

#if defined (__GNUC__)
set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -]
+ set gcc_compiled __GNUC__
#else
set gcc_compiled 0
#endif

! #if defined (__HP_cc)
! set compiler_info [join {hpcc __HP_cc} -]
! set hp_cc_compiler __HP_cc
! #else
! set hp_cc_compiler 0
! #endif
!
! #if defined (__HP_aCC)
! set compiler_info [join {hpacc __HP_aCC} -]
! set hp_aCC_compiler __HP_aCC
! #else
! set hp_aCC_compiler 0
! #endif
!
! /* gdb.base/whatis.exp still uses this */
! #if defined (__STDC__) || defined (_AIX)
! set signed_keyword_not_used 0
! #else
! set signed_keyword_not_used 1
! #endif
Index: lib/compiler.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/compiler.cc,v
retrieving revision 1.4
diff -c -3 -p -r1.4 compiler.cc
*** lib/compiler.cc 2 Jan 2004 23:20:51 -0000 1.4
--- lib/compiler.cc 6 Jan 2004 20:42:57 -0000
***************
*** 19,45 ****
Please email any bugs, comments, and/or additions to this file to:
bug-gdb@prep.ai.mit.edu */

! /* Often the behavior of any particular test depends upon what compiler was
! used to compile the test. As each test is compiled, this file is
! preprocessed by the same compiler used to compile that specific test
! (different tests might be compiled by different compilers, particularly
! if compiled at different times), and used to generate a *.ci (compiler
! info) file for that test.

! I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
! which can then be sourced by callfuncs.exp to give callfuncs.exp access
! to information about the compilation environment.
!
! TODO: It might be a good idea to add expect code that tests each
! definition made with 'set" to see if one already exists, and if so
! warn about conflicts if it is being set to something else. */

#if defined (__GNUC__)
- set gcc_compiled __GNUC__
set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -]
#else
set gcc_compiled 0
- set compiler_info ""
#endif

! return 0
--- 19,53 ----
Please email any bugs, comments, and/or additions to this file to:
bug-gdb@prep.ai.mit.edu */

! /* This file is exactly like compiler.c. I could just use compiler.c if
! I could be sure that every C++ compiler accepted extensions of ".c". */

! set compiler_info ""

#if defined (__GNUC__)
set compiler_info [join {gcc __GNUC__ __GNUC_MINOR__ } -]
+ set gcc_compiled __GNUC__
#else
set gcc_compiled 0
#endif

! #if defined (__HP_cc)
! set compiler_info [join {hpcc __HP_cc} -]
! set hp_cc_compiler __HP_cc
! #else
! set hp_cc_compiler 0
! #endif
!
! #if defined (__HP_aCC)
! set compiler_info [join {hpacc __HP_aCC} -]
! set hp_aCC_compiler __HP_aCC
! #else
! set hp_aCC_compiler 0
! #endif
!
! /* gdb.base/whatis.exp still uses this */
! #if defined (__STDC__) || defined (_AIX)
! set signed_keyword_not_used 0
! #else
! set signed_keyword_not_used 1
! #endif
Index: lib/gdb.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/lib/gdb.exp,v
retrieving revision 1.41
diff -c -3 -p -r1.41 gdb.exp
*** lib/gdb.exp 23 Nov 2003 01:09:19 -0000 1.41
--- lib/gdb.exp 6 Jan 2004 20:42:58 -0000
***************
*** 1,5 ****
# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
! # 2002, 2003
# Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
--- 1,5 ----
# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
! # 2002, 2003, 2004
# Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
*************** proc skip_hp_tests {} {
*** 1094,1179 ****
return $skip_hp
}

! global compiler_info
! set compiler_info unknown

proc get_compiler_info {binfile args} {
! # Create and source the file that provides information about the compiler
! # used to compile the test case.
! # Compiler_type can be null or c++. If null we assume c.
global srcdir
! global subdir
! # These two come from compiler.c.
! global signed_keyword_not_used
! global gcc_compiled
global compiler_info

! if {![istarget "hppa*-*-hpux*"] && ![istarget "mips*-*-irix*"]} {
! if { [llength $args] > 0 } {
! if {$args == "c++"} {
! if { [gdb_compile "${srcdir}/lib/compiler.cc" "${binfile}.ci" preprocess {}] != "" } {
! perror "Couldn't make ${binfile}.ci file"
! return 1;
! }
! }
! } else {
! if { [gdb_compile "${srcdir}/lib/compiler.c" "${binfile}.ci" preprocess {}] != "" } {
! perror "Couldn't make ${binfile}.ci file"
! return 1;
! }
! }
! } else {
! if { [llength $args] > 0 } {
! if {$args == "c++"} {
! if { [eval gdb_preprocess \
! [list "${srcdir}/lib/compiler.cc" "${binfile}.ci"] \
! $args] != "" } {
! perror "Couldn't make ${binfile}.ci file"
! return 1;
! }
! }
! } elseif { $args != "f77" } {
! if { [eval gdb_preprocess \
! [list "${srcdir}/lib/compiler.c" "${binfile}.ci"] \
! $args] != "" } {
! perror "Couldn't make ${binfile}.ci file"
! return 1;
! }
! }
}
-
- uplevel \#0 { set gcc_compiled 0 }

! if { [llength $args] == 0 || $args != "f77" } {
! source ${binfile}.ci
}

# Most compilers will evaluate comparisons and other boolean
# operations to 0 or 1.
uplevel \#0 { set true 1 }
uplevel \#0 { set false 0 }

! uplevel \#0 { set hp_cc_compiler 0 }
! uplevel \#0 { set hp_aCC_compiler 0 }
! uplevel \#0 { set hp_f77_compiler 0 }
! uplevel \#0 { set hp_f90_compiler 0 }
! if { !$gcc_compiled && [istarget "hppa*-*-hpux*"] } {
! # Check for the HP compilers
! set compiler [lindex [split [get_compiler $args] " "] 0]
! catch "exec what $compiler" output
! if [regexp ".*HP aC\\+\\+.*" $output] {
! uplevel \#0 { set hp_aCC_compiler 1 }
! # Use of aCC results in boolean results being displayed as
! # "true" or "false"
! uplevel \#0 { set true true }
! uplevel \#0 { set false false }
! } elseif [regexp ".*HP C Compiler.*" $output] {
! uplevel \#0 { set hp_cc_compiler 1 }
! } elseif [regexp ".*HP-UX f77.*" $output] {
! uplevel \#0 { set hp_f77_compiler 1 }
! } elseif [regexp ".*HP-UX f90.*" $output] {
! uplevel \#0 { set hp_f90_compiler 1 }
! }
}

return 0;
--- 1094,1207 ----
return $skip_hp
}

! set compiler_info "unknown"
! set gcc_compiled 0
! set hp_cc_compiler 0
! set hp_aCC_compiler 0
! set signed_keyword_not_used 0
!
! # Figure out what compiler I am using.
! #
! # BINFILE is a "compiler information" output file. This implementation
! # does not use BINFILE.
! #
! # ARGS can be empty or "C++". If empty, "C" is assumed.
! #
! # There are several ways to do this, with various problems.
! #
! # [ gdb_compile -E $ifile -o $binfile.ci ]
! # source $binfile.ci
! #
! # Single Unix Spec v3 says that "-E -o ..." together are not
! # specified. And in fact, the native compiler on hp-ux 11 (among
! # others) does not work with "-E -o ...". Most targets used to do
! # this, and it mostly worked, because it works with gcc.
! #
! # [ catch "exec $compiler -E $ifile > $binfile.ci" exec_output ]
! # source $binfile.ci
! #
! # This avoids the problem with -E and -o together. This almost works
! # if the build machine is the same as the host machine, which is
! # usually true of the targets which are not gcc. But this code does
! # not figure which compiler to call, and it always ends up using the C
! # compiler. Not good for setting hp_aCC_compiler. Targets
! # hppa*-*-hpux* and mips*-*-irix* used to do this.
! #
! # [ gdb_compile -E $ifile > $binfile.ci ]
! # source $binfile.ci
! #
! # dejagnu target_compile says that it supports output redirection,
! # but the code is completely different from the normal path and I
! # don't want to sweep the mines from that path. So I didn't even try
! # this.
! #
! # set cppout [ gdb_compile $ifile "" preprocess $args quiet ]
! # eval $cppout
! #
! # I actually do this for all targets now. gdb_compile runs the right
! # compiler, and TCL captures the output, and I eval the output.
! #
! # Unfortunately, expect logs the output of the command as it goes by,
! # and dejagnu helpfully prints a second copy of it right afterwards.
! # So I turn off expect logging for a moment.
! #
! # [ gdb_compile $ifile $ciexe_file executable $args ]
! # [ remote_exec $ciexe_file ]
! # [ source $ci_file.out ]
! #
! # I could give up on -E and just do this.
! # I didn't get desperate enough to try this.
! #
! # -- chastain 2004-01-06

proc get_compiler_info {binfile args} {
! # For compiler.c and compiler.cc
global srcdir
!
! # I am going to play with the log to keep noise out.
! global outdir
! global tool
!
! # These come from compiler.c or compiler.cc
global compiler_info
+ global gcc_compiled
+ global hp_cc_compiler
+ global hp_aCC_compiler
+ global signed_keyword_not_used

! # Choose which file to preprocess.
! set ifile "${srcdir}/lib/compiler.c"
! if { [llength $args] > 0 && [lindex $args 0] == "c++" } {
! set ifile "${srcdir}/lib/compiler.cc"
}

! # Run $ifile through the right preprocessor.
! # Toggle gdb.log to keep the compiler output out of the log.
! log_file
! set cppout [ gdb_compile "${ifile}" "" preprocess [list "$args" quiet] ]
! log_file -a "$outdir/$tool.log"
!
! # Source the output.
! foreach cppline [ split "$cppout" "\n" ] {
! if { ! [ regexp "^#" "$cppline" ] } {
! if { ! [ regexp "^\[\n\r\t \]*$" "$cppline" ] } {
! verbose "get_compiler_info: $cppline" 2
! eval "$cppline"
! }
! }
}
+ verbose -log "get_compiler_info: $compiler_info"

# Most compilers will evaluate comparisons and other boolean
# operations to 0 or 1.
uplevel \#0 { set true 1 }
uplevel \#0 { set false 0 }

! # Use of aCC results in boolean results being displayed as
! # "true" or "false"
! if { $hp_aCC_compiler } {
! uplevel \#0 { set true true }
! uplevel \#0 { set false false }
}

return 0;
*************** proc get_compiler_info {binfile args} {
*** 1182,1266 ****
proc test_compiler_info { compiler } {
global compiler_info
return [string match $compiler $compiler_info]
- }
-
- proc get_compiler {args} {
- global CC CC_FOR_TARGET CXX CXX_FOR_TARGET F77_FOR_TARGET
-
- if { [llength $args] == 0
- || ([llength $args] == 1 && [lindex $args 0] == "") } {
- set which_compiler "c"
- } else {
- if { $args =="c++" } {
- set which_compiler "c++"
- } elseif { $args =="f77" } {
- set which_compiler "f77"
- } else {
- perror "Unknown compiler type supplied to gdb_preprocess"
- return ""
- }
- }
-
- if [info exists CC_FOR_TARGET] {
- if {$which_compiler == "c"} {
- set compiler $CC_FOR_TARGET
- }
- }
-
- if [info exists CXX_FOR_TARGET] {
- if {$which_compiler == "c++"} {
- set compiler $CXX_FOR_TARGET
- }
- }
-
- if [info exists F77_FOR_TARGET] {
- if {$which_compiler == "f77"} {
- set compiler $F77_FOR_TARGET
- }
- }
-
- if { ![info exists compiler] } {
- if { $which_compiler == "c" } {
- if {[info exists CC]} {
- set compiler $CC
- }
- }
- if { $which_compiler == "c++" } {
- if {[info exists CXX]} {
- set compiler $CXX
- }
- }
- if {![info exists compiler]} {
- set compiler [board_info [target_info name] compiler];
- if { $compiler == "" } {
- perror "get_compiler: No compiler found"
- return ""
- }
- }
- }
-
- return $compiler
- }
-
- proc gdb_preprocess {source dest args} {
- set compiler [get_compiler "$args"]
- if { $compiler == "" } {
- return 1
- }
-
- set cmdline "$compiler -E $source > $dest"
-
- verbose "Invoking $compiler -E $source > $dest"
- verbose -log "Executing on local host: $cmdline" 2
- set status [catch "exec ${cmdline}" exec_output]
-
- set result [prune_warnings $exec_output]
- regsub "\[\r\n\]*$" "$result" "" result;
- regsub "^\[\r\n\]*" "$result" "" result;
- if { $result != "" } {
- clone_output "gdb compile failed, $result"
- }
- return $result;
}

set gdb_wrapper_initialized 0
--- 1210,1215 ----