#include "llvm/ADT/Twine.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
+#include <cctype>
+#include <cstring>
#include <map>
using namespace llvm;
+// Ordering on Info. The logic should match with the consumer-side function in
+// llvm/Option/OptTable.h.
static int StrCmpOptionName(const char *A, const char *B) {
- char a = *A, b = *B;
+ const char *X = A, *Y = B;
+ char a = tolower(*A), b = tolower(*B);
while (a == b) {
if (a == '\0')
- return 0;
+ return strcmp(A, B);
- a = *++A;
- b = *++B;
+ a = tolower(*++X);
+ b = tolower(*++Y);
}
if (a == '\0') // A is a prefix of B.
return (a < b) ? -1 : 1;
}
-static int CompareOptionRecords(const void *Av, const void *Bv) {
- const Record *A = *(const Record*const*) Av;
- const Record *B = *(const Record*const*) Bv;
+static int CompareOptionRecords(Record *const *Av, Record *const *Bv) {
+ const Record *A = *Av;
+ const Record *B = *Bv;
// Sentinel options precede all others and are only ordered by precedence.
bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");
if (!ASent)
if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(),
B->getValueAsString("Name").c_str()))
- return Cmp;
+ return Cmp;
if (!ASent) {
std::vector<std::string> APrefixes = A->getValueAsListOfStrings("Prefixes");
if (APrec == BPrec &&
A->getValueAsListOfStrings("Prefixes") ==
B->getValueAsListOfStrings("Prefixes")) {
- PrintError(A->getLoc(), Twine("Option is equivilent to"));
+ PrintError(A->getLoc(), Twine("Option is equivalent to"));
PrintError(B->getLoc(), Twine("Other defined here"));
PrintFatalError("Equivalent Options found.");
}
PE = I->first.end(); PI != PE; ++PI) {
OS << "\"" << *PI << "\" COMMA ";
}
- OS << "0})\n";
+ OS << "nullptr})\n";
}
OS << "#undef COMMA\n";
- OS << "#endif\n\n";
+ OS << "#endif // PREFIX\n\n";
OS << "/////////\n";
OS << "// Groups\n\n";
OS << "OPTION(";
// The option prefix;
- OS << "0";
+ OS << "nullptr";
// The option string.
OS << ", \"" << R.getValueAsString("Name") << '"';
OS << "INVALID";
// The other option arguments (unused for groups).
- OS << ", INVALID, 0, 0";
+ OS << ", INVALID, nullptr, 0, 0";
// The option help text.
if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
OS << " ";
write_cstring(OS, R.getValueAsString("HelpText"));
} else
- OS << ", 0";
+ OS << ", nullptr";
// The option meta-variable name (unused).
- OS << ", 0)\n";
+ OS << ", nullptr)\n";
}
OS << "\n";
// The containing option group (if any).
OS << ", ";
- if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
+ const ListInit *GroupFlags = nullptr;
+ if (const DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group"))) {
+ GroupFlags = DI->getDef()->getValueAsListInit("Flags");
OS << getOptionName(*DI->getDef());
- else
+ } else
OS << "INVALID";
// The option alias (if any).
else
OS << "INVALID";
+ // The option alias arguments (if any).
+ // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
+ // would become "foo\0bar\0". Note that the compiler adds an implicit
+ // terminating \0 at the end.
+ OS << ", ";
+ std::vector<std::string> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
+ if (AliasArgs.size() == 0) {
+ OS << "nullptr";
+ } else {
+ OS << "\"";
+ for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
+ OS << AliasArgs[i] << "\\0";
+ OS << "\"";
+ }
+
// The option flags.
+ OS << ", ";
+ int NumFlags = 0;
const ListInit *LI = R.getValueAsListInit("Flags");
- if (LI->empty()) {
- OS << ", 0";
- } else {
- OS << ", ";
- for (unsigned i = 0, e = LI->size(); i != e; ++i) {
- if (i)
- OS << " | ";
- OS << cast<DefInit>(LI->getElement(i))->getDef()->getName();
- }
+ for (Init *I : *LI)
+ OS << (NumFlags++ ? " | " : "")
+ << cast<DefInit>(I)->getDef()->getName();
+ if (GroupFlags) {
+ for (Init *I : *GroupFlags)
+ OS << (NumFlags++ ? " | " : "")
+ << cast<DefInit>(I)->getDef()->getName();
}
+ if (NumFlags == 0)
+ OS << '0';
// The option parameter field.
OS << ", " << R.getValueAsInt("NumArgs");
OS << " ";
write_cstring(OS, R.getValueAsString("HelpText"));
} else
- OS << ", 0";
+ OS << ", nullptr";
// The option meta-variable name.
OS << ", ";
if (!isa<UnsetInit>(R.getValueInit("MetaVarName")))
write_cstring(OS, R.getValueAsString("MetaVarName"));
else
- OS << "0";
+ OS << "nullptr";
OS << ")\n";
}
- OS << "#endif\n";
+ OS << "#endif // OPTION\n";
}
} // end namespace llvm