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