1 //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
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 "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"
16 #include <cctype>
17 #include <cstring>
18 #include <map>
19 #include <memory>
20
21 using namespace llvm;
22
getOptionName(const Record & R)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());
27
28 return std::string(R.getValueAsString("EnumName"));
29 }
30
write_cstring(raw_ostream & OS,llvm::StringRef Str)31 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
32 OS << '"';
33 OS.write_escaped(Str);
34 OS << '"';
35 return OS;
36 }
37
getOptionSpelling(const Record & R,size_t & PrefixLength)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
43 if (Prefixes.empty()) {
44 PrefixLength = 0;
45 return Name.str();
46 }
47
48 PrefixLength = Prefixes[0].size();
49 return (Twine(Prefixes[0]) + Twine(Name)).str();
50 }
51
getOptionSpelling(const Record & R)52 static const std::string getOptionSpelling(const Record &R) {
53 size_t PrefixLength;
54 return getOptionSpelling(R, PrefixLength);
55 }
56
emitNameUsingSpelling(raw_ostream & OS,const Record & R)57 static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
58 size_t PrefixLength;
59 OS << "&";
60 write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength)));
61 OS << "[" << PrefixLength << "]";
62 }
63
64 class MarshallingInfo {
65 public:
66 static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
67 const Record &R;
68 bool ShouldAlwaysEmit;
69 StringRef KeyPath;
70 StringRef DefaultValue;
71 StringRef NormalizedValuesScope;
72 StringRef ImpliedCheck;
73 StringRef ImpliedValue;
74 StringRef Normalizer;
75 StringRef Denormalizer;
76 StringRef ValueMerger;
77 StringRef ValueExtractor;
78 int TableIndex = -1;
79 std::vector<StringRef> Values;
80 std::vector<StringRef> NormalizedValues;
81 std::string ValueTableName;
82
83 static size_t NextTableIndex;
84
85 static constexpr const char *ValueTablePreamble = R"(
86 struct SimpleEnumValue {
87 const char *Name;
88 unsigned Value;
89 };
90
91 struct SimpleEnumValueTable {
92 const SimpleEnumValue *Table;
93 unsigned Size;
94 };
95 )";
96
97 static constexpr const char *ValueTablesDecl =
98 "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
99
MarshallingInfo(const Record & R)100 MarshallingInfo(const Record &R) : R(R) {}
101
emit(raw_ostream & OS) const102 void emit(raw_ostream &OS) const {
103 write_cstring(OS, StringRef(getOptionSpelling(R)));
104 OS << ", ";
105 OS << ShouldAlwaysEmit;
106 OS << ", ";
107 OS << KeyPath;
108 OS << ", ";
109 emitScopedNormalizedValue(OS, DefaultValue);
110 OS << ", ";
111 OS << ImpliedCheck;
112 OS << ", ";
113 emitScopedNormalizedValue(OS, ImpliedValue);
114 OS << ", ";
115 OS << Normalizer;
116 OS << ", ";
117 OS << Denormalizer;
118 OS << ", ";
119 OS << ValueMerger;
120 OS << ", ";
121 OS << ValueExtractor;
122 OS << ", ";
123 OS << TableIndex;
124 }
125
emitValueTable(raw_ostream & OS) const126 Optional<StringRef> emitValueTable(raw_ostream &OS) const {
127 if (TableIndex == -1)
128 return {};
129 OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n";
130 for (unsigned I = 0, E = Values.size(); I != E; ++I) {
131 OS << "{";
132 write_cstring(OS, Values[I]);
133 OS << ",";
134 OS << "static_cast<unsigned>(";
135 emitScopedNormalizedValue(OS, NormalizedValues[I]);
136 OS << ")},";
137 }
138 OS << "};\n";
139 return StringRef(ValueTableName);
140 }
141
142 private:
emitScopedNormalizedValue(raw_ostream & OS,StringRef NormalizedValue) const143 void emitScopedNormalizedValue(raw_ostream &OS,
144 StringRef NormalizedValue) const {
145 if (!NormalizedValuesScope.empty())
146 OS << NormalizedValuesScope << "::";
147 OS << NormalizedValue;
148 }
149 };
150
151 size_t MarshallingInfo::NextTableIndex = 0;
152
createMarshallingInfo(const Record & R)153 static MarshallingInfo createMarshallingInfo(const Record &R) {
154 assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
155 !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
156 !isa<UnsetInit>(R.getValueInit("ValueMerger")) &&
157 "MarshallingInfo must have a provide a keypath, default value and a "
158 "value merger");
159
160 MarshallingInfo Ret(R);
161
162 Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
163 Ret.KeyPath = R.getValueAsString("KeyPath");
164 Ret.DefaultValue = R.getValueAsString("DefaultValue");
165 Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
166 Ret.ImpliedCheck = R.getValueAsString("ImpliedCheck");
167 Ret.ImpliedValue =
168 R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret.DefaultValue);
169
170 Ret.Normalizer = R.getValueAsString("Normalizer");
171 Ret.Denormalizer = R.getValueAsString("Denormalizer");
172 Ret.ValueMerger = R.getValueAsString("ValueMerger");
173 Ret.ValueExtractor = R.getValueAsString("ValueExtractor");
174
175 if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
176 assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
177 "Cannot provide normalized values for value-less options");
178 Ret.TableIndex = MarshallingInfo::NextTableIndex++;
179 Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
180 Ret.Values.reserve(Ret.NormalizedValues.size());
181 Ret.ValueTableName = getOptionName(R) + "ValueTable";
182
183 StringRef ValuesStr = R.getValueAsString("Values");
184 for (;;) {
185 size_t Idx = ValuesStr.find(',');
186 if (Idx == StringRef::npos)
187 break;
188 if (Idx > 0)
189 Ret.Values.push_back(ValuesStr.slice(0, Idx));
190 ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
191 }
192 if (!ValuesStr.empty())
193 Ret.Values.push_back(ValuesStr);
194
195 assert(Ret.Values.size() == Ret.NormalizedValues.size() &&
196 "The number of normalized values doesn't match the number of "
197 "values");
198 }
199
200 return Ret;
201 }
202
203 /// OptParserEmitter - This tablegen backend takes an input .td file
204 /// describing a list of options and emits a data structure for parsing and
205 /// working with those options when given an input command line.
206 namespace llvm {
EmitOptParser(RecordKeeper & Records,raw_ostream & OS)207 void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
208 // Get the option groups and options.
209 const std::vector<Record*> &Groups =
210 Records.getAllDerivedDefinitions("OptionGroup");
211 std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");
212
213 emitSourceFileHeader("Option Parsing Definitions", OS);
214
215 array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
216 // Generate prefix groups.
217 typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
218 typedef std::map<PrefixKeyT, std::string> PrefixesT;
219 PrefixesT Prefixes;
220 Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
221 unsigned CurPrefix = 0;
222 for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
223 const Record &R = *Opts[i];
224 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
225 PrefixKeyT prfkey(prf.begin(), prf.end());
226 unsigned NewPrefix = CurPrefix + 1;
227 if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
228 Twine(NewPrefix)).str())).second)
229 CurPrefix = NewPrefix;
230 }
231
232 // Dump prefixes.
233
234 OS << "/////////\n";
235 OS << "// Prefixes\n\n";
236 OS << "#ifdef PREFIX\n";
237 OS << "#define COMMA ,\n";
238 for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
239 I != E; ++I) {
240 OS << "PREFIX(";
241
242 // Prefix name.
243 OS << I->second;
244
245 // Prefix values.
246 OS << ", {";
247 for (PrefixKeyT::const_iterator PI = I->first.begin(),
248 PE = I->first.end(); PI != PE; ++PI) {
249 OS << "\"" << *PI << "\" COMMA ";
250 }
251 OS << "nullptr})\n";
252 }
253 OS << "#undef COMMA\n";
254 OS << "#endif // PREFIX\n\n";
255
256 OS << "/////////\n";
257 OS << "// Groups\n\n";
258 OS << "#ifdef OPTION\n";
259 for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
260 const Record &R = *Groups[i];
261
262 // Start a single option entry.
263 OS << "OPTION(";
264
265 // The option prefix;
266 OS << "nullptr";
267
268 // The option string.
269 OS << ", \"" << R.getValueAsString("Name") << '"';
270
271 // The option identifier name.
272 OS << ", " << getOptionName(R);
273
274 // The option kind.
275 OS << ", Group";
276
277 // The containing option group (if any).
278 OS << ", ";
279 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
280 OS << getOptionName(*DI->getDef());
281 else
282 OS << "INVALID";
283
284 // The other option arguments (unused for groups).
285 OS << ", INVALID, nullptr, 0, 0";
286
287 // The option help text.
288 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
289 OS << ",\n";
290 OS << " ";
291 write_cstring(OS, R.getValueAsString("HelpText"));
292 } else
293 OS << ", nullptr";
294
295 // The option meta-variable name (unused).
296 OS << ", nullptr";
297
298 // The option Values (unused for groups).
299 OS << ", nullptr)\n";
300 }
301 OS << "\n";
302
303 OS << "//////////\n";
304 OS << "// Options\n\n";
305
306 auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
307 // The option prefix;
308 std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
309 OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
310
311 // The option string.
312 emitNameUsingSpelling(OS, R);
313
314 // The option identifier name.
315 OS << ", " << getOptionName(R);
316
317 // The option kind.
318 OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
319
320 // The containing option group (if any).
321 OS << ", ";
322 const ListInit *GroupFlags = nullptr;
323 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
324 GroupFlags = DI->getDef()->getValueAsListInit("Flags");
325 OS << getOptionName(*DI->getDef());
326 } else
327 OS << "INVALID";
328
329 // The option alias (if any).
330 OS << ", ";
331 if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))
332 OS << getOptionName(*DI->getDef());
333 else
334 OS << "INVALID";
335
336 // The option alias arguments (if any).
337 // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
338 // would become "foo\0bar\0". Note that the compiler adds an implicit
339 // terminating \0 at the end.
340 OS << ", ";
341 std::vector<StringRef> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
342 if (AliasArgs.size() == 0) {
343 OS << "nullptr";
344 } else {
345 OS << "\"";
346 for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
347 OS << AliasArgs[i] << "\\0";
348 OS << "\"";
349 }
350
351 // The option flags.
352 OS << ", ";
353 int NumFlags = 0;
354 const ListInit *LI = R.getValueAsListInit("Flags");
355 for (Init *I : *LI)
356 OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
357 if (GroupFlags) {
358 for (Init *I : *GroupFlags)
359 OS << (NumFlags++ ? " | " : "")
360 << cast<DefInit>(I)->getDef()->getName();
361 }
362 if (NumFlags == 0)
363 OS << '0';
364
365 // The option parameter field.
366 OS << ", " << R.getValueAsInt("NumArgs");
367
368 // The option help text.
369 if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
370 OS << ",\n";
371 OS << " ";
372 write_cstring(OS, R.getValueAsString("HelpText"));
373 } else
374 OS << ", nullptr";
375
376 // The option meta-variable name.
377 OS << ", ";
378 if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
379 write_cstring(OS, R.getValueAsString("MetaVarName"));
380 else
381 OS << "nullptr";
382
383 // The option Values. Used for shell autocompletion.
384 OS << ", ";
385 if (!isa<UnsetInit>(R.getValueInit("Values")))
386 write_cstring(OS, R.getValueAsString("Values"));
387 else
388 OS << "nullptr";
389 };
390
391 auto IsMarshallingOption = [](const Record &R) {
392 return !isa<UnsetInit>(R.getValueInit("KeyPath")) &&
393 !R.getValueAsString("KeyPath").empty();
394 };
395
396 std::vector<const Record *> OptsWithMarshalling;
397 for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
398 const Record &R = *Opts[I];
399
400 // Start a single option entry.
401 OS << "OPTION(";
402 WriteOptRecordFields(OS, R);
403 OS << ")\n";
404 if (IsMarshallingOption(R))
405 OptsWithMarshalling.push_back(&R);
406 }
407 OS << "#endif // OPTION\n";
408
409 auto CmpMarshallingOpts = [](const Record *const *A, const Record *const *B) {
410 unsigned AID = (*A)->getID();
411 unsigned BID = (*B)->getID();
412
413 if (AID < BID)
414 return -1;
415 if (AID > BID)
416 return 1;
417 return 0;
418 };
419 // The RecordKeeper stores records (options) in lexicographical order, and we
420 // have reordered the options again when generating prefix groups. We need to
421 // restore the original definition order of options with marshalling to honor
422 // the topology of the dependency graph implied by `DefaultAnyOf`.
423 array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(),
424 CmpMarshallingOpts);
425
426 std::vector<MarshallingInfo> MarshallingInfos;
427 for (const auto *R : OptsWithMarshalling)
428 MarshallingInfos.push_back(createMarshallingInfo(*R));
429
430 for (const auto &MI : MarshallingInfos) {
431 OS << "#ifdef " << MarshallingInfo::MacroName << "\n";
432 OS << MarshallingInfo::MacroName << "(";
433 WriteOptRecordFields(OS, MI.R);
434 OS << ", ";
435 MI.emit(OS);
436 OS << ")\n";
437 OS << "#endif // " << MarshallingInfo::MacroName << "\n";
438 }
439
440 OS << "\n";
441 OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE";
442 OS << "\n";
443 OS << MarshallingInfo::ValueTablePreamble;
444 std::vector<StringRef> ValueTableNames;
445 for (const auto &MI : MarshallingInfos)
446 if (auto MaybeValueTableName = MI.emitValueTable(OS))
447 ValueTableNames.push_back(*MaybeValueTableName);
448
449 OS << MarshallingInfo::ValueTablesDecl << "{";
450 for (auto ValueTableName : ValueTableNames)
451 OS << "{" << ValueTableName << ", sizeof(" << ValueTableName
452 << ") / sizeof(SimpleEnumValue)"
453 << "},\n";
454 OS << "};\n";
455 OS << "static const unsigned SimpleEnumValueTablesSize = "
456 "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n";
457
458 OS << "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
459 OS << "\n";
460
461 OS << "\n";
462 OS << "#ifdef OPTTABLE_ARG_INIT\n";
463 OS << "//////////\n";
464 OS << "// Option Values\n\n";
465 for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
466 const Record &R = *Opts[I];
467 if (isa<UnsetInit>(R.getValueInit("ValuesCode")))
468 continue;
469 OS << "{\n";
470 OS << "bool ValuesWereAdded;\n";
471 OS << R.getValueAsString("ValuesCode");
472 OS << "\n";
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 "
481 "OptTable!\");\n";
482 }
483 OS << "}\n";
484 }
485 OS << "\n";
486 OS << "#endif // OPTTABLE_ARG_INIT\n";
487 }
488 } // end namespace llvm
489