1 //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "OptEmitter.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Support/raw_ostream.h"
14 #include "llvm/TableGen/Record.h"
15 #include "llvm/TableGen/TableGenBackend.h"
22 static std::string
getOptionName(const Record
&R
) {
23 // Use the record name unless EnumName is defined.
24 if (isa
<UnsetInit
>(R
.getValueInit("EnumName")))
25 return std::string(R
.getName());
27 return std::string(R
.getValueAsString("EnumName"));
30 static raw_ostream
&write_cstring(raw_ostream
&OS
, llvm::StringRef Str
) {
32 OS
.write_escaped(Str
);
37 static std::string
getOptionPrefixedName(const Record
&R
) {
38 std::vector
<StringRef
> Prefixes
= R
.getValueAsListOfStrings("Prefixes");
39 StringRef Name
= R
.getValueAsString("Name");
44 return (Prefixes
[0] + Twine(Name
)).str();
47 class MarshallingInfo
{
49 static constexpr const char *MacroName
= "OPTION_WITH_MARSHALLING";
51 bool ShouldAlwaysEmit
= false;
52 StringRef MacroPrefix
;
54 StringRef DefaultValue
;
55 StringRef NormalizedValuesScope
;
56 StringRef ImpliedCheck
;
57 StringRef ImpliedValue
;
58 StringRef ShouldParse
;
60 StringRef Denormalizer
;
61 StringRef ValueMerger
;
62 StringRef ValueExtractor
;
64 std::vector
<StringRef
> Values
;
65 std::vector
<StringRef
> NormalizedValues
;
66 std::string ValueTableName
;
68 static size_t NextTableIndex
;
70 static constexpr const char *ValueTablePreamble
= R
"(
71 struct SimpleEnumValue {
76 struct SimpleEnumValueTable {
77 const SimpleEnumValue *Table;
82 static constexpr const char *ValueTablesDecl
=
83 "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
85 MarshallingInfo(const Record
&R
) : R(R
) {}
87 std::string
getMacroName() const {
88 return (MacroPrefix
+ MarshallingInfo::MacroName
).str();
91 void emit(raw_ostream
&OS
) const {
94 OS
<< ShouldAlwaysEmit
;
98 emitScopedNormalizedValue(OS
, DefaultValue
);
102 emitScopedNormalizedValue(OS
, ImpliedValue
);
110 OS
<< ValueExtractor
;
115 std::optional
<StringRef
> emitValueTable(raw_ostream
&OS
) const {
116 if (TableIndex
== -1)
118 OS
<< "static const SimpleEnumValue " << ValueTableName
<< "[] = {\n";
119 for (unsigned I
= 0, E
= Values
.size(); I
!= E
; ++I
) {
121 write_cstring(OS
, Values
[I
]);
123 OS
<< "static_cast<unsigned>(";
124 emitScopedNormalizedValue(OS
, NormalizedValues
[I
]);
128 return StringRef(ValueTableName
);
132 void emitScopedNormalizedValue(raw_ostream
&OS
,
133 StringRef NormalizedValue
) const {
134 if (!NormalizedValuesScope
.empty())
135 OS
<< NormalizedValuesScope
<< "::";
136 OS
<< NormalizedValue
;
140 size_t MarshallingInfo::NextTableIndex
= 0;
142 static MarshallingInfo
createMarshallingInfo(const Record
&R
) {
143 assert(!isa
<UnsetInit
>(R
.getValueInit("KeyPath")) &&
144 !isa
<UnsetInit
>(R
.getValueInit("DefaultValue")) &&
145 !isa
<UnsetInit
>(R
.getValueInit("ValueMerger")) &&
146 "MarshallingInfo must have a provide a keypath, default value and a "
149 MarshallingInfo
Ret(R
);
151 Ret
.ShouldAlwaysEmit
= R
.getValueAsBit("ShouldAlwaysEmit");
152 Ret
.MacroPrefix
= R
.getValueAsString("MacroPrefix");
153 Ret
.KeyPath
= R
.getValueAsString("KeyPath");
154 Ret
.DefaultValue
= R
.getValueAsString("DefaultValue");
155 Ret
.NormalizedValuesScope
= R
.getValueAsString("NormalizedValuesScope");
156 Ret
.ImpliedCheck
= R
.getValueAsString("ImpliedCheck");
158 R
.getValueAsOptionalString("ImpliedValue").value_or(Ret
.DefaultValue
);
160 Ret
.ShouldParse
= R
.getValueAsString("ShouldParse");
161 Ret
.Normalizer
= R
.getValueAsString("Normalizer");
162 Ret
.Denormalizer
= R
.getValueAsString("Denormalizer");
163 Ret
.ValueMerger
= R
.getValueAsString("ValueMerger");
164 Ret
.ValueExtractor
= R
.getValueAsString("ValueExtractor");
166 if (!isa
<UnsetInit
>(R
.getValueInit("NormalizedValues"))) {
167 assert(!isa
<UnsetInit
>(R
.getValueInit("Values")) &&
168 "Cannot provide normalized values for value-less options");
169 Ret
.TableIndex
= MarshallingInfo::NextTableIndex
++;
170 Ret
.NormalizedValues
= R
.getValueAsListOfStrings("NormalizedValues");
171 Ret
.Values
.reserve(Ret
.NormalizedValues
.size());
172 Ret
.ValueTableName
= getOptionName(R
) + "ValueTable";
174 StringRef ValuesStr
= R
.getValueAsString("Values");
176 size_t Idx
= ValuesStr
.find(',');
177 if (Idx
== StringRef::npos
)
180 Ret
.Values
.push_back(ValuesStr
.slice(0, Idx
));
181 ValuesStr
= ValuesStr
.slice(Idx
+ 1, StringRef::npos
);
183 if (!ValuesStr
.empty())
184 Ret
.Values
.push_back(ValuesStr
);
186 assert(Ret
.Values
.size() == Ret
.NormalizedValues
.size() &&
187 "The number of normalized values doesn't match the number of "
194 /// OptParserEmitter - This tablegen backend takes an input .td file
195 /// describing a list of options and emits a data structure for parsing and
196 /// working with those options when given an input command line.
197 static void EmitOptParser(RecordKeeper
&Records
, raw_ostream
&OS
) {
198 // Get the option groups and options.
199 const std::vector
<Record
*> &Groups
=
200 Records
.getAllDerivedDefinitions("OptionGroup");
201 std::vector
<Record
*> Opts
= Records
.getAllDerivedDefinitions("Option");
203 emitSourceFileHeader("Option Parsing Definitions", OS
);
205 array_pod_sort(Opts
.begin(), Opts
.end(), CompareOptionRecords
);
206 // Generate prefix groups.
207 typedef SmallVector
<SmallString
<2>, 2> PrefixKeyT
;
208 typedef std::map
<PrefixKeyT
, std::string
> PrefixesT
;
210 Prefixes
.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
211 unsigned CurPrefix
= 0;
212 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
213 std::vector
<StringRef
> RPrefixes
= R
.getValueAsListOfStrings("Prefixes");
214 PrefixKeyT
PrefixKey(RPrefixes
.begin(), RPrefixes
.end());
215 unsigned NewPrefix
= CurPrefix
+ 1;
216 std::string Prefix
= (Twine("prefix_") + Twine(NewPrefix
)).str();
217 if (Prefixes
.insert(std::make_pair(PrefixKey
, Prefix
)).second
)
218 CurPrefix
= NewPrefix
;
221 DenseSet
<StringRef
> PrefixesUnionSet
;
222 for (const auto &Prefix
: Prefixes
)
223 PrefixesUnionSet
.insert(Prefix
.first
.begin(), Prefix
.first
.end());
224 SmallVector
<StringRef
> PrefixesUnion(PrefixesUnionSet
.begin(),
225 PrefixesUnionSet
.end());
226 array_pod_sort(PrefixesUnion
.begin(), PrefixesUnion
.end());
230 OS
<< "// Prefixes\n\n";
231 OS
<< "#ifdef PREFIX\n";
232 OS
<< "#define COMMA ,\n";
233 for (const auto &Prefix
: Prefixes
) {
241 for (const auto &PrefixKey
: Prefix
.first
)
242 OS
<< "llvm::StringLiteral(\"" << PrefixKey
<< "\") COMMA ";
243 // Append an empty element to avoid ending up with an empty array.
244 OS
<< "llvm::StringLiteral(\"\")})\n";
246 OS
<< "#undef COMMA\n";
247 OS
<< "#endif // PREFIX\n\n";
249 // Dump prefix unions.
251 OS
<< "// Prefix Union\n\n";
252 OS
<< "#ifdef PREFIX_UNION\n";
253 OS
<< "#define COMMA ,\n";
254 OS
<< "PREFIX_UNION({\n";
255 for (const auto &Prefix
: PrefixesUnion
) {
256 OS
<< "llvm::StringLiteral(\"" << Prefix
<< "\") COMMA ";
258 OS
<< "llvm::StringLiteral(\"\")})\n";
259 OS
<< "#undef COMMA\n";
260 OS
<< "#endif // PREFIX_UNION\n\n";
264 OS
<< "// ValuesCode\n\n";
265 OS
<< "#ifdef OPTTABLE_VALUES_CODE\n";
266 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
267 // The option values, if any;
268 if (!isa
<UnsetInit
>(R
.getValueInit("ValuesCode"))) {
269 assert(isa
<UnsetInit
>(R
.getValueInit("Values")) &&
270 "Cannot choose between Values and ValuesCode");
271 OS
<< "#define VALUES_CODE " << getOptionName(R
) << "_Values\n";
272 OS
<< R
.getValueAsString("ValuesCode") << "\n";
273 OS
<< "#undef VALUES_CODE\n";
279 OS
<< "// Groups\n\n";
280 OS
<< "#ifdef OPTION\n";
281 for (const Record
&R
: llvm::make_pointee_range(Groups
)) {
282 // Start a single option entry.
285 // The option prefix;
286 OS
<< "llvm::ArrayRef<llvm::StringLiteral>()";
288 // The option string.
289 OS
<< ", \"" << R
.getValueAsString("Name") << '"';
291 // The option identifier name.
292 OS
<< ", " << getOptionName(R
);
297 // The containing option group (if any).
299 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Group")))
300 OS
<< getOptionName(*DI
->getDef());
304 // The other option arguments (unused for groups).
305 OS
<< ", INVALID, nullptr, 0, 0, 0";
307 // The option help text.
308 if (!isa
<UnsetInit
>(R
.getValueInit("HelpText"))) {
311 write_cstring(OS
, R
.getValueAsString("HelpText"));
315 // The option meta-variable name (unused).
318 // The option Values (unused for groups).
319 OS
<< ", nullptr)\n";
323 OS
<< "//////////\n";
324 OS
<< "// Options\n\n";
326 auto WriteOptRecordFields
= [&](raw_ostream
&OS
, const Record
&R
) {
327 // The option prefix;
328 std::vector
<StringRef
> RPrefixes
= R
.getValueAsListOfStrings("Prefixes");
329 OS
<< Prefixes
[PrefixKeyT(RPrefixes
.begin(), RPrefixes
.end())] << ", ";
331 // The option prefixed name.
332 write_cstring(OS
, getOptionPrefixedName(R
));
334 // The option identifier name.
335 OS
<< ", " << getOptionName(R
);
338 OS
<< ", " << R
.getValueAsDef("Kind")->getValueAsString("Name");
340 // The containing option group (if any).
342 const ListInit
*GroupFlags
= nullptr;
343 const ListInit
*GroupVis
= nullptr;
344 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Group"))) {
345 GroupFlags
= DI
->getDef()->getValueAsListInit("Flags");
346 GroupVis
= DI
->getDef()->getValueAsListInit("Visibility");
347 OS
<< getOptionName(*DI
->getDef());
351 // The option alias (if any).
353 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Alias")))
354 OS
<< getOptionName(*DI
->getDef());
358 // The option alias arguments (if any).
359 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
360 // would become "foo\0bar\0". Note that the compiler adds an implicit
361 // terminating \0 at the end.
363 std::vector
<StringRef
> AliasArgs
= R
.getValueAsListOfStrings("AliasArgs");
364 if (AliasArgs
.size() == 0) {
368 for (StringRef AliasArg
: AliasArgs
)
369 OS
<< AliasArg
<< "\\0";
373 // "Flags" for the option, such as HelpHidden and Render*
376 const ListInit
*LI
= R
.getValueAsListInit("Flags");
378 OS
<< (NumFlags
++ ? " | " : "") << cast
<DefInit
>(I
)->getDef()->getName();
380 for (Init
*I
: *GroupFlags
)
381 OS
<< (NumFlags
++ ? " | " : "")
382 << cast
<DefInit
>(I
)->getDef()->getName();
387 // Option visibility, for sharing options between drivers.
390 LI
= R
.getValueAsListInit("Visibility");
392 OS
<< (NumVisFlags
++ ? " | " : "")
393 << cast
<DefInit
>(I
)->getDef()->getName();
395 for (Init
*I
: *GroupVis
)
396 OS
<< (NumVisFlags
++ ? " | " : "")
397 << cast
<DefInit
>(I
)->getDef()->getName();
399 if (NumVisFlags
== 0)
402 // The option parameter field.
403 OS
<< ", " << R
.getValueAsInt("NumArgs");
405 // The option help text.
406 if (!isa
<UnsetInit
>(R
.getValueInit("HelpText"))) {
409 write_cstring(OS
, R
.getValueAsString("HelpText"));
413 // The option meta-variable name.
415 if (!isa
<UnsetInit
>(R
.getValueInit("MetaVarName")))
416 write_cstring(OS
, R
.getValueAsString("MetaVarName"));
420 // The option Values. Used for shell autocompletion.
422 if (!isa
<UnsetInit
>(R
.getValueInit("Values")))
423 write_cstring(OS
, R
.getValueAsString("Values"));
424 else if (!isa
<UnsetInit
>(R
.getValueInit("ValuesCode"))) {
425 OS
<< getOptionName(R
) << "_Values";
431 auto IsMarshallingOption
= [](const Record
&R
) {
432 return !isa
<UnsetInit
>(R
.getValueInit("KeyPath")) &&
433 !R
.getValueAsString("KeyPath").empty();
436 std::vector
<const Record
*> OptsWithMarshalling
;
437 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
438 // Start a single option entry.
440 WriteOptRecordFields(OS
, R
);
442 if (IsMarshallingOption(R
))
443 OptsWithMarshalling
.push_back(&R
);
445 OS
<< "#endif // OPTION\n";
447 auto CmpMarshallingOpts
= [](const Record
*const *A
, const Record
*const *B
) {
448 unsigned AID
= (*A
)->getID();
449 unsigned BID
= (*B
)->getID();
457 // The RecordKeeper stores records (options) in lexicographical order, and we
458 // have reordered the options again when generating prefix groups. We need to
459 // restore the original definition order of options with marshalling to honor
460 // the topology of the dependency graph implied by `DefaultAnyOf`.
461 array_pod_sort(OptsWithMarshalling
.begin(), OptsWithMarshalling
.end(),
464 std::vector
<MarshallingInfo
> MarshallingInfos
;
465 MarshallingInfos
.reserve(OptsWithMarshalling
.size());
466 for (const auto *R
: OptsWithMarshalling
)
467 MarshallingInfos
.push_back(createMarshallingInfo(*R
));
469 for (const auto &MI
: MarshallingInfos
) {
470 OS
<< "#ifdef " << MI
.getMacroName() << "\n";
471 OS
<< MI
.getMacroName() << "(";
472 WriteOptRecordFields(OS
, MI
.R
);
476 OS
<< "#endif // " << MI
.getMacroName() << "\n";
480 OS
<< "#ifdef SIMPLE_ENUM_VALUE_TABLE";
482 OS
<< MarshallingInfo::ValueTablePreamble
;
483 std::vector
<StringRef
> ValueTableNames
;
484 for (const auto &MI
: MarshallingInfos
)
485 if (auto MaybeValueTableName
= MI
.emitValueTable(OS
))
486 ValueTableNames
.push_back(*MaybeValueTableName
);
488 OS
<< MarshallingInfo::ValueTablesDecl
<< "{";
489 for (auto ValueTableName
: ValueTableNames
)
490 OS
<< "{" << ValueTableName
<< ", std::size(" << ValueTableName
<< ")},\n";
492 OS
<< "static const unsigned SimpleEnumValueTablesSize = "
493 "std::size(SimpleEnumValueTables);\n";
495 OS
<< "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
501 static TableGen::Emitter::Opt
X("gen-opt-parser-defs", EmitOptParser
,
502 "Generate option definitions");