[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- PostfixExpressionTest.cpp -----------------------------------------===//
|
2019-04-24 15:27:05 +08:00
|
|
|
//
|
|
|
|
// 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 "lldb/Symbol/PostfixExpression.h"
|
2019-04-26 16:52:04 +08:00
|
|
|
#include "lldb/Utility/DataExtractor.h"
|
|
|
|
#include "lldb/Utility/StreamString.h"
|
2020-05-25 21:59:48 +08:00
|
|
|
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
2019-04-24 15:27:05 +08:00
|
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2019-08-26 19:44:14 +08:00
|
|
|
#include "gmock/gmock.h"
|
2019-04-24 15:27:05 +08:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
using namespace lldb_private::postfix;
|
|
|
|
|
|
|
|
static std::string ToString(BinaryOpNode::OpType type) {
|
|
|
|
switch (type) {
|
|
|
|
case BinaryOpNode::Align:
|
|
|
|
return "@";
|
|
|
|
case BinaryOpNode::Minus:
|
|
|
|
return "-";
|
|
|
|
case BinaryOpNode::Plus:
|
|
|
|
return "+";
|
|
|
|
}
|
|
|
|
llvm_unreachable("Fully covered switch!");
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string ToString(UnaryOpNode::OpType type) {
|
|
|
|
switch (type) {
|
|
|
|
case UnaryOpNode::Deref:
|
|
|
|
return "^";
|
|
|
|
}
|
|
|
|
llvm_unreachable("Fully covered switch!");
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ASTPrinter : public Visitor<std::string> {
|
|
|
|
protected:
|
|
|
|
std::string Visit(BinaryOpNode &binary, Node *&) override {
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(
|
|
|
|
llvm::formatv("{0}({1}, {2})", ToString(binary.GetOpType()),
|
|
|
|
Dispatch(binary.Left()), Dispatch(binary.Right())));
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
2019-04-30 21:33:18 +08:00
|
|
|
std::string Visit(InitialValueNode &, Node *&) override { return "InitialValue"; }
|
|
|
|
|
2019-04-24 15:27:05 +08:00
|
|
|
std::string Visit(IntegerNode &integer, Node *&) override {
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(llvm::formatv("int({0})", integer.GetValue()));
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string Visit(RegisterNode ®, Node *&) override {
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(llvm::formatv("reg({0})", reg.GetRegNum()));
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string Visit(SymbolNode &symbol, Node *&) override {
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(symbol.GetName());
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string Visit(UnaryOpNode &unary, Node *&) override {
|
2020-01-29 03:23:46 +08:00
|
|
|
return std::string(llvm::formatv("{0}({1})", ToString(unary.GetOpType()),
|
|
|
|
Dispatch(unary.Operand())));
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
static std::string Print(Node *node) {
|
|
|
|
if (node)
|
|
|
|
return ASTPrinter().Dispatch(node);
|
|
|
|
return "nullptr";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-08-26 19:44:14 +08:00
|
|
|
static std::string ParseOneAndStringify(llvm::StringRef expr) {
|
2019-04-24 15:27:05 +08:00
|
|
|
llvm::BumpPtrAllocator alloc;
|
2019-08-26 19:44:14 +08:00
|
|
|
return ASTPrinter::Print(ParseOneExpression(expr, alloc));
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
|
|
|
|
2019-08-26 19:44:14 +08:00
|
|
|
TEST(PostfixExpression, ParseOneExpression) {
|
|
|
|
EXPECT_EQ("int(47)", ParseOneAndStringify("47"));
|
|
|
|
EXPECT_EQ("$foo", ParseOneAndStringify("$foo"));
|
|
|
|
EXPECT_EQ("+(int(1), int(2))", ParseOneAndStringify("1 2 +"));
|
|
|
|
EXPECT_EQ("-(int(1), int(2))", ParseOneAndStringify("1 2 -"));
|
|
|
|
EXPECT_EQ("@(int(1), int(2))", ParseOneAndStringify("1 2 @"));
|
|
|
|
EXPECT_EQ("+(int(1), +(int(2), int(3)))", ParseOneAndStringify("1 2 3 + +"));
|
|
|
|
EXPECT_EQ("+(+(int(1), int(2)), int(3))", ParseOneAndStringify("1 2 + 3 +"));
|
|
|
|
EXPECT_EQ("^(int(1))", ParseOneAndStringify("1 ^"));
|
|
|
|
EXPECT_EQ("^(^(int(1)))", ParseOneAndStringify("1 ^ ^"));
|
|
|
|
EXPECT_EQ("^(+(int(1), ^(int(2))))", ParseOneAndStringify("1 2 ^ + ^"));
|
|
|
|
EXPECT_EQ("-($foo, int(47))", ParseOneAndStringify("$foo 47 -"));
|
|
|
|
EXPECT_EQ("+(int(47), int(-42))", ParseOneAndStringify("47 -42 +"));
|
|
|
|
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("+"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("^"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("1 +"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 ^"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("1 2 3 +"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("^ 1"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("+ 1 2"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("1 + 2"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify("1 2"));
|
|
|
|
EXPECT_EQ("nullptr", ParseOneAndStringify(""));
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::vector<std::pair<std::string, std::string>>
|
|
|
|
ParseFPOAndStringify(llvm::StringRef prog) {
|
|
|
|
llvm::BumpPtrAllocator alloc;
|
|
|
|
std::vector<std::pair<llvm::StringRef, Node *>> parsed =
|
|
|
|
ParseFPOProgram(prog, alloc);
|
2019-08-26 20:42:32 +08:00
|
|
|
std::vector<std::pair<std::string, std::string>> result;
|
|
|
|
for (const auto &p : parsed)
|
2020-08-28 08:20:50 +08:00
|
|
|
result.emplace_back(p.first.str(), ASTPrinter::Print(p.second));
|
2019-08-26 20:42:32 +08:00
|
|
|
return result;
|
2019-08-26 19:44:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(PostfixExpression, ParseFPOProgram) {
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("a 1 ="),
|
|
|
|
testing::ElementsAre(std::make_pair("a", "int(1)")));
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("a 1 = b 2 3 + ="),
|
|
|
|
testing::ElementsAre(std::make_pair("a", "int(1)"),
|
|
|
|
std::make_pair("b", "+(int(2), int(3))")));
|
|
|
|
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify(""), testing::IsEmpty());
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("="), testing::IsEmpty());
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("a 1"), testing::IsEmpty());
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("a 1 = ="), testing::IsEmpty());
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("a 1 + ="), testing::IsEmpty());
|
|
|
|
EXPECT_THAT(ParseFPOAndStringify("= a 1 ="), testing::IsEmpty());
|
2019-04-24 15:27:05 +08:00
|
|
|
}
|
2019-04-26 16:52:04 +08:00
|
|
|
|
|
|
|
static std::string ParseAndGenerateDWARF(llvm::StringRef expr) {
|
|
|
|
llvm::BumpPtrAllocator alloc;
|
2019-08-26 19:44:14 +08:00
|
|
|
Node *ast = ParseOneExpression(expr, alloc);
|
2019-04-26 16:52:04 +08:00
|
|
|
if (!ast)
|
|
|
|
return "Parse failed.";
|
|
|
|
if (!ResolveSymbols(ast, [&](SymbolNode &symbol) -> Node * {
|
2019-04-30 21:33:18 +08:00
|
|
|
if (symbol.GetName() == "INIT")
|
|
|
|
return MakeNode<InitialValueNode>(alloc);
|
|
|
|
|
2019-04-26 16:52:04 +08:00
|
|
|
uint32_t num;
|
|
|
|
if (to_integer(symbol.GetName().drop_front(), num))
|
|
|
|
return MakeNode<RegisterNode>(alloc, num);
|
|
|
|
return nullptr;
|
|
|
|
})) {
|
|
|
|
return "Resolution failed.";
|
|
|
|
}
|
|
|
|
|
|
|
|
const size_t addr_size = 4;
|
|
|
|
StreamString dwarf(Stream::eBinary, addr_size, lldb::eByteOrderLittle);
|
|
|
|
ToDWARF(*ast, dwarf);
|
|
|
|
|
|
|
|
// print dwarf expression to comparable textual representation
|
2020-05-25 21:59:48 +08:00
|
|
|
llvm::DataExtractor extractor(dwarf.GetString(), /*IsLittleEndian=*/true,
|
|
|
|
addr_size);
|
|
|
|
|
|
|
|
std::string result;
|
|
|
|
llvm::raw_string_ostream os(result);
|
|
|
|
llvm::DWARFExpression(extractor, addr_size, llvm::dwarf::DWARF32)
|
2020-10-24 10:19:36 +08:00
|
|
|
.print(os, llvm::DIDumpOptions(), nullptr, nullptr);
|
2020-05-25 21:59:48 +08:00
|
|
|
return std::move(os.str());
|
2019-04-26 16:52:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(PostfixExpression, ToDWARF) {
|
PostfixExpression: Use signed integers in IntegerNode
Summary:
This is necessary to support parsing expressions like ".cfa -16 + ^", as
that format is used in breakpad STACK CFI expressions.
Since the PDB expressions use the same parser, this change will affect
them too, but I don't believe that should be a problem in practice. If
PDBs do contain the negative values, it's very likely that they are
intended to be parsed the same way, and if they don't, then it doesn't
matter.
In case that we do ever need to handle this differently, we can always
make the parser behavior customizable, or just use a different parser.
To make sure that the integer size is big enough for everyone, I switch
from using a (unsigned) 32-bit integer to a 64-bit (signed) one.
Reviewers: amccarth, clayborg, aleksandr.urakov
Subscribers: markmentovai, lldb-commits
Differential Revision: https://reviews.llvm.org/D61311
llvm-svn: 360166
2019-05-07 23:58:20 +08:00
|
|
|
EXPECT_EQ("DW_OP_consts +0", ParseAndGenerateDWARF("0"));
|
2019-04-26 16:52:04 +08:00
|
|
|
|
|
|
|
EXPECT_EQ("DW_OP_breg1 +0", ParseAndGenerateDWARF("R1"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_bregx 0x41 +0", ParseAndGenerateDWARF("R65"));
|
2019-04-26 16:52:04 +08:00
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_pick 0x0", ParseAndGenerateDWARF("INIT"));
|
2019-04-30 21:33:18 +08:00
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_pick 0x0, DW_OP_pick 0x1, DW_OP_plus",
|
2019-04-30 21:33:18 +08:00
|
|
|
ParseAndGenerateDWARF("INIT INIT +"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_breg1 +0, DW_OP_pick 0x1, DW_OP_plus",
|
2019-04-30 21:33:18 +08:00
|
|
|
ParseAndGenerateDWARF("R1 INIT +"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_consts +1, DW_OP_pick 0x1, DW_OP_deref, DW_OP_plus",
|
2019-04-30 21:33:18 +08:00
|
|
|
ParseAndGenerateDWARF("1 INIT ^ +"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_plus",
|
2019-04-26 16:52:04 +08:00
|
|
|
ParseAndGenerateDWARF("4 5 +"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_consts +4, DW_OP_consts +5, DW_OP_minus",
|
2019-04-26 16:52:04 +08:00
|
|
|
ParseAndGenerateDWARF("4 5 -"));
|
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_consts +4, DW_OP_deref", ParseAndGenerateDWARF("4 ^"));
|
2019-04-26 16:52:04 +08:00
|
|
|
|
2020-05-25 21:59:48 +08:00
|
|
|
EXPECT_EQ("DW_OP_breg6 +0, DW_OP_consts +128, DW_OP_lit1, DW_OP_minus, "
|
|
|
|
"DW_OP_not, DW_OP_and",
|
2019-04-26 16:52:04 +08:00
|
|
|
ParseAndGenerateDWARF("R6 128 @"));
|
|
|
|
}
|