# Copyright (C) 1992-2021 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
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# This file was written by Rob Savoye (rob@cygnus.com)
# Currently maintained by Doug Evans (dje@cygnus.com)

# This file is loaded by the tool init file (eg: unix.exp).  It provides
# default definitions for gcc_start, etc. and other supporting cast members.

# These globals are used by gcc_start if no compiler arguments are provided.
# They are also used by the various testsuites to define the environment:
# where to find stdio.h, libc.a, etc.

# we want to use libgloss so we can get find_gcc.
load_lib libgloss.exp
load_lib prune.exp
load_lib gcc-defs.exp
load_lib timeout.exp

#
# GCC_UNDER_TEST is the compiler under test.
#

#
# default_gcc_version -- extract and print the version number of the compiler
#

proc default_gcc_version { } {
    global GCC_UNDER_TEST

    gcc_init

    # ignore any arguments after the command
    set compiler [lindex $GCC_UNDER_TEST 0]

    if ![is_remote host] {
	set compiler_name [which $compiler]
    } else {
	set compiler_name $compiler
    }

    # verify that the compiler exists
    if { $compiler_name != 0 } then {
	set tmp [remote_exec host "$compiler -v"]
	set status [lindex $tmp 0]
	set output [lindex $tmp 1]
	regexp " version \[^\n\r\]*" $output version
	if { $status == 0 && [info exists version] } then {
	    clone_output "$compiler_name $version\n"
	} else {
	    clone_output "Couldn't determine version of $compiler_name: $output\n"
	}
    } else {
	# compiler does not exist (this should have already been detected)
	warning "$compiler does not exist"
    }
}

#
# gcc_version -- Call default_gcc_version, so we can override it if needed.
#

proc gcc_version { } {
    default_gcc_version
}

#
# gcc_init -- called at the start of each .exp script.
#
# There currently isn't much to do, but always using it allows us to
# make some enhancements without having to go back and rewrite the scripts.
#

set gcc_initialized 0

proc gcc_init { args } {
    global tmpdir
    global libdir
    global gluefile wrap_flags
    global gcc_initialized
    global GCC_UNDER_TEST
    global TOOL_EXECUTABLE
    global gcc_warning_prefix
    global gcc_error_prefix

    if { $gcc_initialized == 1 } { return; }

    if ![info exists GCC_UNDER_TEST] {
	if [info exists TOOL_EXECUTABLE] {
	    set GCC_UNDER_TEST $TOOL_EXECUTABLE
	} else {
	    set GCC_UNDER_TEST "[find_gcc]"
	}
    }

    if ![info exists tmpdir] then {
	set tmpdir /tmp
    }

    set gcc_warning_prefix "warning:"
    set gcc_error_prefix "(fatal )?error:"

    gcc_maybe_build_wrapper "${tmpdir}/gcc-testglue.o"
}

#
# gcc_target_compile -- compile a source file
#

proc gcc_target_compile { source dest type options } {
    global tmpdir
    global gluefile wrap_flags
    global GCC_UNDER_TEST
    global TOOL_OPTIONS
    global TEST_ALWAYS_FLAGS
    global flags_to_postpone
    global board_info

    if {[target_info needs_status_wrapper] != "" && \
	    [target_info needs_status_wrapper] != "0" && \
	    [info exists gluefile] } {
	lappend options "libs=${gluefile}"
	lappend options "ldflags=$wrap_flags"
	if { $type == "executable" } {
	    set options [concat "{additional_flags=-dumpbase \"\"}" $options]
	}
    }

    global TEST_EXTRA_LIBS
    if [info exists TEST_EXTRA_LIBS] {
	lappend options "ldflags=$TEST_EXTRA_LIBS"
    }

    # TEST_ALWAYS_FLAGS are flags that should be passed to every
    # compilation.  They are passed first to allow individual
    # tests to override them.
    if [info exists TEST_ALWAYS_FLAGS] {
	set options [concat "{additional_flags=$TEST_ALWAYS_FLAGS}" $options]
    }

    # TOOL_OPTIONS must come first, so that it doesn't override testcase
    # specific options.
    if [info exists TOOL_OPTIONS] {
	set options [concat "{additional_flags=$TOOL_OPTIONS}" $options]
    }

    # bind_pic_locally adds -fpie/-fPIE flags to flags_to_postpone and it is
    # appended here to multilib_flags as it can be overridden by the latter
    # if it was added earlier. After the target_compile, multilib_flags is
    # restored to its orignal content.
    set tboard [target_info name]
    if {[board_info $tboard exists multilib_flags]} {
        set orig_multilib_flags "[board_info [target_info name] multilib_flags]"
        append board_info($tboard,multilib_flags) " $flags_to_postpone"
    }

    lappend options "timeout=[timeout_value]"
    lappend options "compiler=$GCC_UNDER_TEST"
    set options [dg-additional-files-options $options $source]
    set return_val [target_compile $source $dest $type $options]

    if {[board_info $tboard exists multilib_flags]} {
        set board_info($tboard,multilib_flags) $orig_multilib_flags
        set flags_to_postpone ""
    }

    return $return_val
}

