1 //===-- PostfixExpression.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 // This file implements support for postfix expressions found in several symbol 10 // file formats, and their conversion to DWARF. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "lldb/Symbol/PostfixExpression.h" 15 #include "llvm/ADT/StringExtras.h" 16 17 using namespace lldb_private; 18 using namespace lldb_private::postfix; 19 20 static llvm::Optional<BinaryOpNode::OpType> 21 GetBinaryOpType(llvm::StringRef token) { 22 if (token.size() != 1) 23 return llvm::None; 24 switch (token[0]) { 25 case '@': 26 return BinaryOpNode::Align; 27 case '-': 28 return BinaryOpNode::Minus; 29 case '+': 30 return BinaryOpNode::Plus; 31 } 32 return llvm::None; 33 } 34 35 static llvm::Optional<UnaryOpNode::OpType> 36 GetUnaryOpType(llvm::StringRef token) { 37 if (token == "^") 38 return UnaryOpNode::Deref; 39 return llvm::None; 40 } 41 42 Node *postfix::Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc) { 43 llvm::SmallVector<Node *, 4> stack; 44 45 llvm::StringRef token; 46 while (std::tie(token, expr) = getToken(expr), !token.empty()) { 47 if (auto op_type = GetBinaryOpType(token)) { 48 // token is binary operator 49 if (stack.size() < 2) 50 return nullptr; 51 52 Node *right = stack.pop_back_val(); 53 Node *left = stack.pop_back_val(); 54 stack.push_back(MakeNode<BinaryOpNode>(alloc, *op_type, *left, *right)); 55 continue; 56 } 57 58 if (auto op_type = GetUnaryOpType(token)) { 59 // token is unary operator 60 if (stack.empty()) 61 return nullptr; 62 63 Node *operand = stack.pop_back_val(); 64 stack.push_back(MakeNode<UnaryOpNode>(alloc, *op_type, *operand)); 65 continue; 66 } 67 68 uint32_t value; 69 if (to_integer(token, value, 10)) { 70 // token is integer literal 71 stack.push_back(MakeNode<IntegerNode>(alloc, value)); 72 continue; 73 } 74 75 stack.push_back(MakeNode<SymbolNode>(alloc, token)); 76 } 77 78 if (stack.size() != 1) 79 return nullptr; 80 81 return stack.back(); 82 } 83