]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Driver/MinGWToolChain.cpp
Vendor import of clang 4.0.0 release r297347:
[FreeBSD/FreeBSD.git] / lib / Driver / MinGWToolChain.cpp
1 //===--- MinGWToolChain.cpp - MinGWToolChain Implementation ---------------===//
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 "ToolChains.h"
11 #include "clang/Driver/Driver.h"
12 #include "clang/Driver/Options.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Support/FileSystem.h"
15 #include "llvm/Support/Path.h"
16
17 using namespace clang::diag;
18 using namespace clang::driver;
19 using namespace clang::driver::toolchains;
20 using namespace clang;
21 using namespace llvm::opt;
22
23 // Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple.
24 static bool findGccVersion(StringRef LibDir, std::string &GccLibDir,
25                            std::string &Ver) {
26   Generic_GCC::GCCVersion Version = Generic_GCC::GCCVersion::Parse("0.0.0");
27   std::error_code EC;
28   for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE;
29        LI = LI.increment(EC)) {
30     StringRef VersionText = llvm::sys::path::filename(LI->path());
31     Generic_GCC::GCCVersion CandidateVersion =
32         Generic_GCC::GCCVersion::Parse(VersionText);
33     if (CandidateVersion.Major == -1)
34       continue;
35     if (CandidateVersion <= Version)
36       continue;
37     Ver = VersionText;
38     GccLibDir = LI->path();
39   }
40   return Ver.size();
41 }
42
43 void MinGW::findGccLibDir() {
44   llvm::SmallVector<llvm::SmallString<32>, 2> Archs;
45   Archs.emplace_back(getTriple().getArchName());
46   Archs[0] += "-w64-mingw32";
47   Archs.emplace_back("mingw32");
48   Arch = Archs[0].str();
49   // lib: Arch Linux, Ubuntu, Windows
50   // lib64: openSUSE Linux
51   for (StringRef CandidateLib : {"lib", "lib64"}) {
52     for (StringRef CandidateArch : Archs) {
53       llvm::SmallString<1024> LibDir(Base);
54       llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch);
55       if (findGccVersion(LibDir, GccLibDir, Ver)) {
56         Arch = CandidateArch;
57         return;
58       }
59     }
60   }
61 }
62
63 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
64     : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
65   getProgramPaths().push_back(getDriver().getInstalledDir());
66
67 // In Windows there aren't any standard install locations, we search
68 // for gcc on the PATH. In Linux the base is always /usr.
69 #ifdef LLVM_ON_WIN32
70   if (getDriver().SysRoot.size())
71     Base = getDriver().SysRoot;
72   else if (llvm::ErrorOr<std::string> GPPName =
73                llvm::sys::findProgramByName("gcc"))
74     Base = llvm::sys::path::parent_path(
75         llvm::sys::path::parent_path(GPPName.get()));
76   else
77     Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
78 #else
79   if (getDriver().SysRoot.size())
80     Base = getDriver().SysRoot;
81   else
82     Base = "/usr";
83 #endif
84
85   Base += llvm::sys::path::get_separator();
86   findGccLibDir();
87   // GccLibDir must precede Base/lib so that the
88   // correct crtbegin.o ,cetend.o would be found.
89   getFilePaths().push_back(GccLibDir);
90   getFilePaths().push_back(
91       (Base + Arch + llvm::sys::path::get_separator() + "lib").str());
92   getFilePaths().push_back(Base + "lib");
93   // openSUSE
94   getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");
95 }
96
97 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
98
99 Tool *MinGW::getTool(Action::ActionClass AC) const {
100   switch (AC) {
101   case Action::PreprocessJobClass:
102     if (!Preprocessor)
103       Preprocessor.reset(new tools::gcc::Preprocessor(*this));
104     return Preprocessor.get();
105   case Action::CompileJobClass:
106     if (!Compiler)
107       Compiler.reset(new tools::gcc::Compiler(*this));
108     return Compiler.get();
109   default:
110     return ToolChain::getTool(AC);
111   }
112 }
113
114 Tool *MinGW::buildAssembler() const {
115   return new tools::MinGW::Assembler(*this);
116 }
117
118 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
119
120 bool MinGW::IsUnwindTablesDefault() const {
121   return getArch() == llvm::Triple::x86_64;
122 }
123
124 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
125
126 bool MinGW::isPIEDefault() const { return false; }
127
128 bool MinGW::isPICDefaultForced() const {
129   return getArch() == llvm::Triple::x86_64;
130 }
131
132 bool MinGW::UseSEHExceptions() const {
133   return getArch() == llvm::Triple::x86_64;
134 }
135
136 void MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
137                                ArgStringList &CC1Args) const {
138   CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
139 }
140
141 void MinGW::printVerboseInfo(raw_ostream &OS) const {
142   CudaInstallation.print(OS);
143 }
144
145 // Include directories for various hosts:
146
147 // Windows, mingw.org
148 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++
149 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32
150 // c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward
151 // c:\mingw\lib\gcc\mingw32\4.8.1\include
152 // c:\mingw\include
153 // c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed
154 // c:\mingw\mingw32\include
155
156 // Windows, mingw-w64 mingw-builds
157 // c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include
158 // c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed
159 // c:\mingw32\i686-w64-mingw32\include
160 // c:\mingw32\i686-w64-mingw32\include\c++
161 // c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32
162 // c:\mingw32\i686-w64-mingw32\include\c++\backward
163
164 // Windows, mingw-w64 msys2
165 // c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include
166 // c:\msys64\mingw32\include
167 // c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed
168 // c:\msys64\mingw32\i686-w64-mingw32\include
169 // c:\msys64\mingw32\include\c++\4.9.2
170 // c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32
171 // c:\msys64\mingw32\include\c++\4.9.2\backward
172
173 // openSUSE
174 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++
175 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32
176 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward
177 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include
178 // /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed
179 // /usr/x86_64-w64-mingw32/sys-root/mingw/include
180
181 // Arch Linux
182 // /usr/i686-w64-mingw32/include/c++/5.1.0
183 // /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32
184 // /usr/i686-w64-mingw32/include/c++/5.1.0/backward
185 // /usr/lib/gcc/i686-w64-mingw32/5.1.0/include
186 // /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed
187 // /usr/i686-w64-mingw32/include
188
189 // Ubuntu
190 // /usr/include/c++/4.8
191 // /usr/include/c++/4.8/x86_64-w64-mingw32
192 // /usr/include/c++/4.8/backward
193 // /usr/lib/gcc/x86_64-w64-mingw32/4.8/include
194 // /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed
195 // /usr/x86_64-w64-mingw32/include
196
197 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
198                                       ArgStringList &CC1Args) const {
199   if (DriverArgs.hasArg(options::OPT_nostdinc))
200     return;
201
202   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
203     SmallString<1024> P(getDriver().ResourceDir);
204     llvm::sys::path::append(P, "include");
205     addSystemInclude(DriverArgs, CC1Args, P.str());
206   }
207
208   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
209     return;
210
211   if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) {
212     llvm::SmallString<1024> IncludeDir(GccLibDir);
213     llvm::sys::path::append(IncludeDir, "include");
214     addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
215     IncludeDir += "-fixed";
216     // openSUSE
217     addSystemInclude(DriverArgs, CC1Args,
218                      Base + Arch + "/sys-root/mingw/include");
219     addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
220   }
221   addSystemInclude(DriverArgs, CC1Args,
222                    Base + Arch + llvm::sys::path::get_separator() + "include");
223   addSystemInclude(DriverArgs, CC1Args, Base + "include");
224 }
225
226 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
227                                          ArgStringList &CC1Args) const {
228   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
229       DriverArgs.hasArg(options::OPT_nostdincxx))
230     return;
231
232   switch (GetCXXStdlibType(DriverArgs)) {
233   case ToolChain::CST_Libcxx:
234     addSystemInclude(DriverArgs, CC1Args,
235                      Base + "include" + llvm::sys::path::get_separator() +
236                          "c++" + llvm::sys::path::get_separator() + "v1");
237     break;
238
239   case ToolChain::CST_Libstdcxx:
240     llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases;
241     CppIncludeBases.emplace_back(Base);
242     llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
243     CppIncludeBases.emplace_back(Base);
244     llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver);
245     CppIncludeBases.emplace_back(Base);
246     llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver);
247     CppIncludeBases.emplace_back(GccLibDir);
248     llvm::sys::path::append(CppIncludeBases[3], "include", "c++");
249     for (auto &CppIncludeBase : CppIncludeBases) {
250       addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
251       CppIncludeBase += llvm::sys::path::get_separator();
252       addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
253       addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
254     }
255     break;
256   }
257 }