Coverage Report

Created: 2020-02-15 09:57

/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
327
    : ToolChain(D, Triple, Args) {
33
327
  getProgramPaths().push_back(getDriver().getInstalledDir());
34
327
  if (getDriver().getInstalledDir() != getDriver().Dir)
35
0
    getProgramPaths().push_back(getDriver().Dir);
36
327
}
37
38
327
BareMetal::~BareMetal() {}
39
40
/// Is the triple {arm,thumb}-none-none-{eabi,eabihf} ?
41
4.12k
static bool isARMBareMetal(const llvm::Triple &Triple) {
42
4.12k
  if (Triple.getArch() != llvm::Triple::arm &&
43
4.12k
      
Triple.getArch() != llvm::Triple::thumb3.34k
)
44
3.31k
    return false;
45
801
46
801
  if (Triple.getVendor() != llvm::Triple::UnknownVendor)
47
27
    return false;
48
774
49
774
  if (Triple.getOS() != llvm::Triple::UnknownOS)
50
2
    return false;
51
772
52
772
  if (Triple.getEnvironment() != llvm::Triple::EABI &&
53
772
      
Triple.getEnvironment() != llvm::Triple::EABIHF451
)
54
445
    return false;
55
327
56
327
  return true;
57
327
}
58
59
4.12k
bool BareMetal::handlesTarget(const llvm::Triple &Triple) {
60
4.12k
  return isARMBareMetal(Triple);
61
4.12k
}
62
63
67
Tool *BareMetal::buildLinker() const {
64
67
  return new tools::baremetal::Linker(*this);
65
67
}
66
67
67
std::string BareMetal::getRuntimesDir() const {
68
67
  SmallString<128> Dir(getDriver().ResourceDir);
69
67
  llvm::sys::path::append(Dir, "lib", "baremetal");
70
67
  return std::string(Dir.str());
71
67
}
72
73
void BareMetal::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
74
300
                                          ArgStringList &CC1Args) const {
75
300
  if (DriverArgs.hasArg(options::OPT_nostdinc))
76
1
    return;
77
299
78
299
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
79
298
    SmallString<128> Dir(getDriver().ResourceDir);
80
298
    llvm::sys::path::append(Dir, "include");
81
298
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
82
298
  }
83
299
84
299
  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
85
298
    SmallString<128> Dir(getDriver().SysRoot);
86
298
    llvm::sys::path::append(Dir, "include");
87
298
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
88
298
  }
89
299
}
90
91
void BareMetal::addClangTargetOptions(const ArgList &DriverArgs,
92
                                      ArgStringList &CC1Args,
93
300
                                      Action::OffloadKind) const {
94
300
  CC1Args.push_back("-nostdsysteminc");
95
300
}
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
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
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
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
66
                                  ArgStringList &CmdArgs) const {
159
66
  CmdArgs.push_back(Args.MakeArgString("-lclang_rt.builtins-" +
160
66
                                       getTriple().getArchName()));
161
66
}
162
163
void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
164
                                     const InputInfo &Output,
165
                                     const InputInfoList &Inputs,
166
                                     const ArgList &Args,
167
67
                                     const char *LinkingOutput) const {
168
67
  ArgStringList CmdArgs;
169
67
170
67
  auto &TC = static_cast<const toolchains::BareMetal&>(getToolChain());
171
67
172
67
  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
173
67
174
67
  CmdArgs.push_back("-Bstatic");
175
67
176
67
  CmdArgs.push_back(Args.MakeArgString("-L" + TC.getRuntimesDir()));
177
67
178
67
  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
179
67
                            options::OPT_e, options::OPT_s, options::OPT_t,
180
67
                            options::OPT_Z_Flag, options::OPT_r});
181
67
182
67
  if (TC.ShouldLinkCXXStdlib(Args))
183
3
    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
184
67
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
185
66
    CmdArgs.push_back("-lc");
186
66
    CmdArgs.push_back("-lm");
187
66
188
66
    TC.AddLinkRuntimeLib(Args, CmdArgs);
189
66
  }
190
67
191
67
  CmdArgs.push_back("-o");
192
67
  CmdArgs.push_back(Output.getFilename());
193
67
194
67
  C.addCommand(std::make_unique<Command>(JA, *this,
195
67
                                          Args.MakeArgString(TC.GetLinkerPath()),
196
67
                                          CmdArgs, Inputs));
197
67
}