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