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