Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/ToolChains/Gnu.h
Line
Count
Source (jump to first uncovered line)
1
//===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- 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
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
10
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H
11
12
#include "Cuda.h"
13
#include "clang/Driver/Tool.h"
14
#include "clang/Driver/ToolChain.h"
15
#include <set>
16
17
namespace clang {
18
namespace driver {
19
20
struct DetectedMultilibs {
21
  /// The set of multilibs that the detected installation supports.
22
  MultilibSet Multilibs;
23
24
  /// The primary multilib appropriate for the given flags.
25
  Multilib SelectedMultilib;
26
27
  /// On Biarch systems, this corresponds to the default multilib when
28
  /// targeting the non-default multilib. Otherwise, it is empty.
29
  llvm::Optional<Multilib> BiarchSibling;
30
};
31
32
bool findMIPSMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
33
                       StringRef Path, const llvm::opt::ArgList &Args,
34
                       DetectedMultilibs &Result);
35
36
namespace tools {
37
38
/// Base class for all GNU tools that provide the same behavior when
39
/// it comes to response files support
40
class LLVM_LIBRARY_VISIBILITY GnuTool : public Tool {
41
  virtual void anchor();
42
43
public:
44
  GnuTool(const char *Name, const char *ShortName, const ToolChain &TC)
45
2.50k
      : Tool(Name, ShortName, TC, RF_Full, llvm::sys::WEM_CurrentCodePage) {}
46
};
47
48
/// Directly call GNU Binutils' assembler and linker.
49
namespace gnutools {
50
class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
51
public:
52
340
  Assembler(const ToolChain &TC) : GnuTool("GNU::Assembler", "assembler", TC) {}
53
54
340
  bool hasIntegratedCPP() const override { return false; }
55
56
  void ConstructJob(Compilation &C, const JobAction &JA,
57
                    const InputInfo &Output, const InputInfoList &Inputs,
58
                    const llvm::opt::ArgList &TCArgs,
59
                    const char *LinkingOutput) const override;
60
};
61
62
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
63
public:
64
1.35k
  Linker(const ToolChain &TC) : GnuTool("GNU::Linker", "linker", TC) {}
65
66
1.33k
  bool hasIntegratedCPP() const override { return false; }
67
0
  bool isLinkJob() const override { return true; }
68
69
  void ConstructJob(Compilation &C, const JobAction &JA,
70
                    const InputInfo &Output, const InputInfoList &Inputs,
71
                    const llvm::opt::ArgList &TCArgs,
72
                    const char *LinkingOutput) const override;
73
};
74
} // end namespace gnutools
75
76
/// gcc - Generic GCC tool implementations.
77
namespace gcc {
78
class LLVM_LIBRARY_VISIBILITY Common : public GnuTool {
79
public:
80
  Common(const char *Name, const char *ShortName, const ToolChain &TC)
81
256
      : GnuTool(Name, ShortName, TC) {}
82
83
  // A gcc tool has an "integrated" assembler that it will call to produce an
84
  // object. Let it use that assembler so that we don't have to deal with
85
  // assembly syntax incompatibilities.
86
3
  bool hasIntegratedAssembler() const override { return true; }
87
  void ConstructJob(Compilation &C, const JobAction &JA,
88
                    const InputInfo &Output, const InputInfoList &Inputs,
89
                    const llvm::opt::ArgList &TCArgs,
90
                    const char *LinkingOutput) const override;
91
92
  /// RenderExtraToolArgs - Render any arguments necessary to force
93
  /// the particular tool mode.
94
  virtual void RenderExtraToolArgs(const JobAction &JA,
95
                                   llvm::opt::ArgStringList &CmdArgs) const = 0;
96
};
97
98
class LLVM_LIBRARY_VISIBILITY Preprocessor : public Common {
99
public:
100
  Preprocessor(const ToolChain &TC)
101
0
      : Common("gcc::Preprocessor", "gcc preprocessor", TC) {}
102
103
0
  bool hasGoodDiagnostics() const override { return true; }
104
0
  bool hasIntegratedCPP() const override { return false; }
105
106
  void RenderExtraToolArgs(const JobAction &JA,
107
                           llvm::opt::ArgStringList &CmdArgs) const override;
108
};
109
110
class LLVM_LIBRARY_VISIBILITY Compiler : public Common {
111
public:
112
6
  Compiler(const ToolChain &TC) : Common("gcc::Compiler", "gcc frontend", TC) {}
113
114
0
  bool hasGoodDiagnostics() const override { return true; }
115
6
  bool hasIntegratedCPP() const override { return true; }
116
117
  void RenderExtraToolArgs(const JobAction &JA,
118
                           llvm::opt::ArgStringList &CmdArgs) const override;
119
};
120
121
class LLVM_LIBRARY_VISIBILITY Linker : public Common {
122
public:
123
250
  Linker(const ToolChain &TC) : Common("gcc::Linker", "linker (via gcc)", TC) {}
124
125
250
  bool hasIntegratedCPP() const override { return false; }
126
0
  bool isLinkJob() const override { return true; }
127
128
  void RenderExtraToolArgs(const JobAction &JA,
129
                           llvm::opt::ArgStringList &CmdArgs) const override;
130
};
131
} // end namespace gcc
132
} // end namespace tools
133
134
namespace toolchains {
135
136
/// Generic_GCC - A tool chain using the 'gcc' command to perform
137
/// all subcommands; this relies on gcc translating the majority of
138
/// command line options.
139
class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
140
public:
141
  /// Struct to store and manipulate GCC versions.
142
  ///
143
  /// We rely on assumptions about the form and structure of GCC version
144
  /// numbers: they consist of at most three '.'-separated components, and each
145
  /// component is a non-negative integer except for the last component. For
146
  /// the last component we are very flexible in order to tolerate release
147
  /// candidates or 'x' wildcards.
148
  ///
149
  /// Note that the ordering established among GCCVersions is based on the
150
  /// preferred version string to use. For example we prefer versions without
151
  /// a hard-coded patch number to those with a hard coded patch number.
152
  ///
153
  /// Currently this doesn't provide any logic for textual suffixes to patches
154
  /// in the way that (for example) Debian's version format does. If that ever
155
  /// becomes necessary, it can be added.
156
  struct GCCVersion {
157
    /// The unparsed text of the version.
158
    std::string Text;
159
160
    /// The parsed major, minor, and patch numbers.
161
    int Major, Minor, Patch;
162
163
    /// The text of the parsed major, and major+minor versions.
164
    std::string MajorStr, MinorStr;
165
166
    /// Any textual suffix on the patch number.
167
    std::string PatchSuffix;
168
169
    static GCCVersion Parse(StringRef VersionText);
170
    bool isOlderThan(int RHSMajor, int RHSMinor, int RHSPatch,
171
                     StringRef RHSPatchSuffix = StringRef()) const;
172
586
    bool operator<(const GCCVersion &RHS) const {
173
586
      return isOlderThan(RHS.Major, RHS.Minor, RHS.Patch, RHS.PatchSuffix);
174
586
    }
175
586
    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
176
586
    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
177
0
    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
178
  };
179
180
  /// This is a class to find a viable GCC installation for Clang to
181
  /// use.
182
  ///
183
  /// This class tries to find a GCC installation on the system, and report
184
  /// information about it. It starts from the host information provided to the
185
  /// Driver, and has logic for fuzzing that where appropriate.
186
  class GCCInstallationDetector {
187
    bool IsValid;
188
    llvm::Triple GCCTriple;
189
    const Driver &D;
190
191
    // FIXME: These might be better as path objects.
192
    std::string GCCInstallPath;
193
    std::string GCCParentLibPath;
194
195
    /// The primary multilib appropriate for the given flags.
196
    Multilib SelectedMultilib;
197
    /// On Biarch systems, this corresponds to the default multilib when
198
    /// targeting the non-default multilib. Otherwise, it is empty.
199
    llvm::Optional<Multilib> BiarchSibling;
200
201
    GCCVersion Version;
202
203
    // We retain the list of install paths that were considered and rejected in
204
    // order to print out detailed information in verbose mode.
205
    std::set<std::string> CandidateGCCInstallPaths;
206
207
    /// The set of multilibs that the detected installation supports.
208
    MultilibSet Multilibs;
209
210
  public:
211
7.60k
    explicit GCCInstallationDetector(const Driver &D) : IsValid(false), D(D) {}
212
    void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args,
213
              ArrayRef<std::string> ExtraTripleAliases = None);
214
215
    /// Check whether we detected a valid GCC install.
216
23.7k
    bool isValid() const { return IsValid; }
217
218
    /// Get the GCC triple for the detected install.
219
2.41k
    const llvm::Triple &getTriple() const { return GCCTriple; }
220
221
    /// Get the detected GCC installation path.
222
1.71k
    StringRef getInstallPath() const { return GCCInstallPath; }
223
224
    /// Get the detected GCC parent lib path.
225
4.67k
    StringRef getParentLibPath() const { return GCCParentLibPath; }
226
227
    /// Get the detected Multilib
228
4.32k
    const Multilib &getMultilib() const { return SelectedMultilib; }
229
230
    /// Get the whole MultilibSet
231
3.19k
    const MultilibSet &getMultilibs() const { return Multilibs; }
232
233
    /// Get the biarch sibling multilib (if it exists).
234
    /// \return true iff such a sibling exists
235
    bool getBiarchSibling(Multilib &M) const;
236
237
    /// Get the detected GCC version string.
238
7.25k
    const GCCVersion &getVersion() const { return Version; }
239
240
    /// Print information about the detected GCC installation.
241
    void print(raw_ostream &OS) const;
242
243
  private:
244
    static void
245
    CollectLibDirsAndTriples(const llvm::Triple &TargetTriple,
246
                             const llvm::Triple &BiarchTriple,
247
                             SmallVectorImpl<StringRef> &LibDirs,
248
                             SmallVectorImpl<StringRef> &TripleAliases,
249
                             SmallVectorImpl<StringRef> &BiarchLibDirs,
250
                             SmallVectorImpl<StringRef> &BiarchTripleAliases);
251
252
    void AddDefaultGCCPrefixes(const llvm::Triple &TargetTriple,
253
                               SmallVectorImpl<std::string> &Prefixes,
254
                               StringRef SysRoot);
255
256
    bool ScanGCCForMultilibs(const llvm::Triple &TargetTriple,
257
                             const llvm::opt::ArgList &Args,
258
                             StringRef Path,
259
                             bool NeedsBiarchSuffix = false);
260
261
    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
262
                                const llvm::opt::ArgList &Args,
263
                                const std::string &LibDir,
264
                                StringRef CandidateTriple,
265
                                bool NeedsBiarchSuffix = false);
266
267
    bool ScanGentooConfigs(const llvm::Triple &TargetTriple,
268
                           const llvm::opt::ArgList &Args,
269
                           const SmallVectorImpl<StringRef> &CandidateTriples,
270
                           const SmallVectorImpl<StringRef> &BiarchTriples);
271
272
    bool ScanGentooGccConfig(const llvm::Triple &TargetTriple,
273
                             const llvm::opt::ArgList &Args,
274
                             StringRef CandidateTriple,
275
                             bool NeedsBiarchSuffix = false);
276
  };
277
278
protected:
279
  GCCInstallationDetector GCCInstallation;
280
  CudaInstallationDetector CudaInstallation;
281
282
public:
283
  Generic_GCC(const Driver &D, const llvm::Triple &Triple,
284
              const llvm::opt::ArgList &Args);
285
  ~Generic_GCC() override;
286
287
  void printVerboseInfo(raw_ostream &OS) const override;
288
289
  bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const override;
290
  bool isPICDefault() const override;
291
  bool isPIEDefault() const override;
292
  bool isPICDefaultForced() const override;
293
  bool IsIntegratedAssemblerDefault() const override;
294
  llvm::opt::DerivedArgList *
295
  TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
296
                Action::OffloadKind DeviceOffloadKind) const override;
297
298
protected:
299
  Tool *getTool(Action::ActionClass AC) const override;
300
  Tool *buildAssembler() const override;
301
  Tool *buildLinker() const override;
302
303
  /// \name ToolChain Implementation Helper Functions
304
  /// @{
305
306
  /// Check whether the target triple's architecture is 64-bits.
307
0
  bool isTarget64Bit() const { return getTriple().isArch64Bit(); }
308
309
  /// Check whether the target triple's architecture is 32-bits.
310
0
  bool isTarget32Bit() const { return getTriple().isArch32Bit(); }
311
312
  // FIXME: This should be final, but the CrossWindows toolchain does weird
313
  // things that can't be easily generalized.
314
  void AddClangCXXStdlibIncludeArgs(
315
      const llvm::opt::ArgList &DriverArgs,
316
      llvm::opt::ArgStringList &CC1Args) const override;
317
318
  virtual void
319
  addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
320
                        llvm::opt::ArgStringList &CC1Args) const;
321
  virtual void
322
  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
323
                           llvm::opt::ArgStringList &CC1Args) const;
324
325
  bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix, StringRef GCCTriple,
326
                                StringRef GCCMultiarchTriple,
327
                                StringRef TargetMultiarchTriple,
328
                                Twine IncludeSuffix,
329
                                const llvm::opt::ArgList &DriverArgs,
330
                                llvm::opt::ArgStringList &CC1Args) const;
331
332
  /// @}
333
334
private:
335
  mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocess;
336
  mutable std::unique_ptr<tools::gcc::Compiler> Compile;
337
};
338
339
class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
340
  virtual void anchor();
341
342
public:
343
  Generic_ELF(const Driver &D, const llvm::Triple &Triple,
344
              const llvm::opt::ArgList &Args)
345
7.53k
      : Generic_GCC(D, Triple, Args) {}
346
347
  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
348
                             llvm::opt::ArgStringList &CC1Args,
349
                             Action::OffloadKind DeviceOffloadKind) const override;
350
};
351
352
} // end namespace toolchains
353
} // end namespace driver
354
} // end namespace clang
355
356
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_GNU_H