Skip to content

Commit 7808380

Browse files
Merge pull request #10852 from charles-zablit/charles-zablit/lldb/add-formatting-swift-plugin
[lldb] add syntax highlighting infrastructure to Swift plugin
2 parents 3549481 + 6909a5f commit 7808380

File tree

7 files changed

+194
-1
lines changed

7 files changed

+194
-1
lines changed

lldb/.clang-format-ignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
2+
source/Plugins/Language/Swift/LanguageSwiftProperties.td

lldb/include/lldb/Core/PluginManager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,14 @@ class PluginManager {
610610
static bool CreateSettingForCPlusPlusLanguagePlugin(
611611
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
612612
llvm::StringRef description, bool is_global_property);
613+
614+
static lldb::OptionValuePropertiesSP
615+
GetSettingForSwiftLanguagePlugin(Debugger &debugger,
616+
llvm::StringRef setting_name);
617+
618+
static bool CreateSettingForSwiftLanguagePlugin(
619+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
620+
llvm::StringRef description, bool is_global_property);
613621
};
614622

615623
} // namespace lldb_private

lldb/source/Core/PluginManager.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,7 @@ static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
17661766
static constexpr llvm::StringLiteral
17671767
kStructuredDataPluginName("structured-data");
17681768
static constexpr llvm::StringLiteral kCPlusPlusLanguagePlugin("cplusplus");
1769+
static constexpr llvm::StringLiteral kSwiftLanguagePlugin("swift");
17691770

17701771
lldb::OptionValuePropertiesSP
17711772
PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
@@ -1937,3 +1938,17 @@ bool PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
19371938
"Settings for CPlusPlus language plug-ins",
19381939
properties_sp, description, is_global_property);
19391940
}
1941+
1942+
lldb::OptionValuePropertiesSP
1943+
PluginManager::GetSettingForSwiftLanguagePlugin(Debugger &debugger,
1944+
llvm::StringRef setting_name) {
1945+
return GetSettingForPlugin(debugger, setting_name, kSwiftLanguagePlugin);
1946+
}
1947+
1948+
bool PluginManager::CreateSettingForSwiftLanguagePlugin(
1949+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1950+
llvm::StringRef description, bool is_global_property) {
1951+
return CreateSettingForPlugin(debugger, kSwiftLanguagePlugin,
1952+
"Settings for Swift language plug-ins",
1953+
properties_sp, description, is_global_property);
1954+
}

lldb/source/Plugins/Language/Swift/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
lldb_tablegen(LanguageSwiftProperties.inc -gen-lldb-property-defs
2+
SOURCE LanguageSwiftProperties.td
3+
TARGET LLDBPluginLanguageSwiftPropertiesGen)
4+
5+
lldb_tablegen(LanguageSwiftPropertiesEnum.inc -gen-lldb-property-enum-defs
6+
SOURCE LanguageSwiftProperties.td
7+
TARGET LLDBPluginLanguageSwiftPropertiesEnumGen)
8+
19
set(LLVM_NO_RTTI 1)
210

311
add_lldb_library(lldbPluginSwiftLanguage PLUGIN
@@ -36,3 +44,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT SWIFT_COMPILER_MSVC_LIKE)
3644
target_compile_options(lldbPluginSwiftLanguage PRIVATE
3745
-Wno-dollar-in-identifier-extension)
3846
endif()
47+
48+
add_dependencies(lldbPluginSwiftLanguage
49+
LLDBPluginLanguageSwiftPropertiesGen
50+
LLDBPluginLanguageSwiftPropertiesEnumGen)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include "../../../../include/lldb/Core/PropertiesBase.td"
2+
3+
let Definition = "language_swift" in {
4+
def FunctionNameFormat: Property<"function-name-format", "FormatEntity">,
5+
Global,
6+
DefaultStringValue<"${function.prefix}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.formatted-arguments}${function.suffix}">,
7+
Desc<"Swift specific frame format string to use when displaying stack frame information for threads.">;
8+
}

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void SwiftLanguage::Initialize() {
6868
static ConstString g_SwiftStringStorageClass("_TtCs15__StringStorage");
6969
static ConstString g_NSArrayClass1("_TtCs22__SwiftDeferredNSArray");
7070
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Swift Language",
71-
CreateInstance);
71+
CreateInstance, &DebuggerInitialize);
7272

7373
lldb_private::formatters::NSString_Additionals::GetAdditionalSummaries()
7474
.emplace(
@@ -1894,6 +1894,144 @@ SwiftLanguage::GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
18941894
return mangled_name;
18951895
}
18961896

1897+
static std::optional<llvm::StringRef>
1898+
GetDemangledBasename(const SymbolContext &sc) {
1899+
return std::nullopt;
1900+
}
1901+
1902+
static std::optional<llvm::StringRef>
1903+
GetDemangledFunctionPrefix(const SymbolContext &sc) {
1904+
return std::nullopt;
1905+
}
1906+
1907+
static std::optional<llvm::StringRef>
1908+
GetDemangledFunctionSuffix(const SymbolContext &sc) {
1909+
return std::nullopt;
1910+
}
1911+
1912+
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
1913+
return false;
1914+
}
1915+
1916+
static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
1917+
assert(sc.function);
1918+
1919+
if (sc.block)
1920+
if (Block *inline_block = sc.block->GetContainingInlinedBlock())
1921+
return inline_block->GetBlockVariableList(true);
1922+
1923+
return sc.function->GetBlock(true).GetBlockVariableList(true);
1924+
}
1925+
1926+
bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
1927+
const ExecutionContext *exe_ctx,
1928+
FormatEntity::Entry::Type type,
1929+
Stream &s) {
1930+
switch (type) {
1931+
case FormatEntity::Entry::Type::FunctionBasename: {
1932+
std::optional<llvm::StringRef> name = GetDemangledBasename(sc);
1933+
if (!name)
1934+
return false;
1935+
1936+
s << *name;
1937+
1938+
return true;
1939+
}
1940+
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
1941+
// This ensures we print the arguments even when no debug-info is available.
1942+
//
1943+
// FIXME: we should have a Entry::Type::FunctionArguments and
1944+
// use it in the plugin.cplusplus.display.function-name-format
1945+
// once we have a "fallback operator" in the frame-format language.
1946+
if (!sc.function && sc.symbol)
1947+
return PrintDemangledArgumentList(s, sc);
1948+
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
1949+
sc.function->GetMangled().GetMangledName().GetStringRef(),
1950+
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
1951+
if (display_name.empty())
1952+
return false;
1953+
1954+
VariableList args;
1955+
if (auto variable_list_sp = GetFunctionVariableList(sc))
1956+
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
1957+
args);
1958+
1959+
s << GetFunctionDisplayArgs(sc, args, exe_ctx);
1960+
return true;
1961+
}
1962+
case FormatEntity::Entry::Type::FunctionPrefix: {
1963+
std::optional<llvm::StringRef> prefix = GetDemangledFunctionPrefix(sc);
1964+
if (!prefix)
1965+
return false;
1966+
1967+
s << *prefix;
1968+
1969+
return true;
1970+
}
1971+
case FormatEntity::Entry::Type::FunctionSuffix: {
1972+
std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
1973+
if (!suffix)
1974+
return false;
1975+
1976+
s << *suffix;
1977+
1978+
return true;
1979+
}
1980+
1981+
case FormatEntity::Entry::Type::FunctionScope:
1982+
case FormatEntity::Entry::Type::FunctionTemplateArguments:
1983+
case FormatEntity::Entry::Type::FunctionReturnRight:
1984+
case FormatEntity::Entry::Type::FunctionReturnLeft:
1985+
case FormatEntity::Entry::Type::FunctionQualifiers:
1986+
default:
1987+
return true;
1988+
}
1989+
}
1990+
1991+
#define LLDB_PROPERTIES_language_swift
1992+
#include "LanguageSwiftProperties.inc"
1993+
1994+
enum {
1995+
#define LLDB_PROPERTIES_language_swift
1996+
#include "LanguageSwiftPropertiesEnum.inc"
1997+
};
1998+
1999+
namespace {
2000+
class PluginProperties : public Properties {
2001+
public:
2002+
static llvm::StringRef GetSettingName() { return "display"; }
2003+
2004+
PluginProperties() {
2005+
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
2006+
m_collection_sp->Initialize(g_language_swift_properties);
2007+
}
2008+
2009+
FormatEntity::Entry GetFunctionNameFormat() const {
2010+
return GetPropertyAtIndexAs<const FormatEntity::Entry>(
2011+
ePropertyFunctionNameFormat, {});
2012+
}
2013+
};
2014+
} // namespace
2015+
2016+
static PluginProperties &GetGlobalPluginProperties() {
2017+
static PluginProperties g_settings;
2018+
return g_settings;
2019+
}
2020+
2021+
FormatEntity::Entry SwiftLanguage::GetFunctionNameFormat() const {
2022+
return GetGlobalPluginProperties().GetFunctionNameFormat();
2023+
}
2024+
2025+
void SwiftLanguage::DebuggerInitialize(Debugger &debugger) {
2026+
if (!PluginManager::GetSettingForSwiftLanguagePlugin(
2027+
debugger, PluginProperties::GetSettingName())) {
2028+
PluginManager::CreateSettingForSwiftLanguagePlugin(
2029+
debugger, GetGlobalPluginProperties().GetValueProperties(),
2030+
"Properties for the Swift language plug-in.",
2031+
/*is_global_property=*/true);
2032+
}
2033+
}
2034+
18972035
namespace {
18982036
using namespace swift::Demangle;
18992037
struct AsyncInfo {

lldb/source/Plugins/Language/Swift/SwiftLanguage.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ class SwiftLanguage : public Language {
130130

131131
llvm::StringRef GetInstanceVariableName() override { return "self"; }
132132

133+
bool HandleFrameFormatVariable(const SymbolContext &sc,
134+
const ExecutionContext *exe_ctx,
135+
FormatEntity::Entry::Type type,
136+
Stream &s) override;
137+
138+
FormatEntity::Entry GetFunctionNameFormat() const override;
139+
133140
/// Override that skips breakpoints inside await resume ("Q") async funclets.
134141
void FilterForLineBreakpoints(
135142
llvm::SmallVectorImpl<SymbolContext> &) const override;
@@ -138,6 +145,9 @@ class SwiftLanguage : public Language {
138145
// PluginInterface protocol
139146
//------------------------------------------------------------------
140147
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
148+
149+
private:
150+
static void DebuggerInitialize(Debugger &);
141151
};
142152

143153
} // namespace lldb_private

0 commit comments

Comments
 (0)