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"
23 static std::string
getOptionName(const Record
&R
) {
24 // Use the record name unless EnumName is defined.
25 if (isa
<UnsetInit
>(R
.getValueInit("EnumName")))
26 return std::string(R
.getName());
28 return std::string(R
.getValueAsString("EnumName"));
31 static raw_ostream
&write_cstring(raw_ostream
&OS
, llvm::StringRef Str
) {
33 OS
.write_escaped(Str
);
38 static std::string
getOptionSpelling(const Record
&R
, size_t &PrefixLength
) {
39 std::vector
<StringRef
> Prefixes
= R
.getValueAsListOfStrings("Prefixes");
40 StringRef Name
= R
.getValueAsString("Name");
42 if (Prefixes
.empty()) {
47 PrefixLength
= Prefixes
[0].size();
48 return (Twine(Prefixes
[0]) + Twine(Name
)).str();
51 static std::string
getOptionSpelling(const Record
&R
) {
53 return getOptionSpelling(R
, PrefixLength
);
56 static void emitNameUsingSpelling(raw_ostream
&OS
, const Record
&R
) {
59 write_cstring(OS
, StringRef(getOptionSpelling(R
, PrefixLength
)));
60 OS
<< "[" << PrefixLength
<< "]";
63 class MarshallingInfo
{
65 static constexpr const char *MacroName
= "OPTION_WITH_MARSHALLING";
67 bool ShouldAlwaysEmit
;
68 StringRef MacroPrefix
;
70 StringRef DefaultValue
;
71 StringRef NormalizedValuesScope
;
72 StringRef ImpliedCheck
;
73 StringRef ImpliedValue
;
74 StringRef ShouldParse
;
76 StringRef Denormalizer
;
77 StringRef ValueMerger
;
78 StringRef ValueExtractor
;
80 std::vector
<StringRef
> Values
;
81 std::vector
<StringRef
> NormalizedValues
;
82 std::string ValueTableName
;
84 static size_t NextTableIndex
;
86 static constexpr const char *ValueTablePreamble
= R
"(
87 struct SimpleEnumValue {
92 struct SimpleEnumValueTable {
93 const SimpleEnumValue *Table;
98 static constexpr const char *ValueTablesDecl
=
99 "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
101 MarshallingInfo(const Record
&R
) : R(R
) {}
103 std::string
getMacroName() const {
104 return (MacroPrefix
+ MarshallingInfo::MacroName
).str();
107 void emit(raw_ostream
&OS
) const {
108 write_cstring(OS
, StringRef(getOptionSpelling(R
)));
112 OS
<< ShouldAlwaysEmit
;
116 emitScopedNormalizedValue(OS
, DefaultValue
);
120 emitScopedNormalizedValue(OS
, ImpliedValue
);
128 OS
<< ValueExtractor
;
133 Optional
<StringRef
> emitValueTable(raw_ostream
&OS
) const {
134 if (TableIndex
== -1)
136 OS
<< "static const SimpleEnumValue " << ValueTableName
<< "[] = {\n";
137 for (unsigned I
= 0, E
= Values
.size(); I
!= E
; ++I
) {
139 write_cstring(OS
, Values
[I
]);
141 OS
<< "static_cast<unsigned>(";
142 emitScopedNormalizedValue(OS
, NormalizedValues
[I
]);
146 return StringRef(ValueTableName
);
150 void emitScopedNormalizedValue(raw_ostream
&OS
,
151 StringRef NormalizedValue
) const {
152 if (!NormalizedValuesScope
.empty())
153 OS
<< NormalizedValuesScope
<< "::";
154 OS
<< NormalizedValue
;
158 size_t MarshallingInfo::NextTableIndex
= 0;
160 static MarshallingInfo
createMarshallingInfo(const Record
&R
) {
161 assert(!isa
<UnsetInit
>(R
.getValueInit("KeyPath")) &&
162 !isa
<UnsetInit
>(R
.getValueInit("DefaultValue")) &&
163 !isa
<UnsetInit
>(R
.getValueInit("ValueMerger")) &&
164 "MarshallingInfo must have a provide a keypath, default value and a "
167 MarshallingInfo
Ret(R
);
169 Ret
.ShouldAlwaysEmit
= R
.getValueAsBit("ShouldAlwaysEmit");
170 Ret
.MacroPrefix
= R
.getValueAsString("MacroPrefix");
171 Ret
.KeyPath
= R
.getValueAsString("KeyPath");
172 Ret
.DefaultValue
= R
.getValueAsString("DefaultValue");
173 Ret
.NormalizedValuesScope
= R
.getValueAsString("NormalizedValuesScope");
174 Ret
.ImpliedCheck
= R
.getValueAsString("ImpliedCheck");
176 R
.getValueAsOptionalString("ImpliedValue").getValueOr(Ret
.DefaultValue
);
178 Ret
.ShouldParse
= R
.getValueAsString("ShouldParse");
179 Ret
.Normalizer
= R
.getValueAsString("Normalizer");
180 Ret
.Denormalizer
= R
.getValueAsString("Denormalizer");
181 Ret
.ValueMerger
= R
.getValueAsString("ValueMerger");
182 Ret
.ValueExtractor
= R
.getValueAsString("ValueExtractor");
184 if (!isa
<UnsetInit
>(R
.getValueInit("NormalizedValues"))) {
185 assert(!isa
<UnsetInit
>(R
.getValueInit("Values")) &&
186 "Cannot provide normalized values for value-less options");
187 Ret
.TableIndex
= MarshallingInfo::NextTableIndex
++;
188 Ret
.NormalizedValues
= R
.getValueAsListOfStrings("NormalizedValues");
189 Ret
.Values
.reserve(Ret
.NormalizedValues
.size());
190 Ret
.ValueTableName
= getOptionName(R
) + "ValueTable";
192 StringRef ValuesStr
= R
.getValueAsString("Values");
194 size_t Idx
= ValuesStr
.find(',');
195 if (Idx
== StringRef::npos
)
198 Ret
.Values
.push_back(ValuesStr
.slice(0, Idx
));
199 ValuesStr
= ValuesStr
.slice(Idx
+ 1, StringRef::npos
);
201 if (!ValuesStr
.empty())
202 Ret
.Values
.push_back(ValuesStr
);
204 assert(Ret
.Values
.size() == Ret
.NormalizedValues
.size() &&
205 "The number of normalized values doesn't match the number of "
212 /// OptParserEmitter - This tablegen backend takes an input .td file
213 /// describing a list of options and emits a data structure for parsing and
214 /// working with those options when given an input command line.
216 void EmitOptParser(RecordKeeper
&Records
, raw_ostream
&OS
) {
217 // Get the option groups and options.
218 const std::vector
<Record
*> &Groups
=
219 Records
.getAllDerivedDefinitions("OptionGroup");
220 std::vector
<Record
*> Opts
= Records
.getAllDerivedDefinitions("Option");
222 emitSourceFileHeader("Option Parsing Definitions", OS
);
224 array_pod_sort(Opts
.begin(), Opts
.end(), CompareOptionRecords
);
225 // Generate prefix groups.
226 typedef SmallVector
<SmallString
<2>, 2> PrefixKeyT
;
227 typedef std::map
<PrefixKeyT
, std::string
> PrefixesT
;
229 Prefixes
.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
230 unsigned CurPrefix
= 0;
231 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
232 std::vector
<StringRef
> RPrefixes
= R
.getValueAsListOfStrings("Prefixes");
233 PrefixKeyT
PrefixKey(RPrefixes
.begin(), RPrefixes
.end());
234 unsigned NewPrefix
= CurPrefix
+ 1;
235 std::string Prefix
= (Twine("prefix_") + Twine(NewPrefix
)).str();
236 if (Prefixes
.insert(std::make_pair(PrefixKey
, Prefix
)).second
)
237 CurPrefix
= NewPrefix
;
243 OS
<< "// Prefixes\n\n";
244 OS
<< "#ifdef PREFIX\n";
245 OS
<< "#define COMMA ,\n";
246 for (const auto &Prefix
: Prefixes
) {
254 for (const auto &PrefixKey
: Prefix
.first
)
255 OS
<< "\"" << PrefixKey
<< "\" COMMA ";
258 OS
<< "#undef COMMA\n";
259 OS
<< "#endif // PREFIX\n\n";
262 OS
<< "// Groups\n\n";
263 OS
<< "#ifdef OPTION\n";
264 for (const Record
&R
: llvm::make_pointee_range(Groups
)) {
265 // Start a single option entry.
268 // The option prefix;
271 // The option string.
272 OS
<< ", \"" << R
.getValueAsString("Name") << '"';
274 // The option identifier name.
275 OS
<< ", " << getOptionName(R
);
280 // The containing option group (if any).
282 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Group")))
283 OS
<< getOptionName(*DI
->getDef());
287 // The other option arguments (unused for groups).
288 OS
<< ", INVALID, nullptr, 0, 0";
290 // The option help text.
291 if (!isa
<UnsetInit
>(R
.getValueInit("HelpText"))) {
294 write_cstring(OS
, R
.getValueAsString("HelpText"));
298 // The option meta-variable name (unused).
301 // The option Values (unused for groups).
302 OS
<< ", nullptr)\n";
306 OS
<< "//////////\n";
307 OS
<< "// Options\n\n";
309 auto WriteOptRecordFields
= [&](raw_ostream
&OS
, const Record
&R
) {
310 // The option prefix;
311 std::vector
<StringRef
> RPrefixes
= R
.getValueAsListOfStrings("Prefixes");
312 OS
<< Prefixes
[PrefixKeyT(RPrefixes
.begin(), RPrefixes
.end())] << ", ";
314 // The option string.
315 emitNameUsingSpelling(OS
, R
);
317 // The option identifier name.
318 OS
<< ", " << getOptionName(R
);
321 OS
<< ", " << R
.getValueAsDef("Kind")->getValueAsString("Name");
323 // The containing option group (if any).
325 const ListInit
*GroupFlags
= nullptr;
326 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Group"))) {
327 GroupFlags
= DI
->getDef()->getValueAsListInit("Flags");
328 OS
<< getOptionName(*DI
->getDef());
332 // The option alias (if any).
334 if (const DefInit
*DI
= dyn_cast
<DefInit
>(R
.getValueInit("Alias")))
335 OS
<< getOptionName(*DI
->getDef());
339 // The option alias arguments (if any).
340 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
341 // would become "foo\0bar\0". Note that the compiler adds an implicit
342 // terminating \0 at the end.
344 std::vector
<StringRef
> AliasArgs
= R
.getValueAsListOfStrings("AliasArgs");
345 if (AliasArgs
.size() == 0) {
349 for (StringRef AliasArg
: AliasArgs
)
350 OS
<< AliasArg
<< "\\0";
357 const ListInit
*LI
= R
.getValueAsListInit("Flags");
359 OS
<< (NumFlags
++ ? " | " : "") << cast
<DefInit
>(I
)->getDef()->getName();
361 for (Init
*I
: *GroupFlags
)
362 OS
<< (NumFlags
++ ? " | " : "")
363 << cast
<DefInit
>(I
)->getDef()->getName();
368 // The option parameter field.
369 OS
<< ", " << R
.getValueAsInt("NumArgs");
371 // The option help text.
372 if (!isa
<UnsetInit
>(R
.getValueInit("HelpText"))) {
375 write_cstring(OS
, R
.getValueAsString("HelpText"));
379 // The option meta-variable name.
381 if (!isa
<UnsetInit
>(R
.getValueInit("MetaVarName")))
382 write_cstring(OS
, R
.getValueAsString("MetaVarName"));
386 // The option Values. Used for shell autocompletion.
388 if (!isa
<UnsetInit
>(R
.getValueInit("Values")))
389 write_cstring(OS
, R
.getValueAsString("Values"));
394 auto IsMarshallingOption
= [](const Record
&R
) {
395 return !isa
<UnsetInit
>(R
.getValueInit("KeyPath")) &&
396 !R
.getValueAsString("KeyPath").empty();
399 std::vector
<const Record
*> OptsWithMarshalling
;
400 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
401 // Start a single option entry.
403 WriteOptRecordFields(OS
, R
);
405 if (IsMarshallingOption(R
))
406 OptsWithMarshalling
.push_back(&R
);
408 OS
<< "#endif // OPTION\n";
410 auto CmpMarshallingOpts
= [](const Record
*const *A
, const Record
*const *B
) {
411 unsigned AID
= (*A
)->getID();
412 unsigned BID
= (*B
)->getID();
420 // The RecordKeeper stores records (options) in lexicographical order, and we
421 // have reordered the options again when generating prefix groups. We need to
422 // restore the original definition order of options with marshalling to honor
423 // the topology of the dependency graph implied by `DefaultAnyOf`.
424 array_pod_sort(OptsWithMarshalling
.begin(), OptsWithMarshalling
.end(),
427 std::vector
<MarshallingInfo
> MarshallingInfos
;
428 for (const auto *R
: OptsWithMarshalling
)
429 MarshallingInfos
.push_back(createMarshallingInfo(*R
));
431 for (const auto &MI
: MarshallingInfos
) {
432 OS
<< "#ifdef " << MI
.getMacroName() << "\n";
433 OS
<< MI
.getMacroName() << "(";
434 WriteOptRecordFields(OS
, MI
.R
);
438 OS
<< "#endif // " << MI
.getMacroName() << "\n";
442 OS
<< "#ifdef SIMPLE_ENUM_VALUE_TABLE";
444 OS
<< MarshallingInfo::ValueTablePreamble
;
445 std::vector
<StringRef
> ValueTableNames
;
446 for (const auto &MI
: MarshallingInfos
)
447 if (auto MaybeValueTableName
= MI
.emitValueTable(OS
))
448 ValueTableNames
.push_back(*MaybeValueTableName
);
450 OS
<< MarshallingInfo::ValueTablesDecl
<< "{";
451 for (auto ValueTableName
: ValueTableNames
)
452 OS
<< "{" << ValueTableName
<< ", sizeof(" << ValueTableName
453 << ") / sizeof(SimpleEnumValue)"
456 OS
<< "static const unsigned SimpleEnumValueTablesSize = "
457 "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n";
459 OS
<< "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
463 OS
<< "#ifdef OPTTABLE_ARG_INIT\n";
464 OS
<< "//////////\n";
465 OS
<< "// Option Values\n\n";
466 for (const Record
&R
: llvm::make_pointee_range(Opts
)) {
467 if (isa
<UnsetInit
>(R
.getValueInit("ValuesCode")))
470 OS
<< "bool ValuesWereAdded;\n";
471 OS
<< R
.getValueAsString("ValuesCode");
473 for (StringRef Prefix
: R
.getValueAsListOfStrings("Prefixes")) {
474 OS
<< "ValuesWereAdded = Opt.addValues(";
475 std::string
S(Prefix
);
476 S
+= R
.getValueAsString("Name");
477 write_cstring(OS
, S
);
478 OS
<< ", Values);\n";
479 OS
<< "(void)ValuesWereAdded;\n";
480 OS
<< "assert(ValuesWereAdded && \"Couldn't add values to "
486 OS
<< "#endif // OPTTABLE_ARG_INIT\n";
488 } // end namespace llvm