#!/usr/bin/env python3
'''A utility to update LLVM IR CHECK lines in C/C++ FileCheck test files.

Example RUN lines in .c/.cc test files:

// RUN: %clang -emit-llvm -S %s -o - -O2 | FileCheck %s
// RUN: %clangxx -emit-llvm -S %s -o - -O2 | FileCheck -check-prefix=CHECK-A %s

Usage:

% utils/update_cc_test_checks.py --llvm-bin=release/bin test/a.cc
% utils/update_cc_test_checks.py --clang=release/bin/clang /tmp/c/a.cc
'''

from __future__ import print_function

import argparse
import collections
import distutils.spawn
import json
import os
import re
import shlex
import subprocess
import sys
import tempfile

from UpdateTestChecks import common

SUBST = {
    '%clang': [],
    '%clang_cc1': ['-cc1'],
    '%clangxx': ['--driver-mode=g++'],
}

def get_line2func_list(args, clang_args):
  ret = collections.defaultdict(list)
  # Use clang's JSON AST dump to get the mangled name
  json_dump_args = [args.clang] + clang_args + ['-fsyntax-only', '-o', '-']
  if '-cc1' not in json_dump_args:
    # For tests that invoke %clang instead if %clang_cc1 we have to use
    # -Xclang -ast-dump=json instead:
    json_dump_args.append('-Xclang')
  json_dump_args.append('-ast-dump=json')
  common.debug('Running', ' '.join(json_dump_args))

  popen = subprocess.Popen(json_dump_args, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE, universal_newlines=True)
  stdout, stderr = popen.communicate()
  if popen.returncode != 0:
    sys.stderr.write('Failed to run ' + ' '.join(json_dump_args) + '\n')
    sys.stderr.write(stderr)
    sys.stderr.write(stdout)
    sys.exit(2)

  # Parse the clang JSON and add all children of type FunctionDecl.
  # TODO: Should we add checks for global variables being emitted?
  def parse_clang_ast_json(node, loc, search):
    node_kind = node['kind']
    # Recurse for the following nodes that can contain nested function decls:
    if node_kind in ('NamespaceDecl', 'LinkageSpecDecl', 'TranslationUnitDecl',
                     'CXXRecordDecl', 'ClassTemplateSpecializationDecl'):
      # Specializations must use the loc from the specialization, not the
      # template, and search for the class's spelling as the specialization
      # does not mention the method names in the source.
      if node_kind == 'ClassTemplateSpecializationDecl':
        inner_loc = node['loc']
        inner_search = node['name']
      else:
        inner_loc = None
        inner_search = None
      if 'inner' in node:
        for inner in node['inner']:
          parse_clang_ast_json(inner, inner_loc, inner_search)
    # Otherwise we ignore everything except functions:
    if node_kind not in ('FunctionDecl', 'CXXMethodDecl', 'CXXConstructorDecl',
                         'CXXDestructorDecl', 'CXXConversionDecl'):
      return
    if loc is None:
      loc = node['loc']
    if node.get('isImplicit') is True and node.get('storageClass') == 'extern':
      common.debug('Skipping builtin function:', node['name'], '@', loc)
      return
    common.debug('Found function:', node['kind'], node['name'], '@', loc)
    line = loc.get('line')
    # If there is no line it is probably a builtin function -> skip
    if line is None:
      common.debug('Skipping function without line number:', node['name'], '@', loc)
      return

    # If there is no 'inner' object, it is a function declaration and we can
    # skip it. However, function declarations may also contain an 'inner' list,
    # but in that case it will only contains ParmVarDecls. If we find an entry
    # that is not a ParmVarDecl, we know that this is a function definition.
    has_body = False
    if 'inner' in node:
      for i in node['inner']:
        if i.get('kind', 'ParmVarDecl') != 'ParmVarDecl':
          has_body = True
          break
    if not has_body:
      common.debug('Skipping function without body:', node['name'], '@', loc)
      return
    spell = node['name']
    if search is None:
      search = spell
    mangled = node.get('mangledName', spell)
    ret[int(line)-1].append((spell, mangled, search))

  ast = json.loads(stdout)
  if ast['kind'] != 'TranslationUnitDecl':
    common.error('Clang AST dump JSON format changed?')
    sys.exit(2)
  parse_clang_ast_json(ast, None, None)

  for line, funcs in sorted(ret.items()):
    for func in funcs:
      common.debug('line {}: found function {}'.format(line+1, func), file=sys.stderr)
  if not ret:
    common.warn('Did not find any functions using', ' '.join(json_dump_args))
  return ret


def str_to_commandline(value):
  if not value:
    return []
  return shlex.split(value)


def infer_dependent_args(args):
  if not args.clang:
    if not args.llvm_bin:
      args.clang = 'clang'
    else:
      args.clang = os.path.join(args.llvm_bin, 'clang')
  if not args.opt:
    if not args.llvm_bin:
      args.opt = 'opt'
    else:
      args.opt = os.path.join(args.llvm_bin, 'opt')


def config():
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawTextHelpFormatter)
  parser.add_argument('--llvm-bin', help='llvm $prefix/bin path')
  parser.add_argument('--clang',
                      help='"clang" executable, defaults to $llvm_bin/clang')
  parser.add_argument('--clang-args', default=[], type=str_to_commandline,
                      help='Space-separated extra args to clang, e.g. --clang-args=-v')
  parser.add_argument('--opt',
                      help='"opt" executable, defaults to $llvm_bin/opt')
  parser.add_argument(
      '--functions', nargs='+', help='A list of function name regexes. '
      'If specified, update CHECK lines for functions matching at least one regex')
  parser.add_argument(
      '--x86_extra_scrub', action='store_true',
      help='Use more regex for x86 matching to reduce diffs between various subtargets')
  parser.add_argument('--function-signature', action='store_true',
                      help='Keep function signature information around for the check line')
  parser.add_argument('--check-attributes', action='store_true',
                      help='Check "Function Attributes" for functions')
  parser.add_argument('--check-globals', action='store_true',
                      help='Check global entries (global variables, metadata, attribute sets, ...) for functions')
  parser.add_argument('tests', nargs='+')
  args = common.parse_commandline_args(parser)
  infer_dependent_args(args)

  if not distutils.spawn.find_executable(args.clang):
    print('Please specify --llvm-bin or --clang', file=sys.stderr)
    sys.exit(1)

  # Determine the builtin includes directory so that we can update tests that
  # depend on the builtin headers. See get_clang_builtin_include_dir() and
  # use_clang() in llvm/utils/lit/lit/llvm/config.py.
  try:
    builtin_include_dir = subprocess.check_output(
      [args.clang, '-print-file-name=include']).decode().strip()
    SUBST['%clang_cc1'] = ['-cc1', '-internal-isystem', builtin_include_dir,
                           '-nostdsysteminc']
  except subprocess.CalledProcessError:
    common.warn('Could not determine clang builtins directory, some tests '
                'might not update correctly.')

  if not distutils.spawn.find_executable(args.opt):
    # Many uses of this tool will not need an opt binary, because it's only
    # needed for updating a test that runs clang | opt | FileCheck. So we
    # defer this error message until we find that opt is actually needed.
    args.opt = None

  return args, parser


def get_function_body(builder, args, filename, clang_args, extra_commands,
                      prefixes):
  # TODO Clean up duplication of asm/common build_function_body_dictionary
  # Invoke external tool and extract function bodies.
  raw_tool_output = common.invoke_tool(args.clang, clang_args, filename)
  for extra_command in extra_commands:
    extra_args = shlex.split(extra_command)
    with tempfile.NamedTemporaryFile() as f:
      f.write(raw_tool_output.encode())
      f.flush()
      if extra_args[0] == 'opt':
        if args.opt is None:
          print(filename, 'needs to run opt. '
                'Please specify --llvm-bin or --opt', file=sys.stderr)
          sys.exit(1)
        extra_args[0] = args.opt
      raw_tool_output = common.invoke_tool(extra_args[0],
                                           extra_args[1:], f.name)
  if '-emit-llvm' in clang_args:
    builder.process_run_line(
            common.OPT_FUNCTION_RE, common.scrub_body, raw_tool_output,
            prefixes, False)
    builder.processed_prefixes(prefixes)
  else:
    print('The clang command line should include -emit-llvm as asm tests '
          'are discouraged in Clang testsuite.', file=sys.stderr)
    sys.exit(1)

def exec_run_line(exe):
  popen = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
  stdout, stderr = popen.communicate()
  if popen.returncode != 0:
    sys.stderr.write('Failed to run ' + ' '.join(exe) + '\n')
    sys.stderr.write(stderr)
    sys.stderr.write(stdout)
    sys.exit(3)

def main():
  initial_args, parser = config()
  script_name = os.path.basename(__file__)

  for ti in common.itertests(initial_args.tests, parser, 'utils/' + script_name,
                             comment_prefix='//', argparse_callback=infer_dependent_args):
    # Build a list of filechecked and non-filechecked RUN lines.
    run_list = []
    line2func_list = collections.defaultdict(list)

    subs = {
      '%s' : ti.path,
      '%t' : tempfile.NamedTemporaryFile().name,
      '%S' : os.path.dirname(ti.path),
    }

    for l in ti.run_lines:
      commands = [cmd.strip() for cmd in l.split('|')]

      triple_in_cmd = None
      m = common.TRIPLE_ARG_RE.search(commands[0])
      if m:
        triple_in_cmd = m.groups()[0]

      # Parse executable args.
      exec_args = shlex.split(commands[0])
      # Execute non-clang runline.
      if exec_args[0] not in SUBST:
        # Do lit-like substitutions.
        for s in subs:
          exec_args = [i.replace(s, subs[s]) if s in i else i for i in exec_args]
        run_list.append((None, exec_args, None, None))
        continue
      # This is a clang runline, apply %clang substitution rule, do lit-like substitutions,
      # and append args.clang_args
      clang_args = exec_args
      clang_args[0:1] = SUBST[clang_args[0]]
      for s in subs:
        clang_args = [i.replace(s, subs[s]) if s in i else i for i in clang_args]
      clang_args += ti.args.clang_args

      # Extract -check-prefix in FileCheck args
      filecheck_cmd = commands[-1]
      common.verify_filecheck_prefixes(filecheck_cmd)
      if not filecheck_cmd.startswith('FileCheck '):
        # Execute non-filechecked clang runline.
        exe = [ti.args.clang] + clang_args
        run_list.append((None, exe, None, None))
        continue

      check_prefixes = [item for m in common.CHECK_PREFIX_RE.finditer(filecheck_cmd)
                               for item in m.group(1).split(',')]
      if not check_prefixes:
        check_prefixes = ['CHECK']
      run_list.append((check_prefixes, clang_args, commands[1:-1], triple_in_cmd))

    # Execute clang, generate LLVM IR, and extract functions.

    # Store only filechecked runlines.
    filecheck_run_list = [i for i in run_list if i[0]]
    builder = common.FunctionTestBuilder(
      run_list=filecheck_run_list,
      flags=ti.args,
      scrubber_args=[],
      path=ti.path)

    for prefixes, args, extra_commands, triple_in_cmd in run_list:
      # Execute non-filechecked runline.
      if not prefixes:
        print('NOTE: Executing non-FileChecked RUN line: ' + ' '.join(args), file=sys.stderr)
        exec_run_line(args)
        continue

      clang_args = args
      common.debug('Extracted clang cmd: clang {}'.format(clang_args))
      common.debug('Extracted FileCheck prefixes: {}'.format(prefixes))

      get_function_body(builder, ti.args, ti.path, clang_args, extra_commands,
                        prefixes)

      # Invoke clang -Xclang -ast-dump=json to get mapping from start lines to
      # mangled names. Forward all clang args for now.
      for k, v in get_line2func_list(ti.args, clang_args).items():
        line2func_list[k].extend(v)

    func_dict = builder.finish_and_get_func_dict()
    global_vars_seen_dict = {}
    prefix_set = set([prefix for p in filecheck_run_list for prefix in p[0]])
    output_lines = []
    has_checked_pre_function_globals = False

    include_generated_funcs = common.find_arg_in_test(ti,
                                                      lambda args: ti.args.include_generated_funcs,
                                                      '--include-generated-funcs',
                                                      True)

    if include_generated_funcs:
      # Generate the appropriate checks for each function.  We need to emit
      # these in the order according to the generated output so that CHECK-LABEL
      # works properly.  func_order provides that.

      # It turns out that when clang generates functions (for example, with
      # -fopenmp), it can sometimes cause functions to be re-ordered in the
      # output, even functions that exist in the source file.  Therefore we
      # can't insert check lines before each source function and instead have to
      # put them at the end.  So the first thing to do is dump out the source
      # lines.
      common.dump_input_lines(output_lines, ti, prefix_set, '//')

      # Now generate all the checks.
      def check_generator(my_output_lines, prefixes, func):
        if '-emit-llvm' in clang_args:
          return common.add_ir_checks(my_output_lines, '//',
                                      prefixes,
                                      func_dict, func, False,
                                      ti.args.function_signature,
                                      global_vars_seen_dict,
                                      is_filtered=builder.is_filtered())
        else:
          return asm.add_checks(my_output_lines, '//',
                                prefixes,
                                func_dict, func, global_vars_seen_dict,
                                is_filtered=builder.is_filtered())

      if ti.args.check_globals:
        common.add_global_checks(builder.global_var_dict(), '//', run_list,
                                 output_lines, global_vars_seen_dict, True,
                                 True)
      common.add_checks_at_end(output_lines, filecheck_run_list, builder.func_order(),
                               '//', lambda my_output_lines, prefixes, func:
                               check_generator(my_output_lines,
                                               prefixes, func))
    else:
      # Normal mode.  Put checks before each source function.
      for line_info in ti.iterlines(output_lines):
        idx = line_info.line_number
        line = line_info.line
        args = line_info.args
        include_line = True
        m = common.CHECK_RE.match(line)
        if m and m.group(1) in prefix_set:
          continue  # Don't append the existing CHECK lines
        # Skip special separator comments added by commmon.add_global_checks.
        if line.strip() == '//' + common.SEPARATOR:
          continue
        if idx in line2func_list:
          added = set()
          for spell, mangled, search in line2func_list[idx]:
            # One line may contain multiple function declarations.
            # Skip if the mangled name has been added before.
            # The line number may come from an included file, we simply require
            # the search string (normally the function's spelling name, but is
            # the class's spelling name for class specializations) to appear on
            # the line to exclude functions from other files.
            if mangled in added or search not in line:
              continue
            if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
              last_line = output_lines[-1].strip()
              while last_line == '//':
                # Remove the comment line since we will generate a new  comment
                # line as part of common.add_ir_checks()
                output_lines.pop()
                last_line = output_lines[-1].strip()
              if ti.args.check_globals and not has_checked_pre_function_globals:
                common.add_global_checks(builder.global_var_dict(), '//',
                                         run_list, output_lines,
                                         global_vars_seen_dict, True, True)
                has_checked_pre_function_globals = True
              if added:
                output_lines.append('//')
              added.add(mangled)
              common.add_ir_checks(output_lines, '//', filecheck_run_list, func_dict, mangled,
                                   False, args.function_signature, global_vars_seen_dict,
                                   is_filtered=builder.is_filtered())
              if line.rstrip('\n') == '//':
                include_line = False

        if include_line:
          output_lines.append(line.rstrip('\n'))

    if ti.args.check_globals:
      common.add_global_checks(builder.global_var_dict(), '//', run_list,
                               output_lines, global_vars_seen_dict, True, False)
    common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
    with open(ti.path, 'wb') as f:
      f.writelines(['{}\n'.format(l).encode('utf-8') for l in output_lines])

  return 0


if __name__ == '__main__':
  sys.exit(main())
