ArgList.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. //===--- ArgList.cpp - Argument List Management ---------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Option/ArgList.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/Twine.h"
  13. #include "llvm/Option/Arg.h"
  14. #include "llvm/Option/Option.h"
  15. #include "llvm/Support/raw_ostream.h"
  16. using namespace llvm;
  17. using namespace llvm::opt;
  18. void arg_iterator::SkipToNextArg() {
  19. for (; Current != Args.end(); ++Current) {
  20. // Done if there are no filters.
  21. if (!Id0.isValid())
  22. break;
  23. // Otherwise require a match.
  24. const Option &O = (*Current)->getOption();
  25. if (O.matches(Id0) ||
  26. (Id1.isValid() && O.matches(Id1)) ||
  27. (Id2.isValid() && O.matches(Id2)))
  28. break;
  29. }
  30. }
  31. void ArgList::append(Arg *A) {
  32. Args.push_back(A);
  33. }
  34. void ArgList::eraseArg(OptSpecifier Id) {
  35. Args.erase(std::remove_if(begin(), end(),
  36. [=](Arg *A) { return A->getOption().matches(Id); }),
  37. end());
  38. }
  39. Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
  40. // FIXME: Make search efficient?
  41. for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
  42. if ((*it)->getOption().matches(Id))
  43. return *it;
  44. return nullptr;
  45. }
  46. Arg *ArgList::getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const {
  47. // FIXME: Make search efficient?
  48. for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
  49. if ((*it)->getOption().matches(Id0) ||
  50. (*it)->getOption().matches(Id1))
  51. return *it;
  52. return nullptr;
  53. }
  54. Arg *ArgList::getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
  55. OptSpecifier Id2) const {
  56. // FIXME: Make search efficient?
  57. for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
  58. if ((*it)->getOption().matches(Id0) || (*it)->getOption().matches(Id1) ||
  59. (*it)->getOption().matches(Id2))
  60. return *it;
  61. return nullptr;
  62. }
  63. Arg *ArgList::getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
  64. OptSpecifier Id2, OptSpecifier Id3) const {
  65. // FIXME: Make search efficient?
  66. for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
  67. if ((*it)->getOption().matches(Id0) || (*it)->getOption().matches(Id1) ||
  68. (*it)->getOption().matches(Id2) || (*it)->getOption().matches(Id3))
  69. return *it;
  70. return nullptr;
  71. }
  72. Arg *ArgList::getLastArg(OptSpecifier Id) const {
  73. Arg *Res = nullptr;
  74. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  75. if ((*it)->getOption().matches(Id)) {
  76. Res = *it;
  77. Res->claim();
  78. }
  79. }
  80. return Res;
  81. }
  82. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
  83. Arg *Res = nullptr;
  84. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  85. if ((*it)->getOption().matches(Id0) ||
  86. (*it)->getOption().matches(Id1)) {
  87. Res = *it;
  88. Res->claim();
  89. }
  90. }
  91. return Res;
  92. }
  93. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  94. OptSpecifier Id2) const {
  95. Arg *Res = nullptr;
  96. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  97. if ((*it)->getOption().matches(Id0) ||
  98. (*it)->getOption().matches(Id1) ||
  99. (*it)->getOption().matches(Id2)) {
  100. Res = *it;
  101. Res->claim();
  102. }
  103. }
  104. return Res;
  105. }
  106. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  107. OptSpecifier Id2, OptSpecifier Id3) const {
  108. Arg *Res = nullptr;
  109. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  110. if ((*it)->getOption().matches(Id0) ||
  111. (*it)->getOption().matches(Id1) ||
  112. (*it)->getOption().matches(Id2) ||
  113. (*it)->getOption().matches(Id3)) {
  114. Res = *it;
  115. Res->claim();
  116. }
  117. }
  118. return Res;
  119. }
  120. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  121. OptSpecifier Id2, OptSpecifier Id3,
  122. OptSpecifier Id4) const {
  123. Arg *Res = nullptr;
  124. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  125. if ((*it)->getOption().matches(Id0) ||
  126. (*it)->getOption().matches(Id1) ||
  127. (*it)->getOption().matches(Id2) ||
  128. (*it)->getOption().matches(Id3) ||
  129. (*it)->getOption().matches(Id4)) {
  130. Res = *it;
  131. Res->claim();
  132. }
  133. }
  134. return Res;
  135. }
  136. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  137. OptSpecifier Id2, OptSpecifier Id3,
  138. OptSpecifier Id4, OptSpecifier Id5) const {
  139. Arg *Res = nullptr;
  140. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  141. if ((*it)->getOption().matches(Id0) ||
  142. (*it)->getOption().matches(Id1) ||
  143. (*it)->getOption().matches(Id2) ||
  144. (*it)->getOption().matches(Id3) ||
  145. (*it)->getOption().matches(Id4) ||
  146. (*it)->getOption().matches(Id5)) {
  147. Res = *it;
  148. Res->claim();
  149. }
  150. }
  151. return Res;
  152. }
  153. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  154. OptSpecifier Id2, OptSpecifier Id3,
  155. OptSpecifier Id4, OptSpecifier Id5,
  156. OptSpecifier Id6) const {
  157. Arg *Res = nullptr;
  158. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  159. if ((*it)->getOption().matches(Id0) ||
  160. (*it)->getOption().matches(Id1) ||
  161. (*it)->getOption().matches(Id2) ||
  162. (*it)->getOption().matches(Id3) ||
  163. (*it)->getOption().matches(Id4) ||
  164. (*it)->getOption().matches(Id5) ||
  165. (*it)->getOption().matches(Id6)) {
  166. Res = *it;
  167. Res->claim();
  168. }
  169. }
  170. return Res;
  171. }
  172. Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
  173. OptSpecifier Id2, OptSpecifier Id3,
  174. OptSpecifier Id4, OptSpecifier Id5,
  175. OptSpecifier Id6, OptSpecifier Id7) const {
  176. Arg *Res = nullptr;
  177. for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
  178. if ((*it)->getOption().matches(Id0) ||
  179. (*it)->getOption().matches(Id1) ||
  180. (*it)->getOption().matches(Id2) ||
  181. (*it)->getOption().matches(Id3) ||
  182. (*it)->getOption().matches(Id4) ||
  183. (*it)->getOption().matches(Id5) ||
  184. (*it)->getOption().matches(Id6) ||
  185. (*it)->getOption().matches(Id7)) {
  186. Res = *it;
  187. Res->claim();
  188. }
  189. }
  190. return Res;
  191. }
  192. bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
  193. if (Arg *A = getLastArg(Pos, Neg))
  194. return A->getOption().matches(Pos);
  195. return Default;
  196. }
  197. bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg,
  198. bool Default) const {
  199. if (Arg *A = getLastArg(Pos, PosAlias, Neg))
  200. return A->getOption().matches(Pos) || A->getOption().matches(PosAlias);
  201. return Default;
  202. }
  203. StringRef ArgList::getLastArgValue(OptSpecifier Id,
  204. StringRef Default) const {
  205. if (Arg *A = getLastArg(Id))
  206. return A->getValue();
  207. return Default;
  208. }
  209. std::vector<std::string> ArgList::getAllArgValues(OptSpecifier Id) const {
  210. SmallVector<const char *, 16> Values;
  211. AddAllArgValues(Values, Id);
  212. return std::vector<std::string>(Values.begin(), Values.end());
  213. }
  214. void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
  215. if (Arg *A = getLastArg(Id)) {
  216. A->claim();
  217. A->render(*this, Output);
  218. }
  219. }
  220. void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id0,
  221. OptSpecifier Id1) const {
  222. if (Arg *A = getLastArg(Id0, Id1)) {
  223. A->claim();
  224. A->render(*this, Output);
  225. }
  226. }
  227. void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
  228. OptSpecifier Id1, OptSpecifier Id2) const {
  229. for (auto Arg: filtered(Id0, Id1, Id2)) {
  230. Arg->claim();
  231. Arg->render(*this, Output);
  232. }
  233. }
  234. void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
  235. OptSpecifier Id1, OptSpecifier Id2) const {
  236. for (auto Arg : filtered(Id0, Id1, Id2)) {
  237. Arg->claim();
  238. const auto &Values = Arg->getValues();
  239. Output.append(Values.begin(), Values.end());
  240. }
  241. }
  242. void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
  243. const char *Translation,
  244. bool Joined) const {
  245. for (auto Arg: filtered(Id0)) {
  246. Arg->claim();
  247. if (Joined) {
  248. Output.push_back(MakeArgString(StringRef(Translation) +
  249. Arg->getValue(0)));
  250. } else {
  251. Output.push_back(Translation);
  252. Output.push_back(Arg->getValue(0));
  253. }
  254. }
  255. }
  256. void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
  257. for (auto Arg : filtered(Id0))
  258. Arg->claim();
  259. }
  260. void ArgList::ClaimAllArgs() const {
  261. for (const_iterator it = begin(), ie = end(); it != ie; ++it)
  262. if (!(*it)->isClaimed())
  263. (*it)->claim();
  264. }
  265. const char *ArgList::GetOrMakeJoinedArgString(unsigned Index,
  266. StringRef LHS,
  267. StringRef RHS) const {
  268. StringRef Cur = getArgString(Index);
  269. if (Cur.size() == LHS.size() + RHS.size() &&
  270. Cur.startswith(LHS) && Cur.endswith(RHS))
  271. return Cur.data();
  272. return MakeArgString(LHS + RHS);
  273. }
  274. //
  275. void InputArgList::releaseMemory() {
  276. // An InputArgList always owns its arguments.
  277. for (Arg *A : *this)
  278. delete A;
  279. }
  280. InputArgList::InputArgList(const char* const *ArgBegin,
  281. const char* const *ArgEnd)
  282. : NumInputArgStrings(ArgEnd - ArgBegin) {
  283. ArgStrings.append(ArgBegin, ArgEnd);
  284. }
  285. unsigned InputArgList::MakeIndex(StringRef String0) const {
  286. unsigned Index = ArgStrings.size();
  287. // Tuck away so we have a reliable const char *.
  288. SynthesizedStrings.push_back(String0);
  289. ArgStrings.push_back(SynthesizedStrings.back().c_str());
  290. return Index;
  291. }
  292. unsigned InputArgList::MakeIndex(StringRef String0,
  293. StringRef String1) const {
  294. unsigned Index0 = MakeIndex(String0);
  295. unsigned Index1 = MakeIndex(String1);
  296. assert(Index0 + 1 == Index1 && "Unexpected non-consecutive indices!");
  297. (void) Index1;
  298. return Index0;
  299. }
  300. const char *InputArgList::MakeArgStringRef(StringRef Str) const {
  301. return getArgString(MakeIndex(Str));
  302. }
  303. //
  304. DerivedArgList::DerivedArgList(const InputArgList &BaseArgs)
  305. : BaseArgs(BaseArgs) {}
  306. const char *DerivedArgList::MakeArgStringRef(StringRef Str) const {
  307. return BaseArgs.MakeArgString(Str);
  308. }
  309. void DerivedArgList::AddSynthesizedArg(Arg *A) {
  310. SynthesizedArgs.push_back(std::unique_ptr<Arg>(A));
  311. }
  312. Arg *DerivedArgList::MakeFlagArg(const Arg *BaseArg, const Option Opt) const {
  313. SynthesizedArgs.push_back(
  314. make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
  315. BaseArgs.MakeIndex(Opt.getName()), BaseArg));
  316. return SynthesizedArgs.back().get();
  317. }
  318. Arg *DerivedArgList::MakePositionalArg(const Arg *BaseArg, const Option Opt,
  319. StringRef Value) const {
  320. unsigned Index = BaseArgs.MakeIndex(Value);
  321. SynthesizedArgs.push_back(
  322. make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
  323. Index, BaseArgs.getArgString(Index), BaseArg));
  324. return SynthesizedArgs.back().get();
  325. }
  326. Arg *DerivedArgList::MakeSeparateArg(const Arg *BaseArg, const Option Opt,
  327. StringRef Value) const {
  328. unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value);
  329. SynthesizedArgs.push_back(
  330. make_unique<Arg>(Opt, MakeArgString(Opt.getPrefix() + Opt.getName()),
  331. Index, BaseArgs.getArgString(Index + 1), BaseArg));
  332. return SynthesizedArgs.back().get();
  333. }
  334. Arg *DerivedArgList::MakeJoinedArg(const Arg *BaseArg, const Option Opt,
  335. StringRef Value) const {
  336. unsigned Index = BaseArgs.MakeIndex((Opt.getName() + Value).str());
  337. SynthesizedArgs.push_back(make_unique<Arg>(
  338. Opt, MakeArgString(Opt.getPrefix() + Opt.getName()), Index,
  339. BaseArgs.getArgString(Index) + Opt.getName().size(), BaseArg));
  340. return SynthesizedArgs.back().get();
  341. }