Skip to content

Commit 7408359

Browse files
committed
fixup! add tests; account for ':' in mangled name; adjust error messages
1 parent 308d33d commit 7408359

File tree

4 files changed

+135
-10
lines changed

4 files changed

+135
-10
lines changed

lldb/source/Expression/Expression.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,23 @@ static llvm::Expected<llvm::SmallVector<llvm::StringRef, 3>>
3939
splitFunctionCallLabel(llvm::StringRef label) {
4040
if (!label.consume_front(FunctionCallLabelPrefix))
4141
return llvm::createStringError(
42-
"expected function call label prefix not found in %s", label.data());
42+
"expected function call label prefix not found.");
4343
if (!label.consume_front(":"))
4444
return llvm::createStringError(
45-
"incorrect format: expected ':' as the first character.");
45+
"expected ':' as the first character after prefix.");
4646

47-
llvm::SmallVector<llvm::StringRef, 3> components;
48-
label.split(components, ":");
47+
auto sep1 = label.find_first_of(":");
48+
if (sep1 == llvm::StringRef::npos)
49+
return llvm::createStringError("no ':' separator found.");
4950

50-
if (components.size() != 3)
51-
return llvm::createStringError(
52-
"incorrect format: too many label subcomponents.");
51+
auto sep2 = label.find_first_of(":", sep1 + 1);
52+
if (sep2 == llvm::StringRef::npos)
53+
return llvm::createStringError("only single ':' separator found.");
54+
55+
llvm::SmallVector<llvm::StringRef, 3> components;
56+
components.push_back(label.slice(0, sep1));
57+
components.push_back(label.slice(sep1 + 1, sep2));
58+
components.push_back(label.slice(sep2 + 1, llvm::StringRef::npos));
5359

5460
return components;
5561
}
@@ -59,7 +65,8 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
5965
auto components_or_err = splitFunctionCallLabel(label);
6066
if (!components_or_err)
6167
return llvm::joinErrors(
62-
llvm::createStringError("Failed to decode function call label"),
68+
llvm::createStringError("failed to split function call label '%s'",
69+
label.data()),
6370
components_or_err.takeError());
6471

6572
const auto &components = *components_or_err;
@@ -75,7 +82,7 @@ lldb_private::FunctionCallLabel::fromString(llvm::StringRef label) {
7582
lldb::user_id_t die_id;
7683
if (die_label.consumeInteger(/*Radix=*/0, die_id))
7784
return llvm::createStringError(
78-
llvm::formatv("failed to parse DIE ID from '{0}'.", components[1]));
85+
llvm::formatv("failed to parse symbol ID from '{0}'.", components[1]));
7986

8087
return FunctionCallLabel{/*.module_id=*/module_id,
8188
/*.symbol_id=*/die_id,

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,15 @@ static std::optional<std::string> MakeLLDBFuncAsmLabel(const DWARFDIE &die) {
255255
if (!name)
256256
return std::nullopt;
257257

258-
auto module_sp = die.GetModule();
258+
SymbolFileDWARF *dwarf = die.GetDWARF();
259+
if (!dwarf)
260+
return std::nullopt;
261+
262+
ObjectFile *main_obj = dwarf->GetMainObjectFile();
263+
if (!main_obj)
264+
return std::nullopt;
265+
266+
auto module_sp = main_obj->GetModule();
259267
if (!module_sp)
260268
return std::nullopt;
261269

lldb/unittests/Expression/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_lldb_unittest(ExpressionTests
44
DiagnosticManagerTest.cpp
55
DWARFExpressionTest.cpp
66
CppModuleConfigurationTest.cpp
7+
ExpressionTest.cpp
78

89
LINK_LIBS
910
lldbCore
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//===-- ExpressionTest.cpp ------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "gmock/gmock.h"
10+
#include "gtest/gtest.h"
11+
12+
#include "TestingSupport/TestUtilities.h"
13+
#include "lldb/Expression/Expression.h"
14+
#include "llvm/Testing/Support/Error.h"
15+
16+
using namespace lldb_private;
17+
18+
struct LabelTestCase {
19+
llvm::StringRef encoded;
20+
FunctionCallLabel label;
21+
llvm::SmallVector<llvm::StringRef> error_pattern;
22+
};
23+
24+
static LabelTestCase g_label_test_cases[] = {
25+
// Failure modes
26+
{"0x0:0x0:_Z3foov",
27+
{},
28+
{"failed to split function call label '0x0:0x0:_Z3foov'",
29+
"expected function call label prefix not found."}},
30+
{"$__lldb_func0x0:0x0:_Z3foov",
31+
{},
32+
{"failed to split function call label '$__lldb_func0x0:0x0:_Z3foov'",
33+
"expected ':' as the first character after prefix."}},
34+
{"$__lldb_func:",
35+
{},
36+
{"failed to split function call label '$__lldb_func:'",
37+
"no ':' separator found."}},
38+
{"$__lldb_func:0x0:0x0",
39+
{},
40+
{"failed to split function call label '$__lldb_func:0x0:0x0'",
41+
"only single ':' separator found."}},
42+
{"$__lldb_func:abc:0x0:_Z3foov",
43+
{},
44+
{"failed to parse module ID from 'abc'."}},
45+
{"$__lldb_func:-1:0x0:_Z3foov",
46+
{},
47+
{"failed to parse module ID from '-1'."}},
48+
{"$__lldb_func:0x0:abc:_Z3foov",
49+
{},
50+
{"failed to parse symbol ID from 'abc'."}},
51+
{"$__lldb_func:0x5:-1:_Z3foov",
52+
{},
53+
{"failed to parse symbol ID from '-1'."}},
54+
{"$__lldb_func:0x0:0x0:_Z3foov",
55+
{
56+
/*.module_id=*/0x0,
57+
/*.symbol_id=*/0x0,
58+
/*.lookup_name=*/"_Z3foov",
59+
},
60+
{}},
61+
{"$__lldb_func:0x0:0x0:abc:def:::a",
62+
{
63+
/*.module_id=*/0x0,
64+
/*.symbol_id=*/0x0,
65+
/*.lookup_name=*/"abc:def:::a",
66+
},
67+
{}},
68+
{"$__lldb_func:0xd2:0xf0:$__lldb_func",
69+
{
70+
/*.module_id=*/0xd2,
71+
/*.symbol_id=*/0xf0,
72+
/*.lookup_name=*/"$__lldb_func",
73+
},
74+
{}},
75+
};
76+
77+
struct ExpressionTestFixture : public testing::TestWithParam<LabelTestCase> {};
78+
79+
TEST_P(ExpressionTestFixture, FunctionCallLabel) {
80+
const auto &[encoded, label, errors] = GetParam();
81+
82+
auto decoded_or_err = FunctionCallLabel::fromString(encoded);
83+
if (!errors.empty()) {
84+
EXPECT_THAT_EXPECTED(
85+
decoded_or_err,
86+
llvm::FailedWithMessageArray(testing::ElementsAreArray(errors)));
87+
return;
88+
}
89+
90+
EXPECT_THAT_EXPECTED(decoded_or_err, llvm::Succeeded());
91+
92+
auto label_str = label.toString();
93+
EXPECT_EQ(decoded_or_err->toString(), encoded);
94+
EXPECT_EQ(label_str, encoded);
95+
96+
EXPECT_EQ(decoded_or_err->module_id, label.module_id);
97+
EXPECT_EQ(decoded_or_err->symbol_id, label.symbol_id);
98+
EXPECT_EQ(decoded_or_err->lookup_name, label.lookup_name);
99+
100+
auto roundtrip_or_err = FunctionCallLabel::fromString(label_str);
101+
EXPECT_THAT_EXPECTED(roundtrip_or_err, llvm::Succeeded());
102+
103+
EXPECT_EQ(roundtrip_or_err->module_id, label.module_id);
104+
EXPECT_EQ(roundtrip_or_err->symbol_id, label.symbol_id);
105+
EXPECT_EQ(roundtrip_or_err->lookup_name, label.lookup_name);
106+
}
107+
108+
INSTANTIATE_TEST_SUITE_P(FunctionCallLabelTest, ExpressionTestFixture,
109+
testing::ValuesIn(g_label_test_cases));

0 commit comments

Comments
 (0)