reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
//===-- ClangExpressionVariable.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 liblldb_ClangExpressionVariable_h_
#define liblldb_ClangExpressionVariable_h_

#include <signal.h>
#include <stdint.h>
#include <string.h>

#include <map>
#include <string>
#include <vector>

#include "llvm/Support/Casting.h"

#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Symbol/TaggedASTType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-public.h"

namespace llvm {
class Value;
}

namespace lldb_private {

class ValueObjectConstResult;

/// \class ClangExpressionVariable ClangExpressionVariable.h
/// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for
/// the expression parser.
///
/// The expression parser uses variables in three different contexts:
///
/// First, it stores persistent variables along with the process for use in
/// expressions.  These persistent variables contain their own data and are
/// typed.
///
/// Second, in an interpreted expression, it stores the local variables for
/// the expression along with the expression.  These variables contain their
/// own data and are typed.
///
/// Third, in a JIT-compiled expression, it stores the variables that the
/// expression needs to have materialized and dematerialized at each
/// execution.  These do not contain their own data but are named and typed.
///
/// This class supports all of these use cases using simple type polymorphism,
/// and provides necessary support methods.  Its interface is RTTI-neutral.
class ClangExpressionVariable : public ExpressionVariable {
public:
  ClangExpressionVariable(ExecutionContextScope *exe_scope,
                          lldb::ByteOrder byte_order, uint32_t addr_byte_size);

  ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value,
                          ConstString name, uint16_t flags = EVNone);

  ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);

  ClangExpressionVariable(ExecutionContextScope *exe_scope,
                          ConstString name,
                          const TypeFromUser &user_type,
                          lldb::ByteOrder byte_order, uint32_t addr_byte_size);

  /// Utility functions for dealing with ExpressionVariableLists in Clang-
  /// specific ways

  /// Finds a variable by NamedDecl in the list.
  ///
  /// \param[in] name
  ///     The name of the requested variable.
  ///
  /// \return
  ///     The variable requested, or NULL if that variable is not in the list.
  static ClangExpressionVariable *
  FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl,
                     uint64_t parser_id) {
    lldb::ExpressionVariableSP var_sp;
    for (size_t index = 0, size = list.GetSize(); index < size; ++index) {
      var_sp = list.GetVariableAtIndex(index);

      if (ClangExpressionVariable *clang_var =
              llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) {
        ClangExpressionVariable::ParserVars *parser_vars =
            clang_var->GetParserVars(parser_id);

        if (parser_vars && parser_vars->m_named_decl == decl)
          return clang_var;
      }
    }
    return nullptr;
  }

  /// If the variable contains its own data, make a Value point at it. If \a
  /// exe_ctx in not NULL, the value will be resolved in with that execution
  /// context.
  ///
  /// \param[in] value
  ///     The value to point at the data.
  ///
  /// \param[in] exe_ctx
  ///     The execution context to use to resolve \a value.
  ///
  /// \return
  ///     True on success; false otherwise (in particular, if this variable
  ///     does not contain its own data).
  bool PointValueAtData(Value &value, ExecutionContext *exe_ctx);

  /// The following values should not live beyond parsing
  class ParserVars {
  public:
    ParserVars()
        : m_parser_type(), m_named_decl(nullptr), m_llvm_value(nullptr),
          m_lldb_value(), m_lldb_var(), m_lldb_sym(nullptr) {}

    TypeFromParser
        m_parser_type; ///< The type of the variable according to the parser
    const clang::NamedDecl
        *m_named_decl;         ///< The Decl corresponding to this variable
    llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable;
                               ///usually a GlobalValue
    lldb_private::Value
        m_lldb_value;            ///< The value found in LLDB for this variable
    lldb::VariableSP m_lldb_var; ///< The original variable for this variable
    const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this
                                            ///variable, if it was a symbol
  };

private:
  typedef std::map<uint64_t, ParserVars> ParserVarMap;
  ParserVarMap m_parser_vars;

public:
  /// Make this variable usable by the parser by allocating space for parser-
  /// specific variables
  void EnableParserVars(uint64_t parser_id) {
    m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
  }

  /// Deallocate parser-specific variables
  void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); }

  /// Access parser-specific variables
  ParserVars *GetParserVars(uint64_t parser_id) {
    ParserVarMap::iterator i = m_parser_vars.find(parser_id);

    if (i == m_parser_vars.end())
      return nullptr;
    else
      return &i->second;
  }

  /// The following values are valid if the variable is used by JIT code
  struct JITVars {
    JITVars() : m_alignment(0), m_size(0), m_offset(0) {}

    lldb::offset_t
        m_alignment; ///< The required alignment of the variable, in bytes
    size_t m_size;   ///< The space required for the variable, in bytes
    lldb::offset_t
        m_offset; ///< The offset of the variable in the struct, in bytes
  };

private:
  typedef std::map<uint64_t, JITVars> JITVarMap;
  JITVarMap m_jit_vars;

public:
  /// Make this variable usable for materializing for the JIT by allocating
  /// space for JIT-specific variables
  void EnableJITVars(uint64_t parser_id) {
    m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
  }

  /// Deallocate JIT-specific variables
  void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); }

  JITVars *GetJITVars(uint64_t parser_id) {
    JITVarMap::iterator i = m_jit_vars.find(parser_id);

    if (i == m_jit_vars.end())
      return nullptr;
    else
      return &i->second;
  }

  TypeFromUser GetTypeFromUser();

  // llvm casting support
  static bool classof(const ExpressionVariable *ev) {
    return ev->getKind() == ExpressionVariable::eKindClang;
  }

  /// Members
  DISALLOW_COPY_AND_ASSIGN(ClangExpressionVariable);
};

} // namespace lldb_private

#endif // liblldb_ClangExpressionVariable_h_