191 lines · cpp
1//===- LLDBPropertyDefEmitter.cpp -----------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// These tablegen backends emits LLDB's PropertyDefinition values.10//11//===----------------------------------------------------------------------===//12 13#include "LLDBTableGenBackends.h"14#include "LLDBTableGenUtils.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/TableGen/Record.h"17#include "llvm/TableGen/StringMatcher.h"18#include "llvm/TableGen/TableGenBackend.h"19#include <vector>20 21using namespace llvm;22using namespace lldb_private;23 24static void emitPropertyEnum(const Record *Property, raw_ostream &OS) {25 OS << "eProperty";26 OS << Property->getName();27 OS << ",\n";28}29 30static void emitProperty(const Record *Property, raw_ostream &OS) {31 OS << " {";32 33 // Emit the property name.34 OS << "\"" << Property->getValueAsString("Name") << "\"";35 OS << ", ";36 37 // Emit the property type.38 llvm::StringRef type = Property->getValueAsString("Type");39 OS << "OptionValue::eType";40 OS << type;41 OS << ", ";42 43 // Emit the property's global value.44 OS << (Property->getValue("Global") ? "true" : "false");45 OS << ", ";46 47 bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");48 bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");49 bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");50 bool hasElementType = Property->getValue("HasElementType");51 52 // Guarantee that every property has a default value.53 assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||54 hasDefaultStringValue || hasElementType) &&55 "Property must have a default value or an element type");56 57 // Guarantee that no property has both a default unsigned value and a default58 // enum value, since they're bothed stored in the same field.59 assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&60 "Property cannot have both a unsigned and enum default value.");61 62 // Guarantee that every boolean property has a boolean default value.63 assert(!(Property->getValueAsString("Type") == "Boolean" &&64 !Property->getValue("HasDefaultBooleanValue")) &&65 "Boolean property must have a boolean default value.");66 67 // Guarantee that every string property has a string default value.68 assert(!(Property->getValueAsString("Type") == "String" &&69 !hasDefaultStringValue) &&70 "String property must have a string default value.");71 72 // Guarantee that every enum property has an enum default value.73 assert(74 !(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&75 "Enum property must have a enum default value.");76 77 // Guarantee that only arrays and dictionaries have an element type;78 assert(((type != "Array" && type != "Dictionary") || hasElementType) &&79 "Only dictionaries and arrays can have an element type.");80 81 // Emit the default uint value.82 if (hasDefaultUnsignedValue) {83 OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));84 } else if (hasDefaultEnumValue) {85 OS << Property->getValueAsString("DefaultEnumValue");86 } else if (hasElementType) {87 OS << "OptionValue::eType";88 OS << Property->getValueAsString("ElementType");89 } else {90 OS << "0";91 }92 OS << ", ";93 94 // Emit the default string value.95 if (hasDefaultStringValue) {96 if (auto D = Property->getValue("DefaultStringValue")) {97 OS << "\"";98 OS << D->getValue()->getAsUnquotedString();99 OS << "\"";100 } else {101 OS << "\"\"";102 }103 } else {104 OS << "nullptr";105 }106 OS << ", ";107 108 // Emit the enum values value.109 if (Property->getValue("EnumValues"))110 OS << Property->getValueAsString("EnumValues");111 else112 OS << "{}";113 OS << ", ";114 115 // Emit the property description.116 if (auto D = Property->getValue("Description")) {117 OS << "\"";118 OS << D->getValue()->getAsUnquotedString();119 OS << "\"";120 } else {121 OS << "\"\"";122 }123 124 OS << "},\n";125}126 127/// Emits all property initializers to the raw_ostream.128static void emityProperties(std::string PropertyName,129 const std::vector<const Record *> &PropertyRecords,130 raw_ostream &OS) {131 // Generate the macro that the user needs to define before including the132 // *.inc file.133 std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;134 llvm::replace(NeededMacro, ' ', '_');135 136 // All options are in one file, so we need put them behind macros and ask the137 // user to define the macro for the options that are needed.138 OS << "// Property definitions for " << PropertyName << "\n";139 OS << "#ifdef " << NeededMacro << "\n";140 OS << "static constexpr PropertyDefinition g_" << PropertyName141 << "_properties[] = {\n";142 for (const Record *R : PropertyRecords)143 emitProperty(R, OS);144 OS << "};\n";145 // We undefine the macro for the user like Clang's include files are doing it.146 OS << "#undef " << NeededMacro << "\n";147 OS << "#endif // " << PropertyName << " Property\n\n";148}149 150/// Emits all property initializers to the raw_ostream.151static void emitPropertyEnum(std::string PropertyName,152 ArrayRef<const Record *> PropertyRecords,153 raw_ostream &OS) {154 // Generate the macro that the user needs to define before including the155 // *.inc file.156 std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;157 llvm::replace(NeededMacro, ' ', '_');158 159 // All options are in one file, so we need put them behind macros and ask the160 // user to define the macro for the options that are needed.161 OS << "// Property enum cases for " << PropertyName << "\n";162 OS << "#ifdef " << NeededMacro << "\n";163 for (const Record *R : PropertyRecords)164 emitPropertyEnum(R, OS);165 // We undefine the macro for the user like Clang's include files are doing it.166 OS << "#undef " << NeededMacro << "\n";167 OS << "#endif // " << PropertyName << " Property\n\n";168}169 170void lldb_private::EmitPropertyDefs(const RecordKeeper &Records,171 raw_ostream &OS) {172 emitSourceFileHeader("Property definitions for LLDB.", OS, Records);173 174 ArrayRef<const Record *> Properties =175 Records.getAllDerivedDefinitions("Property");176 for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {177 emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);178 }179}180 181void lldb_private::EmitPropertyEnumDefs(const RecordKeeper &Records,182 raw_ostream &OS) {183 emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);184 185 ArrayRef<const Record *> Properties =186 Records.getAllDerivedDefinitions("Property");187 for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {188 emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);189 }190}191