clang  8.0.0svn
CrossWindows.cpp
Go to the documentation of this file.
1 //===--- CrossWindowsToolChain.cpp - Cross Windows Tool Chain -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CrossWindows.h"
11 #include "CommonArgs.h"
13 #include "clang/Driver/Driver.h"
14 #include "clang/Driver/Options.h"
16 #include "llvm/Option/ArgList.h"
17 #include "llvm/Support/Path.h"
18 
19 using namespace clang::driver;
20 using namespace clang::driver::toolchains;
21 
22 using llvm::opt::ArgList;
23 using llvm::opt::ArgStringList;
24 
26  Compilation &C, const JobAction &JA, const InputInfo &Output,
27  const InputInfoList &Inputs, const ArgList &Args,
28  const char *LinkingOutput) const {
29  claimNoWarnArgs(Args);
30  const auto &TC =
31  static_cast<const toolchains::CrossWindowsToolChain &>(getToolChain());
32  ArgStringList CmdArgs;
33  const char *Exec;
34 
35  switch (TC.getArch()) {
36  default:
37  llvm_unreachable("unsupported architecture");
38  case llvm::Triple::arm:
39  case llvm::Triple::thumb:
40  case llvm::Triple::aarch64:
41  break;
42  case llvm::Triple::x86:
43  CmdArgs.push_back("--32");
44  break;
45  case llvm::Triple::x86_64:
46  CmdArgs.push_back("--64");
47  break;
48  }
49 
50  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
51 
52  CmdArgs.push_back("-o");
53  CmdArgs.push_back(Output.getFilename());
54 
55  for (const auto &Input : Inputs)
56  CmdArgs.push_back(Input.getFilename());
57 
58  const std::string Assembler = TC.GetProgramPath("as");
59  Exec = Args.MakeArgString(Assembler);
60 
61  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
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(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
207 }
208 
210  const llvm::Triple &T,
211  const llvm::opt::ArgList &Args)
212  : Generic_GCC(D, T, Args) {}
213 
214 bool CrossWindowsToolChain::IsUnwindTablesDefault(const ArgList &Args) const {
215  // FIXME: all non-x86 targets need unwind tables, however, LLVM currently does
216  // not know how to emit them.
217  return getArch() == llvm::Triple::x86_64;
218 }
219 
221  return getArch() == llvm::Triple::x86_64;
222 }
223 
225  return getArch() == llvm::Triple::x86_64;
226 }
227 
229  return getArch() == llvm::Triple::x86_64;
230 }
231 
233 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
234  llvm::opt::ArgStringList &CC1Args) const {
235  const Driver &D = getDriver();
236  const std::string &SysRoot = D.SysRoot;
237 
238  auto AddSystemAfterIncludes = [&]() {
239  for (const auto &P : DriverArgs.getAllArgValues(options::OPT_isystem_after))
240  addSystemInclude(DriverArgs, CC1Args, P);
241  };
242 
243  if (DriverArgs.hasArg(options::OPT_nostdinc)) {
244  AddSystemAfterIncludes();
245  return;
246  }
247 
248  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/local/include");
249  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
250  SmallString<128> ResourceDir(D.ResourceDir);
251  llvm::sys::path::append(ResourceDir, "include");
252  addSystemInclude(DriverArgs, CC1Args, ResourceDir);
253  }
254  AddSystemAfterIncludes();
255  addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
256 }
257 
259 AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
260  llvm::opt::ArgStringList &CC1Args) const {
261  const std::string &SysRoot = getDriver().SysRoot;
262 
263  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
264  DriverArgs.hasArg(options::OPT_nostdincxx))
265  return;
266 
267  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
268  addSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include/c++/v1");
269 }
270 
272 AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
273  llvm::opt::ArgStringList &CC1Args) const {
274  if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx)
275  CC1Args.push_back("-lc++");
276 }
277 
280  Res |= SanitizerKind::Address;
281  return Res;
282 }
283 
285  return new tools::CrossWindows::Linker(*this);
286 }
287 
289  return new tools::CrossWindows::Assembler(*this);
290 }
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:717
Generic_GCC - A tool chain using the &#39;gcc&#39; command to perform all subcommands; this relies on gcc tra...
Definition: Gnu.h:140
StringRef P
bool isPICDefault() const override
Test whether this toolchain defaults to PIC.
void AddRunTimeLibs(const ToolChain &TC, const Driver &D, llvm::opt::ArgStringList &CmdArgs, const llvm::opt::ArgList &Args)
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...
const char * getFilename() const
Definition: InputInfo.h:84
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:23
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:58
CrossWindowsToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args)
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
void addCommand(std::unique_ptr< Command > C)
Definition: Compilation.h:206
bool isPIEDefault() const override
Test whether this toolchain defaults to PIE.
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
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...
llvm::Triple::ArchType getArch() const
Definition: ToolChain.h:201
const Driver & getDriver() const
Definition: ToolChain.h:185
bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override
IsUnwindTablesDefault - Does this tool chain use -funwind-tables by default.
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:702
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
std::string SysRoot
sysroot, if present
Definition: Driver.h:148
Tool - Information on a specific compilation tool.
Definition: Tool.h:34
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
uint64_t SanitizerMask
Definition: Sanitizers.h:26
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:46
const llvm::Triple & getTriple() const
Definition: ToolChain.h:187
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:818
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...
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const
Definition: ToolChain.cpp:683
bool isPICDefaultForced() const override
Tests whether this toolchain forces its default for PIC, PIE or non-PIC.
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...
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:132