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