#=============================================================================
# Copyright Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================

# Keep test binaries away from main binaries.
unset(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
unset(CMAKE_LIBRARY_OUTPUT_DIRECTORY)
unset(CMAKE_ARCHIVE_OUTPUT_DIRECTORY)

find_package(LibXml2 QUIET)

macro(castxml_test_cmd test)
  set(command $<TARGET_FILE:castxml> ${ARGN})
  set(_castxml_expect ${castxml_test_cmd_expect} cmd.${test})
  add_test(
    NAME cmd.${test}
    COMMAND ${CMAKE_COMMAND}
    "-Dcommand:STRING=${command}"
    "-Dexpect=${_castxml_expect}"
    ${castxml_test_cmd_extra_arguments}
    -P ${CMAKE_CURRENT_SOURCE_DIR}/run.cmake
    )
endmacro()

macro(castxml_test_output_common prefix ext std test)
  if(DEFINED castxml_test_output_custom_start)
    set(_castxml_start ${castxml_test_output_custom_start})
  else()
    set(_castxml_start --castxml-start start)
  endif()
  if(castxml_test_output_custom_input)
    set(_castxml_input ${castxml_test_output_custom_input})
  else()
    set(_castxml_input ${test})
  endif()
  set(_castxml_expect ${prefix}.${std}.${test})
  if("${std}" MATCHES "^gnu(.*)$")
    list(APPEND _castxml_expect ${prefix}.c${CMAKE_MATCH_1}.${test})
  endif()
  if("${std}" MATCHES "^(c|gnu)[^+]")
    list(APPEND _castxml_expect ${prefix}.c.${test})
  endif()
  list(APPEND _castxml_expect ${prefix}.any.${test})

  if ("${prefix}" MATCHES "^gccxml(.*)$")
    set(flag --castxml-gccxml)
  elseif ("${prefix}" MATCHES "^castxml1(.*)$")
    set(flag --castxml-output=1)
  endif()

  set(std_flag -std=${std})
  if(LLVM_VERSION_MAJOR VERSION_LESS 5)
    if("${std_flag}" MATCHES "^(.*)17$")
      set(std_flag "${CMAKE_MATCH_1}1z")
    endif()
  endif()

  set(command $<TARGET_FILE:castxml>
    ${flag}
    ${_castxml_start}
    ${std_flag}
    ${CMAKE_CURRENT_LIST_DIR}/input/${_castxml_input}.${ext}
    -o ${prefix}.${std}.${test}.xml
    ${castxml_test_output_extra_arguments}
    )
  add_test(
    NAME ${prefix}.${std}.${test}
    COMMAND ${CMAKE_COMMAND}
    "-Dcommand:STRING=${command}"
    "-Dexpect=${_castxml_expect}"
    "-Dxml=${prefix}.${std}.${test}.xml"
    "-Dxmllint=${LIBXML2_XMLLINT_EXECUTABLE}"
    -P ${CMAKE_CURRENT_SOURCE_DIR}/run.cmake
    )
endmacro()

macro(castxml_test_output_c89 test)
  castxml_test_output_common(gccxml c c89 ${test})
  castxml_test_output_common(castxml1 c c89 ${test})
endmacro()

macro(castxml_test_output_c99 test)
  castxml_test_output_common(gccxml c c99 ${test})
  castxml_test_output_common(castxml1 c c99 ${test})
endmacro()

macro(castxml_test_output_c11 test)
  castxml_test_output_common(gccxml c c11 ${test})
  castxml_test_output_common(castxml1 c c11 ${test})
endmacro()

macro(castxml_test_output_gnu89 test)
  castxml_test_output_common(gccxml c gnu89 ${test})
  castxml_test_output_common(castxml1 c gnu89 ${test})
endmacro()

macro(castxml_test_output_gnu99 test)
  castxml_test_output_common(gccxml c gnu99 ${test})
  castxml_test_output_common(castxml1 c gnu99 ${test})
endmacro()

macro(castxml_test_output_gnu11 test)
  castxml_test_output_common(gccxml c gnu11 ${test})
  castxml_test_output_common(castxml1 c gnu11 ${test})
endmacro()

macro(castxml_test_output_cxx98 test)
  castxml_test_output_common(gccxml cxx c++98 ${test})
  castxml_test_output_common(castxml1 cxx c++98 ${test})
endmacro()

macro(castxml_test_output_gnuxx98 test)
  castxml_test_output_common(gccxml cxx gnu++98 ${test})
  castxml_test_output_common(castxml1 cxx gnu++98 ${test})
endmacro()

macro(castxml_test_output_cxx11 test)
  castxml_test_output_common(gccxml cxx c++11 ${test})
  castxml_test_output_common(castxml1 cxx c++11 ${test})
endmacro()

macro(castxml_test_output_gnuxx11 test)
  castxml_test_output_common(gccxml cxx gnu++11 ${test})
  castxml_test_output_common(castxml1 cxx gnu++11 ${test})
endmacro()

macro(castxml_test_output_cxx14 test)
  castxml_test_output_common(gccxml cxx c++14 ${test})
  castxml_test_output_common(castxml1 cxx c++14 ${test})
endmacro()

macro(castxml_test_output_gnuxx14 test)
  castxml_test_output_common(gccxml cxx gnu++14 ${test})
  castxml_test_output_common(castxml1 cxx gnu++14 ${test})
endmacro()

macro(castxml_test_output_cxx17 test)
  castxml_test_output_common(gccxml cxx c++17 ${test})
  castxml_test_output_common(castxml1 cxx c++17 ${test})
endmacro()

macro(castxml_test_output_gnuxx17 test)
  castxml_test_output_common(gccxml cxx gnu++17 ${test})
  castxml_test_output_common(castxml1 cxx gnu++17 ${test})
endmacro()

macro(castxml_test_output_broken_cxx98 test)
  castxml_test_output_common(gccxml.broken cxx c++98 ${test})
  castxml_test_output_common(castxml1.broken cxx c++98 ${test})
endmacro()

macro(castxml_test_output_broken_gnuxx98 test)
  castxml_test_output_common(gccxml.broken cxx gnu++98 ${test})
  castxml_test_output_common(castxml1.broken cxx gnu++98 ${test})
endmacro()

macro(castxml_test_output_broken_cxx11 test)
  castxml_test_output_common(gccxml.broken cxx c++11 ${test})
  castxml_test_output_common(castxml1.broken cxx c++11 ${test})
endmacro()

macro(castxml_test_output_broken_gnuxx11 test)
  castxml_test_output_common(gccxml.broken cxx gnu++11 ${test})
  castxml_test_output_common(castxml1.broken cxx gnu++11 ${test})
endmacro()

macro(castxml_test_output_broken_cxx14 test)
  castxml_test_output_common(gccxml.broken cxx c++14 ${test})
  castxml_test_output_common(castxml1.broken cxx c++14 ${test})
endmacro()

macro(castxml_test_output_broken_gnuxx14 test)
  castxml_test_output_common(gccxml.broken cxx gnu++14 ${test})
  castxml_test_output_common(castxml1.broken cxx gnu++14 ${test})
endmacro()

macro(castxml_test_output_broken_cxx17 test)
  castxml_test_output_common(gccxml.broken cxx c++17 ${test})
  castxml_test_output_common(castxml1.broken cxx c++17 ${test})
endmacro()

macro(castxml_test_output_broken_gnuxx17 test)
  castxml_test_output_common(gccxml.broken cxx gnu++17 ${test})
  castxml_test_output_common(castxml1.broken cxx gnu++17 ${test})
endmacro()

macro(castxml_test_output_c test)
  castxml_test_output_c89(${test})
  castxml_test_output_gnu89(${test})
  castxml_test_output_c99(${test})
  castxml_test_output_gnu99(${test})
  castxml_test_output_c11(${test})
  castxml_test_output_gnu11(${test})
endmacro()

macro(castxml_test_output test)
  castxml_test_output_cxx98(${test})
  castxml_test_output_gnuxx98(${test})
  castxml_test_output_cxx11(${test})
  castxml_test_output_gnuxx11(${test})
  castxml_test_output_cxx14(${test})
  castxml_test_output_gnuxx14(${test})
  castxml_test_output_cxx17(${test})
  castxml_test_output_gnuxx17(${test})
endmacro()

macro(castxml_test_output_11 test)
  castxml_test_output_cxx11(${test})
  castxml_test_output_gnuxx11(${test})
  castxml_test_output_cxx14(${test})
  castxml_test_output_gnuxx14(${test})
  castxml_test_output_cxx17(${test})
  castxml_test_output_gnuxx17(${test})
endmacro()

macro(castxml_test_output_14 test)
  castxml_test_output_cxx14(${test})
  castxml_test_output_gnuxx14(${test})
  castxml_test_output_cxx17(${test})
  castxml_test_output_gnuxx17(${test})
endmacro()

macro(castxml_test_output_14below test)
  castxml_test_output_cxx98(${test})
  castxml_test_output_gnuxx98(${test})
  castxml_test_output_cxx11(${test})
  castxml_test_output_gnuxx11(${test})
  castxml_test_output_cxx14(${test})
  castxml_test_output_gnuxx14(${test})
endmacro()

macro(castxml_test_output_broken test)
  castxml_test_output_broken_cxx98(${test})
  castxml_test_output_broken_gnuxx98(${test})
  castxml_test_output_broken_cxx11(${test})
  castxml_test_output_broken_gnuxx11(${test})
  castxml_test_output_broken_cxx14(${test})
  castxml_test_output_broken_gnuxx14(${test})
  castxml_test_output_broken_cxx17(${test})
  castxml_test_output_broken_gnuxx17(${test})
endmacro()

set(input ${CMAKE_CURRENT_LIST_DIR}/input)
set(empty_c ${input}/empty.c)
set(empty_cxx ${input}/empty.cxx)
set(empty_m ${input}/empty.m)
set(empty_mm ${input}/empty.mm)

castxml_test_cmd(help1 -help)
castxml_test_cmd(help2 --help)
castxml_test_cmd(no-arguments)
castxml_test_cmd(version --version)

castxml_test_cmd(cc-missing --castxml-cc-gnu)
castxml_test_cmd(cc-option --castxml-cc-gnu -)
castxml_test_cmd(cc-paren-castxml --castxml-cc-gnu "(" --castxml-cc-msvc ")")
castxml_test_cmd(cc-paren-nested --castxml-cc-gnu "(" "(" ")" ")")
castxml_test_cmd(cc-paren-unbalanced --castxml-cc-gnu "(")
castxml_test_cmd(cc-twice --castxml-cc-msvc cl --castxml-cc-gnu gcc)
castxml_test_cmd(cc-unknown --castxml-cc-unknown cc)

castxml_test_cmd(gccxml-and-E --castxml-gccxml -E)
castxml_test_cmd(castxml-and-E --castxml-output=1 -E)

castxml_test_cmd(gccxml-twice --castxml-gccxml --castxml-gccxml)
castxml_test_cmd(castxml-twice --castxml-output=1 --castxml-output=1)

castxml_test_cmd(castxml-mix1 --castxml-gccxml --castxml-output=1)
castxml_test_cmd(castxml-mix2 --castxml-output=1 --castxml-gccxml)

castxml_test_cmd(castxml-wrong-epic-version --castxml-output=0)

castxml_test_cmd(gccxml-and-c99 --castxml-gccxml -std=c99 ${empty_c})
castxml_test_cmd(castxml-and-c99 --castxml-output=1 -std=c99 ${empty_c})

castxml_test_cmd(gccxml-and-c11 --castxml-gccxml -std=c11 ${empty_c})
castxml_test_cmd(castxml-and-c11 --castxml-output=1 -std=c11 ${empty_c})

castxml_test_cmd(gccxml-and-c++11 --castxml-gccxml -std=c++11 ${empty_cxx})
castxml_test_cmd(castxml-and-c++11 --castxml-output=1 -std=c++11 ${empty_cxx})

castxml_test_cmd(gccxml-and-c++14 --castxml-gccxml -std=c++14 ${empty_cxx})
castxml_test_cmd(castxml-and-c++14 --castxml-output=1 -std=c++14 ${empty_cxx})

if(LLVM_VERSION_MAJOR VERSION_LESS 5)
  castxml_test_cmd(gccxml-and-c++17 --castxml-gccxml -std=c++1z ${empty_cxx})
  castxml_test_cmd(castxml-and-c++17 --castxml-output=1 -std=c++1z ${empty_cxx})
else()
  castxml_test_cmd(gccxml-and-c++17 --castxml-gccxml -std=c++17 ${empty_cxx})
  castxml_test_cmd(castxml-and-c++17 --castxml-output=1 -std=c++17 ${empty_cxx})
endif()

castxml_test_cmd(gccxml-and-objc1 --castxml-gccxml ${empty_m})
castxml_test_cmd(castxml-and-objc1 --castxml-output=1 ${empty_m})

castxml_test_cmd(gccxml-and-objc2 --castxml-gccxml ${empty_mm})
castxml_test_cmd(castxml-and-objc2 --castxml-output=1 ${empty_mm})

castxml_test_cmd(gccxml-empty-c++98 --castxml-gccxml -std=c++98 ${empty_cxx})
castxml_test_cmd(castxml-empty-c++98 --castxml-output=1 -std=c++98 ${empty_cxx})

castxml_test_cmd(gccxml-empty-c++98-E --castxml-gccxml -std=c++98 ${empty_cxx} -E)
castxml_test_cmd(castxml-empty-c++98-E --castxml-output=1 -std=c++98 ${empty_cxx} -E)

castxml_test_cmd(gccxml-empty-c++98-c --castxml-gccxml -std=c++98 ${empty_cxx} -c)
castxml_test_cmd(castxml-empty-c++98-c --castxml-output=1 -std=c++98 ${empty_cxx} -c)

castxml_test_cmd(std-c++98-src-c -std=c++98 ${empty_c})
castxml_test_cmd(std-c89-src-cxx -std=c89 ${empty_cxx})
castxml_test_cmd(input-missing ${input}/does-not-exist.c)
castxml_test_cmd(o-missing -o)
castxml_test_cmd(start-missing --castxml-start)
castxml_test_cmd(rsp-empty @${input}/empty.rsp)
castxml_test_cmd(rsp-missing @${input}/does-not-exist.rsp)
castxml_test_cmd(rsp-o-missing @${input}/o-missing.rsp)

# Test predefined macros when not using --castxml-cc-<id>.
configure_file(expect/cmd.predefined-macros.stdout.txt.in
               expect/cmd.predefined-macros.stdout.txt @ONLY)
set(castxml_test_cmd_expect ${CMAKE_CURRENT_BINARY_DIR}/expect/cmd.predefined-macros)
castxml_test_cmd(gccxml-predefined-macros --castxml-gccxml ${empty_cxx} -E -dM)
castxml_test_cmd(castxml-predefined-macros --castxml-output=1 ${empty_cxx} -E -dM)
unset(castxml_test_cmd_expect)
castxml_test_cmd(castxml-predefined-c ${input}/predefined.c)
castxml_test_cmd(castxml-predefined-cxx ${input}/predefined.cxx)

# Test --castxml-cc-gnu detection.
add_executable(cc-gnu cc-gnu.c)
set_property(SOURCE cc-gnu.c APPEND PROPERTY COMPILE_DEFINITIONS
  "TEST_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"")
castxml_test_cmd(cc-gnu-bad-cmd --castxml-cc-gnu cc-gnu-bad-cmd ${empty_cxx})
castxml_test_cmd(cc-gnu-src-c-E --castxml-cc-gnu $<TARGET_FILE:cc-gnu> ${empty_c} -E -dM)
castxml_test_cmd(cc-gnu-src-cxx-E --castxml-cc-gnu $<TARGET_FILE:cc-gnu> ${empty_cxx} -E -dM)
castxml_test_cmd(cc-gnu-src-cxx-cmd --castxml-cc-gnu $<TARGET_FILE:cc-gnu> ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-aarch64 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__aarch64__ ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-amd64 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__amd64__ ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-explicit --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> ")" -target explicit-target-triple ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-i386 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__i386__ ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-i386-opt-E --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__i386__ --cc-define=__OPTIMIZE__ ")" ${empty_cxx} -E -dM)
castxml_test_cmd(cc-gnu-tgt-mingw --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=_WIN32 --cc-define=__MINGW32__ ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-win --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=_WIN32 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-tgt-x86_64 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__x86_64__ ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-c++98 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu>              -ansi ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-c++11 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201103L -ansi ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-c++14 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201402L -ansi ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-gnu++98 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu>              ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-gnu++11 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201103L ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-std-gnu++14 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201402L ")" ${empty_cxx} "-###")
if(LLVM_VERSION_MAJOR VERSION_LESS 5)
  castxml_test_cmd(cc-gnu-std-c++1z --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201703L -ansi ")" ${empty_cxx} "-###")
  castxml_test_cmd(cc-gnu-std-gnu++1z --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201703L ")" ${empty_cxx} "-###")
else()
  castxml_test_cmd(cc-gnu-std-c++1z --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201406L -ansi ")" ${empty_cxx} "-###")
  castxml_test_cmd(cc-gnu-std-c++17 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201703L -ansi ")" ${empty_cxx} "-###")
  castxml_test_cmd(cc-gnu-std-gnu++1z --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201406L ")" ${empty_cxx} "-###")
  castxml_test_cmd(cc-gnu-std-gnu++17 --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201703L ")" ${empty_cxx} "-###")
endif()
castxml_test_cmd(cc-gnu-std-explicit --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=199901L ")" -std=c++14 ${empty_cxx} "-###")
castxml_test_cmd(cc-gnu-c-bad-cmd --castxml-cc-gnu-c "(" cc-gnu-c-bad-cmd ")" ${empty_c})
castxml_test_cmd(cc-gnu-c-src-c-E --castxml-cc-gnu-c $<TARGET_FILE:cc-gnu> ${empty_c} -E -dM)
castxml_test_cmd(cc-gnu-c-src-c-cmd --castxml-cc-gnu-c $<TARGET_FILE:cc-gnu> ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-c89 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu>              -ansi ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-c99 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> -std=199901L -ansi ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-c11 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> -std=201112L -ansi ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-gnu89 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu>              ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-gnu99 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> -std=199901L ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-std-gnu11 --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> -std=201112L ")" ${empty_c} "-###")
castxml_test_cmd(cc-gnu-c-tgt-i386-opt-E --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> --cc-define=__i386__ --cc-define=__OPTIMIZE__ ")" ${empty_c} -E -dM)
castxml_test_cmd(cc-gnu-builtin-unique-object-representations --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> -std=201703L ")" ${input}/has_unique_object_representations.cxx)

# Test --castxml-cc-msvc detection.
add_executable(cc-msvc cc-msvc.c)
set(castxml_test_cmd_extra_arguments "-Dprologue=${CMAKE_CURRENT_SOURCE_DIR}/cc-msvc.cmake")
castxml_test_cmd(cc-msvc-bad-cmd --castxml-cc-msvc cc-msvc-bad-cmd ${empty_cxx})
castxml_test_cmd(cc-msvc-src-c-E --castxml-cc-msvc $<TARGET_FILE:cc-msvc> ${empty_c} -E -dM)
castxml_test_cmd(cc-msvc-src-cxx-E --castxml-cc-msvc $<TARGET_FILE:cc-msvc> ${empty_cxx} -E -dM)
castxml_test_cmd(cc-msvc-src-cxx-cmd --castxml-cc-msvc $<TARGET_FILE:cc-msvc> ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-aarch64 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> --cc-define=_M_ARM64 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-amd64 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> --cc-define=_M_AMD64 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-explicit --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> ")" -target explicit-target-triple ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-i386 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> --cc-define=_M_IX86 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-win --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> --cc-define=_WIN32 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-tgt-x86_64 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> --cc-define=_M_X64 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-std-c++98 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1500 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-std-c++11 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1600 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-std-c++14 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-std-c++17 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 -msvc_lang=201703L ")" ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-std-c++17-E --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 -msvc_lang=201703L -stdcpp_default_new_alignment=16ll ")" ${empty_cxx} -E -dM)
castxml_test_cmd(cc-msvc-std-explicit --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1500 ")" -std=gnu++14 ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-builtin-1800-E --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1800 ")" ${empty_cxx} -E -dM)
castxml_test_cmd(cc-msvc-builtin-1900-E --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 ")" ${empty_cxx} -E -dM)
castxml_test_cmd(cc-msvc-builtin-1900 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 ")" ${input}/make_integer_seq.cxx)
if(";${LLVM_TARGETS_TO_BUILD};" MATCHES ";X86;")
  castxml_test_cmd(cc-msvc-builtin-1923 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1923 --cc-define=_M_X64 ")" ${input}/assume_aligned.cxx)
endif()
castxml_test_cmd(cc-msvc-c-bad-cmd --castxml-cc-msvc-c "(" cc-msvc-c-bad-cmd ")" ${empty_c})
castxml_test_cmd(cc-msvc-c-src-c-E --castxml-cc-msvc-c $<TARGET_FILE:cc-msvc> ${empty_c} -E -dM)
castxml_test_cmd(cc-msvc-c-src-c-cmd --castxml-cc-msvc-c $<TARGET_FILE:cc-msvc> ${empty_c} "-###")
castxml_test_cmd(cc-msvc-c-std-c89 --castxml-cc-msvc-c "(" $<TARGET_FILE:cc-msvc> ")" ${empty_c} "-###")
unset(castxml_test_cmd_extra_arguments)

castxml_test_output(ArrayType)
castxml_test_output(ArrayType-incomplete)
castxml_test_output(Class)
castxml_test_output(Class-abstract)
castxml_test_output(Class-annotate)
castxml_test_output(Class-deprecated)
castxml_test_output(Class-base-offset)
castxml_test_output(Class-base-typedef)
castxml_test_output(Class-bases)
castxml_test_output(Class-forward)
castxml_test_output(Class-friends)
castxml_test_output(Class-implicit-member-access)
castxml_test_output(Class-implicit-member-access-mutable)
castxml_test_output(Class-implicit-member-array)
castxml_test_output(Class-implicit-member-bad-base)
castxml_test_output(Class-implicit-member-const)
castxml_test_output(Class-implicit-member-const-aggregate)
castxml_test_output(Class-implicit-member-reference)
castxml_test_output(Class-implicit-members)
castxml_test_output(Class-incomplete)
castxml_test_output(Class-incomplete-twice)
castxml_test_output(Class-member-Struct-anonymous)
castxml_test_output(Class-member-template)
castxml_test_output(Class-member-template-access)
castxml_test_output(Class-member-Union-anonymous)
castxml_test_output(Class-partial-template-member-Typedef)
castxml_test_output(Class-template)
castxml_test_output(Class-template-Method-Argument-const)
castxml_test_output(Class-template-Method-Argument-default)
castxml_test_output(Class-template-Method-return-const)
castxml_test_output(Class-template-bases)
castxml_test_output(Class-template-constructor-template)
castxml_test_output(Class-template-friends)
castxml_test_output(Class-template-member-nontemplate-Typedef)
castxml_test_output(Class-template-member-Typedef)
castxml_test_output(Class-template-member-Typedef-const)
castxml_test_output(Class-template-member-template)
castxml_test_output(Class-template-recurse)
castxml_test_output(Constructor)
castxml_test_output(Constructor-annotate)
castxml_test_output(Constructor-deprecated)
castxml_test_output(Converter)
castxml_test_output(Converter-annotate)
castxml_test_output(Converter-deprecated)
castxml_test_output(CvQualifiedType)
castxml_test_output(CXXLiteral)
castxml_test_output(Destructor)
castxml_test_output(Destructor-annotate)
castxml_test_output(Destructor-deprecated)
castxml_test_output(Elaborated)
castxml_test_output(Enumeration)
castxml_test_output(Enumeration-annotate)
castxml_test_output(Enumeration-deprecated)
castxml_test_output(Enumeration-anonymous)
castxml_test_output_11(Enumeration-scoped)
castxml_test_output(Field)
castxml_test_output(Field-annotate)
castxml_test_output(Field-deprecated)
castxml_test_output(Function)
castxml_test_output_14(Function-auto)
castxml_test_output(Function-annotate)
castxml_test_output(Function-deprecated)
castxml_test_output(Function-Argument-annotate)
castxml_test_output(Function-Argument-deprecated)
castxml_test_output(Function-Argument-decay)
castxml_test_output(Function-Argument-default)
castxml_test_output(Function-Argument-default-cast)
castxml_test_output(Function-Argument-default-ns)
castxml_test_output_11(Function-lambda)
castxml_test_output(Function-rvalue-reference)
castxml_test_output(Function-template)
castxml_test_output_14below(Function-throw)
castxml_test_output(Function-variadic)
castxml_test_output(FunctionType)
castxml_test_output(FunctionType-variadic)
castxml_test_output(FundamentalType)
castxml_test_output(FundamentalTypes)
castxml_test_output_11(FundamentalType-nullptr)
castxml_test_output(Method)
castxml_test_output(Method-annotate)
castxml_test_output(Method-deprecated)
castxml_test_output(Method-Argument-default)
castxml_test_output(Method-Argument-default-cast)
castxml_test_output(Method-overrides)
castxml_test_output(Method-rvalue-reference)
castxml_test_output(MethodType)
castxml_test_output(MethodType-cv)
castxml_test_output(Namespace)
castxml_test_output(Namespace-anonymous)
castxml_test_output(Namespace-Class-members)
castxml_test_output(Namespace-Class-partial-template-members)
castxml_test_output(Namespace-Class-template-members)
castxml_test_output(Namespace-Function-template-members)
castxml_test_output(Namespace-empty)
castxml_test_output(Namespace-extern-C-members)
castxml_test_output(Namespace-inline)
castxml_test_output(Namespace-inline-start)
castxml_test_output(Namespace-inline-template)
castxml_test_output(Namespace-nested)
castxml_test_output(Namespace-repeat)
castxml_test_output(Namespace-repeat-start)
castxml_test_output(OffsetType)
castxml_test_output(OffsetType-cv)
castxml_test_output(OperatorFunction)
castxml_test_output(OperatorFunction-annotate)
castxml_test_output(OperatorFunction-deprecated)
castxml_test_output(OperatorMethod)
castxml_test_output(OperatorMethod-annotate)
castxml_test_output(OperatorMethod-deprecated)
castxml_test_output(PointerType)
castxml_test_output(ReferenceType)
castxml_test_output(RValueReferenceType)
castxml_test_output(TypeAlias)
castxml_test_output(TypeAliasTemplate)
castxml_test_output(Typedef-annotate)
castxml_test_output(Typedef-deprecated)
castxml_test_output(Typedef-paren)
castxml_test_output(Typedef-to-Class-template)
castxml_test_output(Typedef-to-Enumeration)
castxml_test_output(Typedef-to-Enumeration-anonymous)
castxml_test_output(Typedef-to-FundamentalType-mode)
castxml_test_output(Typedef-to-extern-C-FundamentalType-mode)
castxml_test_output(Typedef-to-Struct-anonymous)
castxml_test_output(Typedef-to-Union-anonymous)
castxml_test_output(Variable)
castxml_test_output(Variable-annotate)
castxml_test_output(Variable-deprecated)
castxml_test_output(Variable-in-Class)
castxml_test_output(Variable-init)
castxml_test_output(Variable-init-cast)
castxml_test_output(Variable-init-ns)
castxml_test_output_11(Variable-lambda)

# Test multiple start declarations.
set(castxml_test_output_custom_input Namespace-nested)
set(castxml_test_output_custom_start --castxml-start start::ns1,start::ns3)
castxml_test_output(Namespace-nested-1)
set(castxml_test_output_custom_start --castxml-start start::ns1 --castxml-start start::ns3)
castxml_test_output(Namespace-nested-2)
unset(castxml_test_output_custom_start)
unset(castxml_test_output_custom_input)

castxml_test_output(invalid-decl-for-type)
castxml_test_output(qualified-type-name)
castxml_test_output(using-declaration-class)
castxml_test_output(using-declaration-ns)
castxml_test_output(using-declaration-start)
castxml_test_output(using-directive-ns)
castxml_test_output(using-directive-start)

set(castxml_test_output_custom_start "")
castxml_test_output(nostart)
unset(castxml_test_output_custom_start)

if(";${LLVM_TARGETS_TO_BUILD};" MATCHES ";X86;")
  set(castxml_test_output_extra_arguments -target i386-pc-windows-msvc)
  castxml_test_output(Class-ms-dllexport)
  castxml_test_output(Class-ms-dllimport)
  castxml_test_output(Constructor-ms-dllexport)
  castxml_test_output(Constructor-ms-dllimport)
  castxml_test_output(Converter-ms-dllexport)
  castxml_test_output(Converter-ms-dllimport)
  castxml_test_output(Destructor-ms-dllexport)
  castxml_test_output(Destructor-ms-dllimport)
  castxml_test_output(Function-ms-dllexport)
  castxml_test_output(Function-ms-dllimport)
  castxml_test_output(Method-ms-dllexport)
  castxml_test_output(Method-ms-dllimport)
  castxml_test_output(OperatorFunction-ms-dllexport)
  castxml_test_output(OperatorFunction-ms-dllimport)
  castxml_test_output(OperatorMethod-ms-dllexport)
  castxml_test_output(OperatorMethod-ms-dllimport)
  castxml_test_output(Variable-ms-dllexport)
  castxml_test_output(Variable-ms-dllimport)
  castxml_test_output(Function-calling-convention-ms)
  castxml_test_output(Function-calling-convention-ms-annotate)
  castxml_test_output(Function-calling-convention-ms-deprecated)
  castxml_test_output(Function-calling-convention-ms-dllexport)
  castxml_test_output(Function-calling-convention-ms-dllimport)
  castxml_test_output(implicit-decl-ms)
  castxml_test_output(inline-asm-ms)
  unset(castxml_test_output_extra_arguments)
endif()

castxml_test_output_c(FunctionNoProto)
castxml_test_output_c(FundamentalType)
castxml_test_output_c(Typedef-called-class)

castxml_test_output_c(invalid)

castxml_test_output_broken(ReferenceType-to-Class-template)

set(castxml_test_output_extra_arguments --castxml-cc-gnu-c "(" $<TARGET_FILE:cc-gnu> --cc-define=__x86_64__ ")")
castxml_test_output_c(GNU-float128)
set(castxml_test_output_custom_start "")
castxml_test_output_c(GNU-float128-nostart)
unset(castxml_test_output_custom_start)
unset(castxml_test_output_extra_arguments)

set(castxml_test_output_extra_arguments --castxml-cc-gnu "(" $<TARGET_FILE:cc-gnu> --cc-define=__x86_64__ ")")
castxml_test_output(GNU-float128)
set(castxml_test_output_custom_start "")
castxml_test_output(GNU-float128-nostart)
unset(castxml_test_output_custom_start)
unset(castxml_test_output_extra_arguments)

set(castxml_test_output_extra_arguments --castxml-cc-gnu-c $<TARGET_FILE:cc-gnu>)
castxml_test_output_c(GNU-va_arg_pack)
unset(castxml_test_output_extra_arguments)

set(castxml_test_output_extra_arguments --castxml-cc-gnu $<TARGET_FILE:cc-gnu>)
castxml_test_output(GNU-va_arg_pack)
unset(castxml_test_output_extra_arguments)
