clang  14.0.0git
CrossWindows.cpp
Go to the documentation of this file.
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"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/Options.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 
25  Compilation &C, const JobAction &JA, const InputInfo &Output,
26  const InputInfoList &Inputs, const ArgList &Args,
27  const char *LinkingOutput) const {
28  claimNoWarnArgs(Args);
29  const auto &TC =
30  static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
31  ArgStringList CmdArgs;
32  const char *Exec;
33 
34  switch (TC.getArch()) {
35  default:
36  llvm_unreachable("unsupported architecture");
37  case llvm::Triple::arm:
38  case llvm::Triple::thumb:
39  case llvm::Triple::aarch64:
40  break;
41  case llvm::Triple::x86:
42  CmdArgs.push_back("--32");
43  break;
44  case llvm::Triple::x86_64:
45  CmdArgs.push_back("--64");
46  break;
47  }
48 
49  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
50 
51  CmdArgs.push_back("-o");
52  CmdArgs.push_back(Output.getFilename());
53 
54  for (const auto &Input : Inputs)
55  CmdArgs.push_back(Input.getFilename());
56 
57  const std::string Assembler = TC.GetProgramPath("as");
58  Exec = Args.MakeArgString(Assembler);
59 
60  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
61  Exec, CmdArgs, Inputs, Output));
62 }
63 
65  Compilation &C, const JobAction &JA, const InputInfo &Output,
66  const InputInfoList &Inputs, const ArgList &Args,
67  const char *LinkingOutput) const {
68  const auto &TC =
69  static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
70  const llvm::Triple &T = TC.getTriple();
71  const Driver &D = TC.getDriver();
72  SmallString<128> EntryPoint;
73  ArgStringList CmdArgs;
74  const char *Exec;
75 
76  // Silence warning for "clang -g foo.o -o foo"
77  Args.ClaimAllArgs(options::OPT_g_Group);
78  // and "clang -emit-llvm foo.o -o foo"
79  Args.ClaimAllArgs(options::OPT_emit_llvm);
80  // and for "clang -w foo.o -o foo"
81  Args.ClaimAllArgs(options::OPT_w);
82  // Other warning options are already handled somewhere else.
83 
84  if (!D.SysRoot.empty())
85  CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
86 
87  if (Args.hasArg(options::OPT_pie))
88  CmdArgs.push_back("-pie");
89  if (Args.hasArg(options::OPT_rdynamic))
90  CmdArgs.push_back("-export-dynamic");
91  if (Args.hasArg(options::OPT_s))
92  CmdArgs.push_back("--strip-all");
93 
94  CmdArgs.push_back("-m");
95  switch (TC.getArch()) {
96  default:
97  llvm_unreachable("unsupported architecture");
98  case llvm::Triple::arm:
99  case llvm::Triple::thumb:
100  // FIXME: this is incorrect for WinCE
101  CmdArgs.push_back("thumb2pe");
102  break;
103  case llvm::Triple::aarch64:
104  CmdArgs.push_back("arm64pe");
105  break;
106  case llvm::Triple::x86:
107  CmdArgs.push_back("i386pe");
108  EntryPoint.append("_");
109  break;
110  case llvm::Triple::x86_64:
111  CmdArgs.push_back("i386pep");
112  break;
113  }
114 
115  if (Args.hasArg(options::OPT_shared)) {
116  switch (T.getArch()) {
117  default:
118  llvm_unreachable("unsupported architecture");
119  case llvm::Triple::aarch64:
120  case llvm::Triple::arm:
121  case llvm::Triple::thumb:
122  case llvm::Triple::x86_64:
123  EntryPoint.append("_DllMainCRTStartup");
124  break;
125  case llvm::Triple::x86:
126  EntryPoint.append("_DllMainCRTStartup@12");
127  break;
128  }
129 
130  CmdArgs.push_back("-shared");
131  CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
132  : "-Bdynamic");
133 
134  CmdArgs.push_back("--enable-auto-image-base");
135 
136  CmdArgs.push_back("--entry");
137  CmdArgs.push_back(Args.MakeArgString(EntryPoint));
138  } else {
139  EntryPoint.append("mainCRTStartup");
140 
141  CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
142  : "-Bdynamic");
143 
144  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
145  CmdArgs.push_back("--entry");
146  CmdArgs.push_back(Args.MakeArgString(EntryPoint));
147  }
148 
149  // FIXME: handle subsystem
150  }
151 
152  // NOTE: deal with multiple definitions on Windows (e.g. COMDAT)
153  CmdArgs.push_back("--allow-multiple-definition");
154 
155  CmdArgs.push_back("-o");
156  CmdArgs.push_back(Output.getFilename());
157 
158  if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_rdynamic)) {
159  SmallString<261> ImpLib(Output.getFilename());
160  llvm::sys::path::replace_extension(ImpLib, ".lib");
161 
162  CmdArgs.push_back("--out-implib");
163  CmdArgs.push_back(Args.MakeArgString(ImpLib));
164  }
165 
166  Args.AddAllArgs(CmdArgs, options::OPT_L);
167  TC.AddFilePathLibArgs(Args, CmdArgs);
168  AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
169 
170  if (TC.ShouldLinkCXXStdlib(Args)) {
171  bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
172  !Args.hasArg(options::OPT_static);
173  if (StaticCXX)
174  CmdArgs.push_back("-Bstatic");
175  TC.AddCXXStdlibLibArgs(Args, CmdArgs);
176  if (StaticCXX)
177  CmdArgs.push_back("-Bdynamic");
178  }
179 
180  if (!Args.hasArg(options::OPT_nostdlib)) {
181  if (!Args.hasArg(options::OPT_nodefaultlibs)) {
182  // TODO handle /MT[d] /MD[d]
183  CmdArgs.push_back("-lmsvcrt");
184  AddRunTimeLibs(TC, D, CmdArgs, Args);
185  }
186  }
187 
188  if (TC.getSanitizerArgs().needsAsanRt()) {
189  // TODO handle /MT[d] /MD[d]
190  if (Args.hasArg(options::OPT_shared)) {
191  CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
192  } else {
193  for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
194  CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
195  // Make sure the dynamic runtime thunk is not optimized out at link time
196  // to ensure proper SEH handling.
197  CmdArgs.push_back(Args.MakeArgString("--undefined"));
198  CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
199  ? "___asan_seh_interceptor"
200  : "__asan_seh_interceptor"));
201  }
202  }
203 
204  Exec = Args.MakeArgString(TC.GetLinkerPath());
205 
206  C.addCommand(std::make_unique<Command>(JA, *this,
208  Exec, CmdArgs, Inputs, Output));
209 }
210 
212  const llvm::Triple &T,
213  const llvm::opt::ArgList &Args)
214  : Generic_GCC(D, T, Args) {}
215 
216 bool CrossWindowsToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
217  // FIXME: all non-x86 targets need unwind tables, however, LLVM currently does
218  // not know how to emit them.
219  return getArch() == llvm::Triple::x86_64;
220 }
221 
223  return getArch() == llvm::Triple::x86_64;
224 }
225 
227  return getArch() == llvm::Triple::x86_64;
228 }
229 
231  return getArch() == llvm::Triple::x86_64;
232 }
233 
235 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
236  llvm::opt::ArgStringList &CC1Args) const {
237  const Driver &D = getDriver();
238  const std::string &SysRoot = D.SysRoot;
239 
240  auto AddSystemAfterIncludes = [&]() {
241  for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
242  addSystemInclude(DriverArgs, CC1Args, P);
243  };
244 
245  if (DriverArgs.hasArg(options::OPT_nostdinc)) {
246  AddSystemAfterIncludes();
247  return;
248  }
249 
250  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
251  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
252  SmallString<128> ResourceDir(D.ResourceDir);
253  llvm::sys::path::append(ResourceDir, "include");
254  addSystemInclude(DriverArgs, CC1Args, ResourceDir);
255  }
256  AddSystemAfterIncludes();
257  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
258 }
259 
261 AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
262  llvm::opt::ArgStringList &CC1Args) const {
263  const std::string &SysRoot = getDriver().SysRoot;
264 
265  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
266  DriverArgs.hasArg(options::OPT_nostdincxx))
267  return;
268 
269  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
270  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
271 }
272 
274 AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
275  llvm::opt::ArgStringList &CmdArgs) const {
277  CmdArgs.push_back("-lc++");
278 }
279 
282  Res |= SanitizerKind::Address;
283  Res |= SanitizerKind::PointerCompare;
284  Res |= SanitizerKind::PointerSubtract;
285  return Res;
286 }
287 
289  return new tools::CrossWindows::Linker(*this);
290 }
291 
293  return new tools::CrossWindows::Assembler(*this);
294 }
clang::driver::toolchains
Definition: AIX.h:55
clang::driver::tools::CrossWindows::Linker
Definition: CrossWindows.h:35
Driver.h
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::driver::toolchains::CrossWindowsToolChain::AddClangSystemIncludeArgs
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: CrossWindows.cpp:235
clang::driver::ResponseFileSupport::AtFileUTF8
static constexpr ResponseFileSupport AtFileUTF8()
Definition: Job.h:85
clang::driver::toolchains::CrossWindowsToolChain::isPICDefaultForced
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
Definition: CrossWindows.cpp:230
llvm::SmallVector
Definition: LLVM.h:38
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:221
clang::driver::InputInfo
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
clang::driver::tools::AddLinkerInputs
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
clang::driver::toolchains::CrossWindowsToolChain::CrossWindowsToolChain
CrossWindowsToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
Definition: CrossWindows.cpp:211
clang::driver::tools::CrossWindows::Assembler::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: CrossWindows.cpp:24
clang::driver::Tool
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
clang::driver::tools::claimNoWarnArgs
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
Options.h
clang::driver::toolchains::CrossWindowsToolChain::AddCXXStdlibLibArgs
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override
AddCXXStdlibLibArgs - Add the system specific linker arguments to use for the given C++ standard libr...
Definition: CrossWindows.cpp:274
llvm::SmallString< 128 >
clang::driver::ToolChain::getTriple
const llvm::Triple & getTriple() const
Definition: ToolChain.h:223
clang::driver::Driver::SysRoot
std::string SysRoot
sysroot, if present
Definition: Driver.h:151
clang::driver::ToolChain::CST_Libcxx
@ CST_Libcxx
Definition: ToolChain.h:96
clang::driver::toolchains::CrossWindowsToolChain::AddClangCXXStdlibIncludeArgs
void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set the include paths to use for...
Definition: CrossWindows.cpp:261
SanitizerArgs.h
clang::driver::Driver::ResourceDir
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:135
clang::driver::ToolChain::getArch
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:237
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::driver::toolchains::CrossWindowsToolChain::getSupportedSanitizers
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition: CrossWindows.cpp:280
clang::driver::ToolChain::getSupportedSanitizers
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:998
Compilation.h
clang::driver::tools::AddRunTimeLibs
void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args)
clang::driver::toolchains::CrossWindowsToolChain::IsUnwindTablesDefault
bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override
IsUnwindTablesDefault - Does this tool chain use -funwind-tables by default.
Definition: CrossWindows.cpp:216
clang::driver::Compilation
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
clang::driver::toolchains::CrossWindowsToolChain::isPIEDefault
bool isPIEDefault() const override
Test whether this toolchain defaults to PIE.
Definition: CrossWindows.cpp:226
clang::driver::toolchains::CrossWindowsToolChain::isPICDefault
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
Definition: CrossWindows.cpp:222
clang::driver::ToolChain::GetCXXStdlibType
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:819
clang::driver::InputInfo::getFilename
const char * getFilename() const
Definition: InputInfo.h:83
CommonArgs.h
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
clang::driver::tools::CrossWindows::Linker::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: CrossWindows.cpp:64
clang::driver::toolchains::CrossWindowsToolChain::buildLinker
Tool * buildLinker() const override
Definition: CrossWindows.cpp:288
CrossWindows.h
clang::driver::tools::CrossWindows::Assembler
Definition: CrossWindows.h:23
clang::driver::ToolChain::addExternCSystemInclude
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
Definition: ToolChain.cpp:860
clang::driver
Definition: Action.h:31
clang::driver::ResponseFileSupport::None
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition: Job.h:78
clang::driver::ToolChain::addSystemInclude
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
Definition: ToolChain.cpp:845
clang::driver::toolchains::CrossWindowsToolChain
Definition: CrossWindows.h:52
clang::driver::toolchains::CrossWindowsToolChain::buildAssembler
Tool * buildAssembler() const override
Definition: CrossWindows.cpp:292
clang::driver::JobAction
Definition: Action.h:380
clang::SanitizerMask
Definition: Sanitizers.h:30
clang::driver::toolchains::Generic_GCC
Generic_GCC - A tool chain using the 'gcc' command to perform all subcommands; this relies on gcc tra...
Definition: Gnu.h:144