LLDBPropertyDefEmitter.cpp revision 360784
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-exception
6//
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(Record *Property, raw_ostream &OS) {
25  OS << "eProperty";
26  OS << Property->getName();
27  OS << ",\n";
28}
29
30static void emitProperty(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  OS << "OptionValue::eType";
39  OS << Property->getValueAsString("Type");
40  OS << ", ";
41
42  // Emit the property's global value.
43  OS << (Property->getValue("Global") ? "true" : "false");
44  OS << ", ";
45
46  bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");
47  bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");
48  bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");
49
50  // Guarantee that every property has a default value.
51  assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||
52          hasDefaultStringValue) &&
53         "Property must have a default value");
54
55  // Guarantee that no property has both a default unsigned value and a default
56  // enum value, since they're bothed stored in the same field.
57  assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&
58         "Property cannot have both a unsigned and enum default value.");
59
60  // Guarantee that every boolean property has a boolean default value.
61  assert(!(Property->getValueAsString("Type") == "Boolean" &&
62           !Property->getValue("HasDefaultBooleanValue")) &&
63         "Boolean property must have a boolean default value.");
64
65  // Guarantee that every string property has a string default value.
66  assert(!(Property->getValueAsString("Type") == "String" &&
67           !hasDefaultStringValue) &&
68         "String property must have a string default value.");
69
70  // Guarantee that every enum property has an enum default value.
71  assert(
72      !(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&
73      "Enum property must have a enum default value.");
74
75  // Emit the default uint value.
76  if (hasDefaultUnsignedValue) {
77    OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));
78  } else if (hasDefaultEnumValue) {
79    OS << Property->getValueAsString("DefaultEnumValue");
80  } else {
81    OS << "0";
82  }
83  OS << ", ";
84
85  // Emit the default string value.
86  if (hasDefaultStringValue) {
87    if (auto D = Property->getValue("DefaultStringValue")) {
88      OS << "\"";
89      OS << D->getValue()->getAsUnquotedString();
90      OS << "\"";
91    } else {
92      OS << "\"\"";
93    }
94  } else {
95    OS << "nullptr";
96  }
97  OS << ", ";
98
99  // Emit the enum values value.
100  if (Property->getValue("EnumValues"))
101    OS << Property->getValueAsString("EnumValues");
102  else
103    OS << "{}";
104  OS << ", ";
105
106  // Emit the property description.
107  if (auto D = Property->getValue("Description")) {
108    OS << "\"";
109    OS << D->getValue()->getAsUnquotedString();
110    OS << "\"";
111  } else {
112    OS << "\"\"";
113  }
114
115  OS << "},\n";
116}
117
118/// Emits all property initializers to the raw_ostream.
119static void emityProperties(std::string PropertyName,
120                            std::vector<Record *> PropertyRecords,
121                            raw_ostream &OS) {
122  // Generate the macro that the user needs to define before including the
123  // *.inc file.
124  std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
125  std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
126
127  // All options are in one file, so we need put them behind macros and ask the
128  // user to define the macro for the options that are needed.
129  OS << "// Property definitions for " << PropertyName << "\n";
130  OS << "#ifdef " << NeededMacro << "\n";
131  OS << "static constexpr PropertyDefinition g_" << PropertyName
132     << "_properties[] = {\n";
133  for (Record *R : PropertyRecords)
134    emitProperty(R, OS);
135  OS << "};\n";
136  // We undefine the macro for the user like Clang's include files are doing it.
137  OS << "#undef " << NeededMacro << "\n";
138  OS << "#endif // " << PropertyName << " Property\n\n";
139}
140
141/// Emits all property initializers to the raw_ostream.
142static void emitPropertyEnum(std::string PropertyName,
143                             std::vector<Record *> PropertyRecords,
144                             raw_ostream &OS) {
145  // Generate the macro that the user needs to define before including the
146  // *.inc file.
147  std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
148  std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
149
150  // All options are in one file, so we need put them behind macros and ask the
151  // user to define the macro for the options that are needed.
152  OS << "// Property enum cases for " << PropertyName << "\n";
153  OS << "#ifdef " << NeededMacro << "\n";
154  for (Record *R : PropertyRecords)
155    emitPropertyEnum(R, OS);
156  // We undefine the macro for the user like Clang's include files are doing it.
157  OS << "#undef " << NeededMacro << "\n";
158  OS << "#endif // " << PropertyName << " Property\n\n";
159}
160
161void lldb_private::EmitPropertyDefs(RecordKeeper &Records, raw_ostream &OS) {
162  emitSourceFileHeader("Property definitions for LLDB.", OS);
163
164  std::vector<Record *> Properties =
165      Records.getAllDerivedDefinitions("Property");
166  for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
167    emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
168  }
169}
170
171void lldb_private::EmitPropertyEnumDefs(RecordKeeper &Records,
172                                        raw_ostream &OS) {
173  emitSourceFileHeader("Property definition enum for LLDB.", OS);
174
175  std::vector<Record *> Properties =
176      Records.getAllDerivedDefinitions("Property");
177  for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
178    emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
179  }
180}
181