# On Windows, CMAKE_*_FLAGS are built for MSVC but we use the GCC clang.exe,
# which uses completely different flags. Translate some common flag types, and
# drop the rest.
function(translate_msvc_cflags out_flags msvc_flags)
  # Insert an empty string in the list to simplify processing.
  set(msvc_flags ";${msvc_flags}")

  # Canonicalize /flag to -flag.
  string(REPLACE ";/" ";-" msvc_flags "${msvc_flags}")

  # Make space separated -D and -U flags into joined flags.
  string(REGEX REPLACE ";-\([DU]\);" ";-\\1" msvc_flags "${msvc_flags}")

  set(clang_flags "")
  foreach(flag ${msvc_flags})
    if ("${flag}" MATCHES "^-[DU]")
      # Pass through basic command line macro definitions (-DNDEBUG).
      list(APPEND clang_flags "${flag}")
    elseif ("${flag}" MATCHES "^-O[2x]")
      # Canonicalize normal optimization flags to -O2.
      list(APPEND clang_flags "-O2")
    endif()
  endforeach()
  set(${out_flags} "${clang_flags}" PARENT_SCOPE)
endfunction()

# Compile a sanitizer test with a freshly built clang
# for a given architecture, adding the result to the object list.
#  - obj_list: output list of objects, populated by path
#              of a generated object file.
#  - source:   source file of a test.
#  - arch:     architecture to compile for.
# sanitizer_test_compile(<obj_list> <source> <arch>
#                        KIND <custom namespace>
#                        COMPILE_DEPS <list of compile-time dependencies>
#                        DEPS <list of dependencies>
#                        CFLAGS <list of flags>
# )
function(sanitizer_test_compile obj_list source arch)
  cmake_parse_arguments(TEST
      "" "" "KIND;COMPILE_DEPS;DEPS;CFLAGS" ${ARGN})
  get_filename_component(basename ${source} NAME)
  set(output_obj
    "${CMAKE_CFG_RESOLVED_INTDIR}${obj_list}.${basename}.${arch}${TEST_KIND}.o")

  # Write out architecture-specific flags into TARGET_CFLAGS variable.
  get_target_flags_for_arch(${arch} TARGET_CFLAGS)
  set(COMPILE_DEPS ${TEST_COMPILE_DEPS})
  if(NOT COMPILER_RT_STANDALONE_BUILD)
    list(APPEND COMPILE_DEPS ${TEST_DEPS})
  endif()
  clang_compile(${output_obj} ${source}
                CFLAGS ${TEST_CFLAGS} ${TARGET_CFLAGS}
                DEPS ${COMPILE_DEPS})
  list(APPEND ${obj_list} ${output_obj})
  set("${obj_list}" "${${obj_list}}" PARENT_SCOPE)
endfunction()

# Compile a source into an object file with COMPILER_RT_TEST_COMPILER using
# a provided compile flags and dependenices.
# clang_compile(<object> <source>
#               CFLAGS <list of compile flags>
#               DEPS <list of dependencies>)
function(clang_compile object_file source)
  cmake_parse_arguments(SOURCE "" "" "CFLAGS;DEPS" ${ARGN})
  get_filename_component(source_rpath ${source} REALPATH)
  if(NOT COMPILER_RT_STANDALONE_BUILD)
    list(APPEND SOURCE_DEPS clang compiler-rt-headers)
  endif()
  if (TARGET CompilerRTUnitTestCheckCxx)
    list(APPEND SOURCE_DEPS CompilerRTUnitTestCheckCxx)
  endif()
  if(COMPILER_RT_STANDALONE_BUILD)
    # Only add global flags in standalone build.
    string(REGEX MATCH "[.](cc|cpp)$" is_cxx ${source_rpath})
    if(is_cxx)
      string(REPLACE " " ";" global_flags "${CMAKE_CXX_FLAGS}")
    else()
      string(REPLACE " " ";" global_flags "${CMAKE_C_FLAGS}")
    endif()

    if (MSVC)
      translate_msvc_cflags(global_flags "${global_flags}")
    endif()

    if (APPLE)
      set(global_flags ${OSX_SYSROOT_FLAG} ${global_flags})
    endif()

    # Ignore unknown warnings. CMAKE_CXX_FLAGS may contain GCC-specific options
    # which are not supported by Clang.
    list(APPEND global_flags -Wno-unknown-warning-option)
    set(compile_flags ${global_flags} ${SOURCE_CFLAGS})
  else()
    set(compile_flags ${SOURCE_CFLAGS})
  endif()

  string(REGEX MATCH "[.](m|mm)$" is_objc ${source_rpath})
  if (is_objc)
    list(APPEND compile_flags "-ObjC")
  endif()

  add_custom_command(
    OUTPUT ${object_file}
    COMMAND ${COMPILER_RT_TEST_COMPILER} ${compile_flags} -c
            -o "${object_file}"
            ${source_rpath}
    MAIN_DEPENDENCY ${source}
    DEPENDS ${SOURCE_DEPS})
endfunction()

# On Darwin, there are no system-wide C++ headers and the just-built clang is
# therefore not able to compile C++ files unless they are copied/symlinked into
# ${LLVM_BINARY_DIR}/include/c++
# The just-built clang is used to build compiler-rt unit tests. Let's detect
# this before we try to build the tests and print out a suggestion how to fix
# it.
# On other platforms, this is currently not an issue.
macro(clang_compiler_add_cxx_check)
  if (APPLE)
    set(CMD
      "echo '#include <iostream>' | ${COMPILER_RT_TEST_COMPILER} ${OSX_SYSROOT_FLAG} -E -x c++ - > /dev/null"
      "if [ $? != 0 ] "
      "  then echo"
      "  echo 'Your just-built clang cannot find C++ headers, which are needed to build and run compiler-rt tests.'"
      "  echo 'You should copy or symlink your system C++ headers into ${LLVM_BINARY_DIR}/include/c++'"
      "  if [ -d $(dirname $(dirname $(xcrun -f clang)))/include/c++ ]"
      "    then echo 'e.g. with:'"
      "    echo '  cp -r' $(dirname $(dirname $(xcrun -f clang)))/include/c++ '${LLVM_BINARY_DIR}/include/'"
      "  elif [ -d $(dirname $(dirname $(xcrun -f clang)))/lib/c++ ]"
      "    then echo 'e.g. with:'"
      "    echo '  cp -r' $(dirname $(dirname $(xcrun -f clang)))/lib/c++ '${LLVM_BINARY_DIR}/include/'"
      "  fi"
      "  echo 'This can also be fixed by checking out the libcxx project from llvm.org and installing the headers'"
      "  echo 'into your build directory:'"
      "  echo '  cd ${LLVM_MAIN_SRC_DIR}/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx'"
      "  echo '  cd ${LLVM_BINARY_DIR} && make -C ${LLVM_MAIN_SRC_DIR}/projects/libcxx installheaders HEADER_DIR=${LLVM_BINARY_DIR}/include'"
      "  echo"
      "  false"
      "fi"
      )
    add_custom_target(CompilerRTUnitTestCheckCxx
      COMMAND bash -c "${CMD}"
      COMMENT "Checking that just-built clang can find C++ headers..."
      VERBATIM)
    if (NOT COMPILER_RT_STANDALONE_BUILD AND NOT LLVM_RUNTIMES_BUILD)
      ADD_DEPENDENCIES(CompilerRTUnitTestCheckCxx clang)
    endif()
  endif()
endmacro()
