Skip to content

Commit c230ad6

Browse files
committed
[LLDB] Add type summaries for MSVC STL strings
1 parent 30eb97c commit c230ad6

File tree

16 files changed

+557
-35
lines changed

16 files changed

+557
-35
lines changed

lldb/packages/Python/lldbsuite/test/dotest.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,46 @@ def checkLibstdcxxSupport():
831831
configuration.skip_categories.append("libstdcxx")
832832

833833

834+
def canRunMsvcStlTests():
835+
from lldbsuite.test import lldbplatformutil
836+
837+
platform = lldbplatformutil.getPlatform()
838+
if platform != "windows":
839+
return False, f"Don't know how to build with MSVC's STL on {platform}"
840+
841+
with tempfile.NamedTemporaryFile() as f:
842+
cmd = [configuration.compiler, "-xc++", "-o", f.name, "-E", "-"]
843+
p = subprocess.Popen(
844+
cmd,
845+
stdin=subprocess.PIPE,
846+
stdout=subprocess.PIPE,
847+
stderr=subprocess.PIPE,
848+
universal_newlines=True,
849+
)
850+
_, stderr = p.communicate(
851+
"""
852+
#include <yvals_core.h>
853+
#ifndef _MSVC_STL_VERSION
854+
#error _MSVC_STL_VERSION not defined
855+
#endif
856+
"""
857+
)
858+
if not p.returncode:
859+
return True, "Compiling with MSVC STL"
860+
return (False, f"Not compiling with MSVC STL: {stderr}")
861+
862+
863+
def checkMsvcStlSupport():
864+
result, reason = canRunMsvcStlTests()
865+
if result:
866+
return # msvcstl supported
867+
if "msvcstl" in configuration.categories_list:
868+
return # msvcstl category explicitly requested, let it run.
869+
if configuration.verbose:
870+
print(f"msvcstl tests will not be run because: {reason}")
871+
configuration.skip_categories.append("msvcstl")
872+
873+
834874
def canRunWatchpointTests():
835875
from lldbsuite.test import lldbplatformutil
836876

@@ -1044,6 +1084,7 @@ def run_suite():
10441084

10451085
checkLibcxxSupport()
10461086
checkLibstdcxxSupport()
1087+
checkMsvcStlSupport()
10471088
checkWatchpointSupport()
10481089
checkDebugInfoSupport()
10491090
checkDebugServerSupport()

lldb/packages/Python/lldbsuite/test/test_categories.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"lldb-server": "Tests related to lldb-server",
3434
"lldb-dap": "Tests for the Debug Adapter Protocol with lldb-dap",
3535
"llgs": "Tests for the gdb-server functionality of lldb-server",
36+
"msvcstl": "Test for MSVC STL data formatters",
3637
"pexpect": "Tests requiring the pexpect library to be available",
3738
"objc": "Tests related to the Objective-C programming language support",
3839
"pyapi": "Tests related to the Python API",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
3232
LibStdcpp.cpp
3333
LibStdcppTuple.cpp
3434
LibStdcppUniquePointer.cpp
35+
MsvcStl.cpp
3536
MSVCUndecoratedNameParser.cpp
3637

3738
LINK_COMPONENTS

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

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "LibCxxVariant.h"
4747
#include "LibStdcpp.h"
4848
#include "MSVCUndecoratedNameParser.h"
49+
#include "MsvcStl.h"
4950
#include "lldb/lldb-enumerations.h"
5051

5152
using namespace lldb;
@@ -1331,6 +1332,37 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13311332
"${var.__y_} ${var.__m_} ${var.__wdl_}")));
13321333
}
13331334

1335+
static void RegisterStdStringSummaryProvider(
1336+
const lldb::TypeCategoryImplSP &category_sp, llvm::StringRef string_ty,
1337+
llvm::StringRef char_ty, lldb::TypeSummaryImplSP summary_sp) {
1338+
auto makeSpecifier = [](llvm::StringRef name) {
1339+
return std::make_shared<lldb_private::TypeNameSpecifierImpl>(
1340+
name, eFormatterMatchExact);
1341+
};
1342+
1343+
category_sp->AddTypeSummary(makeSpecifier(string_ty), summary_sp);
1344+
1345+
// std::basic_string<char>
1346+
category_sp->AddTypeSummary(
1347+
makeSpecifier(llvm::formatv("std::basic_string<{}>", char_ty).str()),
1348+
summary_sp);
1349+
// std::basic_string<char,std::char_traits<char>,std::allocator<char> >
1350+
category_sp->AddTypeSummary(
1351+
makeSpecifier(llvm::formatv("std::basic_string<{0},std::char_traits<{0}>,"
1352+
"std::allocator<{0}> >",
1353+
char_ty)
1354+
.str()),
1355+
summary_sp);
1356+
// std::basic_string<char, std::char_traits<char>, std::allocator<char> >
1357+
category_sp->AddTypeSummary(
1358+
makeSpecifier(
1359+
llvm::formatv("std::basic_string<{0}, std::char_traits<{0}>, "
1360+
"std::allocator<{0}> >",
1361+
char_ty)
1362+
.str()),
1363+
summary_sp);
1364+
}
1365+
13341366
static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13351367
if (!cpp_category_sp)
13361368
return;
@@ -1347,18 +1379,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13471379
lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(
13481380
stl_summary_flags, LibStdcppStringSummaryProvider,
13491381
"libstdc++ std::(w)string summary provider"));
1350-
1351-
cpp_category_sp->AddTypeSummary("std::string", eFormatterMatchExact,
1352-
string_summary_sp);
1353-
cpp_category_sp->AddTypeSummary("std::basic_string<char>",
1354-
eFormatterMatchExact, string_summary_sp);
1355-
cpp_category_sp->AddTypeSummary(
1356-
"std::basic_string<char,std::char_traits<char>,std::allocator<char> >",
1357-
eFormatterMatchExact, string_summary_sp);
1358-
cpp_category_sp->AddTypeSummary(
1359-
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >",
1360-
eFormatterMatchExact, string_summary_sp);
1361-
13621382
cpp_category_sp->AddTypeSummary("std::__cxx11::string", eFormatterMatchExact,
13631383
string_summary_sp);
13641384
cpp_category_sp->AddTypeSummary(
@@ -1370,23 +1390,6 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
13701390
"std::allocator<unsigned char> >",
13711391
eFormatterMatchExact, string_summary_sp);
13721392

1373-
// making sure we force-pick the summary for printing wstring (_M_p is a
1374-
// wchar_t*)
1375-
lldb::TypeSummaryImplSP std_wstring_summary_sp(
1376-
new StringSummaryFormat(stl_summary_flags, "${var._M_dataplus._M_p%S}"));
1377-
1378-
cpp_category_sp->AddTypeSummary("std::wstring", eFormatterMatchExact,
1379-
std_wstring_summary_sp);
1380-
cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t>",
1381-
eFormatterMatchExact, std_wstring_summary_sp);
1382-
cpp_category_sp->AddTypeSummary("std::basic_string<wchar_t,std::char_traits<"
1383-
"wchar_t>,std::allocator<wchar_t> >",
1384-
eFormatterMatchExact, std_wstring_summary_sp);
1385-
cpp_category_sp->AddTypeSummary(
1386-
"std::basic_string<wchar_t, std::char_traits<wchar_t>, "
1387-
"std::allocator<wchar_t> >",
1388-
eFormatterMatchExact, std_wstring_summary_sp);
1389-
13901393
cpp_category_sp->AddTypeSummary("std::__cxx11::wstring", eFormatterMatchExact,
13911394
string_summary_sp);
13921395
cpp_category_sp->AddTypeSummary(
@@ -1581,6 +1584,81 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
15811584
"^std::optional<.+>(( )?&)?$", stl_summary_flags, true);
15821585
}
15831586

1587+
/// Load formatters that are formatting types from more than one STL
1588+
static void LoadCommonStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1589+
if (!cpp_category_sp)
1590+
return;
1591+
1592+
TypeSummaryImpl::Flags stl_summary_flags;
1593+
stl_summary_flags.SetCascades(true)
1594+
.SetSkipPointers(false)
1595+
.SetSkipReferences(false)
1596+
.SetDontShowChildren(true)
1597+
.SetDontShowValue(false)
1598+
.SetShowMembersOneLiner(false)
1599+
.SetHideItemNames(false);
1600+
using StringElementType = StringPrinter::StringElementType;
1601+
1602+
RegisterStdStringSummaryProvider(
1603+
cpp_category_sp, "std::string", "char",
1604+
std::make_shared<CXXFunctionSummaryFormat>(
1605+
stl_summary_flags,
1606+
[](ValueObject &valobj, Stream &stream,
1607+
const TypeSummaryOptions &options) {
1608+
if (IsMsvcStlStringType(valobj))
1609+
return MsvcStlStringSummaryProvider<StringElementType::ASCII>(
1610+
valobj, stream, options);
1611+
return LibStdcppStringSummaryProvider(valobj, stream, options);
1612+
},
1613+
"MSVC STL/libstdc++ std::string summary provider"));
1614+
RegisterStdStringSummaryProvider(
1615+
cpp_category_sp, "std::wstring", "wchar_t",
1616+
std::make_shared<CXXFunctionSummaryFormat>(
1617+
stl_summary_flags,
1618+
[](ValueObject &valobj, Stream &stream,
1619+
const TypeSummaryOptions &options) {
1620+
if (IsMsvcStlStringType(valobj))
1621+
return MsvcStlWStringSummaryProvider(valobj, stream, options);
1622+
return LibStdcppStringSummaryProvider(valobj, stream, options);
1623+
},
1624+
"MSVC STL/libstdc++ std::wstring summary provider"));
1625+
}
1626+
1627+
static void LoadMsvcStlFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
1628+
if (!cpp_category_sp)
1629+
return;
1630+
1631+
TypeSummaryImpl::Flags stl_summary_flags;
1632+
stl_summary_flags.SetCascades(true)
1633+
.SetSkipPointers(false)
1634+
.SetSkipReferences(false)
1635+
.SetDontShowChildren(true)
1636+
.SetDontShowValue(false)
1637+
.SetShowMembersOneLiner(false)
1638+
.SetHideItemNames(false);
1639+
1640+
using StringElementType = StringPrinter::StringElementType;
1641+
1642+
RegisterStdStringSummaryProvider(
1643+
cpp_category_sp, "std::u8string", "char8_t",
1644+
std::make_shared<CXXFunctionSummaryFormat>(
1645+
stl_summary_flags,
1646+
MsvcStlStringSummaryProvider<StringElementType::UTF8>,
1647+
"MSVC STL std::u8string summary provider"));
1648+
RegisterStdStringSummaryProvider(
1649+
cpp_category_sp, "std::u16string", "char16_t",
1650+
std::make_shared<CXXFunctionSummaryFormat>(
1651+
stl_summary_flags,
1652+
MsvcStlStringSummaryProvider<StringElementType::UTF16>,
1653+
"MSVC STL std::u16string summary provider"));
1654+
RegisterStdStringSummaryProvider(
1655+
cpp_category_sp, "std::u32string", "char32_t",
1656+
std::make_shared<CXXFunctionSummaryFormat>(
1657+
stl_summary_flags,
1658+
MsvcStlStringSummaryProvider<StringElementType::UTF32>,
1659+
"MSVC STL std::u32string summary provider"));
1660+
}
1661+
15841662
static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
15851663
if (!cpp_category_sp)
15861664
return;
@@ -1695,6 +1773,8 @@ lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() {
16951773
// LLDB prioritizes the last loaded matching formatter.
16961774
LoadLibCxxFormatters(g_category);
16971775
LoadLibStdcppFormatters(g_category);
1776+
LoadMsvcStlFormatters(g_category);
1777+
LoadCommonStlFormatters(g_category);
16981778
LoadSystemFormatters(g_category);
16991779
}
17001780
});

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "LibStdcpp.h"
10+
#include "CxxStringTypes.h"
1011
#include "LibCxx.h"
1112

1213
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"

0 commit comments

Comments
 (0)