brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.6 KiB · dddc5a0 Raw
667 lines · c
1//===-- ClangExpressionDeclMap.h --------------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H10#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H11 12#include <csignal>13#include <cstdint>14 15#include <memory>16#include <vector>17 18#include "ClangASTSource.h"19#include "ClangExpressionVariable.h"20 21#include "lldb/Core/Value.h"22#include "lldb/Expression/Materializer.h"23#include "lldb/Symbol/SymbolContext.h"24#include "lldb/Symbol/TaggedASTType.h"25#include "lldb/Target/ExecutionContext.h"26#include "lldb/lldb-public.h"27#include "clang/AST/Decl.h"28#include "llvm/ADT/DenseMap.h"29 30namespace lldb_private {31 32class ClangPersistentVariables;33 34/// \class ClangExpressionDeclMap ClangExpressionDeclMap.h35/// "lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are36/// defined in LLDB's debug information.37///38/// The Clang parser uses the ClangASTSource as an interface to request named39/// entities from outside an expression.  The ClangASTSource reports back,40/// listing all possible objects corresponding to a particular name.  But it41/// in turn relies on ClangExpressionDeclMap, which performs several important42/// functions.43///44/// First, it records what variables and functions were looked up and what45/// Decls were returned for them.46///47/// Second, it constructs a struct on behalf of IRForTarget, recording which48/// variables should be placed where and relaying this information back so49/// that IRForTarget can generate context-independent code.50///51/// Third, it "materializes" this struct on behalf of the expression command,52/// finding the current values of each variable and placing them into the53/// struct so that it can be passed to the JITted version of the IR.54///55/// Fourth and finally, it "dematerializes" the struct after the JITted code56/// has executed, placing the new values back where it found the old ones.57class ClangExpressionDeclMap : public ClangASTSource {58public:59  /// Constructor60  ///61  /// Initializes class variables.62  ///63  /// \param[in] keep_result_in_memory64  ///     If true, inhibits the normal deallocation of the memory for65  ///     the result persistent variable, and instead marks the variable66  ///     as persisting.67  ///68  /// \param[in] result_delegate69  ///     If non-NULL, use this delegate to report result values.  This70  ///     allows the client ClangUserExpression to report a result.71  ///72  /// \param[in] target73  ///     The target to use when parsing.74  ///75  /// \param[in] importer76  ///     The ClangASTImporter to use when parsing.77  ///78  /// \param[in] ctx_obj79  ///     If not empty, then expression is evaluated in context of this object.80  ///     See the comment to `UserExpression::Evaluate` for details.81  ClangExpressionDeclMap(82      bool keep_result_in_memory,83      Materializer::PersistentVariableDelegate *result_delegate,84      const lldb::TargetSP &target,85      const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);86 87  /// Destructor88  ~ClangExpressionDeclMap() override;89 90  /// Enable the state needed for parsing and IR transformation.91  ///92  /// \param[in] exe_ctx93  ///     The execution context to use when finding types for variables.94  ///     Also used to find a "scratch" AST context to store result types.95  ///96  /// \param[in] materializer97  ///     If non-NULL, the materializer to populate with information about98  ///     the variables to use99  ///100  /// \return101  ///     True if parsing is possible; false if it is unsafe to continue.102  bool WillParse(ExecutionContext &exe_ctx, Materializer *materializer);103 104  void InstallCodeGenerator(clang::ASTConsumer *code_gen);105 106  void InstallDiagnosticManager(DiagnosticManager &diag_manager);107 108  /// Disable the state needed for parsing and IR transformation.109  void DidParse();110 111  /// [Used by IRForTarget] Add a variable to the list of persistent112  ///     variables for the process.113  ///114  /// \param[in] decl115  ///     The Clang declaration for the persistent variable, used for116  ///     lookup during parsing.117  ///118  /// \param[in] name119  ///     The name of the persistent variable, usually $something.120  ///121  /// \param[in] type122  ///     The type of the variable, in the Clang parser's context.123  ///124  /// \return125  ///     True on success; false otherwise.126  bool AddPersistentVariable(const clang::NamedDecl *decl,127                             ConstString name, TypeFromParser type,128                             bool is_result, bool is_lvalue);129 130  /// [Used by IRForTarget] Add a variable to the struct that needs to131  ///     be materialized each time the expression runs.132  ///133  /// \param[in] decl134  ///     The Clang declaration for the variable.135  ///136  /// \param[in] name137  ///     The name of the variable.138  ///139  /// \param[in] value140  ///     The LLVM IR value for this variable.141  ///142  /// \param[in] size143  ///     The size of the variable in bytes.144  ///145  /// \param[in] alignment146  ///     The required alignment of the variable in bytes.147  ///148  /// \return149  ///     True on success; false otherwise.150  bool AddValueToStruct(const clang::NamedDecl *decl, ConstString name,151                        llvm::Value *value, size_t size,152                        lldb::offset_t alignment);153 154  /// [Used by IRForTarget] Finalize the struct, laying out the position of155  /// each object in it.156  ///157  /// \return158  ///     True on success; false otherwise.159  bool DoStructLayout();160 161  /// [Used by IRForTarget] Get general information about the laid-out struct162  /// after DoStructLayout() has been called.163  ///164  /// \param[out] num_elements165  ///     The number of elements in the struct.166  ///167  /// \param[out] size168  ///     The size of the struct, in bytes.169  ///170  /// \param[out] alignment171  ///     The alignment of the struct, in bytes.172  ///173  /// \return174  ///     True if the information could be retrieved; false otherwise.175  bool GetStructInfo(uint32_t &num_elements, size_t &size,176                     lldb::offset_t &alignment);177 178  /// [Used by IRForTarget] Get specific information about one field of the179  /// laid-out struct after DoStructLayout() has been called.180  ///181  /// \param[out] decl182  ///     The parsed Decl for the field, as generated by ClangASTSource183  ///     on ClangExpressionDeclMap's behalf.  In the case of the result184  ///     value, this will have the name $__lldb_result even if the185  ///     result value ends up having the name $1.  This is an186  ///     implementation detail of IRForTarget.187  ///188  /// \param[out] value189  ///     The IR value for the field (usually a GlobalVariable).  In190  ///     the case of the result value, this will have the correct191  ///     name ($1, for instance).  This is an implementation detail192  ///     of IRForTarget.193  ///194  /// \param[out] offset195  ///     The offset of the field from the beginning of the struct.196  ///     As long as the struct is aligned according to its required197  ///     alignment, this offset will align the field correctly.198  ///199  /// \param[out] name200  ///     The name of the field as used in materialization.201  ///202  /// \param[in] index203  ///     The index of the field about which information is requested.204  ///205  /// \return206  ///     True if the information could be retrieved; false otherwise.207  bool GetStructElement(const clang::NamedDecl *&decl, llvm::Value *&value,208                        lldb::offset_t &offset, ConstString &name,209                        uint32_t index);210 211  /// [Used by IRForTarget] Get information about a function given its Decl.212  ///213  /// \param[in] decl214  ///     The parsed Decl for the Function, as generated by ClangASTSource215  ///     on ClangExpressionDeclMap's behalf.216  ///217  /// \param[out] ptr218  ///     The absolute address of the function in the target.219  ///220  /// \return221  ///     True if the information could be retrieved; false otherwise.222  bool GetFunctionInfo(const clang::NamedDecl *decl, uint64_t &ptr);223 224  /// [Used by IRForTarget] Get the address of a symbol given nothing but its225  /// name.226  ///227  /// \param[in] target228  ///     The target to find the symbol in.  If not provided,229  ///     then the current parsing context's Target.230  ///231  /// \param[in] process232  ///     The process to use.  For Objective-C symbols, the process's233  ///     Objective-C language runtime may be queried if the process234  ///     is non-NULL.235  ///236  /// \param[in] name237  ///     The name of the symbol.238  ///239  /// \param[in] module240  ///     The module to limit the search to. This can be NULL241  ///242  /// \return243  ///     Valid load address for the symbol244  lldb::addr_t GetSymbolAddress(Target &target, Process *process,245                                ConstString name, lldb::SymbolType symbol_type,246                                Module *module = nullptr);247 248  lldb::addr_t GetSymbolAddress(ConstString name,249                                lldb::SymbolType symbol_type);250 251  struct TargetInfo {252    lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;253    size_t address_byte_size = 0;254 255    TargetInfo() = default;256 257    bool IsValid() {258      return (byte_order != lldb::eByteOrderInvalid && address_byte_size != 0);259    }260  };261  TargetInfo GetTargetInfo();262 263  /// [Used by ClangASTSource] Find all entities matching a given name, using264  /// a NameSearchContext to make Decls for them.265  ///266  /// \param[in] context267  ///     The NameSearchContext that can construct Decls for this name.268  void FindExternalVisibleDecls(NameSearchContext &context) override;269 270  /// Find all entities matching a given name in a given module/namespace,271  /// using a NameSearchContext to make Decls for them.272  ///273  /// \param[in] context274  ///     The NameSearchContext that can construct Decls for this name.275  ///276  /// \param[in] module277  ///     If non-NULL, the module to query.278  ///279  /// \param[in] namespace_decl280  ///     If valid and module is non-NULL, the parent namespace.281  void FindExternalVisibleDecls(NameSearchContext &context,282                                lldb::ModuleSP module,283                                const CompilerDeclContext &namespace_decl);284 285protected:286  /// Retrieves the declaration with the given name from the storage of287  /// persistent declarations.288  ///289  /// \return290  ///     A persistent decl with the given name or a nullptr.291  virtual clang::NamedDecl *GetPersistentDecl(ConstString name);292 293private:294  ExpressionVariableList295      m_found_entities; ///< All entities that were looked up for the parser.296  ExpressionVariableList297      m_struct_members; ///< All entities that need to be placed in the struct.298  bool m_keep_result_in_memory; ///< True if result persistent variables299                                ///generated by this expression should stay in300                                ///memory.301  Materializer::PersistentVariableDelegate302      *m_result_delegate; ///< If non-NULL, used to report expression results to303                          ///ClangUserExpression.304  ValueObject *m_ctx_obj; ///< If not empty, then expression is305                          ///evaluated in context of this object.306                          ///For details see the comment to307                          ///`UserExpression::Evaluate`.308 309  /// The following values should not live beyond parsing310  class ParserVars {311  public:312    ParserVars() = default;313 314    Target *GetTarget() {315      if (m_exe_ctx.GetTargetPtr())316        return m_exe_ctx.GetTargetPtr();317      else if (m_sym_ctx.target_sp)318        return m_sym_ctx.target_sp.get();319      return nullptr;320    }321 322    ExecutionContext m_exe_ctx; ///< The execution context to use when parsing.323    SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables324                             ///and types.325    ClangPersistentVariables *m_persistent_vars =326        nullptr; ///< The persistent variables for the process.327    bool m_enable_lookups = false; ///< Set to true during parsing if we have328                                   ///found the first "$__lldb" name.329    TargetInfo m_target_info;      ///< Basic information about the target.330    Materializer *m_materializer = nullptr;   ///< If non-NULL, the materializer331                                              ///to use when reporting used332                                              ///variables.333    clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator334                                              ///that receives new top-level335                                              ///functions.336    DiagnosticManager *m_diagnostics = nullptr;337 338  private:339    ParserVars(const ParserVars &) = delete;340    const ParserVars &operator=(const ParserVars &) = delete;341  };342 343  std::unique_ptr<ParserVars> m_parser_vars;344 345  /// Activate parser-specific variables346  void EnableParserVars() {347    if (!m_parser_vars)348      m_parser_vars = std::make_unique<ParserVars>();349  }350 351  /// Deallocate parser-specific variables352  void DisableParserVars() { m_parser_vars.reset(); }353 354  /// The following values contain layout information for the materialized355  /// struct, but are not specific to a single materialization356  struct StructVars {357    StructVars() = default;358 359    lldb::offset_t m_struct_alignment =360        0;                    ///< The alignment of the struct in bytes.361    size_t m_struct_size = 0; ///< The size of the struct in bytes.362    bool m_struct_laid_out =363        false; ///< True if the struct has been laid out and the364               /// layout is valid (that is, no new fields have been365               /// added since).366    ConstString367        m_result_name; ///< The name of the result variable ($1, for example)368  };369 370  std::unique_ptr<StructVars> m_struct_vars;371 372  /// Activate struct variables373  void EnableStructVars() {374    if (!m_struct_vars)375      m_struct_vars.reset(new struct StructVars);376  }377 378  /// Deallocate struct variables379  void DisableStructVars() { m_struct_vars.reset(); }380 381  lldb::TypeSystemClangSP GetScratchContext(Target &target) {382    return ScratchTypeSystemClang::GetForTarget(target,383                                                m_ast_context->getLangOpts());384  }385 386  /// Get this parser's ID for use in extracting parser- and JIT-specific data387  /// from persistent variables.388  uint64_t GetParserID() { return (uint64_t) this; }389 390  /// Should be called on all copied functions.391  void MaybeRegisterFunctionBody(clang::FunctionDecl *copied_function_decl);392 393  /// Searches the persistent decls of the target for entities with the394  /// given name.395  ///396  /// \param[in] context397  ///     The NameSearchContext that can construct Decls for this name.398  ///399  /// \param[in] name400  ///     The name of the entities that need to be found.401  void SearchPersistenDecls(NameSearchContext &context, const ConstString name);402 403  /// Handles looking up $__lldb_class which requires special treatment.404  ///405  /// \param[in] context406  ///     The NameSearchContext that can construct Decls for this name.407  void LookUpLldbClass(NameSearchContext &context);408 409  /// Handles looking up $__lldb_objc_class which requires special treatment.410  ///411  /// \param[in] context412  ///     The NameSearchContext that can construct Decls for this name.413  void LookUpLldbObjCClass(NameSearchContext &context);414 415  /// Handles looking up the synthetic namespace that contains our local416  /// variables for the current frame.417  ///418  /// \param[in] sym_ctx419  ///     The current SymbolContext of this frame.420  ///421  /// \param[in] name_context422  ///     The NameSearchContext that can construct Decls for this name.423  void LookupLocalVarNamespace(SymbolContext &sym_ctx,424                               NameSearchContext &name_context);425 426  /// Lookup entities in the ClangModulesDeclVendor.427  /// \param[in] context428  ///     The NameSearchContext that can construct Decls for this name.429  ///430  /// \param[in] name431  ///     The name of the entities that need to be found.432  void LookupInModulesDeclVendor(NameSearchContext &context, ConstString name);433 434  /// Looks up a local variable.435  ///436  /// \param[in] context437  ///     The NameSearchContext that can construct Decls for this name.438  ///439  /// \param[in] name440  ///     The name of the entities that need to be found.441  ///442  /// \param[in] sym_ctx443  ///     The current SymbolContext of this frame.444  ///445  /// \param[in] namespace_decl446  ///     The parent namespace if there is one.447  ///448  /// \return449  ///    True iff a local variable was found.450  bool LookupLocalVariable(NameSearchContext &context, ConstString name,451                           SymbolContext &sym_ctx,452                           const CompilerDeclContext &namespace_decl);453 454  /// Searches for functions in the given SymbolContextList.455  ///456  /// \param[in] sc_list457  ///     The SymbolContextList to search.458  ///459  /// \param[in] frame_decl_context460  ///     The current DeclContext of the current frame.461  ///462  /// \return463  ///     A SymbolContextList with any found functions in the front and464  ///     any unknown SymbolContexts which are not functions in the back.465  ///     The SymbolContexts for the functions are ordered by how close they are466  ///     to the DeclContext for the given frame DeclContext.467  SymbolContextList SearchFunctionsInSymbolContexts(468      const SymbolContextList &sc_list,469      const CompilerDeclContext &frame_decl_context);470 471  /// Looks up a function.472  ///473  /// \param[in] context474  ///     The NameSearchContext that can construct Decls for this name.475  ///476  /// \param[in] module_sp477  ///     If non-NULL, the module to query.478  ///479  /// \param[in] name480  ///     The name of the function that should be find.481  ///482  /// \param[in] namespace_decl483  ///     If valid and module is non-NULL, the parent namespace.484  ///485  /// \returns Returns \c true if we successfully found a function486  /// and could create a decl with correct type-info for it.487  bool LookupFunction(NameSearchContext &context, lldb::ModuleSP module_sp,488                      ConstString name,489                      const CompilerDeclContext &namespace_decl);490 491  /// Given a target, find a variable that matches the given name and type.492  ///493  /// \param[in] target494  ///     The target to use as a basis for finding the variable.495  ///496  /// \param[in] module497  ///     If non-NULL, the module to search.498  ///499  /// \param[in] name500  ///     The name as a plain C string.501  ///502  /// \param[in] namespace_decl503  ///     If non-NULL and module is non-NULL, the parent namespace.504  ///505  /// \return506  ///     The LLDB Variable found, or NULL if none was found.507  lldb::VariableSP508  FindGlobalVariable(Target &target, lldb::ModuleSP &module, ConstString name,509                     const CompilerDeclContext &namespace_decl);510 511  /// Get the value of a variable in a given execution context and return the512  /// associated Types if needed.513  ///514  /// \param[in] var515  ///     The variable to evaluate.516  ///517  /// \param[out] var_location518  ///     The variable location value to fill in519  ///520  /// \param[out] found_type521  ///     The type of the found value, as it was found in the user process.522  ///     This is only useful when the variable is being inspected on behalf523  ///     of the parser, hence the default.524  ///525  /// \param[out] parser_type526  ///     The type of the found value, as it was copied into the parser's527  ///     AST context.  This is only useful when the variable is being528  ///     inspected on behalf of the parser, hence the default.529  ///530  /// \return531  ///     Return true if the value was successfully filled in.532  bool GetVariableValue(lldb::VariableSP &var,533                        lldb_private::Value &var_location,534                        TypeFromUser *found_type = nullptr,535                        TypeFromParser *parser_type = nullptr);536 537  /// Use the NameSearchContext to generate a Decl for the given LLDB538  /// ValueObject, and put it in the list of found entities.539  ///540  /// Helper function used by the other AddOneVariable APIs.541  ///542  /// \param[in,out] context543  ///     The NameSearchContext to use when constructing the Decl.544  ///545  /// \param[in] pt546  ///     The CompilerType of the variable we're adding a Decl for.547  ///548  /// \param[in] var549  ///     The LLDB ValueObject that needs a Decl.550  ClangExpressionVariable::ParserVars *551  AddExpressionVariable(NameSearchContext &context, TypeFromParser const &pt,552                        lldb::ValueObjectSP valobj);553 554  /// Use the NameSearchContext to generate a Decl for the given LLDB555  /// Variable, and put it in the Tuple list.556  ///557  /// \param[in] context558  ///     The NameSearchContext to use when constructing the Decl.559  ///560  /// \param[in] var561  ///     The LLDB Variable that needs a Decl.562  ///563  /// \param[in] valobj564  ///     The LLDB ValueObject for that variable.565  void AddOneVariable(NameSearchContext &context, lldb::VariableSP var,566                      lldb::ValueObjectSP valobj);567 568  /// Use the NameSearchContext to generate a Decl for the given ValueObject569  /// and put it in the list of found entities.570  ///571  /// \param[in,out] context572  ///     The NameSearchContext to use when constructing the Decl.573  ///574  /// \param[in] valobj575  ///     The ValueObject that needs a Decl.576  ///577  /// \param[in] valobj_provider Callback that fetches a ValueObjectSP578  ///            from the specified frame579  void AddOneVariable(NameSearchContext &context, lldb::ValueObjectSP valobj,580                      ValueObjectProviderTy valobj_provider);581 582  /// Use the NameSearchContext to generate a Decl for the given persistent583  /// variable, and put it in the list of found entities.584  ///585  /// \param[in] context586  ///     The NameSearchContext to use when constructing the Decl.587  ///588  /// \param[in] pvar_sp589  ///     The persistent variable that needs a Decl.590  void AddOneVariable(NameSearchContext &context,591                      lldb::ExpressionVariableSP &pvar_sp);592 593  /// Use the NameSearchContext to generate a Decl for the given LLDB symbol594  /// (treated as a variable), and put it in the list of found entities.595  void AddOneGenericVariable(NameSearchContext &context, const Symbol &symbol);596 597  /// Use the NameSearchContext to generate a Decl for the given function.598  /// (Functions are not placed in the Tuple list.)  Can handle both fully599  /// typed functions and generic functions.600  ///601  /// \param[in] context602  ///     The NameSearchContext to use when constructing the Decl.603  ///604  /// \param[in] fun605  ///     The Function that needs to be created.  If non-NULL, this is606  ///     a fully-typed function.607  ///608  /// \param[in] sym609  ///     The Symbol that corresponds to a function that needs to be610  ///     created with generic type (unitptr_t foo(...)).611  void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);612 613  /// Use the NameSearchContext to generate a Decl for the given register.614  ///615  /// \param[in] context616  ///     The NameSearchContext to use when constructing the Decl.617  ///618  /// \param[in] reg_info619  ///     The information corresponding to that register.620  void AddOneRegister(NameSearchContext &context, const RegisterInfo *reg_info);621 622  /// Use the NameSearchContext to generate a Decl for the given type.  (Types623  /// are not placed in the Tuple list.)624  ///625  /// \param[in] context626  ///     The NameSearchContext to use when constructing the Decl.627  ///628  /// \param[in] type629  ///     The type that needs to be created.630  void AddOneType(NameSearchContext &context, const TypeFromUser &type);631 632  /// Adds the class in which the expression is evaluated to the lookup and633  /// prepares the class to be used as a context for expression evaluation (for634  /// example, it creates a fake member function that will contain the635  /// expression LLDB is trying to evaluate).636  ///637  /// \param[in] context638  ///     The NameSearchContext to which the class should be added as a lookup639  ///     result.640  ///641  /// \param[in] type642  ///     The type of the class that serves as the evaluation context.643  void AddContextClassType(NameSearchContext &context,644                           const TypeFromUser &type);645 646  /// Move a type out of the current ASTContext into another, but make sure to647  /// export all components of the type also.648  ///649  /// \param[in] target650  ///     The TypeSystemClang to move to.651  /// \param[in] source652  ///     The TypeSystemClang to move from.  This is assumed to be going away.653  /// \param[in] parser_type654  ///     The type as it appears in the source context.655  ///656  /// \return657  ///     Returns the moved type, or an empty type if there was a problem.658  TypeFromUser DeportType(TypeSystemClang &target, TypeSystemClang &source,659                          TypeFromParser parser_type);660 661  TypeSystemClang *GetTypeSystemClang();662};663 664} // namespace lldb_private665 666#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONDECLMAP_H667