text: #!/usr/bin/env python3
  import argparse
  from itertools import takewhile
  import json
  import os
  import sys
  from typing import Callable, Dict, IO, List
  import io
  from string import Template
  import re
  
  from spirv_common import ignore_overload, emit_guards, close_guards, clang_format
  
  def ignore_function(fun):
      whitelist = [
          "abs",
          "abs_diff",
          "add_sat",
          "BitCount",
          "clz",
          "ControlBarrier",
          "ctz",
          "GroupAsyncCopy",
          "GroupWaitEvents",
          "hadd",
          "mad24",
          "mad_hi",
          "mad_sat",
          "MemoryBarrier",
          "mul24",
          "mul_hi",
          "popcount",
          "prefetch",
          "rhadd",
          "rotate",
          "sub_sat",
          "upsample",
          "vload",
          "vstore"
      ]
  
      return not any([fun.find(b) != -1 for b in whitelist])
  
  def get_builtin_name(func):
      func = func.replace("__spirv_", "")
      builtin = func.replace("ocl_", "")
      kind = "core" if builtin == func else "ocl"
      return (kind, builtin)
  
  if __name__ == "__main__":
      parser = argparse.ArgumentParser(
          description="""
  Generate SPIR-V interface check tests.
  Typical usage:
   clang-tblgen --gen-clang-progmodel-builtins-as-json path/to/SPIRVBuiltins.td \
     -o builtin.json
   generate-test-libclc.py builtin.json -format clang-format -o spirv_builtin.h
  """)
      parser.add_argument("input",
                          metavar="MAPPING",
                          type=argparse.FileType('r'),
                          help="Path to mapping.json")
      parser.add_argument("-format",
                          metavar="clang-format",
                          nargs='?',
                          help="clang-format the output file")
      parser.add_argument("-o", help="Folder to write the tests to")
      args = parser.parse_args()
  
      with args.input as f:
          mapping = json.load(f)
      keys = list(mapping.keys())
      keys.sort()
      for k in keys:
          if ignore_function(k):
              continue
          overloads = mapping[k]
          kind, builtin = get_builtin_name(k)
          test_file = os.path.join(args.o, kind, builtin  + ".cl")
          if not os.path.exists(os.path.join(args.o, kind)):
              os.makedirs(os.path.join(args.o, kind))
          with open(test_file, "w") as out_fd:
              print("gen: " + test_file)
              out_fd.write("""
  //===----------------------------------------------------------------------===//
  //
  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  // See https://llvm.org/LICENSE.txt for license information.
  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  //
  //===----------------------------------------------------------------------===//
  
  // Autogenerated by gen-libclc-test.py
  
  // RUN: %clang -emit-llvm -S -o - %s | FileCheck %s
  
  #include <spirv/spirv_types.h>
  
  // CHECK-NOT: declare {{.*}} @_Z
  // CHECK-NOT: call {{[^ ]*}} bitcast
  """)
              for proto, _ in overloads:
                  if ignore_overload(proto):
                      continue
                  nb_guards = emit_guards(out_fd, proto)
                  ret = proto[0]
                  proto = proto[1:]
                  param = {
                      "RET" : ret,
                      "FN"  : k,
                      "PARAM" : ", ".join(["{} args_{}".format(ty, str(i)) for i, ty in enumerate(proto)]),
                      "RETURN" : "return" if ret != "void" else "",
                      "ARG" : ", ".join(["args_{}".format(str(i)) for i, _ in enumerate(proto)])
                  }
                  out_fd.write("""__attribute__((overloadable)) {RET} test_{FN}({PARAM}) {{
    {RETURN} {FN}({ARG});
  }}
  
  """.format(**param))
                  close_guards(out_fd, nb_guards)
          if args.format:
              clang_format(args.format, test_file)
  