The LLVM Coding Standards [1] specify that: > [T]o match error message styles commonly produced by other tools, > start the first sentence with a lowercase letter, and finish the last > sentence without a period, if it would end in one otherwise. Historically, that hasn't been something we've enforced in LLDB, but in the past year or so I've started to pay more attention to this in code reviews. This PR brings more error messages in compliance, further increasing consistency. I also adopted `createStringErrorV` where it improved the code as a drive-by for lines I was already touching. [1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages Assisted-by: Claude Code
169 lines
6.0 KiB
C++
169 lines
6.0 KiB
C++
//===-- ExpressionTest.cpp ------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "TestingSupport/TestUtilities.h"
|
|
#include "lldb/Expression/Expression.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "llvm/Testing/Support/Error.h"
|
|
|
|
using namespace lldb_private;
|
|
|
|
struct LabelTestCase {
|
|
llvm::StringRef encoded;
|
|
FunctionCallLabel label;
|
|
llvm::SmallVector<llvm::StringRef> error_pattern;
|
|
};
|
|
|
|
static LabelTestCase g_label_test_cases[] = {
|
|
// Failure modes
|
|
{"bar:blah:0x0:0x0:_Z3foov",
|
|
{},
|
|
{"expected function call label prefix '$__lldb_func' but found 'bar' "
|
|
"instead."}},
|
|
{"$__lldb_func :blah:0x0:0x0:_Z3foov",
|
|
{},
|
|
{"expected function call label prefix '$__lldb_func' but found "
|
|
"'$__lldb_func ' instead."}},
|
|
{"$__lldb_funcc:blah:0x0:0x0:_Z3foov",
|
|
{},
|
|
{"expected function call label prefix '$__lldb_func' but found "
|
|
"'$__lldb_funcc' instead."}},
|
|
{"", {}, {"malformed function call label"}},
|
|
{"foo", {}, {"malformed function call label"}},
|
|
{"$__lldb_func", {}, {"malformed function call label"}},
|
|
{"$__lldb_func:", {}, {"malformed function call label"}},
|
|
{"$__lldb_func:blah", {}, {"malformed function call label"}},
|
|
{"$__lldb_func:blah:0x0", {}, {"malformed function call label"}},
|
|
{"$__lldb_func:111:0x0:0x0", {}, {"malformed function call label"}},
|
|
{"$__lldb_func:111:abc:0x0:_Z3foov",
|
|
{},
|
|
{"failed to parse module ID from 'abc'"}},
|
|
{"$__lldb_func:111:-1:0x0:_Z3foov",
|
|
{},
|
|
{"failed to parse module ID from '-1'"}},
|
|
{"$__lldb_func:111:0x0invalid:0x0:_Z3foov",
|
|
{},
|
|
{"failed to parse module ID from '0x0invalid'"}},
|
|
{"$__lldb_func:111:0x0 :0x0:_Z3foov",
|
|
{},
|
|
{"failed to parse module ID from '0x0 '"}},
|
|
{"$__lldb_func:blah:0x0:abc:_Z3foov",
|
|
{},
|
|
{"failed to parse symbol ID from 'abc'"}},
|
|
{"$__lldb_func:blah:0x5:-1:_Z3foov",
|
|
{},
|
|
{"failed to parse symbol ID from '-1'"}},
|
|
{"$__lldb_func:blah:0x5:0x0invalid:_Z3foov",
|
|
{},
|
|
{"failed to parse symbol ID from '0x0invalid'"}},
|
|
{"$__lldb_func:blah:0x5:0x0 :_Z3foov",
|
|
{},
|
|
{"failed to parse symbol ID from '0x0 '"}},
|
|
{"$__lldb_func:blah:0x0:0x0:_Z3foov",
|
|
{
|
|
/*.discriminator=*/"blah",
|
|
/*.module_id=*/0x0,
|
|
/*.symbol_id=*/0x0,
|
|
/*.lookup_name=*/"_Z3foov",
|
|
},
|
|
{}},
|
|
{"$__lldb_func::0x0:0x0:abc:def:::a",
|
|
{
|
|
/*.discriminator=*/"",
|
|
/*.module_id=*/0x0,
|
|
/*.symbol_id=*/0x0,
|
|
/*.lookup_name=*/"abc:def:::a",
|
|
},
|
|
{}},
|
|
{"$__lldb_func:0x45:0xd2:0xf0:$__lldb_func",
|
|
{
|
|
/*.discriminator=*/"0x45",
|
|
/*.module_id=*/0xd2,
|
|
/*.symbol_id=*/0xf0,
|
|
/*.lookup_name=*/"$__lldb_func",
|
|
},
|
|
{}},
|
|
};
|
|
|
|
struct ExpressionTestFixture : public testing::TestWithParam<LabelTestCase> {};
|
|
|
|
TEST_P(ExpressionTestFixture, FunctionCallLabel) {
|
|
const auto &[encoded, label, errors] = GetParam();
|
|
|
|
auto decoded_or_err = FunctionCallLabel::fromString(encoded);
|
|
if (!errors.empty()) {
|
|
EXPECT_THAT_EXPECTED(
|
|
decoded_or_err,
|
|
llvm::FailedWithMessageArray(testing::ElementsAreArray(errors)));
|
|
return;
|
|
}
|
|
|
|
EXPECT_THAT_EXPECTED(decoded_or_err, llvm::Succeeded());
|
|
|
|
auto label_str = label.toString();
|
|
EXPECT_EQ(decoded_or_err->toString(), encoded);
|
|
EXPECT_EQ(label_str, encoded);
|
|
|
|
EXPECT_EQ(decoded_or_err->discriminator, label.discriminator);
|
|
EXPECT_EQ(decoded_or_err->module_id, label.module_id);
|
|
EXPECT_EQ(decoded_or_err->symbol_id, label.symbol_id);
|
|
EXPECT_EQ(decoded_or_err->lookup_name, label.lookup_name);
|
|
|
|
auto roundtrip_or_err = FunctionCallLabel::fromString(label_str);
|
|
EXPECT_THAT_EXPECTED(roundtrip_or_err, llvm::Succeeded());
|
|
|
|
EXPECT_EQ(roundtrip_or_err->discriminator, label.discriminator);
|
|
EXPECT_EQ(roundtrip_or_err->module_id, label.module_id);
|
|
EXPECT_EQ(roundtrip_or_err->symbol_id, label.symbol_id);
|
|
EXPECT_EQ(roundtrip_or_err->lookup_name, label.lookup_name);
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(FunctionCallLabelTest, ExpressionTestFixture,
|
|
testing::ValuesIn(g_label_test_cases));
|
|
|
|
TEST(ExpressionTests, ExpressionOptions_Basic) {
|
|
EvaluateExpressionOptions options;
|
|
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("foo"),
|
|
llvm::FailedWithMessage("option 'foo' does not exist"));
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("bar"),
|
|
llvm::FailedWithMessage("option 'bar' does not exist"));
|
|
|
|
EXPECT_THAT_ERROR(options.SetBooleanLanguageOption("foo", true),
|
|
llvm::Succeeded());
|
|
EXPECT_THAT_ERROR(options.SetBooleanLanguageOption("bar", false),
|
|
llvm::Succeeded());
|
|
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("foo"),
|
|
llvm::HasValue(true));
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("bar"),
|
|
llvm::HasValue(false));
|
|
|
|
EXPECT_THAT_ERROR(options.SetBooleanLanguageOption("foo", false),
|
|
llvm::Succeeded());
|
|
EXPECT_THAT_ERROR(options.SetBooleanLanguageOption("bar", true),
|
|
llvm::Succeeded());
|
|
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("foo"),
|
|
llvm::HasValue(false));
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption("bar"),
|
|
llvm::HasValue(true));
|
|
|
|
// Empty option names not allowed.
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption(""),
|
|
llvm::FailedWithMessage("option '' does not exist"));
|
|
EXPECT_THAT_ERROR(
|
|
options.SetBooleanLanguageOption("", true),
|
|
llvm::FailedWithMessage("can't set an option with an empty name"));
|
|
EXPECT_THAT_EXPECTED(options.GetBooleanLanguageOption(""),
|
|
llvm::FailedWithMessage("option '' does not exist"));
|
|
}
|