Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
39648 views
//===-- ClangExpressionDeclMap.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_CLANGEXPRESSIONDECLMAP_H9#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H1011#include <csignal>12#include <cstdint>1314#include <memory>15#include <vector>1617#include "ClangASTSource.h"18#include "ClangExpressionVariable.h"1920#include "lldb/Core/Value.h"21#include "lldb/Expression/Materializer.h"22#include "lldb/Symbol/SymbolContext.h"23#include "lldb/Symbol/TaggedASTType.h"24#include "lldb/Target/ExecutionContext.h"25#include "lldb/lldb-public.h"26#include "clang/AST/Decl.h"27#include "llvm/ADT/DenseMap.h"2829namespace lldb_private {3031class ClangPersistentVariables;3233/// \class ClangExpressionDeclMap ClangExpressionDeclMap.h34/// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are35/// defined in LLDB's debug information.36///37/// The Clang parser uses the ClangASTSource as an interface to request named38/// entities from outside an expression. The ClangASTSource reports back,39/// listing all possible objects corresponding to a particular name. But it40/// in turn relies on ClangExpressionDeclMap, which performs several important41/// functions.42///43/// First, it records what variables and functions were looked up and what44/// Decls were returned for them.45///46/// Second, it constructs a struct on behalf of IRForTarget, recording which47/// variables should be placed where and relaying this information back so48/// that IRForTarget can generate context-independent code.49///50/// Third, it "materializes" this struct on behalf of the expression command,51/// finding the current values of each variable and placing them into the52/// struct so that it can be passed to the JITted version of the IR.53///54/// Fourth and finally, it "dematerializes" the struct after the JITted code55/// has executed, placing the new values back where it found the old ones.56class ClangExpressionDeclMap : public ClangASTSource {57public:58/// Constructor59///60/// Initializes class variables.61///62/// \param[in] keep_result_in_memory63/// If true, inhibits the normal deallocation of the memory for64/// the result persistent variable, and instead marks the variable65/// as persisting.66///67/// \param[in] result_delegate68/// If non-NULL, use this delegate to report result values. This69/// allows the client ClangUserExpression to report a result.70///71/// \param[in] target72/// The target to use when parsing.73///74/// \param[in] importer75/// The ClangASTImporter to use when parsing.76///77/// \param[in] ctx_obj78/// If not empty, then expression is evaluated in context of this object.79/// See the comment to `UserExpression::Evaluate` for details.80ClangExpressionDeclMap(81bool keep_result_in_memory,82Materializer::PersistentVariableDelegate *result_delegate,83const lldb::TargetSP &target,84const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);8586/// Destructor87~ClangExpressionDeclMap() override;8889/// Enable the state needed for parsing and IR transformation.90///91/// \param[in] exe_ctx92/// The execution context to use when finding types for variables.93/// Also used to find a "scratch" AST context to store result types.94///95/// \param[in] materializer96/// If non-NULL, the materializer to populate with information about97/// the variables to use98///99/// \return100/// True if parsing is possible; false if it is unsafe to continue.101bool WillParse(ExecutionContext &exe_ctx, Materializer *materializer);102103void InstallCodeGenerator(clang::ASTConsumer *code_gen);104105void InstallDiagnosticManager(DiagnosticManager &diag_manager);106107/// Disable the state needed for parsing and IR transformation.108void DidParse();109110/// [Used by IRForTarget] Add a variable to the list of persistent111/// variables for the process.112///113/// \param[in] decl114/// The Clang declaration for the persistent variable, used for115/// lookup during parsing.116///117/// \param[in] name118/// The name of the persistent variable, usually $something.119///120/// \param[in] type121/// The type of the variable, in the Clang parser's context.122///123/// \return124/// True on success; false otherwise.125bool AddPersistentVariable(const clang::NamedDecl *decl,126ConstString name, TypeFromParser type,127bool is_result, bool is_lvalue);128129/// [Used by IRForTarget] Add a variable to the struct that needs to130/// be materialized each time the expression runs.131///132/// \param[in] decl133/// The Clang declaration for the variable.134///135/// \param[in] name136/// The name of the variable.137///138/// \param[in] value139/// The LLVM IR value for this variable.140///141/// \param[in] size142/// The size of the variable in bytes.143///144/// \param[in] alignment145/// The required alignment of the variable in bytes.146///147/// \return148/// True on success; false otherwise.149bool AddValueToStruct(const clang::NamedDecl *decl, ConstString name,150llvm::Value *value, size_t size,151lldb::offset_t alignment);152153/// [Used by IRForTarget] Finalize the struct, laying out the position of154/// each object in it.155///156/// \return157/// True on success; false otherwise.158bool DoStructLayout();159160/// [Used by IRForTarget] Get general information about the laid-out struct161/// after DoStructLayout() has been called.162///163/// \param[out] num_elements164/// The number of elements in the struct.165///166/// \param[out] size167/// The size of the struct, in bytes.168///169/// \param[out] alignment170/// The alignment of the struct, in bytes.171///172/// \return173/// True if the information could be retrieved; false otherwise.174bool GetStructInfo(uint32_t &num_elements, size_t &size,175lldb::offset_t &alignment);176177/// [Used by IRForTarget] Get specific information about one field of the178/// laid-out struct after DoStructLayout() has been called.179///180/// \param[out] decl181/// The parsed Decl for the field, as generated by ClangASTSource182/// on ClangExpressionDeclMap's behalf. In the case of the result183/// value, this will have the name $__lldb_result even if the184/// result value ends up having the name $1. This is an185/// implementation detail of IRForTarget.186///187/// \param[out] value188/// The IR value for the field (usually a GlobalVariable). In189/// the case of the result value, this will have the correct190/// name ($1, for instance). This is an implementation detail191/// of IRForTarget.192///193/// \param[out] offset194/// The offset of the field from the beginning of the struct.195/// As long as the struct is aligned according to its required196/// alignment, this offset will align the field correctly.197///198/// \param[out] name199/// The name of the field as used in materialization.200///201/// \param[in] index202/// The index of the field about which information is requested.203///204/// \return205/// True if the information could be retrieved; false otherwise.206bool GetStructElement(const clang::NamedDecl *&decl, llvm::Value *&value,207lldb::offset_t &offset, ConstString &name,208uint32_t index);209210/// [Used by IRForTarget] Get information about a function given its Decl.211///212/// \param[in] decl213/// The parsed Decl for the Function, as generated by ClangASTSource214/// on ClangExpressionDeclMap's behalf.215///216/// \param[out] ptr217/// The absolute address of the function in the target.218///219/// \return220/// True if the information could be retrieved; false otherwise.221bool GetFunctionInfo(const clang::NamedDecl *decl, uint64_t &ptr);222223/// [Used by IRForTarget] Get the address of a symbol given nothing but its224/// name.225///226/// \param[in] target227/// The target to find the symbol in. If not provided,228/// then the current parsing context's Target.229///230/// \param[in] process231/// The process to use. For Objective-C symbols, the process's232/// Objective-C language runtime may be queried if the process233/// is non-NULL.234///235/// \param[in] name236/// The name of the symbol.237///238/// \param[in] module239/// The module to limit the search to. This can be NULL240///241/// \return242/// Valid load address for the symbol243lldb::addr_t GetSymbolAddress(Target &target, Process *process,244ConstString name, lldb::SymbolType symbol_type,245Module *module = nullptr);246247lldb::addr_t GetSymbolAddress(ConstString name,248lldb::SymbolType symbol_type);249250struct TargetInfo {251lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;252size_t address_byte_size = 0;253254TargetInfo() = default;255256bool IsValid() {257return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);258}259};260TargetInfo GetTargetInfo();261262/// [Used by ClangASTSource] Find all entities matching a given name, using263/// a NameSearchContext to make Decls for them.264///265/// \param[in] context266/// The NameSearchContext that can construct Decls for this name.267void FindExternalVisibleDecls(NameSearchContext &context) override;268269/// Find all entities matching a given name in a given module/namespace,270/// using a NameSearchContext to make Decls for them.271///272/// \param[in] context273/// The NameSearchContext that can construct Decls for this name.274///275/// \param[in] module276/// If non-NULL, the module to query.277///278/// \param[in] namespace_decl279/// If valid and module is non-NULL, the parent namespace.280void FindExternalVisibleDecls(NameSearchContext &context,281lldb::ModuleSP module,282const CompilerDeclContext &namespace_decl);283284protected:285/// Retrieves the declaration with the given name from the storage of286/// persistent declarations.287///288/// \return289/// A persistent decl with the given name or a nullptr.290virtual clang::NamedDecl *GetPersistentDecl(ConstString name);291292private:293ExpressionVariableList294m_found_entities; ///< All entities that were looked up for the parser.295ExpressionVariableList296m_struct_members; ///< All entities that need to be placed in the struct.297bool m_keep_result_in_memory; ///< True if result persistent variables298///generated by this expression should stay in299///memory.300Materializer::PersistentVariableDelegate301*m_result_delegate; ///< If non-NULL, used to report expression results to302///ClangUserExpression.303ValueObject *m_ctx_obj; ///< If not empty, then expression is304///evaluated in context of this object.305///For details see the comment to306///`UserExpression::Evaluate`.307308/// The following values should not live beyond parsing309class ParserVars {310public:311ParserVars() = default;312313Target *GetTarget() {314if (m_exe_ctx.GetTargetPtr())315return m_exe_ctx.GetTargetPtr();316else if (m_sym_ctx.target_sp)317return m_sym_ctx.target_sp.get();318return nullptr;319}320321ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.322SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables323///and types.324ClangPersistentVariables *m_persistent_vars =325nullptr; ///< The persistent variables for the process.326bool m_enable_lookups = false; ///< Set to true during parsing if we have327///found the first "$__lldb" name.328TargetInfo m_target_info; ///< Basic information about the target.329Materializer *m_materializer = nullptr; ///< If non-NULL, the materializer330///to use when reporting used331///variables.332clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator333///that receives new top-level334///functions.335DiagnosticManager *m_diagnostics = nullptr;336337private:338ParserVars(const ParserVars &) = delete;339const ParserVars &operator=(const ParserVars &) = delete;340};341342std::unique_ptr<ParserVars> m_parser_vars;343344/// Activate parser-specific variables345void EnableParserVars() {346if (!m_parser_vars.get())347m_parser_vars = std::make_unique<ParserVars>();348}349350/// Deallocate parser-specific variables351void DisableParserVars() { m_parser_vars.reset(); }352353/// The following values contain layout information for the materialized354/// struct, but are not specific to a single materialization355struct StructVars {356StructVars() = default;357358lldb::offset_t m_struct_alignment =3590; ///< The alignment of the struct in bytes.360size_t m_struct_size = 0; ///< The size of the struct in bytes.361bool m_struct_laid_out =362false; ///< True if the struct has been laid out and the363/// layout is valid (that is, no new fields have been364/// added since).365ConstString366m_result_name; ///< The name of the result variable ($1, for example)367};368369std::unique_ptr<StructVars> m_struct_vars;370371/// Activate struct variables372void EnableStructVars() {373if (!m_struct_vars.get())374m_struct_vars.reset(new struct StructVars);375}376377/// Deallocate struct variables378void DisableStructVars() { m_struct_vars.reset(); }379380lldb::TypeSystemClangSP GetScratchContext(Target &target) {381return ScratchTypeSystemClang::GetForTarget(target,382m_ast_context->getLangOpts());383}384385/// Get this parser's ID for use in extracting parser- and JIT-specific data386/// from persistent variables.387uint64_t GetParserID() { return (uint64_t) this; }388389/// Should be called on all copied functions.390void MaybeRegisterFunctionBody(clang::FunctionDecl *copied_function_decl);391392/// Searches the persistent decls of the target for entities with the393/// given name.394///395/// \param[in] context396/// The NameSearchContext that can construct Decls for this name.397///398/// \param[in] name399/// The name of the entities that need to be found.400void SearchPersistenDecls(NameSearchContext &context, const ConstString name);401402/// Handles looking up $__lldb_class which requires special treatment.403///404/// \param[in] context405/// The NameSearchContext that can construct Decls for this name.406void LookUpLldbClass(NameSearchContext &context);407408/// Handles looking up $__lldb_objc_class which requires special treatment.409///410/// \param[in] context411/// The NameSearchContext that can construct Decls for this name.412void LookUpLldbObjCClass(NameSearchContext &context);413414/// Handles looking up the synthetic namespace that contains our local415/// variables for the current frame.416///417/// \param[in] sym_ctx418/// The current SymbolContext of this frame.419///420/// \param[in] name_context421/// The NameSearchContext that can construct Decls for this name.422void LookupLocalVarNamespace(SymbolContext &sym_ctx,423NameSearchContext &name_context);424425/// Lookup entities in the ClangModulesDeclVendor.426/// \param[in] context427/// The NameSearchContext that can construct Decls for this name.428///429/// \param[in] name430/// The name of the entities that need to be found.431void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name);432433/// Looks up a local variable.434///435/// \param[in] context436/// The NameSearchContext that can construct Decls for this name.437///438/// \param[in] name439/// The name of the entities that need to be found.440///441/// \param[in] sym_ctx442/// The current SymbolContext of this frame.443///444/// \param[in] namespace_decl445/// The parent namespace if there is one.446///447/// \return448/// True iff a local variable was found.449bool LookupLocalVariable(NameSearchContext &context, ConstString name,450SymbolContext &sym_ctx,451const CompilerDeclContext &namespace_decl);452453/// Searches for functions in the given SymbolContextList.454///455/// \param[in] sc_list456/// The SymbolContextList to search.457///458/// \param[in] frame_decl_context459/// The current DeclContext of the current frame.460///461/// \return462/// A SymbolContextList with any found functions in the front and463/// any unknown SymbolContexts which are not functions in the back.464/// The SymbolContexts for the functions are ordered by how close they are465/// to the DeclContext for the given frame DeclContext.466SymbolContextList SearchFunctionsInSymbolContexts(467const SymbolContextList &sc_list,468const CompilerDeclContext &frame_decl_context);469470/// Looks up a function.471///472/// \param[in] context473/// The NameSearchContext that can construct Decls for this name.474///475/// \param[in] module_sp476/// If non-NULL, the module to query.477///478/// \param[in] name479/// The name of the function that should be find.480///481/// \param[in] namespace_decl482/// If valid and module is non-NULL, the parent namespace.483void LookupFunction(NameSearchContext &context, lldb::ModuleSP module_sp,484ConstString name,485const CompilerDeclContext &namespace_decl);486487/// Given a target, find a variable that matches the given name and type.488///489/// \param[in] target490/// The target to use as a basis for finding the variable.491///492/// \param[in] module493/// If non-NULL, the module to search.494///495/// \param[in] name496/// The name as a plain C string.497///498/// \param[in] namespace_decl499/// If non-NULL and module is non-NULL, the parent namespace.500///501/// \return502/// The LLDB Variable found, or NULL if none was found.503lldb::VariableSP504FindGlobalVariable(Target &target, lldb::ModuleSP &module, ConstString name,505const CompilerDeclContext &namespace_decl);506507/// Get the value of a variable in a given execution context and return the508/// associated Types if needed.509///510/// \param[in] var511/// The variable to evaluate.512///513/// \param[out] var_location514/// The variable location value to fill in515///516/// \param[out] found_type517/// The type of the found value, as it was found in the user process.518/// This is only useful when the variable is being inspected on behalf519/// of the parser, hence the default.520///521/// \param[out] parser_type522/// The type of the found value, as it was copied into the parser's523/// AST context. This is only useful when the variable is being524/// inspected on behalf of the parser, hence the default.525///526/// \return527/// Return true if the value was successfully filled in.528bool GetVariableValue(lldb::VariableSP &var,529lldb_private::Value &var_location,530TypeFromUser *found_type = nullptr,531TypeFromParser *parser_type = nullptr);532533/// Use the NameSearchContext to generate a Decl for the given LLDB534/// ValueObject, and put it in the list of found entities.535///536/// Helper function used by the other AddOneVariable APIs.537///538/// \param[in,out] context539/// The NameSearchContext to use when constructing the Decl.540///541/// \param[in] pt542/// The CompilerType of the variable we're adding a Decl for.543///544/// \param[in] var545/// The LLDB ValueObject that needs a Decl.546ClangExpressionVariable::ParserVars *547AddExpressionVariable(NameSearchContext &context, TypeFromParser const &pt,548lldb::ValueObjectSP valobj);549550/// Use the NameSearchContext to generate a Decl for the given LLDB551/// Variable, and put it in the Tuple list.552///553/// \param[in] context554/// The NameSearchContext to use when constructing the Decl.555///556/// \param[in] var557/// The LLDB Variable that needs a Decl.558///559/// \param[in] valobj560/// The LLDB ValueObject for that variable.561void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,562lldb::ValueObjectSP valobj);563564/// Use the NameSearchContext to generate a Decl for the given ValueObject565/// and put it in the list of found entities.566///567/// \param[in,out] context568/// The NameSearchContext to use when constructing the Decl.569///570/// \param[in] valobj571/// The ValueObject that needs a Decl.572///573/// \param[in] valobj_provider Callback that fetches a ValueObjectSP574/// from the specified frame575void AddOneVariable(NameSearchContext &context, lldb::ValueObjectSP valobj,576ValueObjectProviderTy valobj_provider);577578/// Use the NameSearchContext to generate a Decl for the given persistent579/// variable, and put it in the list of found entities.580///581/// \param[in] context582/// The NameSearchContext to use when constructing the Decl.583///584/// \param[in] pvar_sp585/// The persistent variable that needs a Decl.586void AddOneVariable(NameSearchContext &context,587lldb::ExpressionVariableSP &pvar_sp);588589/// Use the NameSearchContext to generate a Decl for the given LLDB symbol590/// (treated as a variable), and put it in the list of found entities.591void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol);592593/// Use the NameSearchContext to generate a Decl for the given function.594/// (Functions are not placed in the Tuple list.) Can handle both fully595/// typed functions and generic functions.596///597/// \param[in] context598/// The NameSearchContext to use when constructing the Decl.599///600/// \param[in] fun601/// The Function that needs to be created. If non-NULL, this is602/// a fully-typed function.603///604/// \param[in] sym605/// The Symbol that corresponds to a function that needs to be606/// created with generic type (unitptr_t foo(...)).607void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);608609/// Use the NameSearchContext to generate a Decl for the given register.610///611/// \param[in] context612/// The NameSearchContext to use when constructing the Decl.613///614/// \param[in] reg_info615/// The information corresponding to that register.616void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info);617618/// Use the NameSearchContext to generate a Decl for the given type. (Types619/// are not placed in the Tuple list.)620///621/// \param[in] context622/// The NameSearchContext to use when constructing the Decl.623///624/// \param[in] type625/// The type that needs to be created.626void AddOneType(NameSearchContext &context, const TypeFromUser &type);627628/// Adds the class in which the expression is evaluated to the lookup and629/// prepares the class to be used as a context for expression evaluation (for630/// example, it creates a fake member function that will contain the631/// expression LLDB is trying to evaluate).632///633/// \param[in] context634/// The NameSearchContext to which the class should be added as a lookup635/// result.636///637/// \param[in] type638/// The type of the class that serves as the evaluation context.639void AddContextClassType(NameSearchContext &context,640const TypeFromUser &type);641642/// Move a type out of the current ASTContext into another, but make sure to643/// export all components of the type also.644///645/// \param[in] target646/// The TypeSystemClang to move to.647/// \param[in] source648/// The TypeSystemClang to move from. This is assumed to be going away.649/// \param[in] parser_type650/// The type as it appears in the source context.651///652/// \return653/// Returns the moved type, or an empty type if there was a problem.654TypeFromUser DeportType(TypeSystemClang &target, TypeSystemClang &source,655TypeFromParser parser_type);656657TypeSystemClang *GetTypeSystemClang();658};659660} // namespace lldb_private661662#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H663664665