Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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
299
    : ToolChain(D, Triple, Args) {
33
299
  getProgramPaths().push_back(getDriver().getInstalledDir());
34
299
  if (getDriver().getInstalledDir() != getDriver().Dir)
35
0
    getProgramPaths().push_back(getDriver().Dir);
36
299
}
37
38
299
BareMetal::~BareMetal() {}
39
40
/// Is the triple {arm,thumb}-none-none-{eabi,eabihf} ?
41
4.66k
static bool isARMBareMetal(const llvm::Triple &Triple) {
42
4.66k
  if (Triple.getArch() != llvm::Triple::arm &&
43
4.66k
      
Triple.getArch() != llvm::Triple::thumb3.11k
)
44
3.09k
    return false;
45
1.57k
46
1.57k
  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
47
811
    return false;
48
759
49
759
  if (Triple.getOS() != llvm::Triple::UnknownOS)
50
2
    return false;
51
757
52
757
  if (Triple.getEnvironment() != llvm::Triple::EABI &&
53
757
      
Triple.getEnvironment() != llvm::Triple::EABIHF464
)
54
458
    return false;
55
299
56
299
  return true;
57
299
}
58
59
4.66k
bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
60
4.66k
  return isARMBareMetal(Triple);
61
4.66k
}
62
63
66
Tool *BareMetal::buildLinker() const {
64
66
  return new tools::baremetal::Linker(*this);
65
66
}
66
67
66
std::string BareMetal::getRuntimesDir() const {
68
66
  SmallString<128> Dir(getDriver().ResourceDir);
69
66
  llvm::sys::path::append(Dir, "lib", "baremetal");
70
66
  return Dir.str();
71
66
}
72
73
void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
74
272
                                          ArgStringList &CC1Args) const {
75
272
  if (DriverArgs.hasArg(options::OPT_nostdinc))
76
1
    return;
77
271
78
271
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
79
270
    SmallString<128> Dir(getDriver().ResourceDir);
80
270
    llvm::sys::path::append(Dir, "include");
81
270
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
82
270
  }
83
271
84
271
  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
85
270
    SmallString<128> Dir(getDriver().SysRoot);
86
270
    llvm::sys::path::append(Dir, "include");
87
270
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
88
270
  }
89
271
}
90
91
void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
92
                                      ArgStringList &CC1Args,
93
272
                                      Action::OffloadKind) const {
94
272
  CC1Args.push_back("-nostdsysteminc");
95
272
}
96
97
void BareMetal::AddClangCXXStdlibIncludeArgs(
98
12
    const ArgList &DriverArgs, ArgStringList &CC1Args) const {
99
12
  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
100
12
      
DriverArgs.hasArg(options::OPT_nostdlibinc)11
||
101
12
      
DriverArgs.hasArg(options::OPT_nostdincxx)10
)
102
2
    return;
103
10
104
10
  StringRef SysRoot = getDriver().SysRoot;
105
10
  if (SysRoot.empty())
106
5
    return;
107
5
108
5
  switch (GetCXXStdlibType(DriverArgs)) {
109
5
  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
5
  }
115
5
  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
1
    // 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
3
  case ToolChain::CST_Libcxx:
146
2
    CmdArgs.push_back("-lc++");
147
2
    CmdArgs.push_back("-lc++abi");
148
2
    break;
149
3
  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
65
                                  ArgStringList &CmdArgs) const {
159
65
  CmdArgs.push_back(Args.MakeArgString("-lclang_rt.builtins-" +
160
65
                                       getTriple().getArchName() + ".a"));
161
65
}
162
163
void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
164
                                     const InputInfo &Output,
165
                                     const InputInfoList &Inputs,
166
                                     const ArgList &Args,
167
66
                                     const char *LinkingOutput) const {
168
66
  ArgStringList CmdArgs;
169
66
170
66
  auto &TC = static_cast<const toolchains::BareMetal&>(getToolChain());
171
66
172
66
  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
173
66
174
66
  CmdArgs.push_back("-Bstatic");
175
66
176
66
  CmdArgs.push_back(Args.MakeArgString("-L" + TC.getRuntimesDir()));
177
66
178
66
  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
179
66
                            options::OPT_e, options::OPT_s, options::OPT_t,
180
66
                            options::OPT_Z_Flag, options::OPT_r});
181
66
182
66
  if (TC.ShouldLinkCXXStdlib(Args))
183
3
    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
184
66
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
185
65
    CmdArgs.push_back("-lc");
186
65
    CmdArgs.push_back("-lm");
187
65
188
65
    TC.AddLinkRuntimeLib(Args, CmdArgs);
189
65
  }
190
66
191
66
  CmdArgs.push_back("-o");
192
66
  CmdArgs.push_back(Output.getFilename());
193
66
194
66
  C.addCommand(llvm::make_unique<Command>(JA, *this,
195
66
                                          Args.MakeArgString(TC.GetLinkerPath()),
196
66
                                          CmdArgs, Inputs));
197
66
}