================ @@ -0,0 +1,446 @@ +//===-- DILAST.h ------------------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_DIL_AST_H_ +#define LLDB_DIL_AST_H_ + +#include <memory> +#include <optional> +#include <string> +#include <variant> +#include <vector> + +#include "lldb/Core/ValueObject.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/Utility/ConstString.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" + +namespace lldb_private { + +/// Struct to hold information about member fields. Used by the parser for the +/// Data Inspection Language (DIL). +struct DILMemberInfo { + std::optional<std::string> name; + CompilerType type; + bool is_bitfield; + uint32_t bitfield_size_in_bits; + bool is_synthetic; + bool is_dynamic; + lldb::ValueObjectSP val_obj_sp; + + explicit operator bool() const { return type.IsValid(); } +}; + +/// This determines if the type is a shared, unique or weak pointer, either +/// from stdlibc++ or libc+++. +bool IsSmartPtrType(CompilerType type); + +/// Finds the member field with the given name and type, stores the child index +/// corresponding to the field in the idx vector and returns a DILMemberInfo +/// struct with appropriate information about the field. +DILMemberInfo GetFieldWithNameIndexPath(lldb::ValueObjectSP lhs_val_sp, + CompilerType type, + const std::string &name, + std::vector<uint32_t> *idx, + CompilerType empty_type, + bool use_synthetic, bool is_dynamic); + +std::tuple<DILMemberInfo, std::vector<uint32_t>> +GetMemberInfo(lldb::ValueObjectSP lhs_val_sp, CompilerType type, + const std::string &name, bool use_synthetic); + +/// Get the appropriate ValueObjectSP, consulting the use_dynamic and +/// use_synthetic options passed, acquiring the process & target locks if +/// appropriate. +lldb::ValueObjectSP +DILGetSPWithLock(lldb::ValueObjectSP valobj_sp, + lldb::DynamicValueType use_dynamic = lldb::eNoDynamicValues, + bool use_synthetic = false); + +/// The various types DIL AST nodes (used by the DIL parser). +enum class DILNodeKind { + kDILErrorNode, + kLiteralNode, + kIdentifierNode, + kBuiltinFunctionCallNode, + kCStyleCastNode, + kMemberOfNode, + kArraySubscriptNode, + kUnaryOpNode, + kSmartPtrToPtrDecay +}; + +/// The C-Style casts allowed by DIL. +enum class CStyleCastKind { + kArithmetic, + kEnumeration, + kPointer, + kNullptr, + kReference, +}; + +/// The Unary operators recognized by DIL. +enum class UnaryOpKind { + AddrOf, // "&" + Deref, // "*" + Minus, // "-" +}; + +/// Given a string representing a type, returns the CompilerType corresponding +/// to the named type, if it exists. +CompilerType +ResolveTypeByName(const std::string &name, + std::shared_ptr<ExecutionContextScope> ctx_scope); + +/// Quick lookup to check if a type name already exists in a +/// name-to-CompilerType map the DIL parser keeps of previously found +/// name/type pairs. +bool IsContextVar(const std::string &name); + +/// Checks to see if the CompilerType is a Smart Pointer (shared, unique, weak) +/// or not. Only applicable for C++, which is why this is here and not part of +/// the CompilerType class. +bool IsSmartPtrType(CompilerType type); + +/// Class used to store & manipulate information about identifiers. +class IdentifierInfo { +private: + using MemberPath = std::vector<uint32_t>; + using IdentifierInfoPtr = std::unique_ptr<IdentifierInfo>; + +public: + enum class Kind { + kValue, + kContextArg, + kMemberPath, + kThisKeyword, + }; + + static IdentifierInfoPtr FromValue(lldb::ValueObjectSP value_sp) { + CompilerType type; + lldb::ValueObjectSP value = DILGetSPWithLock(value_sp); + if (value) + type = value->GetCompilerType(); + return IdentifierInfoPtr(new IdentifierInfo(Kind::kValue, type, value, {})); + } + + static IdentifierInfoPtr FromContextArg(CompilerType type) { + lldb::ValueObjectSP empty_value; + return IdentifierInfoPtr( + new IdentifierInfo(Kind::kContextArg, type, empty_value, {})); + } + + static IdentifierInfoPtr FromMemberPath(CompilerType type, MemberPath path) { + lldb::ValueObjectSP empty_value; + return IdentifierInfoPtr(new IdentifierInfo(Kind::kMemberPath, type, + empty_value, std::move(path))); + } + + static IdentifierInfoPtr FromThisKeyword(CompilerType type) { + lldb::ValueObjectSP empty_value; + return IdentifierInfoPtr( + new IdentifierInfo(Kind::kThisKeyword, type, empty_value, {})); + } + + Kind kind() const { return m_kind; } + lldb::ValueObjectSP value() const { return m_value; } + const MemberPath &path() const { return m_path; } + + CompilerType GetType() { return m_type; } + bool IsValid() const { return m_type.IsValid(); } + + IdentifierInfo(Kind kind, CompilerType type, lldb::ValueObjectSP value, + MemberPath path) + : m_kind(kind), m_type(type), m_value(std::move(value)), + m_path(std::move(path)) {} + +private: + Kind m_kind; + CompilerType m_type; + lldb::ValueObjectSP m_value; + MemberPath m_path; +}; + +/// Given the name of an identifier (variable name, member name, type name, +/// etc.), find the ValueObject for that name (if it exists) and create and +/// return an IdentifierInfo object containing all the relevant information +/// about that object (for DIL parsing and evaluating). +std::unique_ptr<IdentifierInfo> LookupIdentifier( + const std::string &name, std::shared_ptr<ExecutionContextScope> ctx_scope, + lldb::DynamicValueType use_dynamic, CompilerType *scope_ptr = nullptr); + +/// Forward declaration, for use in DIL AST nodes. Definition is at the very +/// end of this file. +class DILVisitor; + +/// The rest of the classes in this file, except for the DILVisitor class at the +/// very end, define all the types of AST nodes used by the DIL parser and +/// expression evaluator. The DIL parser parses the input string and creates the +/// AST parse tree from the AST nodes. The resulting AST node tree gets passed +/// to the DIL expression evaluator, which evaluates the DIL AST nodes and +/// creates/returns a ValueObjectSP containing the result. + +/// Base class for AST nodes used by the Data Inspection Language (DIL) parser. +/// All of the specialized types of AST nodes inherit from this (virtual) base +/// class. +class DILASTNode { +public: + DILASTNode(clang::SourceLocation location) : location_(location) {} + virtual ~DILASTNode() {} + + virtual void Accept(DILVisitor *v) const = 0; + + virtual bool is_error() const { return false; }; + virtual bool is_rvalue() const = 0; + virtual bool is_bitfield() const { return false; }; + virtual bool is_context_var() const { return false; }; + virtual bool is_literal_zero() const { return false; } + virtual uint32_t bitfield_size() const { return 0; } + virtual CompilerType result_type() const = 0; + + virtual DILNodeKind what_am_i() const = 0; + + clang::SourceLocation location() const { return location_; } + + // The expression result type, but dereferenced in case it's a reference. This + // is for convenience, since for the purposes of the semantic analysis only + // the dereferenced type matters. + CompilerType result_type_deref() const; + +private: + clang::SourceLocation location_; ---------------- cmtice wrote:
Done. https://github.com/llvm/llvm-project/pull/95738 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits