xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
11061da546Spatrick 
12be691f3bSpatrick #include <csignal>
13be691f3bSpatrick #include <cstdint>
14be691f3bSpatrick #include <cstring>
15061da546Spatrick 
16061da546Spatrick #include <map>
17061da546Spatrick #include <string>
18061da546Spatrick #include <vector>
19061da546Spatrick 
20061da546Spatrick #include "llvm/Support/Casting.h"
21061da546Spatrick 
22061da546Spatrick #include "lldb/Core/Value.h"
23061da546Spatrick #include "lldb/Expression/ExpressionVariable.h"
24061da546Spatrick #include "lldb/Symbol/TaggedASTType.h"
25061da546Spatrick #include "lldb/Utility/ConstString.h"
26061da546Spatrick #include "lldb/lldb-public.h"
27061da546Spatrick 
28061da546Spatrick namespace llvm {
29061da546Spatrick class Value;
30061da546Spatrick }
31061da546Spatrick 
32dda28197Spatrick namespace clang {
33dda28197Spatrick class NamedDecl;
34dda28197Spatrick }
35dda28197Spatrick 
36061da546Spatrick namespace lldb_private {
37061da546Spatrick 
38061da546Spatrick class ValueObjectConstResult;
39061da546Spatrick 
40061da546Spatrick /// \class ClangExpressionVariable ClangExpressionVariable.h
41061da546Spatrick /// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for
42061da546Spatrick /// the expression parser.
43061da546Spatrick ///
44061da546Spatrick /// The expression parser uses variables in three different contexts:
45061da546Spatrick ///
46061da546Spatrick /// First, it stores persistent variables along with the process for use in
47061da546Spatrick /// expressions.  These persistent variables contain their own data and are
48061da546Spatrick /// typed.
49061da546Spatrick ///
50061da546Spatrick /// Second, in an interpreted expression, it stores the local variables for
51061da546Spatrick /// the expression along with the expression.  These variables contain their
52061da546Spatrick /// own data and are typed.
53061da546Spatrick ///
54061da546Spatrick /// Third, in a JIT-compiled expression, it stores the variables that the
55061da546Spatrick /// expression needs to have materialized and dematerialized at each
56061da546Spatrick /// execution.  These do not contain their own data but are named and typed.
57061da546Spatrick ///
58061da546Spatrick /// This class supports all of these use cases using simple type polymorphism,
59061da546Spatrick /// and provides necessary support methods.  Its interface is RTTI-neutral.
60061da546Spatrick class ClangExpressionVariable : public ExpressionVariable {
61061da546Spatrick public:
62061da546Spatrick   ClangExpressionVariable(ExecutionContextScope *exe_scope,
63061da546Spatrick                           lldb::ByteOrder byte_order, uint32_t addr_byte_size);
64061da546Spatrick 
65061da546Spatrick   ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value,
66061da546Spatrick                           ConstString name, uint16_t flags = EVNone);
67061da546Spatrick 
68061da546Spatrick   ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
69061da546Spatrick 
70061da546Spatrick   ClangExpressionVariable(ExecutionContextScope *exe_scope,
71061da546Spatrick                           ConstString name,
72061da546Spatrick                           const TypeFromUser &user_type,
73061da546Spatrick                           lldb::ByteOrder byte_order, uint32_t addr_byte_size);
74061da546Spatrick 
75061da546Spatrick   /// Utility functions for dealing with ExpressionVariableLists in Clang-
76061da546Spatrick   /// specific ways
77061da546Spatrick 
78061da546Spatrick   /// Finds a variable by NamedDecl in the list.
79061da546Spatrick   ///
80061da546Spatrick   /// \return
81061da546Spatrick   ///     The variable requested, or NULL if that variable is not in the list.
82061da546Spatrick   static ClangExpressionVariable *
FindVariableInList(ExpressionVariableList & list,const clang::NamedDecl * decl,uint64_t parser_id)83061da546Spatrick   FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl,
84061da546Spatrick                      uint64_t parser_id) {
85061da546Spatrick     lldb::ExpressionVariableSP var_sp;
86061da546Spatrick     for (size_t index = 0, size = list.GetSize(); index < size; ++index) {
87061da546Spatrick       var_sp = list.GetVariableAtIndex(index);
88061da546Spatrick 
89061da546Spatrick       if (ClangExpressionVariable *clang_var =
90061da546Spatrick               llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) {
91061da546Spatrick         ClangExpressionVariable::ParserVars *parser_vars =
92061da546Spatrick             clang_var->GetParserVars(parser_id);
93061da546Spatrick 
94061da546Spatrick         if (parser_vars && parser_vars->m_named_decl == decl)
95061da546Spatrick           return clang_var;
96061da546Spatrick       }
97061da546Spatrick     }
98061da546Spatrick     return nullptr;
99061da546Spatrick   }
100061da546Spatrick 
101061da546Spatrick   /// If the variable contains its own data, make a Value point at it. If \a
102061da546Spatrick   /// exe_ctx in not NULL, the value will be resolved in with that execution
103061da546Spatrick   /// context.
104061da546Spatrick   ///
105061da546Spatrick   /// \param[in] value
106061da546Spatrick   ///     The value to point at the data.
107061da546Spatrick   ///
108061da546Spatrick   /// \param[in] exe_ctx
109061da546Spatrick   ///     The execution context to use to resolve \a value.
110061da546Spatrick   ///
111061da546Spatrick   /// \return
112061da546Spatrick   ///     True on success; false otherwise (in particular, if this variable
113061da546Spatrick   ///     does not contain its own data).
114061da546Spatrick   bool PointValueAtData(Value &value, ExecutionContext *exe_ctx);
115061da546Spatrick 
116061da546Spatrick   /// The following values should not live beyond parsing
117061da546Spatrick   class ParserVars {
118061da546Spatrick   public:
119*f6aab3d8Srobert     ParserVars() = default;
120061da546Spatrick 
121be691f3bSpatrick     const clang::NamedDecl *m_named_decl =
122be691f3bSpatrick         nullptr; ///< The Decl corresponding to this variable
123be691f3bSpatrick     llvm::Value *m_llvm_value =
124be691f3bSpatrick         nullptr; ///< The IR value corresponding to this variable;
125061da546Spatrick                  /// usually a GlobalValue
126061da546Spatrick     lldb_private::Value
127061da546Spatrick         m_lldb_value;            ///< The value found in LLDB for this variable
128061da546Spatrick     lldb::VariableSP m_lldb_var; ///< The original variable for this variable
129be691f3bSpatrick     const lldb_private::Symbol *m_lldb_sym =
130be691f3bSpatrick         nullptr; ///< The original symbol for this
131061da546Spatrick                  /// variable, if it was a symbol
132*f6aab3d8Srobert 
133*f6aab3d8Srobert     /// Callback that provides a ValueObject for the
134*f6aab3d8Srobert     /// specified frame. Used by the materializer for
135*f6aab3d8Srobert     /// re-fetching ValueObjects when materializing
136*f6aab3d8Srobert     /// ivars.
137*f6aab3d8Srobert     ValueObjectProviderTy m_lldb_valobj_provider;
138061da546Spatrick   };
139061da546Spatrick 
140061da546Spatrick private:
141061da546Spatrick   typedef std::map<uint64_t, ParserVars> ParserVarMap;
142061da546Spatrick   ParserVarMap m_parser_vars;
143061da546Spatrick 
144061da546Spatrick public:
145061da546Spatrick   /// Make this variable usable by the parser by allocating space for parser-
146061da546Spatrick   /// specific variables
EnableParserVars(uint64_t parser_id)147061da546Spatrick   void EnableParserVars(uint64_t parser_id) {
148061da546Spatrick     m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
149061da546Spatrick   }
150061da546Spatrick 
151061da546Spatrick   /// Deallocate parser-specific variables
DisableParserVars(uint64_t parser_id)152061da546Spatrick   void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); }
153061da546Spatrick 
154061da546Spatrick   /// Access parser-specific variables
GetParserVars(uint64_t parser_id)155061da546Spatrick   ParserVars *GetParserVars(uint64_t parser_id) {
156061da546Spatrick     ParserVarMap::iterator i = m_parser_vars.find(parser_id);
157061da546Spatrick 
158061da546Spatrick     if (i == m_parser_vars.end())
159061da546Spatrick       return nullptr;
160061da546Spatrick     else
161061da546Spatrick       return &i->second;
162061da546Spatrick   }
163061da546Spatrick 
164061da546Spatrick   /// The following values are valid if the variable is used by JIT code
165061da546Spatrick   struct JITVars {
166be691f3bSpatrick     JITVars() = default;
167061da546Spatrick 
168be691f3bSpatrick     lldb::offset_t m_alignment =
169be691f3bSpatrick         0;             ///< The required alignment of the variable, in bytes
170be691f3bSpatrick     size_t m_size = 0; ///< The space required for the variable, in bytes
171be691f3bSpatrick     lldb::offset_t m_offset =
172be691f3bSpatrick         0; ///< The offset of the variable in the struct, in bytes
173061da546Spatrick   };
174061da546Spatrick 
175061da546Spatrick private:
176061da546Spatrick   typedef std::map<uint64_t, JITVars> JITVarMap;
177061da546Spatrick   JITVarMap m_jit_vars;
178061da546Spatrick 
179061da546Spatrick public:
180061da546Spatrick   /// Make this variable usable for materializing for the JIT by allocating
181061da546Spatrick   /// space for JIT-specific variables
EnableJITVars(uint64_t parser_id)182061da546Spatrick   void EnableJITVars(uint64_t parser_id) {
183061da546Spatrick     m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
184061da546Spatrick   }
185061da546Spatrick 
186061da546Spatrick   /// Deallocate JIT-specific variables
DisableJITVars(uint64_t parser_id)187061da546Spatrick   void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); }
188061da546Spatrick 
GetJITVars(uint64_t parser_id)189061da546Spatrick   JITVars *GetJITVars(uint64_t parser_id) {
190061da546Spatrick     JITVarMap::iterator i = m_jit_vars.find(parser_id);
191061da546Spatrick 
192061da546Spatrick     if (i == m_jit_vars.end())
193061da546Spatrick       return nullptr;
194061da546Spatrick     else
195061da546Spatrick       return &i->second;
196061da546Spatrick   }
197061da546Spatrick 
198061da546Spatrick   TypeFromUser GetTypeFromUser();
199061da546Spatrick 
200061da546Spatrick   // llvm casting support
classof(const ExpressionVariable * ev)201061da546Spatrick   static bool classof(const ExpressionVariable *ev) {
202061da546Spatrick     return ev->getKind() == ExpressionVariable::eKindClang;
203061da546Spatrick   }
204061da546Spatrick 
205061da546Spatrick   /// Members
206dda28197Spatrick   ClangExpressionVariable(const ClangExpressionVariable &) = delete;
207dda28197Spatrick   const ClangExpressionVariable &
208dda28197Spatrick   operator=(const ClangExpressionVariable &) = delete;
209061da546Spatrick };
210061da546Spatrick 
211061da546Spatrick } // namespace lldb_private
212061da546Spatrick 
213dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H
214