CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
215 lines
7.7 KiB
C++
215 lines
7.7 KiB
C++
//===- LLDBPropertyDefEmitter.cpp -----------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// These tablegen backends emits LLDB's PropertyDefinition values.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "LLDBTableGenBackends.h"
|
|
#include "LLDBTableGenUtils.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/TableGen/Record.h"
|
|
#include "llvm/TableGen/StringMatcher.h"
|
|
#include "llvm/TableGen/TableGenBackend.h"
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
using namespace llvm;
|
|
using namespace lldb_private;
|
|
|
|
static void emitPropertyEnum(const Record *Property, raw_ostream &OS) {
|
|
OS << "eProperty";
|
|
OS << Property->getName();
|
|
OS << ",\n";
|
|
}
|
|
|
|
static void emitProperty(const Record *Property, raw_ostream &OS) {
|
|
OS << " {";
|
|
|
|
// Emit the property name.
|
|
OS << "\"" << Property->getValueAsString("Name") << "\"";
|
|
OS << ", ";
|
|
|
|
// Emit the property type.
|
|
llvm::StringRef type = Property->getValueAsString("Type");
|
|
OS << "OptionValue::eType";
|
|
OS << type;
|
|
OS << ", ";
|
|
|
|
// Emit the property's global value.
|
|
OS << (Property->getValue("Global") ? "true" : "false");
|
|
OS << ", ";
|
|
|
|
bool hasDefaultUnsignedValue = Property->getValue("HasDefaultUnsignedValue");
|
|
bool hasDefaultEnumValue = Property->getValue("HasDefaultEnumValue");
|
|
bool hasDefaultStringValue = Property->getValue("HasDefaultStringValue");
|
|
bool hasElementType = Property->getValue("HasElementType");
|
|
|
|
// Guarantee that every property has a default value.
|
|
assert((hasDefaultUnsignedValue || hasDefaultEnumValue ||
|
|
hasDefaultStringValue || hasElementType) &&
|
|
"Property must have a default value or an element type");
|
|
|
|
// Guarantee that no property has both a default unsigned value and a default
|
|
// enum value, since they're bothed stored in the same field.
|
|
assert(!(hasDefaultUnsignedValue && hasDefaultEnumValue) &&
|
|
"Property cannot have both a unsigned and enum default value.");
|
|
|
|
// Guarantee that every boolean property has a boolean default value.
|
|
assert(!(Property->getValueAsString("Type") == "Boolean" &&
|
|
!Property->getValue("HasDefaultBooleanValue")) &&
|
|
"Boolean property must have a boolean default value.");
|
|
|
|
// Guarantee that every string property has a string default value.
|
|
assert(!(Property->getValueAsString("Type") == "String" &&
|
|
!hasDefaultStringValue) &&
|
|
"String property must have a string default value.");
|
|
|
|
// Guarantee that every enum property has an enum default value.
|
|
assert(
|
|
!(Property->getValueAsString("Type") == "Enum" && !hasDefaultEnumValue) &&
|
|
"Enum property must have a enum default value.");
|
|
|
|
// Guarantee that only arrays and dictionaries have an element type;
|
|
assert(((type != "Array" && type != "Dictionary") || hasElementType) &&
|
|
"Only dictionaries and arrays can have an element type.");
|
|
|
|
// Emit the default uint value.
|
|
if (hasDefaultUnsignedValue) {
|
|
OS << std::to_string(Property->getValueAsInt("DefaultUnsignedValue"));
|
|
} else if (hasDefaultEnumValue) {
|
|
OS << Property->getValueAsString("DefaultEnumValue");
|
|
} else if (hasElementType) {
|
|
OS << "OptionValue::eType";
|
|
OS << Property->getValueAsString("ElementType");
|
|
} else {
|
|
OS << "0";
|
|
}
|
|
OS << ", ";
|
|
|
|
// Emit the default string value.
|
|
if (hasDefaultStringValue) {
|
|
if (auto D = Property->getValue("DefaultStringValue")) {
|
|
OS << "\"";
|
|
OS << D->getValue()->getAsUnquotedString();
|
|
OS << "\"";
|
|
} else {
|
|
OS << "\"\"";
|
|
}
|
|
} else {
|
|
OS << "nullptr";
|
|
}
|
|
OS << ", ";
|
|
|
|
// Emit the enum values value.
|
|
if (Property->getValue("EnumValues"))
|
|
OS << Property->getValueAsString("EnumValues");
|
|
else
|
|
OS << "{}";
|
|
OS << ", ";
|
|
|
|
// Emit the property description.
|
|
if (auto D = Property->getValue("Description")) {
|
|
OS << "\"";
|
|
OS << D->getValue()->getAsUnquotedString();
|
|
OS << "\"";
|
|
} else {
|
|
OS << "\"\"";
|
|
}
|
|
|
|
OS << "},\n";
|
|
}
|
|
|
|
static std::optional<StringRef>
|
|
getPropertyPath(const std::vector<const Record *> &PropertyRecords) {
|
|
std::optional<StringRef> Path;
|
|
for (const Record *R : PropertyRecords) {
|
|
StringRef P = R->getValueAsString("Path");
|
|
if (!Path)
|
|
Path.emplace(P);
|
|
assert(*Path == P &&
|
|
"All records with one definition should have the same path");
|
|
}
|
|
return Path;
|
|
}
|
|
|
|
/// Emits all property initializers to the raw_ostream.
|
|
static void emityProperties(std::string PropertyName,
|
|
const std::vector<const Record *> &PropertyRecords,
|
|
raw_ostream &OS) {
|
|
// Generate the macro that the user needs to define before including the
|
|
// *.inc file.
|
|
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
|
|
llvm::replace(NeededMacro, ' ', '_');
|
|
|
|
std::optional<StringRef> Path = getPropertyPath(PropertyRecords);
|
|
|
|
// All options are in one file, so we need put them behind macros and ask the
|
|
// user to define the macro for the options that are needed.
|
|
OS << "// Property definitions for " << PropertyName << "\n";
|
|
OS << "#ifdef " << NeededMacro << "\n";
|
|
OS << "static constexpr PropertyDefinition g_" << PropertyName
|
|
<< "_properties[] = {\n";
|
|
for (const Record *R : PropertyRecords)
|
|
emitProperty(R, OS);
|
|
OS << "};\n";
|
|
|
|
OS << "static constexpr PropertyCollectionDefinition g_" << PropertyName
|
|
<< "_properties_def = {\n";
|
|
OS << "/*properties=*/g_" << PropertyName << "_properties,\n";
|
|
if (Path)
|
|
OS << "/*expected_path=*/\"" << *Path << "\",\n";
|
|
OS << "};\n";
|
|
|
|
// We undefine the macro for the user like Clang's include files are doing it.
|
|
OS << "#undef " << NeededMacro << "\n";
|
|
OS << "#endif // " << PropertyName << " Property\n\n";
|
|
}
|
|
|
|
/// Emits all property initializers to the raw_ostream.
|
|
static void emitPropertyEnum(std::string PropertyName,
|
|
ArrayRef<const Record *> PropertyRecords,
|
|
raw_ostream &OS) {
|
|
// Generate the macro that the user needs to define before including the
|
|
// *.inc file.
|
|
std::string NeededMacro = "LLDB_PROPERTIES_" + PropertyName;
|
|
llvm::replace(NeededMacro, ' ', '_');
|
|
|
|
// All options are in one file, so we need put them behind macros and ask the
|
|
// user to define the macro for the options that are needed.
|
|
OS << "// Property enum cases for " << PropertyName << "\n";
|
|
OS << "#ifdef " << NeededMacro << "\n";
|
|
for (const Record *R : PropertyRecords)
|
|
emitPropertyEnum(R, OS);
|
|
// We undefine the macro for the user like Clang's include files are doing it.
|
|
OS << "#undef " << NeededMacro << "\n";
|
|
OS << "#endif // " << PropertyName << " Property\n\n";
|
|
}
|
|
|
|
void lldb_private::EmitPropertyDefs(const RecordKeeper &Records,
|
|
raw_ostream &OS) {
|
|
emitSourceFileHeader("Property definitions for LLDB.", OS, Records);
|
|
|
|
ArrayRef<const Record *> Properties =
|
|
Records.getAllDerivedDefinitions("Property");
|
|
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
|
|
emityProperties(PropertyRecordPair.first, PropertyRecordPair.second, OS);
|
|
}
|
|
}
|
|
|
|
void lldb_private::EmitPropertyEnumDefs(const RecordKeeper &Records,
|
|
raw_ostream &OS) {
|
|
emitSourceFileHeader("Property definition enum for LLDB.", OS, Records);
|
|
|
|
ArrayRef<const Record *> Properties =
|
|
Records.getAllDerivedDefinitions("Property");
|
|
for (auto &PropertyRecordPair : getRecordsByName(Properties, "Definition")) {
|
|
emitPropertyEnum(PropertyRecordPair.first, PropertyRecordPair.second, OS);
|
|
}
|
|
}
|