Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/BareMetal.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- BareMetal.cpp - Bare Metal ToolChain --------------------*- C++ -*-===//
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
#include "BareMetal.h"
10
11
#include "CommonArgs.h"
12
#include "InputInfo.h"
13
#include "Gnu.h"
14
15
#include "clang/Driver/Compilation.h"
16
#include "clang/Driver/Driver.h"
17
#include "clang/Driver/DriverDiagnostic.h"
18
#include "clang/Driver/Options.h"
19
#include "llvm/Option/ArgList.h"
20
#include "llvm/Support/Path.h"
21
#include "llvm/Support/VirtualFileSystem.h"
22
#include "llvm/Support/raw_ostream.h"
23
24
using namespace llvm::opt;
25
using namespace clang;
26
using namespace clang::driver;
27
using namespace clang::driver::tools;
28
using namespace clang::driver::toolchains;
29
30
BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple,
31
                           const ArgList &Args)
32
364
    : ToolChain(D, Triple, Args) {
33
364
  getProgramPaths().push_back(getDriver().getInstalledDir());
34
364
  if (getDriver().getInstalledDir() != getDriver().Dir)
35
0
    getProgramPaths().push_back(getDriver().Dir);
36
364
}
37
38
364
BareMetal::~BareMetal() {}
39
40
/// Is the triple {arm,thumb}-none-none-{eabi,eabihf} ?
41
11.0k
static bool isARMBareMetal(const llvm::Triple &Triple) {
42
11.0k
  if (Triple.getArch() != llvm::Triple::arm &&
43
10.2k
      Triple.getArch() != llvm::Triple::thumb)
44
10.2k
    return false;
45
46
855
  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
47
27
    return false;
48
49
828
  if (Triple.getOS() != llvm::Triple::UnknownOS)
50
2
    return false;
51
52
826
  if (Triple.getEnvironment() != llvm::Triple::EABI &&
53
468
      Triple.getEnvironment() != llvm::Triple::EABIHF)
54
462
    return false;
55
56
364
  return true;
57
364
}
58
59
11.0k
bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
60
11.0k
  return isARMBareMetal(Triple);
61
11.0k
}
62
63
77
Tool *BareMetal::buildLinker() const {
64
77
  return new tools::baremetal::Linker(*this);
65
77
}
66
67
77
std::string BareMetal::getRuntimesDir() const {
68
77
  SmallString<128> Dir(getDriver().ResourceDir);
69
77
  llvm::sys::path::append(Dir, "lib", "baremetal");
70
77
  return std::string(Dir.str());
71
77
}
72
73
void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
74
336
                                          ArgStringList &CC1Args) const {
75
336
  if (DriverArgs.hasArg(options::OPT_nostdinc))
76
1
    return;
77
78
335
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
79
334
    SmallString<128> Dir(getDriver().ResourceDir);
80
334
    llvm::sys::path::append(Dir, "include");
81
334
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
82
334
  }
83
84
335
  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
85
334
    SmallString<128> Dir(getDriver().SysRoot);
86
334
    llvm::sys::path::append(Dir, "include");
87
334
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
88
334
  }
89
335
}
90
91
void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
92
                                      ArgStringList &CC1Args,
93
338
                                      Action::OffloadKind) const {
94
338
  CC1Args.push_back("-nostdsysteminc");
95
338
}
96
97
void BareMetal::AddClangCXXStdlibIncludeArgs(
98
13
    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
99
13
  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
100
12
      DriverArgs.hasArg(options::OPT_nostdlibinc) ||
101
11
      DriverArgs.hasArg(options::OPT_nostdincxx))
102
2
    return;
103
104
11
  StringRef SysRoot = getDriver().SysRoot;
105
11
  if (SysRoot.empty())
106
6
    return;
107
108
5
  switch (GetCXXStdlibType(DriverArgs)) {
109
4
  case ToolChain::CST_Libcxx: {
110
4
    SmallString<128> Dir(SysRoot);
111
4
    llvm::sys::path::append(Dir, "include", "c++", "v1");
112
4
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
113
4
    break;
114
0
  }
115
1
  case ToolChain::CST_Libstdcxx: {
116
1
    SmallString<128> Dir(SysRoot);
117
1
    llvm::sys::path::append(Dir, "include", "c++");
118
1
    std::error_code EC;
119
1
    Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""};
120
    // Walk the subdirs, and find the one with the newest gcc version:
121
1
    for (llvm::vfs::directory_iterator
122
1
             LI = getDriver().getVFS().dir_begin(Dir.str(), EC),
123
1
             LE;
124
4
         !EC && LI != LE; 
LI = LI.increment(EC)3
) {
125
3
      StringRef VersionText = llvm::sys::path::filename(LI->path());
126
3
      auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText);
127
3
      if (CandidateVersion.Major == -1)
128
1
        continue;
129
2
      if (CandidateVersion <= Version)
130
1
        continue;
131
1
      Version = CandidateVersion;
132
1
    }
133
1
    if (Version.Major == -1)
134
0
      return;
135
1
    llvm::sys::path::append(Dir, Version.Text);
136
1
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
137
1
    break;
138
1
  }
139
5
  }
140
5
}
141
142
void BareMetal::AddCXXStdlibLibArgs(const ArgList &Args,
143
3
                                    ArgStringList &CmdArgs) const {
144
3
  switch (GetCXXStdlibType(Args)) {
145
2
  case ToolChain::CST_Libcxx:
146
2
    CmdArgs.push_back("-lc++");
147
2
    CmdArgs.push_back("-lc++abi");
148
2
    break;
149
1
  case ToolChain::CST_Libstdcxx:
150
1
    CmdArgs.push_back("-lstdc++");
151
1
    CmdArgs.push_back("-lsupc++");
152
1
    break;
153
3
  }
154
3
  CmdArgs.push_back("-lunwind");
155
3
}
156
157
void BareMetal::AddLinkRuntimeLib(const ArgList &Args,
158
76
                                  ArgStringList &CmdArgs) const {
159
76
  ToolChain::RuntimeLibType RLT = GetRuntimeLibType(Args);
160
76
  switch (RLT) {
161
75
  case ToolChain::RLT_CompilerRT:
162
75
    CmdArgs.push_back(
163
75
        Args.MakeArgString("-lclang_rt.builtins-" + getTriple().getArchName()));
164
75
    return;
165
1
  case ToolChain::RLT_Libgcc:
166
1
    CmdArgs.push_back("-lgcc");
167
1
    return;
168
0
  }
169
0
  llvm_unreachable("Unhandled RuntimeLibType.");
170
0
}
171
172
void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
173
                                     const InputInfo &Output,
174
                                     const InputInfoList &Inputs,
175
                                     const ArgList &Args,
176
77
                                     const char *LinkingOutput) const {
177
77
  ArgStringList CmdArgs;
178
179
77
  auto &TC = static_cast<const toolchains::BareMetal&>(getToolChain());
180
181
77
  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
182
183
77
  CmdArgs.push_back("-Bstatic");
184
185
77
  CmdArgs.push_back(Args.MakeArgString("-L" + TC.getRuntimesDir()));
186
187
77
  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
188
77
                            options::OPT_e, options::OPT_s, options::OPT_t,
189
77
                            options::OPT_Z_Flag, options::OPT_r});
190
191
77
  if (TC.ShouldLinkCXXStdlib(Args))
192
3
    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
193
77
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
194
76
    CmdArgs.push_back("-lc");
195
76
    CmdArgs.push_back("-lm");
196
197
76
    TC.AddLinkRuntimeLib(Args, CmdArgs);
198
76
  }
199
200
77
  CmdArgs.push_back("-o");
201
77
  CmdArgs.push_back(Output.getFilename());
202
203
77
  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
204
77
                                         Args.MakeArgString(TC.GetLinkerPath()),
205
77
                                         CmdArgs, Inputs));
206
77
}