# -*- 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_arch)
  config.substitutions.append( ("%librt ", base_lib) )
else:
  base_lib = os.path.join(config.compiler_rt_libdir, "libclang_rt.builtins-%s.a"
                          % config.target_arch)
  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')

config.available_features.add('not-android')
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')
