Skip to content

Commit 7fa6de1

Browse files
committed
[lldb][CPlusPlus] Add plugin.cplusplus.language.function-name-format setting
1 parent 07d271d commit 7fa6de1

File tree

12 files changed

+261
-8
lines changed

12 files changed

+261
-8
lines changed

lldb/include/lldb/Core/PluginManager.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,10 @@ class PluginManager {
141141
GetOperatingSystemCreateCallbackForPluginName(llvm::StringRef name);
142142

143143
// Language
144-
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
145-
LanguageCreateInstance create_callback);
144+
static bool
145+
RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
146+
LanguageCreateInstance create_callback,
147+
DebuggerInitializeCallback debugger_init_callback = nullptr);
146148

147149
static bool UnregisterPlugin(LanguageCreateInstance create_callback);
148150

@@ -613,6 +615,14 @@ class PluginManager {
613615
static bool CreateSettingForStructuredDataPlugin(
614616
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
615617
llvm::StringRef description, bool is_global_property);
618+
619+
static lldb::OptionValuePropertiesSP
620+
GetSettingForCPlusPlusLanguagePlugin(Debugger &debugger,
621+
llvm::StringRef setting_name);
622+
623+
static bool CreateSettingForCPlusPlusLanguagePlugin(
624+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
625+
llvm::StringRef description, bool is_global_property);
616626
};
617627

618628
} // namespace lldb_private

lldb/include/lldb/Target/Language.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ class Language : public PluginInterface {
397397
/// Python uses \b except. Defaults to \b catch.
398398
virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }
399399

400+
virtual const FormatEntity::Entry *GetFrameFormat() const { return nullptr; }
401+
400402
protected:
401403
// Classes that inherit from Language can see and modify these
402404

lldb/source/Core/FormatEntity.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,29 @@ static bool HandleFunctionNameWithArgs(Stream &s,
12351235
return true;
12361236
}
12371237

1238+
static bool FormatFunctionNameForLanguage(Stream &s,
1239+
const ExecutionContext *exe_ctx,
1240+
const SymbolContext *sc) {
1241+
assert(sc);
1242+
1243+
Language *language_plugin = nullptr;
1244+
if (sc->function)
1245+
language_plugin = Language::FindPlugin(sc->function->GetLanguage());
1246+
else if (sc->symbol)
1247+
language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
1248+
1249+
if (!language_plugin)
1250+
return false;
1251+
1252+
const auto *format = language_plugin->GetFrameFormat();
1253+
if (!format)
1254+
return false;
1255+
1256+
return FormatEntity::Format(*format, s, sc, exe_ctx, /*addr=*/nullptr,
1257+
/*valobj=*/nullptr, /*function_changed=*/false,
1258+
/*initial_function=*/false);
1259+
}
1260+
12381261
bool FormatEntity::FormatStringRef(const llvm::StringRef &format_str, Stream &s,
12391262
const SymbolContext *sc,
12401263
const ExecutionContext *exe_ctx,
@@ -1811,6 +1834,9 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
18111834
if (!sc)
18121835
return false;
18131836

1837+
if (FormatFunctionNameForLanguage(s, exe_ctx, sc))
1838+
return true;
1839+
18141840
return HandleFunctionNameWithArgs(s, exe_ctx, *sc);
18151841
}
18161842
case Entry::Type::FunctionMangledName: {

lldb/source/Core/PluginManager.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,11 +564,12 @@ static LanguageInstances &GetLanguageInstances() {
564564
return g_instances;
565565
}
566566

567-
bool PluginManager::RegisterPlugin(llvm::StringRef name,
568-
llvm::StringRef description,
569-
LanguageCreateInstance create_callback) {
570-
return GetLanguageInstances().RegisterPlugin(name, description,
571-
create_callback);
567+
bool PluginManager::RegisterPlugin(
568+
llvm::StringRef name, llvm::StringRef description,
569+
LanguageCreateInstance create_callback,
570+
DebuggerInitializeCallback debugger_init_callback) {
571+
return GetLanguageInstances().RegisterPlugin(
572+
name, description, create_callback, debugger_init_callback);
572573
}
573574

574575
bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
@@ -1682,6 +1683,7 @@ void PluginManager::DebuggerInitialize(Debugger &debugger) {
16821683
GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
16831684
GetTracePluginInstances().PerformDebuggerCallback(debugger);
16841685
GetScriptedInterfaceInstances().PerformDebuggerCallback(debugger);
1686+
GetLanguageInstances().PerformDebuggerCallback(debugger);
16851687
}
16861688

16871689
// This is the preferred new way to register plugin specific settings. e.g.
@@ -1810,6 +1812,7 @@ static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
18101812
static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
18111813
static constexpr llvm::StringLiteral
18121814
kStructuredDataPluginName("structured-data");
1815+
static constexpr llvm::StringLiteral kCPlusPlusLanguagePlugin("cplusplus");
18131816

18141817
lldb::OptionValuePropertiesSP
18151818
PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
@@ -1967,3 +1970,17 @@ bool PluginManager::CreateSettingForStructuredDataPlugin(
19671970
"Settings for structured data plug-ins",
19681971
properties_sp, description, is_global_property);
19691972
}
1973+
1974+
lldb::OptionValuePropertiesSP
1975+
PluginManager::GetSettingForCPlusPlusLanguagePlugin(
1976+
Debugger &debugger, llvm::StringRef setting_name) {
1977+
return GetSettingForPlugin(debugger, setting_name, kCPlusPlusLanguagePlugin);
1978+
}
1979+
1980+
bool PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
1981+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1982+
llvm::StringRef description, bool is_global_property) {
1983+
return CreateSettingForPlugin(debugger, kCPlusPlusLanguagePlugin,
1984+
"Settings for CPlusPlus language plug-ins",
1985+
properties_sp, description, is_global_property);
1986+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
lldb_tablegen(LanguageCPlusPlusProperties.inc -gen-lldb-property-defs
2+
SOURCE LanguageCPlusPlusProperties.td
3+
TARGET LLDBPluginLanguageCPlusPlusPropertiesGen)
4+
5+
lldb_tablegen(LanguageCPlusPlusPropertiesEnum.inc -gen-lldb-property-enum-defs
6+
SOURCE LanguageCPlusPlusProperties.td
7+
TARGET LLDBPluginLanguageCPlusPlusPropertiesEnumGen)
8+
19
add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
210
BlockPointer.cpp
311
Coroutines.cpp
@@ -41,3 +49,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
4149
LINK_COMPONENTS
4250
Support
4351
)
52+
53+
add_dependencies(lldbPluginCPlusPlusLanguage
54+
LLDBPluginLanguageCPlusPlusPropertiesGen
55+
LLDBPluginLanguageCPlusPlusPropertiesEnumGen)

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "lldb/DataFormatters/DataVisualization.h"
2828
#include "lldb/DataFormatters/FormattersHelpers.h"
2929
#include "lldb/DataFormatters/VectorType.h"
30+
#include "lldb/Interpreter/OptionValueProperties.h"
3031
#include "lldb/Symbol/SymbolFile.h"
3132
#include "lldb/Symbol/VariableList.h"
3233
#include "lldb/Utility/ConstString.h"
@@ -55,7 +56,7 @@ LLDB_PLUGIN_DEFINE(CPlusPlusLanguage)
5556

5657
void CPlusPlusLanguage::Initialize() {
5758
PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language",
58-
CreateInstance);
59+
CreateInstance, &DebuggerInitialize);
5960
}
6061

6162
void CPlusPlusLanguage::Terminate() {
@@ -1995,3 +1996,47 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
19951996
return false;
19961997
}
19971998
}
1999+
2000+
#define LLDB_PROPERTIES_language_cplusplus
2001+
#include "LanguageCPlusPlusProperties.inc"
2002+
2003+
enum {
2004+
#define LLDB_PROPERTIES_language_cplusplus
2005+
#include "LanguageCPlusPlusPropertiesEnum.inc"
2006+
};
2007+
2008+
namespace {
2009+
class PluginProperties : public Properties {
2010+
public:
2011+
static llvm::StringRef GetSettingName() { return "language"; }
2012+
2013+
PluginProperties() {
2014+
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
2015+
m_collection_sp->Initialize(g_language_cplusplus_properties);
2016+
}
2017+
2018+
const FormatEntity::Entry *GetFrameFormat() const {
2019+
return GetPropertyAtIndexAs<const FormatEntity::Entry *>(
2020+
ePropertyFrameFormat);
2021+
}
2022+
};
2023+
} // namespace
2024+
2025+
static PluginProperties &GetGlobalPluginProperties() {
2026+
static PluginProperties g_settings;
2027+
return g_settings;
2028+
}
2029+
2030+
const FormatEntity::Entry *CPlusPlusLanguage::GetFrameFormat() const {
2031+
return GetGlobalPluginProperties().GetFrameFormat();
2032+
}
2033+
2034+
void CPlusPlusLanguage::DebuggerInitialize(Debugger &debugger) {
2035+
if (!PluginManager::GetSettingForCPlusPlusLanguagePlugin(
2036+
debugger, PluginProperties::GetSettingName())) {
2037+
PluginManager::CreateSettingForCPlusPlusLanguagePlugin(
2038+
debugger, GetGlobalPluginProperties().GetValueProperties(),
2039+
"Properties for the CPlusPlus language plug-in.",
2040+
/*is_global_property=*/true);
2041+
}
2042+
}

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,13 @@ class CPlusPlusLanguage : public Language {
174174

175175
llvm::StringRef GetInstanceVariableName() override { return "this"; }
176176

177+
const FormatEntity::Entry *GetFrameFormat() const override;
178+
177179
// PluginInterface protocol
178180
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
181+
182+
private:
183+
static void DebuggerInitialize(Debugger &);
179184
};
180185

181186
} // namespace lldb_private
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_cplusplus" in {
4+
def FrameFormat: Property<"function-name-format", "FormatEntity">,
5+
Global,
6+
DefaultStringValue<"${function.return-left}${function.scope}${function.basename}${function.template-arguments}${function.arguments}${function.return-right}${function.qualifiers}">,
7+
Desc<"C++ specific frame format string to use when displaying stack frame information for threads.">;
8+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Test the ${plugin.cplusplus.language.function-name-format} setting.
2+
3+
# RUN: split-file %s %t
4+
# RUN: %build %t/main.cpp -o %t.out
5+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
6+
# RUN: | FileCheck %s
7+
8+
#--- main.cpp
9+
namespace ns::ns2 {
10+
void custom(int x) asm("_Zinvalid_mangling");
11+
void custom(int x) {}
12+
13+
void bar() { custom(5); }
14+
void foo() { bar(); }
15+
}
16+
17+
int main(int argc, char const *argv[]) {
18+
ns::ns2::foo();
19+
return 0;
20+
}
21+
22+
#--- commands.input
23+
settings set plugin.cplusplus.language.function-name-format "${function.scope}${function.basename}"
24+
settings set -f frame-format "custom-frame '${function.name-with-args}'\n"
25+
break set -l 3
26+
27+
run
28+
bt
29+
30+
# CHECK: custom-frame '_Zinvalid_mangling(x=5)'
31+
# CHECK: custom-frame 'ns::ns2::bar'
32+
# CHECK: custom-frame 'ns::ns2::foo'
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Test the ${plugin.cplusplus.language.function-name-format} setting
2+
# when interoperating multiple languages.
3+
4+
# RUN: split-file %s %t
5+
# RUN: %clangxx_host -x c -c -g %t/lib.c -o %t.clib.o
6+
# RUN: %clangxx_host -c -g %t/lib.cpp -o %t.cxxlib.o
7+
# RUN: %clangxx_host %t/main.m %t.cxxlib.o %t.clib.o -o %t.out
8+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 | FileCheck %s
9+
10+
#--- lib.c
11+
12+
void foo();
13+
14+
void func() {
15+
foo();
16+
}
17+
18+
#--- lib.cpp
19+
20+
namespace ns {
21+
struct Foo {
22+
void method() {}
23+
};
24+
}
25+
26+
extern "C" {
27+
void foo() {
28+
ns::Foo{}.method();
29+
}
30+
}
31+
32+
#--- main.m
33+
34+
void func();
35+
36+
int main() {
37+
func();
38+
}
39+
40+
#--- commands.input
41+
settings set plugin.cplusplus.language.function-name-format "this affects C++ only"
42+
settings set -f frame-format "custom-frame '${function.name-with-args}'\n"
43+
break set -n method
44+
45+
run
46+
bt
47+
48+
# CHECK: custom-frame 'this affects C++ only'
49+
# CHECK: custom-frame 'this affects C++ only'
50+
# CHECK: custom-frame 'func'
51+
# CHECK: custom-frame 'main'

0 commit comments

Comments
 (0)