Path: blob/main/contrib/llvm-project/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp
39563 views
//===- LLDBPropertyDefEmitter.cpp -----------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// These tablegen backends emits LLDB's PropertyDefinition values.9//10//===----------------------------------------------------------------------===//1112#include "LLDBTableGenBackends.h"13#include "LLDBTableGenUtils.h"14#include "llvm/ADT/StringExtras.h"15#include "llvm/TableGen/Record.h"16#include "llvm/TableGen/StringMatcher.h"17#include "llvm/TableGen/TableGenBackend.h"18#include <vector>1920using namespace llvm;21using namespace lldb_private;2223static void emitPropertyEnum(Record *Property, raw_ostream &OS) {24OS << "eProperty";25OS << Property->getName();26OS << ",\n";27}2829static void emitProperty(Record *Property, raw_ostream &OS) {30OS << " {";3132// Emit the property name.33OS << "\"" << Property->getValueAsString("Name") << "\"";34OS << ", ";3536// Emit the property type.37llvm::StringRef type = Property->getValueAsString("Type");38OS << "OptionValue::eType";39OS << type;40OS << ", ";4142// Emit the property's global value.43OS << (Property->getValue("Global") ? "true" : "false");44OS << ", ";4546bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");47bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");48bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");49bool hasElementType = Property->getValue("HasElementType");5051// Guarantee that every property has a default value.52assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||53hasDefaultStringValue || hasElementType) &&54"Property must have a default value or an element type");5556// Guarantee that no property has both a default unsigned value and a default57// enum value, since they're bothed stored in the same field.58assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&59"Property cannot have both a unsigned and enum default value.");6061// Guarantee that every boolean property has a boolean default value.62assert(!(Property->getValueAsString("Type") == "Boolean" &&63!Property->getValue("HasDefaultBooleanValue")) &&64"Boolean property must have a boolean default value.");6566// Guarantee that every string property has a string default value.67assert(!(Property->getValueAsString("Type") == "String" &&68!hasDefaultStringValue) &&69"String property must have a string default value.");7071// Guarantee that every enum property has an enum default value.72assert(73!(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&74"Enum property must have a enum default value.");7576// Guarantee that only arrays and dictionaries have an element type;77assert(((type != "Array" && type != "Dictionary") || hasElementType) &&78"Only dictionaries and arrays can have an element type.");7980// Emit the default uint value.81if (hasDefaultUnsignedValue) {82OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));83} else if (hasDefaultEnumValue) {84OS << Property->getValueAsString("DefaultEnumValue");85} else if (hasElementType) {86OS << "OptionValue::eType";87OS << Property->getValueAsString("ElementType");88} else {89OS << "0";90}91OS << ", ";9293// Emit the default string value.94if (hasDefaultStringValue) {95if (auto D = Property->getValue("DefaultStringValue")) {96OS << "\"";97OS << D->getValue()->getAsUnquotedString();98OS << "\"";99} else {100OS << "\"\"";101}102} else {103OS << "nullptr";104}105OS << ", ";106107// Emit the enum values value.108if (Property->getValue("EnumValues"))109OS << Property->getValueAsString("EnumValues");110else111OS << "{}";112OS << ", ";113114// Emit the property description.115if (auto D = Property->getValue("Description")) {116OS << "\"";117OS << D->getValue()->getAsUnquotedString();118OS << "\"";119} else {120OS << "\"\"";121}122123OS << "},\n";124}125126/// Emits all property initializers to the raw_ostream.127static void emityProperties(std::string PropertyName,128std::vector<Record *> PropertyRecords,129raw_ostream &OS) {130// Generate the macro that the user needs to define before including the131// *.inc file.132std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;133std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');134135// All options are in one file, so we need put them behind macros and ask the136// user to define the macro for the options that are needed.137OS << "// Property definitions for " << PropertyName << "\n";138OS << "#ifdef " << NeededMacro << "\n";139OS << "static constexpr PropertyDefinition g_" << PropertyName140<< "_properties[] = {\n";141for (Record *R : PropertyRecords)142emitProperty(R, OS);143OS << "};\n";144// We undefine the macro for the user like Clang's include files are doing it.145OS << "#undef " << NeededMacro << "\n";146OS << "#endif // " << PropertyName << " Property\n\n";147}148149/// Emits all property initializers to the raw_ostream.150static void emitPropertyEnum(std::string PropertyName,151std::vector<Record *> PropertyRecords,152raw_ostream &OS) {153// Generate the macro that the user needs to define before including the154// *.inc file.155std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;156std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');157158// All options are in one file, so we need put them behind macros and ask the159// user to define the macro for the options that are needed.160OS << "// Property enum cases for " << PropertyName << "\n";161OS << "#ifdef " << NeededMacro << "\n";162for (Record *R : PropertyRecords)163emitPropertyEnum(R, OS);164// We undefine the macro for the user like Clang's include files are doing it.165OS << "#undef " << NeededMacro << "\n";166OS << "#endif // " << PropertyName << " Property\n\n";167}168169void lldb_private::EmitPropertyDefs(RecordKeeper &Records, raw_ostream &OS) {170emitSourceFileHeader("Property definitions for LLDB.", OS, Records);171172std::vector<Record *> Properties =173Records.getAllDerivedDefinitions("Property");174for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {175emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);176}177}178179void lldb_private::EmitPropertyEnumDefs(RecordKeeper &Records,180raw_ostream &OS) {181emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);182183std::vector<Record *> Properties =184Records.getAllDerivedDefinitions("Property");185for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {186emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);187}188}189190191