1 //===-- PostfixExpressionTest.cpp -------------------------------*- C++ -*-===// 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 "lldb/Symbol/PostfixExpression.h" 10 #include "llvm/Support/FormatVariadic.h" 11 #include "llvm/Support/raw_ostream.h" 12 #include "gtest/gtest.h" 13 14 using namespace lldb_private; 15 using namespace lldb_private::postfix; 16 17 static std::string ToString(BinaryOpNode::OpType type) { 18 switch (type) { 19 case BinaryOpNode::Align: 20 return "@"; 21 case BinaryOpNode::Minus: 22 return "-"; 23 case BinaryOpNode::Plus: 24 return "+"; 25 } 26 llvm_unreachable("Fully covered switch!"); 27 } 28 29 static std::string ToString(UnaryOpNode::OpType type) { 30 switch (type) { 31 case UnaryOpNode::Deref: 32 return "^"; 33 } 34 llvm_unreachable("Fully covered switch!"); 35 } 36 37 struct ASTPrinter : public Visitor<std::string> { 38 protected: 39 std::string Visit(BinaryOpNode &binary, Node *&) override { 40 return llvm::formatv("{0}({1}, {2})", ToString(binary.GetOpType()), 41 Dispatch(binary.Left()), Dispatch(binary.Right())); 42 } 43 44 std::string Visit(IntegerNode &integer, Node *&) override { 45 return llvm::formatv("int({0})", integer.GetValue()); 46 } 47 48 std::string Visit(RegisterNode ®, Node *&) override { 49 return llvm::formatv("reg({0})", reg.GetRegNum()); 50 } 51 52 std::string Visit(SymbolNode &symbol, Node *&) override { 53 return symbol.GetName(); 54 } 55 56 std::string Visit(UnaryOpNode &unary, Node *&) override { 57 return llvm::formatv("{0}({1})", ToString(unary.GetOpType()), 58 Dispatch(unary.Operand())); 59 } 60 61 public: 62 static std::string Print(Node *node) { 63 if (node) 64 return ASTPrinter().Dispatch(node); 65 return "nullptr"; 66 } 67 }; 68 69 static std::string ParseAndStringify(llvm::StringRef expr) { 70 llvm::BumpPtrAllocator alloc; 71 return ASTPrinter::Print(Parse(expr, alloc)); 72 } 73 74 TEST(PostfixExpression, Parse) { 75 EXPECT_EQ("int(47)", ParseAndStringify("47")); 76 EXPECT_EQ("$foo", ParseAndStringify("$foo")); 77 EXPECT_EQ("+(int(1), int(2))", ParseAndStringify("1 2 +")); 78 EXPECT_EQ("-(int(1), int(2))", ParseAndStringify("1 2 -")); 79 EXPECT_EQ("@(int(1), int(2))", ParseAndStringify("1 2 @")); 80 EXPECT_EQ("+(int(1), +(int(2), int(3)))", ParseAndStringify("1 2 3 + +")); 81 EXPECT_EQ("+(+(int(1), int(2)), int(3))", ParseAndStringify("1 2 + 3 +")); 82 EXPECT_EQ("^(int(1))", ParseAndStringify("1 ^")); 83 EXPECT_EQ("^(^(int(1)))", ParseAndStringify("1 ^ ^")); 84 EXPECT_EQ("^(+(int(1), ^(int(2))))", ParseAndStringify("1 2 ^ + ^")); 85 EXPECT_EQ("-($foo, int(47))", ParseAndStringify("$foo 47 -")); 86 87 EXPECT_EQ("nullptr", ParseAndStringify("+")); 88 EXPECT_EQ("nullptr", ParseAndStringify("^")); 89 EXPECT_EQ("nullptr", ParseAndStringify("1 +")); 90 EXPECT_EQ("nullptr", ParseAndStringify("1 2 ^")); 91 EXPECT_EQ("nullptr", ParseAndStringify("1 2 3 +")); 92 EXPECT_EQ("nullptr", ParseAndStringify("^ 1")); 93 EXPECT_EQ("nullptr", ParseAndStringify("+ 1 2")); 94 EXPECT_EQ("nullptr", ParseAndStringify("1 + 2")); 95 EXPECT_EQ("nullptr", ParseAndStringify("1 2")); 96 EXPECT_EQ("nullptr", ParseAndStringify("")); 97 } 98