Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Construct a compiler invocation object for command line driver arguments
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Frontend/Utils.h"
14
#include "clang/Basic/DiagnosticOptions.h"
15
#include "clang/Driver/Compilation.h"
16
#include "clang/Driver/Driver.h"
17
#include "clang/Driver/Action.h"
18
#include "clang/Driver/Options.h"
19
#include "clang/Driver/Tool.h"
20
#include "clang/Frontend/CompilerInstance.h"
21
#include "clang/Frontend/FrontendDiagnostic.h"
22
#include "llvm/Option/ArgList.h"
23
#include "llvm/Support/Host.h"
24
using namespace clang;
25
using namespace llvm::opt;
26
27
/// createInvocationFromCommandLine - Construct a compiler invocation object for
28
/// a command line argument vector.
29
///
30
/// \return A CompilerInvocation, or 0 if none was built for the given
31
/// argument vector.
32
std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine(
33
    ArrayRef<const char *> ArgList, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
34
1.06k
    IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
35
1.06k
  if (!Diags.get()) {
36
0
    // No diagnostics engine was provided, so create our own diagnostics object
37
0
    // with the default options.
38
0
    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
39
0
  }
40
1.06k
41
1.06k
  SmallVector<const char *, 16> Args(ArgList.begin(), ArgList.end());
42
1.06k
43
1.06k
  // FIXME: Find a cleaner way to force the driver into restricted modes.
44
1.06k
  Args.push_back("-fsyntax-only");
45
1.06k
46
1.06k
  // FIXME: We shouldn't have to pass in the path info.
47
1.06k
  driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
48
1.06k
                           *Diags, VFS);
49
1.06k
50
1.06k
  // Don't check that inputs exist, they may have been remapped.
51
1.06k
  TheDriver.setCheckInputsExist(false);
52
1.06k
53
1.06k
  std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
54
1.06k
  if (!C)
55
0
    return nullptr;
56
1.06k
57
1.06k
  // Just print the cc1 options if -### was present.
58
1.06k
  if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
59
0
    C->getJobs().Print(llvm::errs(), "\n", true);
60
0
    return nullptr;
61
0
  }
62
1.06k
63
1.06k
  // We expect to get back exactly one command job, if we didn't something
64
1.06k
  // failed. Offload compilation is an exception as it creates multiple jobs. If
65
1.06k
  // that's the case, we proceed with the first job. If caller needs a
66
1.06k
  // particular job, it should be controlled via options (e.g.
67
1.06k
  // --cuda-{host|device}-only for CUDA) passed to the driver.
68
1.06k
  const driver::JobList &Jobs = C->getJobs();
69
1.06k
  bool OffloadCompilation = false;
70
1.06k
  if (Jobs.size() > 1) {
71
4
    for (auto &A : C->getActions()){
72
4
      // On MacOSX real actions may end up being wrapped in BindArchAction
73
4
      if (isa<driver::BindArchAction>(A))
74
4
        A = *A->input_begin();
75
4
      if (isa<driver::OffloadAction>(A)) {
76
2
        OffloadCompilation = true;
77
2
        break;
78
2
      }
79
1.06k
    }
80
2
  }
81
1.06k
  if (Jobs.size() == 0 || !isa<driver::Command>(*Jobs.begin()) ||
82
1.06k
      (Jobs.size() > 1 && 
!OffloadCompilation2
)) {
83
0
    SmallString<256> Msg;
84
0
    llvm::raw_svector_ostream OS(Msg);
85
0
    Jobs.Print(OS, "; ", true);
86
0
    Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
87
0
    return nullptr;
88
0
  }
89
1.06k
90
1.06k
  const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
91
1.06k
  if (StringRef(Cmd.getCreator().getName()) != "clang") {
92
0
    Diags->Report(diag::err_fe_expected_clang_command);
93
0
    return nullptr;
94
0
  }
95
1.06k
96
1.06k
  const ArgStringList &CCArgs = Cmd.getArguments();
97
1.06k
  auto CI = llvm::make_unique<CompilerInvocation>();
98
1.06k
  if (!CompilerInvocation::CreateFromArgs(*CI,
99
1.06k
                                     const_cast<const char **>(CCArgs.data()),
100
1.06k
                                     const_cast<const char **>(CCArgs.data()) +
101
1.06k
                                     CCArgs.size(),
102
1.06k
                                     *Diags))
103
0
    return nullptr;
104
1.06k
  return CI;
105
1.06k
}