OptParserEmitter.cpp 15 KB

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