Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/utils/TableGen/LLDBPropertyDefEmitter.cpp
39563 views
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
21
using namespace llvm;
22
using namespace lldb_private;
23
24
static void emitPropertyEnum(Record *Property, raw_ostream &OS) {
25
OS << "eProperty";
26
OS << Property->getName();
27
OS << ",\n";
28
}
29
30
static 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
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 default
58
// 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
else
112
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.
128
static void emityProperties(std::string PropertyName,
129
std::vector<Record *> PropertyRecords,
130
raw_ostream &OS) {
131
// Generate the macro that the user needs to define before including the
132
// *.inc file.
133
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
134
std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
135
136
// All options are in one file, so we need put them behind macros and ask the
137
// 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_" << PropertyName
141
<< "_properties[] = {\n";
142
for (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.
151
static void emitPropertyEnum(std::string PropertyName,
152
std::vector<Record *> PropertyRecords,
153
raw_ostream &OS) {
154
// Generate the macro that the user needs to define before including the
155
// *.inc file.
156
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
157
std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_');
158
159
// All options are in one file, so we need put them behind macros and ask the
160
// 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 (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
170
void lldb_private::EmitPropertyDefs(RecordKeeper &Records, raw_ostream &OS) {
171
emitSourceFileHeader("Property definitions for LLDB.", OS, Records);
172
173
std::vector<Record *> Properties =
174
Records.getAllDerivedDefinitions("Property");
175
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
176
emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
177
}
178
}
179
180
void lldb_private::EmitPropertyEnumDefs(RecordKeeper &Records,
181
raw_ostream &OS) {
182
emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);
183
184
std::vector<Record *> Properties =
185
Records.getAllDerivedDefinitions("Property");
186
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
187
emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
188
}
189
}
190
191