1//===--- VE.cpp - VE ToolChain Implementations ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "VEToolchain.h"
10#include "clang/Driver/Compilation.h"
11#include "clang/Driver/Driver.h"
12#include "clang/Options/Options.h"
13#include "llvm/Option/ArgList.h"
14#include "llvm/Support/Path.h"
15#include <cstdlib> // ::getenv
16
17using namespace clang::driver;
18using namespace clang::driver::toolchains;
19using namespace clang;
20using namespace llvm::opt;
21
22/// VE tool chain
23VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple,
24 const ArgList &Args)
25 : Linux(D, Triple, Args) {
26 getProgramPaths().push_back(Elt: "/opt/nec/ve/bin");
27 // ProgramPaths are found via 'PATH' environment variable.
28
29 // Default library paths are following:
30 // ${RESOURCEDIR}/lib/ve-unknown-linux-gnu,
31 // These are OK.
32
33 // Default file paths are following:
34 // ${RESOURCEDIR}/lib/ve-unknown-linux-gnu, (== getArchSpecificLibPaths)
35 // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths)
36 // /lib/../lib64,
37 // /usr/lib/../lib64,
38 // ${BINPATH}/../lib,
39 // /lib,
40 // /usr/lib,
41 // These are OK for host, but no go for VE.
42
43 // Define file paths from scratch here.
44 getFilePaths().clear();
45
46 // Add library directories:
47 // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath)
48 // ${RESOURCEDIR}/lib/ve-unknown-linux-gnu, (== getArchSpecificLibPaths)
49 // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths)
50 // ${SYSROOT}/opt/nec/ve/lib,
51 if (std::optional<std::string> Path = getStdlibPath())
52 getFilePaths().push_back(Elt: std::move(*Path));
53 for (const auto &Path : getArchSpecificLibPaths())
54 getFilePaths().push_back(Elt: Path);
55 getFilePaths().push_back(Elt: computeSysRoot() + "/opt/nec/ve/lib");
56}
57
58Tool *VEToolChain::buildAssembler() const {
59 return new tools::gnutools::Assembler(*this);
60}
61
62Tool *VEToolChain::buildLinker() const {
63 return new tools::gnutools::Linker(*this);
64}
65
66bool VEToolChain::isPICDefault() const { return false; }
67
68bool VEToolChain::isPIEDefault(const llvm::opt::ArgList &Args) const {
69 return false;
70}
71
72bool VEToolChain::isPICDefaultForced() const { return false; }
73
74bool VEToolChain::SupportsProfiling() const { return false; }
75
76bool VEToolChain::hasBlocksRuntime() const { return false; }
77
78void VEToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
79 ArgStringList &CC1Args) const {
80 if (DriverArgs.hasArg(Ids: options::OPT_nostdinc))
81 return;
82
83 if (DriverArgs.hasArg(Ids: options::OPT_nobuiltininc) &&
84 DriverArgs.hasArg(Ids: options::OPT_nostdlibinc))
85 return;
86
87 if (!DriverArgs.hasArg(Ids: options::OPT_nobuiltininc)) {
88 SmallString<128> P(getDriver().ResourceDir);
89 llvm::sys::path::append(path&: P, a: "include");
90 addSystemInclude(DriverArgs, CC1Args, Path: P);
91 }
92
93 if (!DriverArgs.hasArg(Ids: options::OPT_nostdlibinc)) {
94 if (const char *cl_include_dir = getenv(name: "NCC_C_INCLUDE_PATH")) {
95 SmallVector<StringRef, 4> Dirs;
96 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
97 StringRef(cl_include_dir).split(A&: Dirs, Separator: StringRef(EnvPathSeparatorStr));
98 ArrayRef<StringRef> DirVec(Dirs);
99 addSystemIncludes(DriverArgs, CC1Args, Paths: DirVec);
100 } else {
101 addSystemInclude(DriverArgs, CC1Args,
102 Path: getDriver().SysRoot + "/opt/nec/ve/include");
103 }
104 }
105}
106
107void VEToolChain::addClangTargetOptions(const ArgList &DriverArgs,
108 ArgStringList &CC1Args, BoundArch BA,
109 Action::OffloadKind) const {
110 CC1Args.push_back(Elt: "-nostdsysteminc");
111 bool UseInitArrayDefault = true;
112 if (!DriverArgs.hasFlag(Pos: options::OPT_fuse_init_array,
113 Neg: options::OPT_fno_use_init_array, Default: UseInitArrayDefault))
114 CC1Args.push_back(Elt: "-fno-use-init-array");
115}
116
117void VEToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
118 ArgStringList &CC1Args) const {
119 if (DriverArgs.hasArg(Ids: options::OPT_nostdinc) ||
120 DriverArgs.hasArg(Ids: options::OPT_nostdlibinc) ||
121 DriverArgs.hasArg(Ids: options::OPT_nostdincxx))
122 return;
123 if (const char *cl_include_dir = getenv(name: "NCC_CPLUS_INCLUDE_PATH")) {
124 SmallVector<StringRef, 4> Dirs;
125 const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
126 StringRef(cl_include_dir).split(A&: Dirs, Separator: StringRef(EnvPathSeparatorStr));
127 ArrayRef<StringRef> DirVec(Dirs);
128 addSystemIncludes(DriverArgs, CC1Args, Paths: DirVec);
129 } else {
130 // Add following paths for multiple target installation.
131 // ${INSTALLDIR}/include/ve-unknown-linux-gnu/c++/v1,
132 // ${INSTALLDIR}/include/c++/v1,
133 addLibCxxIncludePaths(DriverArgs, CC1Args);
134 }
135}
136
137void VEToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
138 ArgStringList &CmdArgs) const {
139 assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) &&
140 "Only -lc++ (aka libxx) is supported in this toolchain.");
141
142 // Add paths for libc++.so and other shared libraries.
143 if (std::optional<std::string> Path = getStdlibPath()) {
144 CmdArgs.push_back(Elt: "-rpath");
145 CmdArgs.push_back(Elt: Args.MakeArgString(Str: *Path));
146 }
147
148 CmdArgs.push_back(Elt: "-lc++");
149 if (Args.hasArg(Ids: options::OPT_fexperimental_library))
150 CmdArgs.push_back(Elt: "-lc++experimental");
151 CmdArgs.push_back(Elt: "-lc++abi");
152 CmdArgs.push_back(Elt: "-lunwind");
153 // libc++ requires -lpthread under glibc environment
154 CmdArgs.push_back(Elt: "-lpthread");
155 // libunwind requires -ldl under glibc environment
156 CmdArgs.push_back(Elt: "-ldl");
157}
158
159llvm::ExceptionHandling
160VEToolChain::GetExceptionModel(const ArgList &Args) const {
161 // VE uses SjLj exceptions.
162 return llvm::ExceptionHandling::SjLj;
163}
164