From ff58e3610f4e12094def69eb2d6dcb4330378d8f Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Sat, 21 Aug 2010 21:55:07 +0000 Subject: [PATCH] Visual Studio tools used on win32 hosts when targeting win32. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111748 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/HostInfo.h | 4 ++ lib/Driver/Driver.cpp | 5 ++ lib/Driver/HostInfo.cpp | 83 +++++++++++++++++++++++++++++++ lib/Driver/ToolChains.cpp | 52 +++++++++++++++++++ lib/Driver/ToolChains.h | 14 ++++++ lib/Driver/Tools.cpp | 41 +++++++++++++++ lib/Driver/Tools.h | 16 ++++++ lib/Frontend/InitHeaderSearch.cpp | 14 +++++- 8 files changed, 227 insertions(+), 2 deletions(-) diff --git a/include/clang/Driver/HostInfo.h b/include/clang/Driver/HostInfo.h index af6ef822fb..04e72992d6 100644 --- a/include/clang/Driver/HostInfo.h +++ b/include/clang/Driver/HostInfo.h @@ -79,6 +79,10 @@ const HostInfo *createLinuxHostInfo(const Driver &D, const llvm::Triple& Triple); const HostInfo *createTCEHostInfo(const Driver &D, const llvm::Triple& Triple); +const HostInfo *createWindowsHostInfo(const Driver &D, + const llvm::Triple &Triple); +const HostInfo *createMinGWHostInfo(const Driver &D, + const llvm::Triple &Triple); const HostInfo *createUnknownHostInfo(const Driver &D, const llvm::Triple& Triple); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 5616300b07..e967cfe7b2 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1272,6 +1272,11 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const { return createMinixHostInfo(*this, Triple); case llvm::Triple::Linux: return createLinuxHostInfo(*this, Triple); + case llvm::Triple::Win32: + return createWindowsHostInfo(*this, Triple); + case llvm::Triple::MinGW32: + case llvm::Triple::MinGW64: + return createMinGWHostInfo(*this, Triple); default: return createUnknownHostInfo(*this, Triple); } diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index cf5e382e60..7c5e430bb7 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -525,8 +525,79 @@ ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args, return TC; } +// Windows Host Info + +/// WindowsHostInfo - Host information to use on Microsoft Windows. +class WindowsHostInfo : public HostInfo { + /// Cache of tool chains we have created. + mutable llvm::StringMap ToolChains; + +public: + WindowsHostInfo(const Driver &D, const llvm::Triple& Triple); + ~WindowsHostInfo(); + + virtual bool useDriverDriver() const; + + virtual types::ID lookupTypeForExtension(const char *Ext) const { + return types::lookupTypeForExtension(Ext); + } + + virtual ToolChain *CreateToolChain(const ArgList &Args, + const char *ArchName) const; +}; + +WindowsHostInfo::WindowsHostInfo(const Driver &D, const llvm::Triple& Triple) + : HostInfo(D, Triple) { } +WindowsHostInfo::~WindowsHostInfo() { + for (llvm::StringMap::iterator + it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it) + delete it->second; +} + +bool WindowsHostInfo::useDriverDriver() const { + return false; +} + +ToolChain *WindowsHostInfo::CreateToolChain(const ArgList &Args, + const char *ArchName) const { + assert(!ArchName && + "Unexpected arch name on platform without driver driver support."); + + // Automatically handle some instances of -m32/-m64 we know about. + std::string Arch = getArchName(); + ArchName = Arch.c_str(); + if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) { + if (Triple.getArch() == llvm::Triple::x86 || + Triple.getArch() == llvm::Triple::x86_64) { + ArchName = + (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64"; + } + } + + ToolChain *&TC = ToolChains[ArchName]; + if (!TC) { + llvm::Triple TCTriple(getTriple()); + TCTriple.setArchName(ArchName); + + TC = new toolchains::Windows(*this, TCTriple); + } + + return TC; +} + +// FIXME: This is a placeholder. +class MinGWHostInfo : public UnknownHostInfo { +public: + MinGWHostInfo(const Driver &D, const llvm::Triple& Triple); +}; + +MinGWHostInfo::MinGWHostInfo(const Driver &D, const llvm::Triple& Triple) + : UnknownHostInfo(D, Triple) {} + +} // end anon namespace + const HostInfo * clang::driver::createAuroraUXHostInfo(const Driver &D, const llvm::Triple& Triple){ @@ -575,6 +646,18 @@ clang::driver::createTCEHostInfo(const Driver &D, return new TCEHostInfo(D, Triple); } +const HostInfo * +clang::driver::createWindowsHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new WindowsHostInfo(D, Triple); +} + +const HostInfo * +clang::driver::createMinGWHostInfo(const Driver &D, + const llvm::Triple& Triple) { + return new MinGWHostInfo(D, Triple); +} + const HostInfo * clang::driver::createUnknownHostInfo(const Driver &D, const llvm::Triple& Triple) { diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index e9d6e34864..db898e978a 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1090,3 +1090,55 @@ Tool &DragonFly::SelectTool(const Compilation &C, const JobAction &JA) const { return *T; } + +Windows::Windows(const HostInfo &Host, const llvm::Triple& Triple) + : ToolChain(Host, Triple) { +} + +Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA) const { + Action::ActionClass Key; + if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) + Key = Action::AnalyzeJobClass; + else + Key = JA.getKind(); + + Tool *&T = Tools[Key]; + if (!T) { + switch (Key) { + case Action::InputClass: + case Action::BindArchClass: + assert(0 && "Invalid tool kind."); + case Action::PreprocessJobClass: + case Action::PrecompileJobClass: + case Action::AnalyzeJobClass: + case Action::CompileJobClass: + T = new tools::Clang(*this); break; + case Action::AssembleJobClass: + T = new tools::ClangAs(*this); break; + case Action::LinkJobClass: + T = new tools::visualstudio::Link(*this); break; + } + } + + return *T; +} + +bool Windows::IsIntegratedAssemblerDefault() const { + return true; +} + +bool Windows::IsUnwindTablesDefault() const { + // FIXME: Gross; we should probably have some separate target + // definition, possibly even reusing the one in clang. + return getArchName() == "x86_64"; +} + +const char *Windows::GetDefaultRelocationModel() const { + return "static"; +} + +const char *Windows::GetForcedPicModel() const { + if (getArchName() == "x86_64") + return "pic"; + return 0; +} diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index e2d72e61dc..742daadab8 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -315,6 +315,20 @@ private: }; +class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain { + mutable llvm::DenseMap Tools; + +public: + Windows(const HostInfo &Host, const llvm::Triple& Triple); + + virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const; + + virtual bool IsIntegratedAssemblerDefault() const; + virtual bool IsUnwindTablesDefault() const; + virtual const char *GetDefaultRelocationModel() const; + virtual const char *GetForcedPicModel() const; +}; + } // end namespace toolchains } // end namespace driver } // end namespace clang diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index dd9e713c92..dfd170e5ad 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3329,3 +3329,44 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetProgramPath("ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } + +void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + ArgStringList CmdArgs; + + if (Output.isFilename()) { + CmdArgs.push_back(Args.MakeArgString(std::string("-out:") + Output.getFilename())); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nostartfiles)) { + CmdArgs.push_back("-defaultlib:libcmt"); + } + + CmdArgs.push_back("-nologo"); + + for (InputInfoList::const_iterator + it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { + const InputInfo &II = *it; + + // Don't try to pass LLVM inputs to visual studio linker. + if (II.getType() == types::TY_LLVM_BC) + D.Diag(clang::diag::err_drv_no_linker_llvm_support) + << getToolChain().getTripleString(); + + if (II.isFilename()) + CmdArgs.push_back(II.getFilename()); + else + II.getInputArg().renderAsInput(Args, CmdArgs); + } + + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath("link.exe")); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); +} diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 725dd4648a..b5defa4569 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -435,6 +435,22 @@ namespace dragonfly { }; } // end namespace dragonfly + /// Visual studio tools. +namespace visualstudio { + class LLVM_LIBRARY_VISIBILITY Link : public Tool { + public: + Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {} + + virtual bool hasIntegratedCPP() const { return false; } + + virtual void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; +} // end namespace visualstudio + } // end namespace toolchains } // end namespace driver } // end namespace clang diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index f666c41663..f03502a438 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -323,9 +323,19 @@ static bool getSystemRegistryString(const char*, const char*, char*, size_t) { // Get Visual Studio installation directory. static bool getVisualStudioDir(std::string &path) { + // First check the environment variables that vsvars32.bat sets. + const char* vcinstalldir = getenv("VCINSTALLDIR"); + if(vcinstalldir) { + char *p = const_cast(strstr(vcinstalldir, "\\VC")); + if (p) + *p = '\0'; + path = vcinstalldir; + return(true); + } + char vsIDEInstallDir[256]; char vsExpressIDEInstallDir[256]; - // Try the Windows registry first. + // Then try the windows registry. bool hasVCDir = getSystemRegistryString( "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION", "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1); @@ -440,7 +450,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, if (getVisualStudioDir(VSDir)) { AddPath(VSDir + "\\VC\\include", System, false, false, false); if (getWindowsSDKDir(WindowsSDKDir)) - AddPath(WindowsSDKDir, System, false, false, false); + AddPath(WindowsSDKDir + "\\include", System, false, false, false); else AddPath(VSDir + "\\VC\\PlatformSDK\\Include", System, false, false, false); -- 2.40.0