Skip to content

[lldb] add syntax highlighting infrastructure to Swift plugin #10852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: swift/release/6.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lldb/.clang-format-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source/Plugins/Language/CPlusPlus/LanguageCPlusPlusProperties.td
source/Plugins/Language/Swift/LanguageSwiftProperties.td
8 changes: 8 additions & 0 deletions lldb/include/lldb/Core/PluginManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,14 @@ class PluginManager {
static bool CreateSettingForCPlusPlusLanguagePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
llvm::StringRef description, bool is_global_property);

static lldb::OptionValuePropertiesSP
GetSettingForSwiftLanguagePlugin(Debugger &debugger,
llvm::StringRef setting_name);

static bool CreateSettingForSwiftLanguagePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
llvm::StringRef description, bool is_global_property);
};

} // namespace lldb_private
Expand Down
15 changes: 15 additions & 0 deletions lldb/source/Core/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1766,6 +1766,7 @@ static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
static constexpr llvm::StringLiteral
kStructuredDataPluginName("structured-data");
static constexpr llvm::StringLiteral kCPlusPlusLanguagePlugin("cplusplus");
static constexpr llvm::StringLiteral kSwiftLanguagePlugin("swift");

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
Expand Down Expand Up @@ -1937,3 +1938,17 @@ bool PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
"Settings for CPlusPlus language plug-ins",
properties_sp, description, is_global_property);
}

lldb::OptionValuePropertiesSP
PluginManager::GetSettingForSwiftLanguagePlugin(Debugger &debugger,
llvm::StringRef setting_name) {
return GetSettingForPlugin(debugger, setting_name, kSwiftLanguagePlugin);
}

bool PluginManager::CreateSettingForSwiftLanguagePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
llvm::StringRef description, bool is_global_property) {
return CreateSettingForPlugin(debugger, kSwiftLanguagePlugin,
"Settings for Swift language plug-ins",
properties_sp, description, is_global_property);
}
12 changes: 12 additions & 0 deletions lldb/source/Plugins/Language/Swift/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
lldb_tablegen(LanguageSwiftProperties.inc -gen-lldb-property-defs
SOURCE LanguageSwiftProperties.td
TARGET LLDBPluginLanguageSwiftPropertiesGen)

lldb_tablegen(LanguageSwiftPropertiesEnum.inc -gen-lldb-property-enum-defs
SOURCE LanguageSwiftProperties.td
TARGET LLDBPluginLanguageSwiftPropertiesEnumGen)

set(LLVM_NO_RTTI 1)

add_lldb_library(lldbPluginSwiftLanguage PLUGIN
Expand Down Expand Up @@ -36,3 +44,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT SWIFT_COMPILER_MSVC_LIKE)
target_compile_options(lldbPluginSwiftLanguage PRIVATE
-Wno-dollar-in-identifier-extension)
endif()

add_dependencies(lldbPluginSwiftLanguage
LLDBPluginLanguageSwiftPropertiesGen
LLDBPluginLanguageSwiftPropertiesEnumGen)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include "../../../../include/lldb/Core/PropertiesBase.td"

let Definition = "language_swift" in {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I think keeping it consistent with all the other plugin setting names seems like the right thing to do

def FunctionNameFormat: Property<"function-name-format", "FormatEntity">,
Global,
DefaultStringValue<"${function.prefix}${ansi.fg.yellow}${function.basename}${ansi.normal}${function.formatted-arguments}${function.suffix}">,
Desc<"Swift specific frame format string to use when displaying stack frame information for threads.">;
}
140 changes: 139 additions & 1 deletion lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void SwiftLanguage::Initialize() {
static ConstString g_SwiftStringStorageClass("_TtCs15__StringStorage");
static ConstString g_NSArrayClass1("_TtCs22__SwiftDeferredNSArray");
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Swift Language",
CreateInstance);
CreateInstance, &DebuggerInitialize);

lldb_private::formatters::NSString_Additionals::GetAdditionalSummaries()
.emplace(
Expand Down Expand Up @@ -1894,6 +1894,144 @@ SwiftLanguage::GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
return mangled_name;
}

static std::optional<llvm::StringRef>
GetDemangledBasename(const SymbolContext &sc) {
return std::nullopt;
}

static std::optional<llvm::StringRef>
GetDemangledFunctionPrefix(const SymbolContext &sc) {
return std::nullopt;
}

static std::optional<llvm::StringRef>
GetDemangledFunctionSuffix(const SymbolContext &sc) {
return std::nullopt;
}

static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
return false;
}

static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
assert(sc.function);

if (sc.block)
if (Block *inline_block = sc.block->GetContainingInlinedBlock())
return inline_block->GetBlockVariableList(true);

return sc.function->GetBlock(true).GetBlockVariableList(true);
}

bool SwiftLanguage::HandleFrameFormatVariable(const SymbolContext &sc,
const ExecutionContext *exe_ctx,
FormatEntity::Entry::Type type,
Stream &s) {
switch (type) {
case FormatEntity::Entry::Type::FunctionBasename: {
std::optional<llvm::StringRef> name = GetDemangledBasename(sc);
if (!name)
return false;

s << *name;

return true;
}
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
// This ensures we print the arguments even when no debug-info is available.
//
// FIXME: we should have a Entry::Type::FunctionArguments and
// use it in the plugin.cplusplus.display.function-name-format
// once we have a "fallback operator" in the frame-format language.
if (!sc.function && sc.symbol)
return PrintDemangledArgumentList(s, sc);
std::string display_name = SwiftLanguageRuntime::DemangleSymbolAsString(
sc.function->GetMangled().GetMangledName().GetStringRef(),
SwiftLanguageRuntime::eSimplified, &sc, exe_ctx);
if (display_name.empty())
return false;

VariableList args;
if (auto variable_list_sp = GetFunctionVariableList(sc))
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
args);

s << GetFunctionDisplayArgs(sc, args, exe_ctx);
return true;
}
case FormatEntity::Entry::Type::FunctionPrefix: {
std::optional<llvm::StringRef> prefix = GetDemangledFunctionPrefix(sc);
if (!prefix)
return false;

s << *prefix;

return true;
}
case FormatEntity::Entry::Type::FunctionSuffix: {
std::optional<llvm::StringRef> suffix = GetDemangledFunctionSuffix(sc);
if (!suffix)
return false;

s << *suffix;

return true;
}

case FormatEntity::Entry::Type::FunctionScope:
case FormatEntity::Entry::Type::FunctionTemplateArguments:
case FormatEntity::Entry::Type::FunctionReturnRight:
case FormatEntity::Entry::Type::FunctionReturnLeft:
case FormatEntity::Entry::Type::FunctionQualifiers:
default:
return true;
}
}

#define LLDB_PROPERTIES_language_swift
#include "LanguageSwiftProperties.inc"

enum {
#define LLDB_PROPERTIES_language_swift
#include "LanguageSwiftPropertiesEnum.inc"
};

namespace {
class PluginProperties : public Properties {
public:
static llvm::StringRef GetSettingName() { return "display"; }

PluginProperties() {
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
m_collection_sp->Initialize(g_language_swift_properties);
}

FormatEntity::Entry GetFunctionNameFormat() const {
return GetPropertyAtIndexAs<const FormatEntity::Entry>(
ePropertyFunctionNameFormat, {});
}
};
} // namespace

static PluginProperties &GetGlobalPluginProperties() {
static PluginProperties g_settings;
return g_settings;
}

FormatEntity::Entry SwiftLanguage::GetFunctionNameFormat() const {
return GetGlobalPluginProperties().GetFunctionNameFormat();
}

void SwiftLanguage::DebuggerInitialize(Debugger &debugger) {
if (!PluginManager::GetSettingForSwiftLanguagePlugin(
debugger, PluginProperties::GetSettingName())) {
PluginManager::CreateSettingForSwiftLanguagePlugin(
debugger, GetGlobalPluginProperties().GetValueProperties(),
"Properties for the Swift language plug-in.",
/*is_global_property=*/true);
}
}

namespace {
using namespace swift::Demangle;
struct AsyncInfo {
Expand Down
10 changes: 10 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ class SwiftLanguage : public Language {

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

bool HandleFrameFormatVariable(const SymbolContext &sc,
const ExecutionContext *exe_ctx,
FormatEntity::Entry::Type type,
Stream &s) override;

FormatEntity::Entry GetFunctionNameFormat() const override;

/// Override that skips breakpoints inside await resume ("Q") async funclets.
void FilterForLineBreakpoints(
llvm::SmallVectorImpl<SymbolContext> &) const override;
Expand All @@ -138,6 +145,9 @@ class SwiftLanguage : public Language {
// PluginInterface protocol
//------------------------------------------------------------------
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

private:
static void DebuggerInitialize(Debugger &);
};

} // namespace lldb_private
Expand Down