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 const 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 const std::string getOptionSpelling(const Record &R,
39 size_t &PrefixLength) {
40 std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes");
41 StringRef Name = R.getValueAsString("Name");
42 if (Prefixes.empty()) {
46 PrefixLength = Prefixes[0].size();
47 return (Twine(Prefixes[0]) + Twine(Name)).str();
50 static const std::string getOptionSpelling(const Record &R) {
52 return getOptionSpelling(R, PrefixLength);
55 static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
58 write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength)));
59 OS << "[" << PrefixLength << "]";
62 class MarshallingKindInfo {
65 const char *MacroName;
66 bool ShouldAlwaysEmit;
68 StringRef DefaultValue;
69 StringRef NormalizedValuesScope;
71 void emit(raw_ostream &OS) const {
72 write_cstring(OS, StringRef(getOptionSpelling(R)));
74 OS << ShouldAlwaysEmit;
78 emitScopedNormalizedValue(OS, DefaultValue);
83 virtual Optional<StringRef> emitValueTable(raw_ostream &OS) const {
87 virtual ~MarshallingKindInfo() = default;
89 static std::unique_ptr<MarshallingKindInfo> create(const Record &R);
92 void emitScopedNormalizedValue(raw_ostream &OS,
93 StringRef NormalizedValue) const {
94 if (!NormalizedValuesScope.empty())
95 OS << NormalizedValuesScope << "::";
96 OS << NormalizedValue;
99 virtual void emitSpecific(raw_ostream &OS) const = 0;
100 MarshallingKindInfo(const Record &R, const char *MacroName)
101 : R(R), MacroName(MacroName) {}
104 class MarshallingFlagInfo final : public MarshallingKindInfo {
108 void emitSpecific(raw_ostream &OS) const override { OS << IsPositive; }
110 static std::unique_ptr<MarshallingKindInfo> create(const Record &R) {
111 std::unique_ptr<MarshallingFlagInfo> Ret(new MarshallingFlagInfo(R));
112 Ret->IsPositive = R.getValueAsBit("IsPositive");
117 MarshallingFlagInfo(const Record &R)
118 : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_FLAG") {}
121 class MarshallingStringInfo final : public MarshallingKindInfo {
123 StringRef NormalizerRetTy;
124 StringRef Normalizer;
125 StringRef Denormalizer;
127 std::vector<StringRef> Values;
128 std::vector<StringRef> NormalizedValues;
129 std::string ValueTableName;
131 static constexpr const char *ValueTablePreamble = R"(
132 struct SimpleEnumValue {
137 struct SimpleEnumValueTable {
138 const SimpleEnumValue *Table;
143 static constexpr const char *ValueTablesDecl =
144 "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
146 void emitSpecific(raw_ostream &OS) const override {
147 emitScopedNormalizedValue(OS, NormalizerRetTy);
156 Optional<StringRef> emitValueTable(raw_ostream &OS) const override {
157 if (TableIndex == -1)
159 OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n";
160 for (unsigned I = 0, E = Values.size(); I != E; ++I) {
162 write_cstring(OS, Values[I]);
164 OS << "static_cast<unsigned>(";
165 emitScopedNormalizedValue(OS, NormalizedValues[I]);
169 return StringRef(ValueTableName);
172 static std::unique_ptr<MarshallingKindInfo> create(const Record &R) {
173 assert(!isa<UnsetInit>(R.getValueInit("NormalizerRetTy")) &&
174 "String options must have a type");
176 std::unique_ptr<MarshallingStringInfo> Ret(new MarshallingStringInfo(R));
177 Ret->NormalizerRetTy = R.getValueAsString("NormalizerRetTy");
179 Ret->Normalizer = R.getValueAsString("Normalizer");
180 Ret->Denormalizer = R.getValueAsString("Denormalizer");
182 if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
183 assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
184 "Cannot provide normalized values for value-less options");
185 Ret->TableIndex = NextTableIndex++;
186 Ret->NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
187 Ret->Values.reserve(Ret->NormalizedValues.size());
188 Ret->ValueTableName = getOptionName(R) + "ValueTable";
190 StringRef ValuesStr = R.getValueAsString("Values");
192 size_t Idx = ValuesStr.find(',');
193 if (Idx == StringRef::npos)
196 Ret->Values.push_back(ValuesStr.slice(0, Idx));
197 ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
199 if (!ValuesStr.empty())
200 Ret->Values.push_back(ValuesStr);
202 assert(Ret->Values.size() == Ret->NormalizedValues.size() &&
203 "The number of normalized values doesn't match the number of "
211 MarshallingStringInfo(const Record &R)
212 : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_STRING") {}
214 static size_t NextTableIndex;
217 size_t MarshallingStringInfo::NextTableIndex = 0;
219 std::unique_ptr<MarshallingKindInfo>
220 MarshallingKindInfo::create(const Record &R) {
221 assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
222 !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
223 "Must provide at least a key-path and a default value for emitting "
224 "marshalling information");
226 std::unique_ptr<MarshallingKindInfo> Ret = nullptr;
227 StringRef MarshallingKindStr = R.getValueAsString("MarshallingKind");
229 if (MarshallingKindStr == "flag")
230 Ret = MarshallingFlagInfo::create(R);
231 else if (MarshallingKindStr == "string")
232 Ret = MarshallingStringInfo::create(R);
234 Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
235 Ret->KeyPath = R.getValueAsString("KeyPath");
236 Ret->DefaultValue = R.getValueAsString("DefaultValue");
237 if (!isa<UnsetInit>(R.getValueInit("NormalizedValuesScope")))
238 Ret->NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
242 /// OptParserEmitter - This tablegen backend takes an input .td file
243 /// describing a list of options and emits a data structure for parsing and
244 /// working with those options when given an input command line.
246 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
247 // Get the option groups and options.
248 const std::vector<Record*> &Groups =
249 Records.getAllDerivedDefinitions("OptionGroup");
250 std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");
252 emitSourceFileHeader("Option Parsing Definitions", OS);
254 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
255 // Generate prefix groups.
256 typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
257 typedef std::map<PrefixKeyT, std::string> PrefixesT;
259 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
260 unsigned CurPrefix = 0;
261 for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
262 const Record &R = *Opts[i];
263 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
264 PrefixKeyT prfkey(prf.begin(), prf.end());
265 unsigned NewPrefix = CurPrefix + 1;
266 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
267 Twine(NewPrefix)).str())).second)
268 CurPrefix = NewPrefix;
274 OS << "// Prefixes\n\n";
275 OS << "#ifdef PREFIX\n";
276 OS << "#define COMMA ,\n";
277 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
286 for (PrefixKeyT::const_iterator PI = I->first.begin(),
287 PE = I->first.end(); PI != PE; ++PI) {
288 OS << "\"" << *PI << "\" COMMA ";
292 OS << "#undef COMMA\n";
293 OS << "#endif // PREFIX\n\n";
296 OS << "// Groups\n\n";
297 OS << "#ifdef OPTION\n";
298 for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
299 const Record &R = *Groups[i];
301 // Start a single option entry.
304 // The option prefix;
307 // The option string.
308 OS << ", \"" << R.getValueAsString("Name") << '"';
310 // The option identifier name.
311 OS << ", " << getOptionName(R);
316 // The containing option group (if any).
318 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
319 OS << getOptionName(*DI->getDef());
323 // The other option arguments (unused for groups).
324 OS << ", INVALID, nullptr, 0, 0";
326 // The option help text.
327 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
330 write_cstring(OS, R.getValueAsString("HelpText"));
334 // The option meta-variable name (unused).
337 // The option Values (unused for groups).
338 OS << ", nullptr)\n";
342 OS << "//////////\n";
343 OS << "// Options\n\n";
345 auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
346 // The option prefix;
347 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
348 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
350 // The option string.
351 emitNameUsingSpelling(OS, R);
353 // The option identifier name.
354 OS << ", " << getOptionName(R);
357 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
359 // The containing option group (if any).
361 const ListInit *GroupFlags = nullptr;
362 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
363 GroupFlags = DI->getDef()->getValueAsListInit("Flags");
364 OS << getOptionName(*DI->getDef());
368 // The option alias (if any).
370 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))
371 OS << getOptionName(*DI->getDef());
375 // The option alias arguments (if any).
376 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
377 // would become "foo\0bar\0". Note that the compiler adds an implicit
378 // terminating \0 at the end.
380 std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
381 if (AliasArgs.size() == 0) {
385 for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
386 OS << AliasArgs[i] << "\\0";
393 const ListInit *LI = R.getValueAsListInit("Flags");
395 OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
397 for (Init *I : *GroupFlags)
398 OS << (NumFlags++ ? " | " : "")
399 << cast<DefInit>(I)->getDef()->getName();
404 // The option parameter field.
405 OS << ", " << R.getValueAsInt("NumArgs");
407 // The option help text.
408 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
411 write_cstring(OS, R.getValueAsString("HelpText"));
415 // The option meta-variable name.
417 if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
418 write_cstring(OS, R.getValueAsString("MetaVarName"));
422 // The option Values. Used for shell autocompletion.
424 if (!isa<UnsetInit>(R.getValueInit("Values")))
425 write_cstring(OS, R.getValueAsString("Values"));
430 std::vector<std::unique_ptr<MarshallingKindInfo>> OptsWithMarshalling;
431 for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
432 const Record &R = *Opts[I];
434 // Start a single option entry.
436 WriteOptRecordFields(OS, R);
438 if (!isa<UnsetInit>(R.getValueInit("MarshallingKind")))
439 OptsWithMarshalling.push_back(MarshallingKindInfo::create(R));
441 OS << "#endif // OPTION\n";
443 for (const auto &KindInfo : OptsWithMarshalling) {
444 OS << "#ifdef " << KindInfo->MacroName << "\n";
445 OS << KindInfo->MacroName << "(";
446 WriteOptRecordFields(OS, KindInfo->R);
450 OS << "#endif // " << KindInfo->MacroName << "\n";
454 OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE";
456 OS << MarshallingStringInfo::ValueTablePreamble;
457 std::vector<StringRef> ValueTableNames;
458 for (const auto &KindInfo : OptsWithMarshalling)
459 if (auto MaybeValueTableName = KindInfo->emitValueTable(OS))
460 ValueTableNames.push_back(*MaybeValueTableName);
462 OS << MarshallingStringInfo::ValueTablesDecl << "{";
463 for (auto ValueTableName : ValueTableNames)
464 OS << "{" << ValueTableName << ", sizeof(" << ValueTableName
465 << ") / sizeof(SimpleEnumValue)"
468 OS << "static const unsigned SimpleEnumValueTablesSize = "
469 "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n";
471 OS << "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
475 OS << "#ifdef OPTTABLE_ARG_INIT\n";
476 OS << "//////////\n";
477 OS << "// Option Values\n\n";
478 for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
479 const Record &R = *Opts[I];
480 if (isa<UnsetInit>(R.getValueInit("ValuesCode")))
483 OS << "bool ValuesWereAdded;\n";
484 OS << R.getValueAsString("ValuesCode");
486 for (StringRef Prefix : R.getValueAsListOfStrings("Prefixes")) {
487 OS << "ValuesWereAdded = Opt.addValues(";
488 std::string S(Prefix);
489 S += R.getValueAsString("Name");
490 write_cstring(OS, S);
491 OS << ", Values);\n";
492 OS << "(void)ValuesWereAdded;\n";
493 OS << "assert(ValuesWereAdded && \"Couldn't add values to "
499 OS << "#endif // OPTTABLE_ARG_INIT\n";
501 } // end namespace llvm