]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Driver/MinGWToolChain.cpp
Update llvm/clang to r242221.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / 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 MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
24     : ToolChain(D, Triple, Args) {
25   getProgramPaths().push_back(getDriver().getInstalledDir());
26
27   llvm::SmallString<1024> LibDir;
28
29 #ifdef LLVM_ON_WIN32
30   if (getDriver().SysRoot.size())
31     Base = getDriver().SysRoot;
32   else if (llvm::ErrorOr<std::string> GPPName =
33                llvm::sys::findProgramByName("gcc"))
34     Base = llvm::sys::path::parent_path(
35         llvm::sys::path::parent_path(GPPName.get()));
36   else
37     Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
38   Base += llvm::sys::path::get_separator();
39   LibDir = Base;
40   llvm::sys::path::append(LibDir, "lib", "gcc");
41 #else
42   if (getDriver().SysRoot.size())
43     Base = getDriver().SysRoot;
44   else
45     Base = "/usr/";
46   LibDir = Base;
47   llvm::sys::path::append(LibDir, "lib64", "gcc");
48 #endif
49
50   LibDir += llvm::sys::path::get_separator();
51
52   // First look for mingw-w64.
53   Arch = getTriple().getArchName();
54   Arch += "-w64-mingw32";
55   std::error_code EC;
56   llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC);
57   if (!EC) {
58     GccLibDir = MingW64Entry->path();
59     Ver = llvm::sys::path::filename(GccLibDir);
60   } else {
61     // If mingw-w64 not found, try looking for mingw.org.
62     Arch = "mingw32";
63     llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC);
64     if (!EC)
65       GccLibDir = MingwOrgEntry->path();
66   }
67   Arch += llvm::sys::path::get_separator();
68   // GccLibDir must precede Base/lib so that the
69   // correct crtbegin.o ,cetend.o would be found.
70   getFilePaths().push_back(GccLibDir);
71   getFilePaths().push_back(Base + "lib");
72   getFilePaths().push_back(Base + Arch + "lib");
73 #ifdef LLVM_ON_UNIX
74   // For openSUSE.
75   getFilePaths().push_back(Base + Arch + "sys-root/mingw/lib");
76 #endif
77 }
78
79 bool MinGW::IsIntegratedAssemblerDefault() const { return true; }
80
81 Tool *MinGW::getTool(Action::ActionClass AC) const {
82   switch (AC) {
83   case Action::PreprocessJobClass:
84     if (!Preprocessor)
85       Preprocessor.reset(new tools::gcc::Preprocessor(*this));
86     return Preprocessor.get();
87   case Action::CompileJobClass:
88     if (!Compiler)
89       Compiler.reset(new tools::gcc::Compiler(*this));
90     return Compiler.get();
91   default:
92     return ToolChain::getTool(AC);
93   }
94 }
95
96 Tool *MinGW::buildAssembler() const {
97   return new tools::MinGW::Assembler(*this);
98 }
99
100 Tool *MinGW::buildLinker() const { return new tools::MinGW::Linker(*this); }
101
102 bool MinGW::IsUnwindTablesDefault() const {
103   return getArch() == llvm::Triple::x86_64;
104 }
105
106 bool MinGW::isPICDefault() const { return getArch() == llvm::Triple::x86_64; }
107
108 bool MinGW::isPIEDefault() const { return false; }
109
110 bool MinGW::isPICDefaultForced() const {
111   return getArch() == llvm::Triple::x86_64;
112 }
113
114 bool MinGW::UseSEHExceptions() const {
115   return getArch() == llvm::Triple::x86_64;
116 }
117
118 void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
119                                       ArgStringList &CC1Args) const {
120   if (DriverArgs.hasArg(options::OPT_nostdinc))
121     return;
122
123   if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
124     SmallString<1024> P(getDriver().ResourceDir);
125     llvm::sys::path::append(P, "include");
126     addSystemInclude(DriverArgs, CC1Args, P.str());
127   }
128
129   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
130     return;
131
132   llvm::SmallString<1024> IncludeDir(GccLibDir);
133   llvm::sys::path::append(IncludeDir, "include");
134   addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
135   IncludeDir += "-fixed";
136 #ifdef LLVM_ON_UNIX
137   // For openSUSE.
138   addSystemInclude(DriverArgs, CC1Args,
139                    "/usr/x86_64-w64-mingw32/sys-root/mingw/include");
140 #endif
141   addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str());
142   addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include");
143   addSystemInclude(DriverArgs, CC1Args, Base + "include");
144 }
145
146 void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
147                                          ArgStringList &CC1Args) const {
148   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
149       DriverArgs.hasArg(options::OPT_nostdincxx))
150     return;
151
152   // C++ includes may be found in several locations depending on distribution.
153   // Windows
154   // -------
155   // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++.
156   // mingw-w64 msys2:        $sysroot/include/c++/4.9.2
157   // mingw.org:              GccLibDir/include/c++
158   //
159   // Linux
160   // -----
161   // openSUSE:               GccLibDir/include/c++
162   llvm::SmallVector<llvm::SmallString<1024>, 3> CppIncludeBases;
163   CppIncludeBases.emplace_back(Base);
164   llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++");
165   CppIncludeBases.emplace_back(Base);
166   llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver);
167   CppIncludeBases.emplace_back(GccLibDir);
168   llvm::sys::path::append(CppIncludeBases[2], "include", "c++");
169   for (auto &CppIncludeBase : CppIncludeBases) {
170     CppIncludeBase += llvm::sys::path::get_separator();
171     addSystemInclude(DriverArgs, CC1Args, CppIncludeBase);
172     addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch);
173     addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward");
174   }
175 }