Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
39654 views
//===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H9#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H1011#include <optional>12#include <vector>1314#include "ASTResultSynthesizer.h"15#include "ASTStructExtractor.h"16#include "ClangExpressionDeclMap.h"17#include "ClangExpressionHelper.h"18#include "ClangExpressionSourceCode.h"19#include "ClangExpressionVariable.h"20#include "IRForTarget.h"2122#include "lldb/Core/Address.h"23#include "lldb/Expression/LLVMUserExpression.h"24#include "lldb/Expression/Materializer.h"25#include "lldb/Target/ExecutionContext.h"26#include "lldb/lldb-forward.h"27#include "lldb/lldb-private.h"2829namespace lldb_private {3031class ClangExpressionParser;3233/// \class ClangUserExpression ClangUserExpression.h34/// "lldb/Expression/ClangUserExpression.h" Encapsulates a single expression35/// for use with Clang36///37/// LLDB uses expressions for various purposes, notably to call functions38/// and as a backend for the expr command. ClangUserExpression encapsulates39/// the objects needed to parse and interpret or JIT an expression. It uses40/// the Clang parser to produce LLVM IR from the expression.41class ClangUserExpression : public LLVMUserExpression {42// LLVM RTTI support43static char ID;4445public:46bool isA(const void *ClassID) const override {47return ClassID == &ID || LLVMUserExpression::isA(ClassID);48}49static bool classof(const Expression *obj) { return obj->isA(&ID); }5051enum { kDefaultTimeout = 500000u };5253class ClangUserExpressionHelper54: public llvm::RTTIExtends<ClangUserExpressionHelper,55ClangExpressionHelper> {56public:57// LLVM RTTI support58static char ID;5960ClangUserExpressionHelper(Target &target, bool top_level)61: m_target(target), m_top_level(top_level) {}6263/// Return the object that the parser should use when resolving external64/// values. May be NULL if everything should be self-contained.65ClangExpressionDeclMap *DeclMap() override {66return m_expr_decl_map_up.get();67}6869void ResetDeclMap() { m_expr_decl_map_up.reset(); }7071void ResetDeclMap(ExecutionContext &exe_ctx,72Materializer::PersistentVariableDelegate &result_delegate,73bool keep_result_in_memory,74ValueObject *ctx_obj);7576/// Return the object that the parser should allow to access ASTs. May be77/// NULL if the ASTs do not need to be transformed.78///79/// \param[in] passthrough80/// The ASTConsumer that the returned transformer should send81/// the ASTs to after transformation.82clang::ASTConsumer *83ASTTransformer(clang::ASTConsumer *passthrough) override;8485void CommitPersistentDecls() override;8687private:88Target &m_target;89std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;90std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class91///that generates92///the argument93///struct layout.94std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;95bool m_top_level;96};9798/// Constructor99///100/// \param[in] expr101/// The expression to parse.102///103/// \param[in] prefix104/// If non-NULL, a C string containing translation-unit level105/// definitions to be included when the expression is parsed.106///107/// \param[in] language108/// If not unknown, a language to use when parsing the109/// expression. Currently restricted to those languages110/// supported by Clang.111///112/// \param[in] desired_type113/// If not eResultTypeAny, the type to use for the expression114/// result.115///116/// \param[in] options117/// Additional options for the expression.118///119/// \param[in] ctx_obj120/// The object (if any) in which context the expression121/// must be evaluated. For details see the comment to122/// `UserExpression::Evaluate`.123ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,124llvm::StringRef prefix, SourceLanguage language,125ResultType desired_type,126const EvaluateExpressionOptions &options,127ValueObject *ctx_obj);128129~ClangUserExpression() override;130131/// Parse the expression132///133/// \param[in] diagnostic_manager134/// A diagnostic manager to report parse errors and warnings to.135///136/// \param[in] exe_ctx137/// The execution context to use when looking up entities that138/// are needed for parsing (locations of functions, types of139/// variables, persistent variables, etc.)140///141/// \param[in] execution_policy142/// Determines whether interpretation is possible or mandatory.143///144/// \param[in] keep_result_in_memory145/// True if the resulting persistent variable should reside in146/// target memory, if applicable.147///148/// \return149/// True on success (no errors); false otherwise.150bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,151lldb_private::ExecutionPolicy execution_policy,152bool keep_result_in_memory, bool generate_debug_info) override;153154bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request,155unsigned complete_pos) override;156157ExpressionTypeSystemHelper *GetTypeSystemHelper() override {158return &m_type_system_helper;159}160161ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }162163void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }164165void ResetDeclMap(ExecutionContext &exe_ctx,166Materializer::PersistentVariableDelegate &result_delegate,167bool keep_result_in_memory) {168m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,169keep_result_in_memory,170m_ctx_obj);171}172173lldb::ExpressionVariableSP174GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;175176/// Returns true iff this expression is using any imported C++ modules.177bool DidImportCxxModules() const { return !m_imported_cpp_modules.empty(); }178179private:180/// Populate m_in_cplusplus_method and m_in_objectivec_method based on the181/// environment.182183/// Contains the actual parsing implementation.184/// The parameter have the same meaning as in ClangUserExpression::Parse.185/// \see ClangUserExpression::Parse186bool TryParse(DiagnosticManager &diagnostic_manager,187ExecutionContext &exe_ctx,188lldb_private::ExecutionPolicy execution_policy,189bool keep_result_in_memory, bool generate_debug_info);190191void SetupCppModuleImports(ExecutionContext &exe_ctx);192193void ScanContext(ExecutionContext &exe_ctx,194lldb_private::Status &err) override;195196bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,197lldb::addr_t struct_address,198DiagnosticManager &diagnostic_manager) override;199200void CreateSourceCode(DiagnosticManager &diagnostic_manager,201ExecutionContext &exe_ctx,202std::vector<std::string> modules_to_import,203bool for_completion);204205lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame,206llvm::StringRef object_name, Status &err);207208/// Defines how the current expression should be wrapped.209ClangExpressionSourceCode::WrapKind GetWrapKind() const;210bool SetupPersistentState(DiagnosticManager &diagnostic_manager,211ExecutionContext &exe_ctx);212bool PrepareForParsing(DiagnosticManager &diagnostic_manager,213ExecutionContext &exe_ctx, bool for_completion);214215ClangUserExpressionHelper m_type_system_helper;216217class ResultDelegate : public Materializer::PersistentVariableDelegate {218public:219ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {}220ConstString GetName() override;221void DidDematerialize(lldb::ExpressionVariableSP &variable) override;222223void RegisterPersistentState(PersistentExpressionState *persistent_state);224lldb::ExpressionVariableSP &GetVariable();225226private:227PersistentExpressionState *m_persistent_state;228lldb::ExpressionVariableSP m_variable;229lldb::TargetSP m_target_sp;230};231232/// The include directories that should be used when parsing the expression.233std::vector<std::string> m_include_directories;234235/// The absolute character position in the transformed source code where the236/// user code (as typed by the user) starts. If the variable is empty, then we237/// were not able to calculate this position.238std::optional<size_t> m_user_expression_start_pos;239ResultDelegate m_result_delegate;240ClangPersistentVariables *m_clang_state;241std::unique_ptr<ClangExpressionSourceCode> m_source_code;242/// The parser instance we used to parse the expression.243std::unique_ptr<ClangExpressionParser> m_parser;244/// File name used for the expression.245std::string m_filename;246247/// The object (if any) in which context the expression is evaluated.248/// See the comment to `UserExpression::Evaluate` for details.249ValueObject *m_ctx_obj;250251/// A list of module names that should be imported when parsing.252/// \see CppModuleConfiguration::GetImportedModules253std::vector<std::string> m_imported_cpp_modules;254255/// True if the expression parser should enforce the presence of a valid class256/// pointer in order to generate the expression as a method.257bool m_enforce_valid_object = true;258/// True if the expression is compiled as a C++ member function (true if it259/// was parsed when exe_ctx was in a C++ method).260bool m_in_cplusplus_method = false;261/// True if the expression is compiled as an Objective-C method (true if it262/// was parsed when exe_ctx was in an Objective-C method).263bool m_in_objectivec_method = false;264/// True if the expression is compiled as a static (or class) method265/// (currently true if it was parsed when exe_ctx was in an Objective-C class266/// method).267bool m_in_static_method = false;268/// True if "this" or "self" must be looked up and passed in. False if the269/// expression doesn't really use them and they can be NULL.270bool m_needs_object_ptr = false;271};272273} // namespace lldb_private274275#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H276277278