Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/ToolChains/CrossWindows.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- CrossWindows.cpp - Cross Windows Tool Chain -----------------------===//
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 "CrossWindows.h"
10
#include "CommonArgs.h"
11
#include "clang/Driver/Compilation.h"
12
#include "clang/Driver/Driver.h"
13
#include "clang/Driver/Options.h"
14
#include "clang/Driver/SanitizerArgs.h"
15
#include "llvm/Option/ArgList.h"
16
#include "llvm/Support/Path.h"
17
18
using namespace clang::driver;
19
using namespace clang::driver::toolchains;
20
21
using llvm::opt::ArgList;
22
using llvm::opt::ArgStringList;
23
24
void tools::CrossWindows::Assembler::ConstructJob(
25
    Compilation &C, const JobAction &JA, const InputInfo &Output,
26
    const InputInfoList &Inputs, const ArgList &Args,
27
0
    const char *LinkingOutput) const {
28
0
  claimNoWarnArgs(Args);
29
0
  const auto &TC =
30
0
      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
31
0
  ArgStringList CmdArgs;
32
0
  const char *Exec;
33
0
34
0
  switch (TC.getArch()) {
35
0
  default:
36
0
    llvm_unreachable("unsupported architecture");
37
0
  case llvm::Triple::arm:
38
0
  case llvm::Triple::thumb:
39
0
  case llvm::Triple::aarch64:
40
0
    break;
41
0
  case llvm::Triple::x86:
42
0
    CmdArgs.push_back("--32");
43
0
    break;
44
0
  case llvm::Triple::x86_64:
45
0
    CmdArgs.push_back("--64");
46
0
    break;
47
0
  }
48
0
49
0
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
50
0
51
0
  CmdArgs.push_back("-o");
52
0
  CmdArgs.push_back(Output.getFilename());
53
0
54
0
  for (const auto &Input : Inputs)
55
0
    CmdArgs.push_back(Input.getFilename());
56
0
57
0
  const std::string Assembler = TC.GetProgramPath("as");
58
0
  Exec = Args.MakeArgString(Assembler);
59
0
60
0
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
61
0
}
62
63
void tools::CrossWindows::Linker::ConstructJob(
64
    Compilation &C, const JobAction &JA, const InputInfo &Output,
65
    const InputInfoList &Inputs, const ArgList &Args,
66
32
    const char *LinkingOutput) const {
67
32
  const auto &TC =
68
32
      static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
69
32
  const llvm::Triple &T = TC.getTriple();
70
32
  const Driver &D = TC.getDriver();
71
32
  SmallString<128> EntryPoint;
72
32
  ArgStringList CmdArgs;
73
32
  const char *Exec;
74
32
75
32
  // Silence warning for "clang -g foo.o -o foo"
76
32
  Args.ClaimAllArgs(options::OPT_g_Group);
77
32
  // and "clang -emit-llvm foo.o -o foo"
78
32
  Args.ClaimAllArgs(options::OPT_emit_llvm);
79
32
  // and for "clang -w foo.o -o foo"
80
32
  Args.ClaimAllArgs(options::OPT_w);
81
32
  // Other warning options are already handled somewhere else.
82
32
83
32
  if (!D.SysRoot.empty())
84
13
    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
85
32
86
32
  if (Args.hasArg(options::OPT_pie))
87
0
    CmdArgs.push_back("-pie");
88
32
  if (Args.hasArg(options::OPT_rdynamic))
89
0
    CmdArgs.push_back("-export-dynamic");
90
32
  if (Args.hasArg(options::OPT_s))
91
0
    CmdArgs.push_back("--strip-all");
92
32
93
32
  CmdArgs.push_back("-m");
94
32
  switch (TC.getArch()) {
95
32
  default:
96
0
    llvm_unreachable("unsupported architecture");
97
32
  case llvm::Triple::arm:
98
14
  case llvm::Triple::thumb:
99
14
    // FIXME: this is incorrect for WinCE
100
14
    CmdArgs.push_back("thumb2pe");
101
14
    break;
102
14
  case llvm::Triple::aarch64:
103
0
    CmdArgs.push_back("arm64pe");
104
0
    break;
105
14
  case llvm::Triple::x86:
106
10
    CmdArgs.push_back("i386pe");
107
10
    EntryPoint.append("_");
108
10
    break;
109
14
  case llvm::Triple::x86_64:
110
8
    CmdArgs.push_back("i386pep");
111
8
    break;
112
32
  }
113
32
114
32
  if (Args.hasArg(options::OPT_shared)) {
115
7
    switch (T.getArch()) {
116
7
    default:
117
0
      llvm_unreachable("unsupported architecture");
118
7
    case llvm::Triple::aarch64:
119
7
    case llvm::Triple::arm:
120
7
    case llvm::Triple::thumb:
121
7
    case llvm::Triple::x86_64:
122
7
      EntryPoint.append("_DllMainCRTStartup");
123
7
      break;
124
7
    case llvm::Triple::x86:
125
0
      EntryPoint.append("_DllMainCRTStartup@12");
126
0
      break;
127
7
    }
128
7
129
7
    CmdArgs.push_back("-shared");
130
7
    CmdArgs.push_back(Args.hasArg(options::OPT_static) ? 
"-Bstatic"1
131
7
                                                       : 
"-Bdynamic"6
);
132
7
133
7
    CmdArgs.push_back("--enable-auto-image-base");
134
7
135
7
    CmdArgs.push_back("--entry");
136
7
    CmdArgs.push_back(Args.MakeArgString(EntryPoint));
137
25
  } else {
138
25
    EntryPoint.append("mainCRTStartup");
139
25
140
25
    CmdArgs.push_back(Args.hasArg(options::OPT_static) ? 
"-Bstatic"1
141
25
                                                       : 
"-Bdynamic"24
);
142
25
143
25
    if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
144
25
      CmdArgs.push_back("--entry");
145
25
      CmdArgs.push_back(Args.MakeArgString(EntryPoint));
146
25
    }
147
25
148
25
    // FIXME: handle subsystem
149
25
  }
150
32
151
32
  // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
152
32
  CmdArgs.push_back("--allow-multiple-definition");
153
32
154
32
  CmdArgs.push_back("-o");
155
32
  CmdArgs.push_back(Output.getFilename());
156
32
157
32
  if (Args.hasArg(options::OPT_shared) || 
Args.hasArg(options::OPT_rdynamic)25
) {
158
7
    SmallString<261> ImpLib(Output.getFilename());
159
7
    llvm::sys::path::replace_extension(ImpLib, ".lib");
160
7
161
7
    CmdArgs.push_back("--out-implib");
162
7
    CmdArgs.push_back(Args.MakeArgString(ImpLib));
163
7
  }
164
32
165
32
  Args.AddAllArgs(CmdArgs, options::OPT_L);
166
32
  TC.AddFilePathLibArgs(Args, CmdArgs);
167
32
  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
168
32
169
32
  if (TC.ShouldLinkCXXStdlib(Args)) {
170
1
    bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
171
1
                     
!Args.hasArg(options::OPT_static)0
;
172
1
    if (StaticCXX)
173
0
      CmdArgs.push_back("-Bstatic");
174
1
    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
175
1
    if (StaticCXX)
176
0
      CmdArgs.push_back("-Bdynamic");
177
1
  }
178
32
179
32
  if (!Args.hasArg(options::OPT_nostdlib)) {
180
32
    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
181
31
      // TODO handle /MT[d] /MD[d]
182
31
      CmdArgs.push_back("-lmsvcrt");
183
31
      AddRunTimeLibs(TC, D, CmdArgs, Args);
184
31
    }
185
32
  }
186
32
187
32
  if (TC.getSanitizerArgs().needsAsanRt()) {
188
3
    // TODO handle /MT[d] /MD[d]
189
3
    if (Args.hasArg(options::OPT_shared)) {
190
1
      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
191
2
    } else {
192
2
      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
193
4
        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
194
2
      // Make sure the dynamic runtime thunk is not optimized out at link time
195
2
      // to ensure proper SEH handling.
196
2
      CmdArgs.push_back(Args.MakeArgString("--undefined"));
197
2
      CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
198
2
                                               ? 
"___asan_seh_interceptor"1
199
2
                                               : 
"__asan_seh_interceptor"1
));
200
2
    }
201
3
  }
202
32
203
32
  Exec = Args.MakeArgString(TC.GetLinkerPath());
204
32
205
32
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
206
32
}
207
208
CrossWindowsToolChain::CrossWindowsToolChain(const Driver &D,
209
                                             const llvm::Triple &T,
210
                                             const llvm::opt::ArgList &Args)
211
52
    : Generic_GCC(D, T, Args) {}
212
213
52
bool CrossWindowsToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
214
52
  // FIXME: all non-x86 targets need unwind tables, however, LLVM currently does
215
52
  // not know how to emit them.
216
52
  return getArch() == llvm::Triple::x86_64;
217
52
}
218
219
43
bool CrossWindowsToolChain::isPICDefault() const {
220
43
  return getArch() == llvm::Triple::x86_64;
221
43
}
222
223
52
bool CrossWindowsToolChain::isPIEDefault() const {
224
52
  return getArch() == llvm::Triple::x86_64;
225
52
}
226
227
44
bool CrossWindowsToolChain::isPICDefaultForced() const {
228
44
  return getArch() == llvm::Triple::x86_64;
229
44
}
230
231
void CrossWindowsToolChain::
232
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
233
52
                          llvm::opt::ArgStringList &CC1Args) const {
234
52
  const Driver &D = getDriver();
235
52
  const std::string &SysRoot = D.SysRoot;
236
52
237
52
  auto AddSystemAfterIncludes = [&]() {
238
52
    for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
239
4
      addSystemInclude(DriverArgs, CC1Args, P);
240
52
  };
241
52
242
52
  if (DriverArgs.hasArg(options::OPT_nostdinc)) {
243
1
    AddSystemAfterIncludes();
244
1
    return;
245
1
  }
246
51
247
51
  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
248
51
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
249
51
    SmallString<128> ResourceDir(D.ResourceDir);
250
51
    llvm::sys::path::append(ResourceDir, "include");
251
51
    addSystemInclude(DriverArgs, CC1Args, ResourceDir);
252
51
  }
253
51
  AddSystemAfterIncludes();
254
51
  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
255
51
}
256
257
void CrossWindowsToolChain::
258
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
259
25
                             llvm::opt::ArgStringList &CC1Args) const {
260
25
  const std::string &SysRoot = getDriver().SysRoot;
261
25
262
25
  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
263
25
      DriverArgs.hasArg(options::OPT_nostdincxx))
264
0
    return;
265
25
266
25
  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
267
1
    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
268
25
}
269
270
void CrossWindowsToolChain::
271
AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
272
1
                    llvm::opt::ArgStringList &CC1Args) const {
273
1
  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
274
1
    CC1Args.push_back("-lc++");
275
1
}
276
277
52
clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const {
278
52
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
279
52
  Res |= SanitizerKind::Address;
280
52
  Res |= SanitizerKind::PointerCompare;
281
52
  Res |= SanitizerKind::PointerSubtract;
282
52
  return Res;
283
52
}
284
285
32
Tool *CrossWindowsToolChain::buildLinker() const {
286
32
  return new tools::CrossWindows::Linker(*this);
287
32
}
288
289
0
Tool *CrossWindowsToolChain::buildAssembler() const {
290
0
  return new tools::CrossWindows::Assembler(*this);
291
0
}