# -*- Python -*-

import os
import platform

import lit.formats

def get_required_attr(config, attr_name):
  attr_value = getattr(config, attr_name, None)
  if attr_value == None:
    lit_config.fatal(
      "No attribute %r in test configuration! You may need to run "
      "tests from your build directory or add this attribute "
      "to lit.site.cfg " % attr_name)
  return attr_value

# Setup config name.
config.name = 'Builtins' + config.name_suffix

# Platform-specific default Builtins_OPTIONS for lit tests.
default_builtins_opts = ''

# Setup source root.
config.test_source_root = os.path.dirname(__file__)

# Path to the static library
is_msvc = get_required_attr(config, "builtins_is_msvc")
if is_msvc:
  base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.builtins%s.lib "
                          % config.target_suffix)
  config.substitutions.append( ("%librt ", base_lib) )
else:
  base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins%s.a"
                          % config.target_suffix)
  config.substitutions.append( ("%librt ", base_lib + ' -lc -lm ') )

builtins_source_dir = os.path.join(
  get_required_attr(config, "compiler_rt_src_root"), "lib", "builtins")
builtins_lit_source_dir = get_required_attr(config, "builtins_lit_source_dir")

extra_link_flags = ["-nodefaultlibs"]

target_cflags = [get_required_attr(config, "target_cflags")]
target_cflags += ['-fno-builtin', '-I', builtins_source_dir]
target_cflags += extra_link_flags
target_cxxflags = config.cxx_mode_flags + target_cflags
clang_builtins_static_cflags = ([""] +
                            config.debug_info_flags + target_cflags)
clang_builtins_static_cxxflags = config.cxx_mode_flags + \
                                 clang_builtins_static_cflags

clang_builtins_cflags = clang_builtins_static_cflags
clang_builtins_cxxflags = clang_builtins_static_cxxflags

if not is_msvc:
  config.available_features.add('c99-complex')

clang_wrapper = ""

def build_invocation(compile_flags):
  return " " + " ".join([clang_wrapper, config.clang] + compile_flags) + " "


target_arch = config.target_arch
if (target_arch == "arm"):
  target_arch = "armv7"

config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) )
config.substitutions.append( ("%clang_builtins ", \
                              build_invocation(clang_builtins_cflags)))
config.substitutions.append( ("%clangxx_builtins ", \
                              build_invocation(clang_builtins_cxxflags)))

# FIXME: move the call_apsr.s into call_apsr.h as inline-asm.
# some ARM tests needs call_apsr.s
call_apsr_source = os.path.join(builtins_lit_source_dir, 'arm', 'call_apsr.S')
march_flag = '-march=' + target_arch
call_apsr_flags = ['-c', march_flag, call_apsr_source]
config.substitutions.append( ("%arm_call_apsr ", \
                              build_invocation(call_apsr_flags)) )

# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']

if not config.emulator:
  config.available_features.add('native-run')
