# Copyright (C) 2003, 2007, 2008 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/>.

load_lib copy-file.exp

proc dg-pch { subdir test options suffix } {
    global runtests dg-do-what-default

    # If we're only testing specific files and this isn't one of them, skip it.
    if ![runtest_file_p $runtests $test] {
	return
    }
    set nshort "$subdir/[file tail $test]"
    set bname "[file rootname [file tail $nshort]]"

    catch { file_on_host delete "$bname$suffix.gch" }
    catch { file_on_host delete "$bname.s" }
    catch { file_on_host delete "$bname.s-gch" }

    # We don't try to use the loop-optimizing options, since they are highly
    # unlikely to make any difference to PCH.
    foreach flags $options {
	verbose "Testing $nshort, $flags" 1

	# For the header files, the default is to precompile.
	set dg-do-what-default precompile
	catch { file_on_host delete "$bname$suffix" }
	gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix"
	dg-test -keep-output "./$bname$suffix" $flags ""

	# For the rest, the default is to compile to .s.
	set dg-do-what-default compile

	set have_errs [llength [grep $test "{\[ \t\]\+dg-error\[ \t\]\+.*\[ \t\]\+}"]]

	if { [ file_on_host exists "$bname$suffix.gch" ] } {
	    # Ensure that the PCH file is used, not the original header.
	    file_on_host delete "$bname$suffix"

	    dg-test -keep-output $test "$flags -I." ""
	    file_on_host delete "$bname$suffix.gch"
	    if { !$have_errs } {
		if { [ file_on_host exists "$bname.s" ] } {
		    remote_upload host "$bname.s" "$bname.s-gch"
		    remote_download host "$bname.s-gch"
		    gcc_copy_files "[file rootname $test]${suffix}s" "$bname$suffix"
		    dg-test -keep-output $test $flags "-I."
		    remote_upload host "$bname.s"
		    set tmp [ diff "$bname.s" "$bname.s-gch" ]
		    if { $tmp == 0 } {
			verbose -log "assembly file '$bname.s', '$bname.s-gch' comparison error"
			fail "$nshort $flags assembly comparison"
		    } elseif { $tmp == 1 } {
			pass "$nshort $flags assembly comparison"
		    } else {
			fail "$nshort $flags assembly comparison"
		    }
		    file_on_host delete "$bname$suffix"
		    file_on_host delete "$bname.s"
		    file_on_host delete "$bname.s-gch"
		} else {
		    verbose -log "assembly file '$bname.s' missing"
 		    fail "$nshort $flags assembly comparison"
		}
	    }
	} else {
	    verbose -log "pch file '$bname$suffix.gch' missing"
	    fail "$nshort $flags"
	    if { !$have_errs } {
		verbose -log "assembly file '$bname.s' missing" 1
		fail "$nshort $flags assembly comparison"
	    }
	}
    }
}
