#include "LLDBTableGenBackends.h"
#include "LLDBTableGenUtils.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringMatcher.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <vector>
using namespace llvm;
using namespace lldb_private;
static void emitPropertyEnum(Record *Property, raw_ostream &OS) {
OS << "eProperty";
OS << Property->getName();
OS << ",\n";
}
static void emitProperty(Record *Property, raw_ostream &OS) {
OS << " {";
OS << "\"" << Property->getValueAsString("Name") << "\"";
OS << ", ";
llvm::StringRef type = Property->getValueAsString("Type");
OS << "OptionValue::eType";
OS << type;
OS << ", ";
OS << (Property->getValue("Global") ? "true" : "false");
OS << ", ";
bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");
bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");
bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");
bool hasElementType = Property->getValue("HasElementType");
assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||
hasDefaultStringValue || hasElementType) &&
"Property must have a default value or an element type");
assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&
"Property cannot have both a unsigned and enum default value.");
assert(!(Property->getValueAsString("Type") == "Boolean" &&
!Property->getValue("HasDefaultBooleanValue")) &&
"Boolean property must have a boolean default value.");
assert(!(Property->getValueAsString("Type") == "String" &&
!hasDefaultStringValue) &&
"String property must have a string default value.");
assert(
!(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&
"Enum property must have a enum default value.");
assert(((type != "Array" && type != "Dictionary") || hasElementType) &&
"Only dictionaries and arrays can have an element type.");
if (hasDefaultUnsignedValue) {
OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));
} else if (hasDefaultEnumValue) {
OS << Property->getValueAsString("DefaultEnumValue");
} else if (hasElementType) {
OS << "OptionValue::eType";
OS << Property->getValueAsString("ElementType");
} else {
OS << "0";
}
OS << ", ";
if (hasDefaultStringValue) {
if (auto D = Property->getValue("DefaultStringValue")) {
OS << "\"";
OS << D->getValue()->getAsUnquotedString();
OS << "\"";
} else {
OS << "\"\"";
}
} else {
OS << "nullptr";
}
OS << ", ";
if (Property->getValue("EnumValues"))
OS << Property->getValueAsString("EnumValues");
else
OS << "{}";
OS << ", ";
if (auto D = Property->getValue("Description")) {
OS << "\"";
OS << D->getValue()->getAsUnquotedString();
OS << "\"";
} else {
OS << "\"\"";
}
OS << "},\n";
}
static void emityProperties(std::string PropertyName,
std::vector<Record *> PropertyRecords,
raw_ostream &OS) {
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
OS << "// Property definitions for " << PropertyName << "\n";
OS << "#ifdef " << NeededMacro << "\n";
OS << "static constexpr PropertyDefinition g_" << PropertyName
<< "_properties[] = {\n";
for (Record *R : PropertyRecords)
emitProperty(R, OS);
OS << "};\n";
OS << "#undef " << NeededMacro << "\n";
OS << "#endif // " << PropertyName << " Property\n\n";
}
static void emitPropertyEnum(std::string PropertyName,
std::vector<Record *> PropertyRecords,
raw_ostream &OS) {
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
OS << "// Property enum cases for " << PropertyName << "\n";
OS << "#ifdef " << NeededMacro << "\n";
for (Record *R : PropertyRecords)
emitPropertyEnum(R, OS);
OS << "#undef " << NeededMacro << "\n";
OS << "#endif // " << PropertyName << " Property\n\n";
}
void lldb_private::EmitPropertyDefs(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Property definitions for LLDB.", OS, Records);
std::vector<Record *> Properties =
Records.getAllDerivedDefinitions("Property");
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
}
}
void lldb_private::EmitPropertyEnumDefs(RecordKeeper &Records,
raw_ostream &OS) {
emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);
std::vector<Record *> Properties =
Records.getAllDerivedDefinitions("Property");
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
}
}