Index: lldb/include/lldb/Core/OptionEnumValueElementsBase.td =================================================================== --- /dev/null +++ lldb/include/lldb/Core/OptionEnumValueElementsBase.td @@ -0,0 +1,12 @@ +// Base class for all option enum value elements. +class OptionEnumValueElement { + string StringValue = value; + string Usage = usage; + string Enum; +} + +// Specify a namespace for the enum value. +class Namespace { + bit HasNamespace = 1; + string Namespace = namespace; +} Index: lldb/source/Core/CMakeLists.txt =================================================================== --- lldb/source/Core/CMakeLists.txt +++ lldb/source/Core/CMakeLists.txt @@ -6,6 +6,10 @@ SOURCE CoreProperties.td TARGET LLDBCorePropertiesEnumGen) +lldb_tablegen(CoreOptionEnumValueElements.inc -gen-lldb-option-enum-value-elements + SOURCE CoreOptionEnumValueElements.td + TARGET LLDBCoreOptionEnumValueElements) + set(LLDB_CURSES_LIBS) set(LLDB_LIBEDIT_LIBS) @@ -86,7 +90,8 @@ add_dependencies(lldbCore LLDBCorePropertiesGen - LLDBCorePropertiesEnumGen) + LLDBCorePropertiesEnumGen + LLDBCoreOptionEnumValueElements) # Needed to properly resolve references in a debug build. # TODO: Remove once we have better layering Index: lldb/source/Core/CoreOptionEnumValueElements.td =================================================================== --- /dev/null +++ lldb/source/Core/CoreOptionEnumValueElements.td @@ -0,0 +1,21 @@ +include "../../include/lldb/Core/OptionEnumValueElementsBase.td" + +let Enum = "language_enumerators" in { + def ScriptLanguageNone: OptionEnumValueElement<"none", "Disable scripting languages.">; + def ScriptLanguagePython: OptionEnumValueElement<"python", "Select python as the default scripting language.">; + def ScriptLanguageDefault: OptionEnumValueElement<"default", "Select the lldb default as the default scripting language.">; +} + +let Enum = "stop_show_column_values" in { + def StopShowColumnAnsiOrCaret: OptionEnumValueElement<"ansi-or-caret", "Highlight the stop column with ANSI terminal codes when color/ANSI mode is enabled; otherwise, fall back to using a text-only caret (^) as if \\\"caret-only\\\" mode was selected.">; + def StopShowColumnAnsi: OptionEnumValueElement<"ansi", "Highlight the stop column with ANSI terminal codes when running LLDB with color/ANSI enabled.">; + def StopShowColumnCaret: OptionEnumValueElement<"caret", "Highlight the stop column with a caret character (^) underneath the stop column. This method introduces a new line in source listings that display thread stop locations.">; + def StopShowColumnNone: OptionEnumValueElement<"none", "Do not highlight the stop column.">; +} + +let Enum = "show_disassembly_enum_values" in { + def StopDisassemblyTypeNever: OptionEnumValueElement<"never", "Never show disassembly when displaying a stop context.">, Namespace<"Debugger">; + def StopDisassemblyTypeNoDebugInfo: OptionEnumValueElement<"no-debuginfo", "Show disassembly when there is no debug information.">, Namespace<"Debugger">; + def StopDisassemblyTypeNoSource: OptionEnumValueElement<"no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context.">, Namespace<"Debugger">; + def StopDisassemblyTypeAlways: OptionEnumValueElement<"always", "Always show disassembly when displaying a stop context.">, Namespace<"Debugger">; +} Index: lldb/source/Core/CoreProperties.td =================================================================== --- lldb/source/Core/CoreProperties.td +++ lldb/source/Core/CoreProperties.td @@ -61,7 +61,7 @@ Desc<"If true, LLDB will highlight the displayed source code.">; def StopShowColumn: Property<"stop-show-column", "Enum">, DefaultEnumValue<"eStopShowColumnAnsiOrCaret">, - EnumValues<"OptionEnumValues(s_stop_show_column_values)">, + EnumValues<"OptionEnumValues(g_stop_show_column_values)">, Desc<"If true, LLDB will use the column information from the debug info to mark the current position when displaying a stopped context.">; def StopShowColumnAnsiPrefix: Property<"stop-show-column-ansi-prefix", "String">, Global, Index: lldb/source/Core/Debugger.cpp =================================================================== --- lldb/source/Core/Debugger.cpp +++ lldb/source/Core/Debugger.cpp @@ -92,23 +92,14 @@ static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain -static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = { - {Debugger::eStopDisassemblyTypeNever, "never", - "Never show disassembly when displaying a stop context."}, - {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", - "Show disassembly when there is no debug information."}, - {Debugger::eStopDisassemblyTypeNoSource, "no-source", - "Show disassembly when there is no source information, or the source file " - "is missing when displaying a stop context."}, - {Debugger::eStopDisassemblyTypeAlways, "always", - "Always show disassembly when displaying a stop context."} }; - -static constexpr OptionEnumValueElement g_language_enumerators[] = { - {eScriptLanguageNone, "none", "Disable scripting languages."}, - {eScriptLanguagePython, "python", - "Select python as the default scripting language."}, - {eScriptLanguageDefault, "default", - "Select the lldb default as the default scripting language."} }; +#define LLDB_OPTION_ENUM_VALUE_ELEMENTS_language_enumerators +#include "CoreOptionEnumValueElements.inc" + +#define LLDB_OPTION_ENUM_VALUE_ELEMENTS_show_disassembly_enum_values +#include "CoreOptionEnumValueElements.inc" + +#define LLDB_OPTION_ENUM_VALUE_ELEMENTS_stop_show_column_values +#include "CoreOptionEnumValueElements.inc" #define MODULE_WITH_FUNC \ "{ " \ @@ -188,19 +179,6 @@ // args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name- // without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: -static constexpr OptionEnumValueElement s_stop_show_column_values[] = { - {eStopShowColumnAnsiOrCaret, "ansi-or-caret", - "Highlight the stop column with ANSI terminal codes when color/ANSI mode " - "is enabled; otherwise, fall back to using a text-only caret (^) as if " - "\"caret-only\" mode was selected."}, - {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI " - "terminal codes when running LLDB with " - "color/ANSI enabled."}, - {eStopShowColumnCaret, "caret", - "Highlight the stop column with a caret character (^) underneath the stop " - "column. This method introduces a new line in source listings that " - "display thread stop locations."}, - {eStopShowColumnNone, "none", "Do not highlight the stop column."}}; #define LLDB_PROPERTIES_debugger #include "CoreProperties.inc" Index: lldb/utils/TableGen/CMakeLists.txt =================================================================== --- lldb/utils/TableGen/CMakeLists.txt +++ lldb/utils/TableGen/CMakeLists.txt @@ -8,6 +8,7 @@ add_tablegen(lldb-tblgen LLDB LLDBOptionDefEmitter.cpp + LLDBOptionEnumValueElementsEmitter.cpp LLDBPropertyDefEmitter.cpp LLDBTableGen.cpp ) Index: lldb/utils/TableGen/LLDBOptionEnumValueElementsEmitter.cpp =================================================================== --- /dev/null +++ lldb/utils/TableGen/LLDBOptionEnumValueElementsEmitter.cpp @@ -0,0 +1,96 @@ +//===- LLDBOptionEnumValueElementsEmitter.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 option enum value elements. +// +//===----------------------------------------------------------------------===// + +#include "LLDBTableGenBackends.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include +#include + +using namespace llvm; +using namespace lldb_private; + +/// Groups all Enums by their name. +static RecordsByName getEnumList(std::vector Enums) { + RecordsByName result; + for (Record *Enum : Enums) + result[Enum->getValueAsString("Enum").str()].push_back(Enum); + return result; +} + +static void emitOptionEnumValueElement(Record *R, raw_ostream &OS) { + OS << " {"; + + // Emit the enum value. + if (R->getValue("HasNamespace")) + OS << R->getValueAsString("Namespace") << "::"; + OS << "e"; + OS << R->getName(); + OS << ", "; + + // Emit the string value. + if (auto V = R->getValue("StringValue")) { + OS << "\""; + OS << V->getValue()->getAsUnquotedString(); + OS << "\""; + } else { + OS << "\"\""; + } + OS << ", "; + + // Emit the usage string. + if (auto V = R->getValue("Usage")) { + OS << "\""; + OS << V->getValue()->getAsUnquotedString(); + OS << "\""; + } else { + OS << "\"\""; + } + + OS << "},\n"; +} + +/// Emits all option enum value elements to the raw_ostream. +static void emitOptionEnumValueElements(std::string EnumName, + std::vector EnumRecords, + raw_ostream &OS) { + // Generate the macro that the user needs to define before including the + // *.inc file. + std::string NeededMacro = "LLDB_OPTION_ENUM_VALUE_ELEMENTS_" + EnumName; + std::replace(NeededMacro.begin(), NeededMacro.end(), ' ', '_'); + + // One file can contain more than one enum, so we need put them behind macros + // and ask the user to define the macro for the enums that are needed. + OS << "// Option enum value elements for " << EnumName << "\n"; + OS << "#ifdef " << NeededMacro << "\n"; + OS << "static constexpr OptionEnumValueElement g_" << EnumName << "[] = {\n"; + for (Record *R : EnumRecords) + emitOptionEnumValueElement(R, OS); + OS << "};\n"; + // We undefine the macro for the user like Clang's include files are doing it. + OS << "#undef " << NeededMacro << "\n"; + OS << "#endif // " << EnumName << " Enum\n\n"; +} + +void lldb_private::EmitOptionEnumValueElements(RecordKeeper &Records, + raw_ostream &OS) { + emitSourceFileHeader("Option enum value elements for LLDB.", OS); + + std::vector Enums = + Records.getAllDerivedDefinitions("OptionEnumValueElement"); + for (auto &EnumRecordPair : getEnumList(Enums)) { + emitOptionEnumValueElements(EnumRecordPair.first, EnumRecordPair.second, + OS); + } +} Index: lldb/utils/TableGen/LLDBTableGen.cpp =================================================================== --- lldb/utils/TableGen/LLDBTableGen.cpp +++ lldb/utils/TableGen/LLDBTableGen.cpp @@ -27,6 +27,7 @@ GenOptionDefs, GenPropertyDefs, GenPropertyEnumDefs, + GenOptionEnumValueElements, }; static cl::opt Action( @@ -40,6 +41,9 @@ clEnumValN(GenPropertyDefs, "gen-lldb-property-defs", "Generate lldb property definitions"), clEnumValN(GenPropertyEnumDefs, "gen-lldb-property-enum-defs", + "Generate lldb property enum definitions"), + clEnumValN(GenOptionEnumValueElements, + "gen-lldb-option-enum-value-elements", "Generate lldb property enum definitions"))); static bool LLDBTableGenMain(raw_ostream &OS, RecordKeeper &Records) { @@ -59,6 +63,9 @@ case GenPropertyEnumDefs: EmitPropertyEnumDefs(Records, OS); break; + case GenOptionEnumValueElements: + EmitOptionEnumValueElements(Records, OS); + break; } return false; } Index: lldb/utils/TableGen/LLDBTableGenBackends.h =================================================================== --- lldb/utils/TableGen/LLDBTableGenBackends.h +++ lldb/utils/TableGen/LLDBTableGenBackends.h @@ -37,6 +37,7 @@ void EmitOptionDefs(RecordKeeper &RK, raw_ostream &OS); void EmitPropertyDefs(RecordKeeper &RK, raw_ostream &OS); void EmitPropertyEnumDefs(RecordKeeper &RK, raw_ostream &OS); +void EmitOptionEnumValueElements(RecordKeeper &RK, raw_ostream &OS); } // namespace lldb_private