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