1 | //===- Arg.cpp - Argument Implementations ---------------------------------===// |
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/SmallString.h" |
10 | #include "llvm/Config/llvm-config.h" |
11 | #include "llvm/Option/Arg.h" |
12 | #include "llvm/Option/ArgList.h" |
13 | #include "llvm/Option/Option.h" |
14 | #include "llvm/Support/Compiler.h" |
15 | #include "llvm/Support/Debug.h" |
16 | #include "llvm/Support/raw_ostream.h" |
17 | |
18 | using namespace llvm; |
19 | using namespace llvm::opt; |
20 | |
21 | Arg::Arg(const Option Opt, StringRef S, unsigned Index, const Arg *BaseArg) |
22 | : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), |
23 | IgnoredTargetSpecific(false), OwnsValues(false) {} |
24 | |
25 | Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0, |
26 | const Arg *BaseArg) |
27 | : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), |
28 | IgnoredTargetSpecific(false), OwnsValues(false) { |
29 | Values.push_back(Elt: Value0); |
30 | } |
31 | |
32 | Arg::Arg(const Option Opt, StringRef S, unsigned Index, const char *Value0, |
33 | const char *Value1, const Arg *BaseArg) |
34 | : Opt(Opt), BaseArg(BaseArg), Spelling(S), Index(Index), Claimed(false), |
35 | IgnoredTargetSpecific(false), OwnsValues(false) { |
36 | Values.push_back(Elt: Value0); |
37 | Values.push_back(Elt: Value1); |
38 | } |
39 | |
40 | Arg::~Arg() { |
41 | if (OwnsValues) { |
42 | for (unsigned i = 0, e = Values.size(); i != e; ++i) |
43 | delete[] Values[i]; |
44 | } |
45 | } |
46 | |
47 | void Arg::print(raw_ostream& O) const { |
48 | O << "<Opt:" ; |
49 | Opt.print(O, /*AddNewLine=*/false); |
50 | |
51 | O << " Index:" << Index; |
52 | |
53 | O << " Values: [" ; |
54 | for (unsigned i = 0, e = Values.size(); i != e; ++i) { |
55 | if (i) O << ", " ; |
56 | O << "'" << Values[i] << "'" ; |
57 | } |
58 | |
59 | O << "]>\n" ; |
60 | } |
61 | |
62 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
63 | LLVM_DUMP_METHOD void Arg::dump() const { print(dbgs()); } |
64 | #endif |
65 | |
66 | std::string Arg::getAsString(const ArgList &Args) const { |
67 | if (Alias) |
68 | return Alias->getAsString(Args); |
69 | |
70 | SmallString<256> Res; |
71 | raw_svector_ostream OS(Res); |
72 | |
73 | ArgStringList ASL; |
74 | render(Args, Output&: ASL); |
75 | for (ArgStringList::iterator |
76 | it = ASL.begin(), ie = ASL.end(); it != ie; ++it) { |
77 | if (it != ASL.begin()) |
78 | OS << ' '; |
79 | OS << *it; |
80 | } |
81 | |
82 | return std::string(OS.str()); |
83 | } |
84 | |
85 | void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const { |
86 | if (!getOption().hasNoOptAsInput()) { |
87 | render(Args, Output); |
88 | return; |
89 | } |
90 | |
91 | Output.append(in_start: Values.begin(), in_end: Values.end()); |
92 | } |
93 | |
94 | void Arg::render(const ArgList &Args, ArgStringList &Output) const { |
95 | switch (getOption().getRenderStyle()) { |
96 | case Option::RenderValuesStyle: |
97 | Output.append(in_start: Values.begin(), in_end: Values.end()); |
98 | break; |
99 | |
100 | case Option::RenderCommaJoinedStyle: { |
101 | SmallString<256> Res; |
102 | raw_svector_ostream OS(Res); |
103 | OS << getSpelling(); |
104 | for (unsigned i = 0, e = getNumValues(); i != e; ++i) { |
105 | if (i) OS << ','; |
106 | OS << getValue(N: i); |
107 | } |
108 | Output.push_back(Elt: Args.MakeArgString(Str: OS.str())); |
109 | break; |
110 | } |
111 | |
112 | case Option::RenderJoinedStyle: |
113 | Output.push_back(Elt: Args.GetOrMakeJoinedArgString( |
114 | Index: getIndex(), LHS: getSpelling(), RHS: getValue(N: 0))); |
115 | Output.append(in_start: Values.begin() + 1, in_end: Values.end()); |
116 | break; |
117 | |
118 | case Option::RenderSeparateStyle: |
119 | Output.push_back(Elt: Args.MakeArgString(Str: getSpelling())); |
120 | Output.append(in_start: Values.begin(), in_end: Values.end()); |
121 | break; |
122 | } |
123 | } |
124 | |