OptParserEmitter.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/TableGen/Error.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/Twine.h"
  13. #include "llvm/TableGen/Record.h"
  14. #include "llvm/TableGen/TableGenBackend.h"
  15. #include <cctype>
  16. #include <cstring>
  17. #include <map>
  18. using namespace llvm;
  19. // Ordering on Info. The logic should match with the consumer-side function in
  20. // llvm/Option/OptTable.h.
  21. static int StrCmpOptionName(const char *A, const char *B) {
  22. const char *X = A, *Y = B;
  23. char a = tolower(*A), b = tolower(*B);
  24. while (a == b) {
  25. if (a == '\0')
  26. return strcmp(A, B);
  27. a = tolower(*++X);
  28. b = tolower(*++Y);
  29. }
  30. if (a == '\0') // A is a prefix of B.
  31. return 1;
  32. if (b == '\0') // B is a prefix of A.
  33. return -1;
  34. // Otherwise lexicographic.
  35. return (a < b) ? -1 : 1;
  36. }
  37. // HLSL Change: changed calling convention to __cdecl
  38. static int __cdecl CompareOptionRecords(Record *const *Av, Record *const *Bv) {
  39. const Record *A = *Av;
  40. const Record *B = *Bv;
  41. // Sentinel options precede all others and are only ordered by precedence.
  42. bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
  43. bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel");
  44. if (ASent != BSent)
  45. return ASent ? -1 : 1;
  46. // Compare options by name, unless they are sentinels.
  47. if (!ASent)
  48. if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
  49. B->getValueAsString("Name").c_str()))
  50. return Cmp;
  51. if (!ASent) {
  52. std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes");
  53. std::vector<std::string> BPrefixes = B->getValueAsListOfStrings("Prefixes");
  54. for (std::vector<std::string>::const_iterator APre = APrefixes.begin(),
  55. AEPre = APrefixes.end(),
  56. BPre = BPrefixes.begin(),
  57. BEPre = BPrefixes.end();
  58. APre != AEPre &&
  59. BPre != BEPre;
  60. ++APre, ++BPre) {
  61. if (int Cmp = StrCmpOptionName(APre->c_str(), BPre->c_str()))
  62. return Cmp;
  63. }
  64. }
  65. // Then by the kind precedence;
  66. int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence");
  67. int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence");
  68. if (APrec == BPrec &&
  69. A->getValueAsListOfStrings("Prefixes") ==
  70. B->getValueAsListOfStrings("Prefixes")) {
  71. PrintError(A->getLoc(), Twine("Option is equivalent to"));
  72. PrintError(B->getLoc(), Twine("Other defined here"));
  73. PrintFatalError("Equivalent Options found.");
  74. }
  75. return APrec < BPrec ? -1 : 1;
  76. }
  77. static const std::string getOptionName(const Record &R) {
  78. // Use the record name unless EnumName is defined.
  79. if (isa<UnsetInit>(R.getValueInit("EnumName")))
  80. return R.getName();
  81. return R.getValueAsString("EnumName");
  82. }
  83. static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
  84. OS << '"';
  85. OS.write_escaped(Str);
  86. OS << '"';
  87. return OS;
  88. }
  89. /// OptParserEmitter - This tablegen backend takes an input .td file
  90. /// describing a list of options and emits a data structure for parsing and
  91. /// working with those options when given an input command line.
  92. namespace llvm {
  93. void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
  94. // Get the option groups and options.
  95. const std::vector<Record*> &Groups =
  96. Records.getAllDerivedDefinitions("OptionGroup");
  97. std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");
  98. emitSourceFileHeader("Option Parsing Definitions", OS);
  99. array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);
  100. // Generate prefix groups.
  101. typedef SmallVector<SmallString<2>, 2> PrefixKeyT;
  102. typedef std::map<PrefixKeyT, std::string> PrefixesT;
  103. PrefixesT Prefixes;
  104. Prefixes.insert(std::make_pair(PrefixKeyT(), "prefix_0"));
  105. unsigned CurPrefix = 0;
  106. for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
  107. const Record &R = *Opts[i];
  108. std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
  109. PrefixKeyT prfkey(prf.begin(), prf.end());
  110. unsigned NewPrefix = CurPrefix + 1;
  111. if (Prefixes.insert(std::make_pair(prfkey, (Twine("prefix_") +
  112. Twine(NewPrefix)).str())).second)
  113. CurPrefix = NewPrefix;
  114. }
  115. // Dump prefixes.
  116. OS << "/////////\n";
  117. OS << "// Prefixes\n\n";
  118. OS << "#ifdef PREFIX\n";
  119. OS << "#define COMMA ,\n";
  120. for (PrefixesT::const_iterator I = Prefixes.begin(), E = Prefixes.end();
  121. I != E; ++I) {
  122. OS << "PREFIX(";
  123. // Prefix name.
  124. OS << I->second;
  125. // Prefix values.
  126. OS << ", {";
  127. for (PrefixKeyT::const_iterator PI = I->first.begin(),
  128. PE = I->first.end(); PI != PE; ++PI) {
  129. OS << "\"" << *PI << "\" COMMA ";
  130. }
  131. OS << "0})\n";
  132. }
  133. OS << "#undef COMMA\n";
  134. OS << "#endif\n\n";
  135. OS << "/////////\n";
  136. OS << "// Groups\n\n";
  137. OS << "#ifdef OPTION\n";
  138. for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
  139. const Record &R = *Groups[i];
  140. // Start a single option entry.
  141. OS << "OPTION(";
  142. // The option prefix;
  143. OS << "0";
  144. // The option string.
  145. OS << ", \"" << R.getValueAsString("Name") << '"';
  146. // The option identifier name.
  147. OS << ", "<< getOptionName(R);
  148. // The option kind.
  149. OS << ", Group";
  150. // The containing option group (if any).
  151. OS << ", ";
  152. if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
  153. OS << getOptionName(*DI->getDef());
  154. else
  155. OS << "INVALID";
  156. // The other option arguments (unused for groups).
  157. OS << ", INVALID, 0, 0, 0";
  158. // The option help text.
  159. if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
  160. OS << ",\n";
  161. OS << " ";
  162. write_cstring(OS, R.getValueAsString("HelpText"));
  163. } else
  164. OS << ", 0";
  165. // The option meta-variable name (unused).
  166. OS << ", 0)\n";
  167. }
  168. OS << "\n";
  169. OS << "//////////\n";
  170. OS << "// Options\n\n";
  171. for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
  172. const Record &R = *Opts[i];
  173. // Start a single option entry.
  174. OS << "OPTION(";
  175. // The option prefix;
  176. std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
  177. OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
  178. // The option string.
  179. write_cstring(OS, R.getValueAsString("Name"));
  180. // The option identifier name.
  181. OS << ", "<< getOptionName(R);
  182. // The option kind.
  183. OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
  184. // The containing option group (if any).
  185. OS << ", ";
  186. const ListInit *GroupFlags = nullptr;
  187. if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
  188. GroupFlags = DI->getDef()->getValueAsListInit("Flags");
  189. OS << getOptionName(*DI->getDef());
  190. } else
  191. OS << "INVALID";
  192. // The option alias (if any).
  193. OS << ", ";
  194. if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Alias")))
  195. OS << getOptionName(*DI->getDef());
  196. else
  197. OS << "INVALID";
  198. // The option alias arguments (if any).
  199. // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
  200. // would become "foo\0bar\0". Note that the compiler adds an implicit
  201. // terminating \0 at the end.
  202. OS << ", ";
  203. std::vector<std::string> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
  204. if (AliasArgs.size() == 0) {
  205. OS << "0";
  206. } else {
  207. OS << "\"";
  208. for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
  209. OS << AliasArgs[i] << "\\0";
  210. OS << "\"";
  211. }
  212. // The option flags.
  213. OS << ", ";
  214. int NumFlags = 0;
  215. const ListInit *LI = R.getValueAsListInit("Flags");
  216. for (Init *I : *LI)
  217. OS << (NumFlags++ ? " | " : "")
  218. << cast<DefInit>(I)->getDef()->getName();
  219. if (GroupFlags) {
  220. for (Init *I : *GroupFlags)
  221. OS << (NumFlags++ ? " | " : "")
  222. << cast<DefInit>(I)->getDef()->getName();
  223. }
  224. if (NumFlags == 0)
  225. OS << '0';
  226. // The option parameter field.
  227. OS << ", " << R.getValueAsInt("NumArgs");
  228. // The option help text.
  229. if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
  230. OS << ",\n";
  231. OS << " ";
  232. write_cstring(OS, R.getValueAsString("HelpText"));
  233. } else
  234. OS << ", 0";
  235. // The option meta-variable name.
  236. OS << ", ";
  237. if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
  238. write_cstring(OS, R.getValueAsString("MetaVarName"));
  239. else
  240. OS << "0";
  241. OS << ")\n";
  242. }
  243. OS << "#endif\n";
  244. }
  245. } // end namespace llvm