Mercurial > hg > CbC > CbC_llvm
comparison llvm/lib/Option/ArgList.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 //===- ArgList.cpp - Argument List Management -----------------------------===// | |
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 "llvm/ADT/ArrayRef.h" | |
10 #include "llvm/ADT/None.h" | |
11 #include "llvm/ADT/SmallVector.h" | |
12 #include "llvm/ADT/STLExtras.h" | |
13 #include "llvm/ADT/StringRef.h" | |
14 #include "llvm/ADT/Twine.h" | |
15 #include "llvm/Config/llvm-config.h" | |
16 #include "llvm/Option/Arg.h" | |
17 #include "llvm/Option/ArgList.h" | |
18 #include "llvm/Option/Option.h" | |
19 #include "llvm/Option/OptSpecifier.h" | |
20 #include "llvm/Support/Compiler.h" | |
21 #include "llvm/Support/Debug.h" | |
22 #include "llvm/Support/raw_ostream.h" | |
23 #include <algorithm> | |
24 #include <cassert> | |
25 #include <memory> | |
26 #include <string> | |
27 #include <utility> | |
28 #include <vector> | |
29 | |
30 using namespace llvm; | |
31 using namespace llvm::opt; | |
32 | |
33 void ArgList::append(Arg *A) { | |
34 Args.push_back(A); | |
35 | |
36 // Update ranges for the option and all of its groups. | |
37 for (Option O = A->getOption().getUnaliasedOption(); O.isValid(); | |
38 O = O.getGroup()) { | |
39 auto &R = | |
40 OptRanges.insert(std::make_pair(O.getID(), emptyRange())).first->second; | |
41 R.first = std::min<unsigned>(R.first, Args.size() - 1); | |
42 R.second = Args.size(); | |
43 } | |
44 } | |
45 | |
46 void ArgList::eraseArg(OptSpecifier Id) { | |
47 // Zero out the removed entries but keep them around so that we don't | |
48 // need to invalidate OptRanges. | |
49 for (Arg *const &A : filtered(Id)) { | |
50 // Avoid the need for a non-const filtered iterator variant. | |
51 Arg **ArgsBegin = Args.data(); | |
52 ArgsBegin[&A - ArgsBegin] = nullptr; | |
53 } | |
54 OptRanges.erase(Id.getID()); | |
55 } | |
56 | |
57 ArgList::OptRange | |
58 ArgList::getRange(std::initializer_list<OptSpecifier> Ids) const { | |
59 OptRange R = emptyRange(); | |
60 for (auto Id : Ids) { | |
61 auto I = OptRanges.find(Id.getID()); | |
62 if (I != OptRanges.end()) { | |
63 R.first = std::min(R.first, I->second.first); | |
64 R.second = std::max(R.second, I->second.second); | |
65 } | |
66 } | |
67 // Map an empty {-1, 0} range to {0, 0} so it can be used to form iterators. | |
68 if (R.first == -1u) | |
69 R.first = 0; | |
70 return R; | |
71 } | |
72 | |
73 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { | |
74 if (Arg *A = getLastArg(Pos, Neg)) | |
75 return A->getOption().matches(Pos); | |
76 return Default; | |
77 } | |
78 | |
79 bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, | |
80 bool Default) const { | |
81 if (Arg *A = getLastArg(Pos, PosAlias, Neg)) | |
82 return A->getOption().matches(Pos) || A->getOption().matches(PosAlias); | |
83 return Default; | |
84 } | |
85 | |
86 StringRef ArgList::getLastArgValue(OptSpecifier Id, StringRef Default) const { | |
87 if (Arg *A = getLastArg(Id)) | |
88 return A->getValue(); | |
89 return Default; | |
90 } | |
91 | |
92 std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const { | |
93 SmallVector<const char *, 16> Values; | |
94 AddAllArgValues(Values, Id); | |
95 return std::vector<std::string>(Values.begin(), Values.end()); | |
96 } | |
97 | |
98 void ArgList::AddAllArgsExcept(ArgStringList &Output, | |
99 ArrayRef<OptSpecifier> Ids, | |
100 ArrayRef<OptSpecifier> ExcludeIds) const { | |
101 for (const Arg *Arg : *this) { | |
102 bool Excluded = false; | |
103 for (OptSpecifier Id : ExcludeIds) { | |
104 if (Arg->getOption().matches(Id)) { | |
105 Excluded = true; | |
106 break; | |
107 } | |
108 } | |
109 if (!Excluded) { | |
110 for (OptSpecifier Id : Ids) { | |
111 if (Arg->getOption().matches(Id)) { | |
112 Arg->claim(); | |
113 Arg->render(*this, Output); | |
114 break; | |
115 } | |
116 } | |
117 } | |
118 } | |
119 } | |
120 | |
121 /// This is a nicer interface when you don't have a list of Ids to exclude. | |
122 void ArgList::AddAllArgs(ArgStringList &Output, | |
123 ArrayRef<OptSpecifier> Ids) const { | |
124 ArrayRef<OptSpecifier> Exclude = None; | |
125 AddAllArgsExcept(Output, Ids, Exclude); | |
126 } | |
127 | |
128 /// This 3-opt variant of AddAllArgs could be eliminated in favor of one | |
129 /// that accepts a single specifier, given the above which accepts any number. | |
130 void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0, | |
131 OptSpecifier Id1, OptSpecifier Id2) const { | |
132 for (auto Arg: filtered(Id0, Id1, Id2)) { | |
133 Arg->claim(); | |
134 Arg->render(*this, Output); | |
135 } | |
136 } | |
137 | |
138 void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, | |
139 OptSpecifier Id1, OptSpecifier Id2) const { | |
140 for (auto Arg : filtered(Id0, Id1, Id2)) { | |
141 Arg->claim(); | |
142 const auto &Values = Arg->getValues(); | |
143 Output.append(Values.begin(), Values.end()); | |
144 } | |
145 } | |
146 | |
147 void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, | |
148 const char *Translation, | |
149 bool Joined) const { | |
150 for (auto Arg: filtered(Id0)) { | |
151 Arg->claim(); | |
152 | |
153 if (Joined) { | |
154 Output.push_back(MakeArgString(StringRef(Translation) + | |
155 Arg->getValue(0))); | |
156 } else { | |
157 Output.push_back(Translation); | |
158 Output.push_back(Arg->getValue(0)); | |
159 } | |
160 } | |
161 } | |
162 | |
163 void ArgList::ClaimAllArgs(OptSpecifier Id0) const { | |
164 for (auto *Arg : filtered(Id0)) | |
165 Arg->claim(); | |
166 } | |
167 | |
168 void ArgList::ClaimAllArgs() const { | |
169 for (auto *Arg : *this) | |
170 if (!Arg->isClaimed()) | |
171 Arg->claim(); | |
172 } | |
173 | |
174 const char *ArgList::GetOrMakeJoinedArgString(unsigned Index, | |
175 StringRef LHS, | |
176 StringRef RHS) const { | |
177 StringRef Cur = getArgString(Index); | |
178 if (Cur.size() == LHS.size() + RHS.size() && | |
179 Cur.startswith(LHS) && Cur.endswith(RHS)) | |
180 return Cur.data(); | |
181 | |
182 return MakeArgString(LHS + RHS); | |
183 } | |
184 | |
185 void ArgList::print(raw_ostream &O) const { | |
186 for (Arg *A : *this) { | |
187 O << "* "; | |
188 A->print(O); | |
189 } | |
190 } | |
191 | |
192 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | |
193 LLVM_DUMP_METHOD void ArgList::dump() const { print(dbgs()); } | |
194 #endif | |
195 | |
196 void InputArgList::releaseMemory() { | |
197 // An InputArgList always owns its arguments. | |
198 for (Arg *A : *this) | |
199 delete A; | |
200 } | |
201 | |
202 InputArgList::InputArgList(const char* const *ArgBegin, | |
203 const char* const *ArgEnd) | |
204 : NumInputArgStrings(ArgEnd - ArgBegin) { | |
205 ArgStrings.append(ArgBegin, ArgEnd); | |
206 } | |
207 | |
208 unsigned InputArgList::MakeIndex(StringRef String0) const { | |
209 unsigned Index = ArgStrings.size(); | |
210 | |
211 // Tuck away so we have a reliable const char *. | |
212 SynthesizedStrings.push_back(std::string(String0)); | |
213 ArgStrings.push_back(SynthesizedStrings.back().c_str()); | |
214 | |
215 return Index; | |
216 } | |
217 | |
218 unsigned InputArgList::MakeIndex(StringRef String0, | |
219 StringRef String1) const { | |
220 unsigned Index0 = MakeIndex(String0); | |
221 unsigned Index1 = MakeIndex(String1); | |
222 assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!"); | |
223 (void) Index1; | |
224 return Index0; | |
225 } | |
226 | |
227 const char *InputArgList::MakeArgStringRef(StringRef Str) const { | |
228 return getArgString(MakeIndex(Str)); | |
229 } | |
230 | |
231 DerivedArgList::DerivedArgList(const InputArgList &BaseArgs) | |
232 : BaseArgs(BaseArgs) {} | |
233 | |
234 const char *DerivedArgList::MakeArgStringRef(StringRef Str) const { | |
235 return BaseArgs.MakeArgString(Str); | |
236 } | |
237 | |
238 void DerivedArgList::AddSynthesizedArg(Arg *A) { | |
239 SynthesizedArgs.push_back(std::unique_ptr<Arg>(A)); | |
240 } | |
241 | |
242 Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const { | |
243 SynthesizedArgs.push_back( | |
244 std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), | |
245 BaseArgs.MakeIndex(Opt.getName()), BaseArg)); | |
246 return SynthesizedArgs.back().get(); | |
247 } | |
248 | |
249 Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt, | |
250 StringRef Value) const { | |
251 unsigned Index = BaseArgs.MakeIndex(Value); | |
252 SynthesizedArgs.push_back( | |
253 std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), | |
254 Index, BaseArgs.getArgString(Index), BaseArg)); | |
255 return SynthesizedArgs.back().get(); | |
256 } | |
257 | |
258 Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt, | |
259 StringRef Value) const { | |
260 unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value); | |
261 SynthesizedArgs.push_back( | |
262 std::make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), | |
263 Index, BaseArgs.getArgString(Index + 1), BaseArg)); | |
264 return SynthesizedArgs.back().get(); | |
265 } | |
266 | |
267 Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt, | |
268 StringRef Value) const { | |
269 unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str()); | |
270 SynthesizedArgs.push_back(std::make_unique<Arg>( | |
271 Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index, | |
272 BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg)); | |
273 return SynthesizedArgs.back().get(); | |
274 } |