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