10b57cec5SDimitry Andric //===--- Clang.h - Clang Tool and ToolChain Implementations ====-*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 904eeddc0SDimitry Andric #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H 1004eeddc0SDimitry Andric #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "MSVC.h" 130b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 140b57cec5SDimitry Andric #include "clang/Driver/Tool.h" 150b57cec5SDimitry Andric #include "clang/Driver/Types.h" 1606c3fb27SDimitry Andric #include "llvm/Frontend/Debug/Options.h" 170b57cec5SDimitry Andric #include "llvm/Option/Option.h" 180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 1906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric class ObjCRuntime; 230b57cec5SDimitry Andric namespace driver { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace tools { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric /// Clang compiler tool. 280b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY Clang : public Tool { 290eae32dcSDimitry Andric // Indicates whether this instance has integrated backend using 300eae32dcSDimitry Andric // internal LLVM infrastructure. 310eae32dcSDimitry Andric bool HasBackend; 320eae32dcSDimitry Andric 330b57cec5SDimitry Andric public: 340b57cec5SDimitry Andric static const char *getBaseInputName(const llvm::opt::ArgList &Args, 350b57cec5SDimitry Andric const InputInfo &Input); 360b57cec5SDimitry Andric static const char *getBaseInputStem(const llvm::opt::ArgList &Args, 370b57cec5SDimitry Andric const InputInfoList &Inputs); 380b57cec5SDimitry Andric static const char *getDependencyFileName(const llvm::opt::ArgList &Args, 390b57cec5SDimitry Andric const InputInfoList &Inputs); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric private: 420b57cec5SDimitry Andric void AddPreprocessingOptions(Compilation &C, const JobAction &JA, 430b57cec5SDimitry Andric const Driver &D, const llvm::opt::ArgList &Args, 440b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 450b57cec5SDimitry Andric const InputInfo &Output, 460b57cec5SDimitry Andric const InputInfoList &Inputs) const; 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric void RenderTargetOptions(const llvm::Triple &EffectiveTriple, 490b57cec5SDimitry Andric const llvm::opt::ArgList &Args, bool KernelOrKext, 500b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric void AddAArch64TargetArgs(const llvm::opt::ArgList &Args, 530b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 540b57cec5SDimitry Andric void AddARMTargetArgs(const llvm::Triple &Triple, 550b57cec5SDimitry Andric const llvm::opt::ArgList &Args, 560b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs, 570b57cec5SDimitry Andric bool KernelOrKext) const; 580b57cec5SDimitry Andric void AddARM64TargetArgs(const llvm::opt::ArgList &Args, 590b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 60bdd1243dSDimitry Andric void AddLoongArchTargetArgs(const llvm::opt::ArgList &Args, 61bdd1243dSDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 620b57cec5SDimitry Andric void AddMIPSTargetArgs(const llvm::opt::ArgList &Args, 630b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 640b57cec5SDimitry Andric void AddPPCTargetArgs(const llvm::opt::ArgList &Args, 650b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 660b57cec5SDimitry Andric void AddR600TargetArgs(const llvm::opt::ArgList &Args, 670b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 680b57cec5SDimitry Andric void AddRISCVTargetArgs(const llvm::opt::ArgList &Args, 690b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 700b57cec5SDimitry Andric void AddSparcTargetArgs(const llvm::opt::ArgList &Args, 710b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 720b57cec5SDimitry Andric void AddSystemZTargetArgs(const llvm::opt::ArgList &Args, 730b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 740b57cec5SDimitry Andric void AddX86TargetArgs(const llvm::opt::ArgList &Args, 750b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 760b57cec5SDimitry Andric void AddHexagonTargetArgs(const llvm::opt::ArgList &Args, 770b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 780b57cec5SDimitry Andric void AddLanaiTargetArgs(const llvm::opt::ArgList &Args, 790b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 800b57cec5SDimitry Andric void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args, 810b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 825ffd83dbSDimitry Andric void AddVETargetArgs(const llvm::opt::ArgList &Args, 835ffd83dbSDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile }; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args, 885ffd83dbSDimitry Andric const InputInfoList &inputs, 890b57cec5SDimitry Andric llvm::opt::ArgStringList &cmdArgs, 900b57cec5SDimitry Andric RewriteKind rewrite) const; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric void AddClangCLArgs(const llvm::opt::ArgList &Args, types::ID InputType, 935f757f3fSDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric mutable std::unique_ptr<llvm::raw_fd_ostream> CompilationDatabase = nullptr; 960b57cec5SDimitry Andric void DumpCompilationDatabase(Compilation &C, StringRef Filename, 970b57cec5SDimitry Andric StringRef Target, 980b57cec5SDimitry Andric const InputInfo &Output, const InputInfo &Input, 990b57cec5SDimitry Andric const llvm::opt::ArgList &Args) const; 1000b57cec5SDimitry Andric 101a7dea167SDimitry Andric void DumpCompilationDatabaseFragmentToDir( 102a7dea167SDimitry Andric StringRef Dir, Compilation &C, StringRef Target, const InputInfo &Output, 103a7dea167SDimitry Andric const InputInfo &Input, const llvm::opt::ArgList &Args) const; 104a7dea167SDimitry Andric 1050b57cec5SDimitry Andric public: 1060eae32dcSDimitry Andric Clang(const ToolChain &TC, bool HasIntegratedBackend = true); 1070b57cec5SDimitry Andric ~Clang() override; 1080b57cec5SDimitry Andric hasGoodDiagnostics()1090b57cec5SDimitry Andric bool hasGoodDiagnostics() const override { return true; } hasIntegratedAssembler()1100b57cec5SDimitry Andric bool hasIntegratedAssembler() const override { return true; } hasIntegratedBackend()1110eae32dcSDimitry Andric bool hasIntegratedBackend() const override { return HasBackend; } hasIntegratedCPP()1120b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return true; } canEmitIR()1130b57cec5SDimitry Andric bool canEmitIR() const override { return true; } 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1160b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1170b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1180b57cec5SDimitry Andric const char *LinkingOutput) const override; 1190b57cec5SDimitry Andric }; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// Clang integrated assembler tool. 1220b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY ClangAs : public Tool { 1230b57cec5SDimitry Andric public: ClangAs(const ToolChain & TC)1240b57cec5SDimitry Andric ClangAs(const ToolChain &TC) 1255ffd83dbSDimitry Andric : Tool("clang::as", "clang integrated assembler", TC) {} 12606c3fb27SDimitry Andric void AddLoongArchTargetArgs(const llvm::opt::ArgList &Args, 12706c3fb27SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 1280b57cec5SDimitry Andric void AddMIPSTargetArgs(const llvm::opt::ArgList &Args, 1290b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 1300b57cec5SDimitry Andric void AddX86TargetArgs(const llvm::opt::ArgList &Args, 1310b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; 1320b57cec5SDimitry Andric void AddRISCVTargetArgs(const llvm::opt::ArgList &Args, 1330b57cec5SDimitry Andric llvm::opt::ArgStringList &CmdArgs) const; hasGoodDiagnostics()1340b57cec5SDimitry Andric bool hasGoodDiagnostics() const override { return true; } hasIntegratedAssembler()1350b57cec5SDimitry Andric bool hasIntegratedAssembler() const override { return false; } hasIntegratedCPP()1360b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1390b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1400b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1410b57cec5SDimitry Andric const char *LinkingOutput) const override; 1420b57cec5SDimitry Andric }; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// Offload bundler tool. 1450b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY OffloadBundler final : public Tool { 1460b57cec5SDimitry Andric public: OffloadBundler(const ToolChain & TC)1470b57cec5SDimitry Andric OffloadBundler(const ToolChain &TC) 1480b57cec5SDimitry Andric : Tool("offload bundler", "clang-offload-bundler", TC) {} 1490b57cec5SDimitry Andric hasIntegratedCPP()1500b57cec5SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1510b57cec5SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1520b57cec5SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1530b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1540b57cec5SDimitry Andric const char *LinkingOutput) const override; 1550b57cec5SDimitry Andric void ConstructJobMultipleOutputs(Compilation &C, const JobAction &JA, 1560b57cec5SDimitry Andric const InputInfoList &Outputs, 1570b57cec5SDimitry Andric const InputInfoList &Inputs, 1580b57cec5SDimitry Andric const llvm::opt::ArgList &TCArgs, 1590b57cec5SDimitry Andric const char *LinkingOutput) const override; 1600b57cec5SDimitry Andric }; 161a7dea167SDimitry Andric 16281ad6265SDimitry Andric /// Offload binary tool. 16381ad6265SDimitry Andric class LLVM_LIBRARY_VISIBILITY OffloadPackager final : public Tool { 16481ad6265SDimitry Andric public: OffloadPackager(const ToolChain & TC)16581ad6265SDimitry Andric OffloadPackager(const ToolChain &TC) 16681ad6265SDimitry Andric : Tool("Offload::Packager", "clang-offload-packager", TC) {} 16781ad6265SDimitry Andric hasIntegratedCPP()16881ad6265SDimitry Andric bool hasIntegratedCPP() const override { return false; } 16981ad6265SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 17081ad6265SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 17181ad6265SDimitry Andric const llvm::opt::ArgList &TCArgs, 17281ad6265SDimitry Andric const char *LinkingOutput) const override; 17381ad6265SDimitry Andric }; 17481ad6265SDimitry Andric 1751fd87a68SDimitry Andric /// Linker wrapper tool. 1761fd87a68SDimitry Andric class LLVM_LIBRARY_VISIBILITY LinkerWrapper final : public Tool { 1771fd87a68SDimitry Andric const Tool *Linker; 1781fd87a68SDimitry Andric 1791fd87a68SDimitry Andric public: LinkerWrapper(const ToolChain & TC,const Tool * Linker)1801fd87a68SDimitry Andric LinkerWrapper(const ToolChain &TC, const Tool *Linker) 1811fd87a68SDimitry Andric : Tool("Offload::Linker", "linker", TC), Linker(Linker) {} 1821fd87a68SDimitry Andric hasIntegratedCPP()1831fd87a68SDimitry Andric bool hasIntegratedCPP() const override { return false; } 1841fd87a68SDimitry Andric void ConstructJob(Compilation &C, const JobAction &JA, 1851fd87a68SDimitry Andric const InputInfo &Output, const InputInfoList &Inputs, 1861fd87a68SDimitry Andric const llvm::opt::ArgList &TCArgs, 1871fd87a68SDimitry Andric const char *LinkingOutput) const override; 1881fd87a68SDimitry Andric }; 1891fd87a68SDimitry Andric 190fcaf7f86SDimitry Andric enum class DwarfFissionKind { None, Split, Single }; 191fcaf7f86SDimitry Andric 192fcaf7f86SDimitry Andric DwarfFissionKind getDebugFissionKind(const Driver &D, 193fcaf7f86SDimitry Andric const llvm::opt::ArgList &Args, 194fcaf7f86SDimitry Andric llvm::opt::Arg *&Arg); 195fcaf7f86SDimitry Andric 196*0fca6ea1SDimitry Andric // Calculate the output path of the module file when compiling a module unit 197*0fca6ea1SDimitry Andric // with the `-fmodule-output` option or `-fmodule-output=` option specified. 198*0fca6ea1SDimitry Andric // The behavior is: 199*0fca6ea1SDimitry Andric // - If `-fmodule-output=` is specfied, then the module file is 200*0fca6ea1SDimitry Andric // writing to the value. 201*0fca6ea1SDimitry Andric // - Otherwise if the output object file of the module unit is specified, the 202*0fca6ea1SDimitry Andric // output path 203*0fca6ea1SDimitry Andric // of the module file should be the same with the output object file except 204*0fca6ea1SDimitry Andric // the corresponding suffix. This requires both `-o` and `-c` are specified. 205*0fca6ea1SDimitry Andric // - Otherwise, the output path of the module file will be the same with the 206*0fca6ea1SDimitry Andric // input with the corresponding suffix. 207*0fca6ea1SDimitry Andric llvm::SmallString<256> 208*0fca6ea1SDimitry Andric getCXX20NamedModuleOutputPath(const llvm::opt::ArgList &Args, 209*0fca6ea1SDimitry Andric const char *BaseInput); 210*0fca6ea1SDimitry Andric 2110b57cec5SDimitry Andric } // end namespace tools 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric } // end namespace driver 2140b57cec5SDimitry Andric } // end namespace clang 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H 217