Beispiel #1
0
def CompileLlvmBytecode(src: str, suffix: str, cflags: typing.List[str],
                        timeout_seconds: int = 60) -> str:
  """Compile input code into textual LLVM byte code.

  Args:
    src: The source code to compile.
    suffix: The suffix to append to the source code temporary file. E.g. '.c'
      for a C program.
    cflags: A list of flags to be passed to clang.
    timeout_seconds: The number of seconds to allow before killing clang.

  Returns:
    The textual LLVM byte code.

  Raises:
    ClangException: In case of an error.
    ClangTimeout: If clang does not complete before timeout_seconds.
  """
  builtin_cflags = ['-S', '-emit-llvm', '-o', '-']
  with tempfile.NamedTemporaryFile('w', prefix='clgen_clang_',
                                   suffix=suffix) as f:
    f.write(src)
    f.flush()
    cmd = ['timeout', '-s9', str(timeout_seconds), str(CLANG),
           f.name] + builtin_cflags + cflags
    logging.debug('$ %s', ' '.join(cmd))
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, universal_newlines=True)
    stdout, stderr = process.communicate()
  if process.returncode == 9:
    raise errors.ClangTimeout(f'Clang timed out after {timeout_seconds}s')
  elif process.returncode != 0:
    raise errors.ClangException(stderr)
  return stdout
Beispiel #2
0
def Preprocess(src: str, cflags: typing.List[str], timeout_seconds: int = 60,
               strip_preprocessor_lines: bool = True):
  """Run input code through the compiler frontend to inline macros.

  This uses the repository clang binary.

  Args:
    src: The source code to preprocess.
    cflags: A list of flags to be passed to clang.
    timeout_seconds: The number of seconds to allow before killing clang.
    strip_preprocessor_lines: Whether to strip the extra lines introduced by
      the preprocessor.

  Returns:
    The preprocessed code.

  Raises:
    ClangException: In case of an error.
    ClangTimeout: If clang does not complete before timeout_seconds.
  """
  cmd = ['timeout', '-s9', str(timeout_seconds),
         str(CLANG), '-E', '-c', '-', '-o', '-'] + cflags
  logging.debug('$ %s', ' '.join(cmd))
  process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE, universal_newlines=True)
  stdout, stderr = process.communicate(src)
  if process.returncode == 9:
    raise errors.ClangTimeout(
        f'Clang preprocessor timed out after {timeout_seconds}s')
  elif process.returncode != 0:
    raise errors.ClangException(stderr)
  if strip_preprocessor_lines:
    return StripPreprocessorLines(stdout)
  else:
    return stdout
Beispiel #3
0
def CompileLlvmBytecode(src: str,
                        suffix: str,
                        cflags: typing.List[str],
                        timeout_seconds: int = 60) -> str:
    """Compile input code into textual LLVM byte code.

  Args:
    src: The source code to compile.
    suffix: The suffix to append to the source code temporary file. E.g. '.c'
      for a C program.
    cflags: A list of flags to be passed to clang.
    timeout_seconds: The number of seconds to allow before killing clang.

  Returns:
    The textual LLVM byte code.

  Raises:
    ClangException: In case of an error.
    ClangTimeout: If clang does not complete before timeout_seconds.
  """
    builtin_cflags = ["-S", "-emit-llvm", "-o", "-"]
    with tempfile.NamedTemporaryFile(
            "w",
            prefix="phd_deeplearning_clgen_preprocessors_clang_",
            suffix=suffix) as f:
        f.write(src)
        f.flush()
        cmd = (
            ["timeout", "-s9",
             str(timeout_seconds),
             str(clang.CLANG), f.name] + builtin_cflags + cflags)
        app.Log(2, "$ %s", " ".join(cmd))
        process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
        )
        stdout, stderr = process.communicate()
    if process.returncode == 9:
        raise errors.ClangTimeout(f"Clang timed out after {timeout_seconds}s")
    elif process.returncode != 0:
        raise errors.ClangException(stderr)
    return stdout
Beispiel #4
0
def ClangPreprocess(text: str) -> str:
    try:
        return clang.StripPreprocessorLines(
            clanglib.Preprocess(text, CLANG_ARGS))
    except llvm.LlvmError as e:
        raise errors.ClangException(str(e.stderr[:1024]))