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