]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/MinGWToolChain.cpp
Merge ^/head r285284 through r285340.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Driver / MinGWToolChain.cpp
1 //===--- MinGWToolChain.cpp - MinGWToolChain Implementation
2 //-----------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "ToolChains.h"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/Options.h"
14 #include "llvm/Option/ArgList.h"
15 #include "llvm/Support/FileSystem.h"
16 #include "llvm/Support/Path.h"
17
18 using namespace clang::diag;
19 using namespace clang::driver;
20 using namespace clang::driver::toolchains;
21 using namespace clang;
22 using namespace llvm::opt;
23
24 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
25     : ToolChain(D, Triple, Args) {
26   getProgramPaths().push_back(getDriver().getInstalledDir());
27
28   if (getDriver().SysRoot.size())
29     Base = getDriver().SysRoot;
30   else if (llvm::ErrorOr<std::string> GPPName =
31                llvm::sys::findProgramByName("gcc"))
32     Base = llvm::sys::path::parent_path(
33         llvm::sys::path::parent_path(GPPName.get()));
34   else
35     Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
36   Base += llvm::sys::path::get_separator();
37   llvm::SmallString<1024> LibDir(Base);
38   llvm::sys::path::append(LibDir, "lib", "gcc");
39   LibDir += llvm::sys::path::get_separator();
40
41   // First look for mingw-w64.
42   Arch = getTriple().getArchName();
43   Arch += "-w64-mingw32";
44   std::error_code EC;
45   llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
46   if (!EC) {
47     GccLibDir = MingW64Entry->path();
48   } else {
49     // If mingw-w64 not found, try looking for mingw.org.
50     Arch = "mingw32";
51     llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
52     if (!EC)
53       GccLibDir = MingwOrgEntry->path();
54   }
55   Arch += llvm::sys::path::get_separator();
56   // GccLibDir must precede Base/lib so that the
57   // correct crtbegin.o ,cetend.o would be found.
58   getFilePaths().push_back(GccLibDir);
59   getFilePaths().push_back(Base + "lib");
60   getFilePaths().push_back(Base + Arch + "lib");
61 }
62
63 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
64
65 Tool *MinGW::getTool(Action::ActionClass AC) const {
66   switch (AC) {
67   case Action::PreprocessJobClass:
68     if (!Preprocessor)
69       Preprocessor.reset(new tools::gcc::Preprocessor(*this));
70     return Preprocessor.get();
71   case Action::CompileJobClass:
72     if (!Compiler)
73       Compiler.reset(new tools::gcc::Compiler(*this));
74     return Compiler.get();
75   default:
76     return ToolChain::getTool(AC);
77   }
78 }
79
80 Tool *MinGW::buildAssembler() const {
81   return new tools::MinGW::Assembler(*this);
82 }
83
84 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
85
86 bool MinGW::IsUnwindTablesDefault() const {
87   return getArch() == llvm::Triple::x86_64;
88 }
89
90 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
91
92 bool MinGW::isPIEDefault() const { return false; }
93
94 bool MinGW::isPICDefaultForced() const {
95   return getArch() == llvm::Triple::x86_64;
96 }
97
98 bool MinGW::UseSEHExceptions() const {
99   return getArch() == llvm::Triple::x86_64;
100 }
101
102 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
103                                       ArgStringList &CC1Args) const {
104   if (DriverArgs.hasArg(options::OPT_nostdinc))
105     return;
106
107   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
108     SmallString<1024> P(getDriver().ResourceDir);
109     llvm::sys::path::append(P, "include");
110     addSystemInclude(DriverArgs, CC1Args, P.str());
111   }
112
113   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
114     return;
115
116   llvm::SmallString<1024> IncludeDir(GccLibDir);
117   llvm::sys::path::append(IncludeDir, "include");
118   addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
119   IncludeDir += "-fixed";
120   addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
121   addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
122   addSystemInclude(DriverArgs, CC1Args, Base + "include");
123 }
124
125 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
126                                          ArgStringList &CC1Args) const {
127   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
128       DriverArgs.hasArg(options::OPT_nostdincxx))
129     return;
130
131   llvm::SmallString<1024> IncludeDir;
132   for (bool MingW64 : {true, false}) {
133     if (MingW64)
134       IncludeDir = Base + Arch;
135     else
136       IncludeDir = GccLibDir;
137     llvm::sys::path::append(IncludeDir, "include", "c++");
138     addSystemInclude(DriverArgs, CC1Args, IncludeDir.str());
139     IncludeDir += llvm::sys::path::get_separator();
140     addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + Arch);
141     addSystemInclude(DriverArgs, CC1Args, IncludeDir.str() + "backward");
142   }
143 }