# Determine the subdirectory relative to Clang's resource dir/installation
# prefix where to install target-specific libraries, to be found by the
# Clang/Flang driver. This was adapted from Compiler-RT's mechanism to find the
# path for libclang_rt.builtins.a.
#
# Compiler-RT has two mechanisms for the path (simplified):
#
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF: lib/${oslibname}/libclang_rt.builtins-${arch}.a
# * LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON : lib/${triple}/libclang_rt.builtins.a
#
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON is the newer scheme, but the old one is
# currently still used by default for some platforms such as Windows. Clang
# looks for which of the files exist before passing the path to the linker.
# Hence, the directories have to match what Clang is looking for, which is done
# in ToolChain::getArchSpecificLibPaths(..), ToolChain::getRuntimePath(),
# ToolChain::getCompilerRTPath(), and ToolChain::getCompilerRT(..), not entirely
# consistent between these functions, overrides in different toolchains, and
# Compiler-RT's CMake code.
#
# For simplicity, we always use the second scheme even as if
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON, even if it actually set to OFF.
# The driver's lookup does not take the build-time
# LLVM_ENABLE_PER_TARGET_RUNTIME_DIR setting into account anyway
# and will always find its files using either scheme.
function (get_toolchain_library_subdir outvar)
  set(outval "lib")

  if (APPLE)
    # Required to be "darwin" for MachO toolchain.
    get_toolchain_os_dirname(os_dirname)
    set(outval "${outval}/${os_dirname}")
  else ()
    get_toolchain_target_dirname(target_dirname)
    set(outval "${outval}/${target_dirname}")
  endif ()

  set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()


# Corresponds to Flang's ToolChain::getDefaultIntrinsicModuleDir().
function (get_toolchain_fortran_module_subdir outvar)
  set(outval "finclude/flang")

  get_toolchain_target_dirname(target_dirname)
  set(outval "${outval}/${target_dirname}")

  set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()


# Corresponds to Flang's ToolChain::getDefaultIntrinsicModuleDir().
function (get_toolchain_module_subdir outvar)
  set(outval "finclude/flang")

  get_toolchain_target_dirname(arch_dirname)
  set(outval "${outval}/${arch_dirname}")

  set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()


# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
function (get_toolchain_os_dirname outvar)
  if (ANDROID)
    # The CMAKE_SYSTEM_NAME for Android is "Android", but the OS is Linux and the
    # driver will search for libraries in the "linux" directory.
    set(outval "linux")
  else ()
    string(TOLOWER "${CMAKE_SYSTEM_NAME}" outval)
  endif ()
  set(${outvar} "${outval}" PARENT_SCOPE)
endfunction ()


# Internal function extracted from compiler-rt. Use get_toolchain_target_dirname
# instead for new code.
function(get_runtimes_target_libdir_common default_target_triple arch variable)
  string(FIND "${default_target_triple}" "-" dash_index)
  string(SUBSTRING "${default_target_triple}" "${dash_index}" -1 triple_suffix)
  string(SUBSTRING "${default_target_triple}" 0 "${dash_index}" triple_cpu)
  if(ANDROID AND "${arch}" STREQUAL "i386")
    set(target "i686${triple_suffix}")
  elseif("${arch}" STREQUAL "amd64")
    set(target "x86_64${triple_suffix}")
  elseif("${arch}" STREQUAL "sparc64")
    set(target "sparcv9${triple_suffix}")
  elseif("${arch}" MATCHES "mips64|mips64el")
    string(REGEX REPLACE "-gnu.*" "-gnuabi64" triple_suffix_gnu "${triple_suffix}")
    string(REGEX REPLACE "mipsisa32" "mipsisa64" triple_cpu_mips "${triple_cpu}")
    string(REGEX REPLACE "^mips$" "mips64" triple_cpu_mips "${triple_cpu_mips}")
    string(REGEX REPLACE "^mipsel$" "mips64el" triple_cpu_mips "${triple_cpu_mips}")
    set(target "${triple_cpu_mips}${triple_suffix_gnu}")
  elseif("${arch}" MATCHES "mips|mipsel")
    string(REGEX REPLACE "-gnuabi.*" "-gnu" triple_suffix_gnu "${triple_suffix}")
    string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
    string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
    set(target "${triple_cpu_mips}${triple_suffix_gnu}")
  elseif("${arch}" MATCHES "^arm")
    # Arch is arm, armhf, armv6m (anything else would come from using
    # COMPILER_RT_DEFAULT_TARGET_ONLY, which is checked above).
    if (${arch} STREQUAL "armhf")
      # If we are building for hard float but our ABI is soft float.
      if ("${triple_suffix}" MATCHES ".*eabi$")
        # Change "eabi" -> "eabihf"
        set(triple_suffix "${triple_suffix}hf")
      endif()
      # ABI is already set in the triple, don't repeat it in the architecture.
      set(arch "arm")
    else ()
      # If we are building for soft float, but the triple's ABI is hard float.
      if ("${triple_suffix}" MATCHES ".*eabihf$")
        # Change "eabihf" -> "eabi"
        string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
      endif()
    endif()
    set(target "${arch}${triple_suffix}")
  elseif("${arch}" MATCHES "^amdgcn")
    set(target "amdgcn-amd-amdhsa")
  elseif("${arch}" MATCHES "^nvptx")
    set(target "nvptx64-nvidia-cuda")
  else()
    set(target "${arch}${triple_suffix}")
  endif()
  set("${variable}" "${target}" PARENT_SCOPE)
endfunction()


# Corresponds to Clang's ToolChain::getRuntimePath().
function (get_toolchain_target_dirname outvar)
  string(FIND "${LLVM_TARGET_TRIPLE}" "-" dash_index)
  if (dash_index EQUAL "-1")
    # This means LLVM_TARGET_TRIPLE is not set and we cannot derive the dirname
    # from it. The proper behavior here would be to emit an error since we have
    # no target we can build for. However, compiler-rt uses
    # COMPILER_RT_DEFAULT_TARGET_TRIPLE instead and ignores LLVM_TARGET_TRIPLE.
    # To not break the build when building only compiler-rt, we skip the triple
    # subdirectory.
    set(target "")
  else ()
    string(SUBSTRING "${LLVM_TARGET_TRIPLE}" 0 "${dash_index}" triple_cpu)
    set(arch "${triple_cpu}")
    if("${arch}" MATCHES "^i.86$")
      set(arch "i386")
    endif()
    get_runtimes_target_libdir_common("${LLVM_TARGET_TRIPLE}" "${arch}" target)
  endif ()
  set("${outvar}" "${target}" PARENT_SCOPE)
endfunction()
