brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 1d4495f Raw
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