Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki added inline comments. Comment at: lib/Basic/Targets.cpp:718 @@ +717,3 @@ +Builder.defineMacro("_LONG_LONG"); +Builder.defineMacro("_ALL_SOURCE"); +Builder.defineMacro("_REENTRANT"); majnemer wrote: > Are we really supposed to define this macro? Does GCC define this? I cannot > find where it does so in the source. I defined both `_ALL_SOURCE` and `_REENTRANT` because the `SolarisTargetInfo` defines them (`__EXTENSIONS__` is the Solaris equivalent of `_ALL_SOURCE`). If that is an oversight in the Solaris work, I'll remove `_ALL_SOURCE` here. GCC does not define it by default. https://reviews.llvm.org/D18360 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki added inline comments. Comment at: lib/Basic/Targets.cpp:718 @@ +717,3 @@ +Builder.defineMacro("_LONG_LONG"); +Builder.defineMacro("_ALL_SOURCE"); +Builder.defineMacro("_REENTRANT"); majnemer wrote: > apaprocki wrote: > > majnemer wrote: > > > Are we really supposed to define this macro? Does GCC define this? I > > > cannot find where it does so in the source. > > I defined both `_ALL_SOURCE` and `_REENTRANT` because the > > `SolarisTargetInfo` defines them (`__EXTENSIONS__` is the Solaris > > equivalent of `_ALL_SOURCE`). If that is an oversight in the Solaris work, > > I'll remove `_ALL_SOURCE` here. GCC does not define it by default. > After a closer examination of the gcc sources, it looks like `ALL_SOURCE` is > defined if gcc is being used for C++ code (via `CPLUSPLUS_CPP_SPEC`). > > I don't see where `_REENTRANT` is defined for AIX though... On AIX, when `gcc` is passed `-pthread`, it defines `_THREAD_SAFE`. I think this should be changed to ``` if (Opts.POSIXThreads) Builder.defineMacro("_THREAD_SAFE"); ``` On Solaris, `gcc` defines `_REENTRANT` when `-pthread` is passed. I think it is a separate bug (and I can file a separate revision) to put the Solaris use of it also on an `Opts.POSIXThreads` check. https://reviews.llvm.org/D18360 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki updated this revision to Diff 64376. https://reviews.llvm.org/D18360 Files: lib/Basic/Targets.cpp lib/Driver/Driver.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/Tools.h tools/libclang/CIndexer.cpp Index: tools/libclang/CIndexer.cpp === --- tools/libclang/CIndexer.cpp +++ tools/libclang/CIndexer.cpp @@ -37,12 +37,71 @@ #ifdef LLVM_ON_WIN32 #include +#elif defined(_AIX) +#include +#include +#include #else #include #endif using namespace clang; +#ifdef _AIX +static int +test_dir(char ret[PATH_MAX], const char *dir, const char *bin) +{ + struct stat sb; + char fullpath[PATH_MAX]; + + snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin); + if (!realpath(fullpath, ret)) +return 1; + if (stat(fullpath, &sb) != 0) +return 1; + + return 0; +} + +static char * +getprogpath(char ret[PATH_MAX], const char *bin) +{ + char *pv, *s, *t; + + /* First approach: absolute path. */ + if (bin[0] == '/') { +if (test_dir(ret, "/", bin) == 0) + return ret; +return nullptr; + } + + /* Second approach: relative path. */ + if (strchr(bin, '/')) { +char cwd[PATH_MAX]; +if (!getcwd(cwd, PATH_MAX)) + return nullptr; +if (test_dir(ret, cwd, bin) == 0) + return ret; +return nullptr; + } + + /* Third approach: $PATH */ + if ((pv = getenv("PATH")) == nullptr) +return nullptr; + s = pv = strdup(pv); + if (!pv) +return nullptr; + while ((t = strsep(&s, ":")) != nullptr) { +if (test_dir(ret, t, bin) == 0) { + free(pv); + return ret; +} + } + free(pv); + return nullptr; +} +#endif + const std::string &CIndexer::getClangResourcesPath() { // Did we already compute the path? if (!ResourcesPath.empty()) @@ -69,6 +128,11 @@ #endif LibClangPath += llvm::sys::path::parent_path(path); +#elif defined(_AIX) + extern char **argv; + char exe_path[MAXPATHLEN]; + if (getprogpath(exe_path, argv[0]) != NULL) +LibClangPath += llvm::sys::path::parent_path(exe_path); #else // This silly cast below avoids a C++ warning. Dl_info info; Index: lib/Driver/Tools.h === --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -652,6 +652,34 @@ }; } // end namespace solaris +/// aix -- Directly call AIX assembler and linker +namespace aix { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) : Tool("aix::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; + +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("aix::Linker", "linker", TC) {} + + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; +} // end namespace aix + /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -5452,6 +5452,7 @@ options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, !IsWindowsCygnus && !IsWindowsGNU && getToolChain().getTriple().getOS() != llvm::Triple::Solaris && + getToolChain().getTriple().getOS() != llvm::Triple::AIX && getToolChain().getArch() != llvm::Triple::hexagon && getToolChain().getArch() != llvm::Triple::xcore && ((getToolChain().getTriple().getVendor() != @@ -8102,6 +8103,94 @@ C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); } +void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + claimNoWarnArgs(Args); + ArgStringList CmdArgs; + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + for (const auto &II : Inputs) +CmdArgs.push_back(II.getFilename()); + + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPat
Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki updated this revision to Diff 64518. apaprocki added a comment. Increased context and removed accidental inclusion of Solaris change. https://reviews.llvm.org/D18360 Files: lib/Basic/Targets.cpp lib/Driver/Driver.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/Tools.h tools/libclang/CIndexer.cpp Index: tools/libclang/CIndexer.cpp === --- tools/libclang/CIndexer.cpp +++ tools/libclang/CIndexer.cpp @@ -37,12 +37,71 @@ #ifdef LLVM_ON_WIN32 #include +#elif defined(_AIX) +#include +#include +#include #else #include #endif using namespace clang; +#ifdef _AIX +static int +test_dir(char ret[PATH_MAX], const char *dir, const char *bin) +{ + struct stat sb; + char fullpath[PATH_MAX]; + + snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin); + if (!realpath(fullpath, ret)) +return 1; + if (stat(fullpath, &sb) != 0) +return 1; + + return 0; +} + +static char * +getprogpath(char ret[PATH_MAX], const char *bin) +{ + char *pv, *s, *t; + + /* First approach: absolute path. */ + if (bin[0] == '/') { +if (test_dir(ret, "/", bin) == 0) + return ret; +return nullptr; + } + + /* Second approach: relative path. */ + if (strchr(bin, '/')) { +char cwd[PATH_MAX]; +if (!getcwd(cwd, PATH_MAX)) + return nullptr; +if (test_dir(ret, cwd, bin) == 0) + return ret; +return nullptr; + } + + /* Third approach: $PATH */ + if ((pv = getenv("PATH")) == nullptr) +return nullptr; + s = pv = strdup(pv); + if (!pv) +return nullptr; + while ((t = strsep(&s, ":")) != nullptr) { +if (test_dir(ret, t, bin) == 0) { + free(pv); + return ret; +} + } + free(pv); + return nullptr; +} +#endif + const std::string &CIndexer::getClangResourcesPath() { // Did we already compute the path? if (!ResourcesPath.empty()) @@ -69,6 +128,11 @@ #endif LibClangPath += llvm::sys::path::parent_path(path); +#elif defined(_AIX) + extern char **argv; + char exe_path[MAXPATHLEN]; + if (getprogpath(exe_path, argv[0]) != NULL) +LibClangPath += llvm::sys::path::parent_path(exe_path); #else // This silly cast below avoids a C++ warning. Dl_info info; Index: lib/Driver/Tools.h === --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -652,6 +652,34 @@ }; } // end namespace solaris +/// aix -- Directly call AIX assembler and linker +namespace aix { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) : Tool("aix::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; + +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("aix::Linker", "linker", TC) {} + + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; +} // end namespace aix + /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -5452,6 +5452,7 @@ options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, !IsWindowsCygnus && !IsWindowsGNU && getToolChain().getTriple().getOS() != llvm::Triple::Solaris && + getToolChain().getTriple().getOS() != llvm::Triple::AIX && getToolChain().getArch() != llvm::Triple::hexagon && getToolChain().getArch() != llvm::Triple::xcore && ((getToolChain().getTriple().getVendor() != @@ -8102,6 +8103,94 @@ C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); } +void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + claimNoWarnArgs(Args); + ArgStringList CmdArgs; + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + for (const auto &II : Inputs) +CmdArgs.p
Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki updated this revision to Diff 64328. apaprocki added a comment. Fixed `wchar_t` type. https://reviews.llvm.org/D18360 Files: lib/Basic/Targets.cpp lib/Driver/Driver.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/Tools.h tools/libclang/CIndexer.cpp Index: tools/libclang/CIndexer.cpp === --- tools/libclang/CIndexer.cpp +++ tools/libclang/CIndexer.cpp @@ -37,12 +37,71 @@ #ifdef LLVM_ON_WIN32 #include +#elif defined(_AIX) +#include +#include +#include #else #include #endif using namespace clang; +#ifdef _AIX +static int +test_dir(char ret[PATH_MAX], const char *dir, const char *bin) +{ + struct stat sb; + char fullpath[PATH_MAX]; + + snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin); + if (!realpath(fullpath, ret)) +return 1; + if (stat(fullpath, &sb) != 0) +return 1; + + return 0; +} + +static char * +getprogpath(char ret[PATH_MAX], const char *bin) +{ + char *pv, *s, *t; + + /* First approach: absolute path. */ + if (bin[0] == '/') { +if (test_dir(ret, "/", bin) == 0) + return ret; +return nullptr; + } + + /* Second approach: relative path. */ + if (strchr(bin, '/')) { +char cwd[PATH_MAX]; +if (!getcwd(cwd, PATH_MAX)) + return nullptr; +if (test_dir(ret, cwd, bin) == 0) + return ret; +return nullptr; + } + + /* Third approach: $PATH */ + if ((pv = getenv("PATH")) == nullptr) +return nullptr; + s = pv = strdup(pv); + if (!pv) +return nullptr; + while ((t = strsep(&s, ":")) != nullptr) { +if (test_dir(ret, t, bin) == 0) { + free(pv); + return ret; +} + } + free(pv); + return nullptr; +} +#endif + const std::string &CIndexer::getClangResourcesPath() { // Did we already compute the path? if (!ResourcesPath.empty()) @@ -69,6 +128,11 @@ #endif LibClangPath += llvm::sys::path::parent_path(path); +#elif defined(_AIX) + extern char **argv; + char exe_path[MAXPATHLEN]; + if (getprogpath(exe_path, argv[0]) != NULL) +LibClangPath += llvm::sys::path::parent_path(exe_path); #else // This silly cast below avoids a C++ warning. Dl_info info; Index: lib/Driver/Tools.h === --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -652,6 +652,34 @@ }; } // end namespace solaris +/// aix -- Directly call AIX assembler and linker +namespace aix { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) : Tool("aix::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; + +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("aix::Linker", "linker", TC) {} + + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; +} // end namespace aix + /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -5452,6 +5452,7 @@ options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, !IsWindowsCygnus && !IsWindowsGNU && getToolChain().getTriple().getOS() != llvm::Triple::Solaris && + getToolChain().getTriple().getOS() != llvm::Triple::AIX && getToolChain().getArch() != llvm::Triple::hexagon && getToolChain().getArch() != llvm::Triple::xcore && ((getToolChain().getTriple().getVendor() != @@ -8102,6 +8103,94 @@ C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs, Inputs)); } +void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + claimNoWarnArgs(Args); + ArgStringList CmdArgs; + + Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); + + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + for (const auto &II : Inputs) +CmdArgs.push_back(II.getFilename()); + + const char *Exe
Re: [PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki added a comment. (I also re-based the patch on top of `trunk`) https://reviews.llvm.org/D18360 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D18360: Add AIX Target/ToolChain to Clang Driver
apaprocki created this revision. apaprocki added a subscriber: cfe-commits. This patch adds Clang driver support for the AIX platform. This allows Clang to be used for compiling code / checking for errors, but does not allow for building executables, as AIX uses XCOFF and not ELF. After applying this patch and the underlying D18359: ``` $ clang -v clang version 3.8.0 (tags/RELEASE_380/final) Target: powerpc-ibm-aix7.1.0.0 Thread model: posix InstalledDir: /tmp/llvm-3.8/bin Found candidate GCC installation: /tmp/gcc-4.8/lib/gcc/powerpc-ibm-aix7.1.0.0/4.8.5 Selected GCC installation: /tmp/gcc-4.8/lib/gcc/powerpc-ibm-aix7.1.0.0/4.8.5 Candidate multilib: .;@maix32 Candidate multilib: ppc64;@maix64 Selected multilib: .;@maix32 ``` http://reviews.llvm.org/D18360 Files: lib/Basic/Targets.cpp lib/Driver/Driver.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/Tools.h tools/libclang/CIndexer.cpp Index: lib/Driver/ToolChains.h === --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -643,6 +643,24 @@ Tool *buildLinker() const override; }; +class LLVM_LIBRARY_VISIBILITY AIX : public Generic_GCC { +public: + AIX(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + + bool IsIntegratedAssemblerDefault() const override { return true; } + + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + + unsigned GetDefaultDwarfVersion() const override { return 2; } + +protected: + Tool *buildAssembler() const override; + Tool *buildLinker() const override; +}; + class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain { public: MinGW(const Driver &D, const llvm::Triple &Triple, Index: lib/Driver/Tools.h === --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -649,6 +649,34 @@ }; } // end namespace solaris +/// aix -- Directly call AIX assembler and linker +namespace aix { +class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { +public: + Assembler(const ToolChain &TC) : Tool("aix::Assembler", "assembler", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; + +class LLVM_LIBRARY_VISIBILITY Linker : public Tool { +public: + Linker(const ToolChain &TC) : Tool("aix::Linker", "linker", TC) {} + + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, +const InputInfo &Output, const InputInfoList &Inputs, +const llvm::opt::ArgList &TCArgs, +const char *LinkingOutput) const override; +}; +} // end namespace aix + /// dragonfly -- Directly call GNU Binutils assembler and linker namespace dragonfly { class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool { Index: lib/Driver/ToolChains.cpp === --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1719,13 +1719,14 @@ // Filter to remove Multilibs that don't exist as a suffix to Path class FilterNonExistent { StringRef Base; + StringRef Crt; vfs::FileSystem &VFS; public: - FilterNonExistent(StringRef Base, vfs::FileSystem &VFS) - : Base(Base), VFS(VFS) {} + FilterNonExistent(StringRef Base, StringRef Crt, vfs::FileSystem &VFS) + : Base(Base), Crt(Crt), VFS(VFS) {} bool operator()(const Multilib &M) { -return !VFS.exists(Base + M.gccSuffix() + "/crtbegin.o"); +return !VFS.exists(Base + M.gccSuffix() + Crt); } }; } // end anonymous namespace @@ -1811,7 +1812,7 @@ // /usr // /lib <= crt*.o files compiled with '-mips32' - FilterNonExistent NonExistent(Path, D.getVFS()); + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); // Check for FSF toolchain multilibs MultilibSet FSFMipsMultilibs; @@ -2112,6 +2113,40 @@ return false; } +static bool findAIXBiarchMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + bool NeedsBiarchSuffix, + DetectedMultilibs &Result) { + Multilib Default = Multilib() + .flag("+maix32") + .flag("-maix64"); + Multilib Alt64 = Multilib() + .gccSuffix("/ppc64") + .includeSuffix("/ppc64") + .flag("-maix32") + .flag("+maix64"); + +