/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- ClangExpressionVariable.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-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H |
10 | | #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H |
11 | | |
12 | | #include <csignal> |
13 | | #include <cstdint> |
14 | | #include <cstring> |
15 | | |
16 | | #include <map> |
17 | | #include <string> |
18 | | #include <vector> |
19 | | |
20 | | #include "llvm/Support/Casting.h" |
21 | | |
22 | | #include "lldb/Core/Value.h" |
23 | | #include "lldb/Expression/ExpressionVariable.h" |
24 | | #include "lldb/Symbol/TaggedASTType.h" |
25 | | #include "lldb/Utility/ConstString.h" |
26 | | #include "lldb/lldb-public.h" |
27 | | |
28 | | namespace llvm { |
29 | | class Value; |
30 | | } |
31 | | |
32 | | namespace clang { |
33 | | class NamedDecl; |
34 | | } |
35 | | |
36 | | namespace lldb_private { |
37 | | |
38 | | class ValueObjectConstResult; |
39 | | |
40 | | /// \class ClangExpressionVariable ClangExpressionVariable.h |
41 | | /// "lldb/Expression/ClangExpressionVariable.h" Encapsulates one variable for |
42 | | /// the expression parser. |
43 | | /// |
44 | | /// The expression parser uses variables in three different contexts: |
45 | | /// |
46 | | /// First, it stores persistent variables along with the process for use in |
47 | | /// expressions. These persistent variables contain their own data and are |
48 | | /// typed. |
49 | | /// |
50 | | /// Second, in an interpreted expression, it stores the local variables for |
51 | | /// the expression along with the expression. These variables contain their |
52 | | /// own data and are typed. |
53 | | /// |
54 | | /// Third, in a JIT-compiled expression, it stores the variables that the |
55 | | /// expression needs to have materialized and dematerialized at each |
56 | | /// execution. These do not contain their own data but are named and typed. |
57 | | /// |
58 | | /// This class supports all of these use cases using simple type polymorphism, |
59 | | /// and provides necessary support methods. Its interface is RTTI-neutral. |
60 | | class ClangExpressionVariable |
61 | | : public llvm::RTTIExtends<ClangExpressionVariable, ExpressionVariable> { |
62 | | public: |
63 | | // LLVM RTTI support |
64 | | static char ID; |
65 | | |
66 | | ClangExpressionVariable(ExecutionContextScope *exe_scope, |
67 | | lldb::ByteOrder byte_order, uint32_t addr_byte_size); |
68 | | |
69 | | ClangExpressionVariable(ExecutionContextScope *exe_scope, Value &value, |
70 | | ConstString name, uint16_t flags = EVNone); |
71 | | |
72 | | ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); |
73 | | |
74 | | ClangExpressionVariable(ExecutionContextScope *exe_scope, |
75 | | ConstString name, |
76 | | const TypeFromUser &user_type, |
77 | | lldb::ByteOrder byte_order, uint32_t addr_byte_size); |
78 | | |
79 | | /// Utility functions for dealing with ExpressionVariableLists in Clang- |
80 | | /// specific ways |
81 | | |
82 | | /// Finds a variable by NamedDecl in the list. |
83 | | /// |
84 | | /// \return |
85 | | /// The variable requested, or NULL if that variable is not in the list. |
86 | | static ClangExpressionVariable * |
87 | | FindVariableInList(ExpressionVariableList &list, const clang::NamedDecl *decl, |
88 | 28.9k | uint64_t parser_id) { |
89 | 28.9k | lldb::ExpressionVariableSP var_sp; |
90 | 56.4k | for (size_t index = 0, size = list.GetSize(); index < size; ++index27.4k ) { |
91 | 40.3k | var_sp = list.GetVariableAtIndex(index); |
92 | | |
93 | 40.3k | if (ClangExpressionVariable *clang_var = |
94 | 40.3k | llvm::dyn_cast<ClangExpressionVariable>(var_sp.get())) { |
95 | 40.3k | ClangExpressionVariable::ParserVars *parser_vars = |
96 | 40.3k | clang_var->GetParserVars(parser_id); |
97 | | |
98 | 40.3k | if (parser_vars && parser_vars->m_named_decl == decl39.8k ) |
99 | 12.8k | return clang_var; |
100 | 40.3k | } |
101 | 40.3k | } |
102 | 16.0k | return nullptr; |
103 | 28.9k | } |
104 | | |
105 | | /// If the variable contains its own data, make a Value point at it. If \a |
106 | | /// exe_ctx in not NULL, the value will be resolved in with that execution |
107 | | /// context. |
108 | | /// |
109 | | /// \param[in] value |
110 | | /// The value to point at the data. |
111 | | /// |
112 | | /// \param[in] exe_ctx |
113 | | /// The execution context to use to resolve \a value. |
114 | | /// |
115 | | /// \return |
116 | | /// True on success; false otherwise (in particular, if this variable |
117 | | /// does not contain its own data). |
118 | | bool PointValueAtData(Value &value, ExecutionContext *exe_ctx); |
119 | | |
120 | | /// The following values should not live beyond parsing |
121 | | class ParserVars { |
122 | | public: |
123 | 21.0k | ParserVars() = default; |
124 | | |
125 | | const clang::NamedDecl *m_named_decl = |
126 | | nullptr; ///< The Decl corresponding to this variable |
127 | | llvm::Value *m_llvm_value = |
128 | | nullptr; ///< The IR value corresponding to this variable; |
129 | | /// usually a GlobalValue |
130 | | lldb_private::Value |
131 | | m_lldb_value; ///< The value found in LLDB for this variable |
132 | | lldb::VariableSP m_lldb_var; ///< The original variable for this variable |
133 | | const lldb_private::Symbol *m_lldb_sym = |
134 | | nullptr; ///< The original symbol for this |
135 | | /// variable, if it was a symbol |
136 | | |
137 | | /// Callback that provides a ValueObject for the |
138 | | /// specified frame. Used by the materializer for |
139 | | /// re-fetching ValueObjects when materializing |
140 | | /// ivars. |
141 | | ValueObjectProviderTy m_lldb_valobj_provider; |
142 | | }; |
143 | | |
144 | | private: |
145 | | typedef std::map<uint64_t, ParserVars> ParserVarMap; |
146 | | ParserVarMap m_parser_vars; |
147 | | |
148 | | public: |
149 | | /// Make this variable usable by the parser by allocating space for parser- |
150 | | /// specific variables |
151 | 21.0k | void EnableParserVars(uint64_t parser_id) { |
152 | 21.0k | m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); |
153 | 21.0k | } |
154 | | |
155 | | /// Deallocate parser-specific variables |
156 | 255k | void DisableParserVars(uint64_t parser_id) { m_parser_vars.erase(parser_id); } |
157 | | |
158 | | /// Access parser-specific variables |
159 | 87.1k | ParserVars *GetParserVars(uint64_t parser_id) { |
160 | 87.1k | ParserVarMap::iterator i = m_parser_vars.find(parser_id); |
161 | | |
162 | 87.1k | if (i == m_parser_vars.end()) |
163 | 509 | return nullptr; |
164 | 86.6k | else |
165 | 86.6k | return &i->second; |
166 | 87.1k | } |
167 | | |
168 | | /// The following values are valid if the variable is used by JIT code |
169 | | struct JITVars { |
170 | 19.6k | JITVars() = default; |
171 | | |
172 | | lldb::offset_t m_alignment = |
173 | | 0; ///< The required alignment of the variable, in bytes |
174 | | size_t m_size = 0; ///< The space required for the variable, in bytes |
175 | | lldb::offset_t m_offset = |
176 | | 0; ///< The offset of the variable in the struct, in bytes |
177 | | }; |
178 | | |
179 | | private: |
180 | | typedef std::map<uint64_t, JITVars> JITVarMap; |
181 | | JITVarMap m_jit_vars; |
182 | | |
183 | | public: |
184 | | /// Make this variable usable for materializing for the JIT by allocating |
185 | | /// space for JIT-specific variables |
186 | 19.6k | void EnableJITVars(uint64_t parser_id) { |
187 | 19.6k | m_jit_vars.insert(std::make_pair(parser_id, JITVars())); |
188 | 19.6k | } |
189 | | |
190 | | /// Deallocate JIT-specific variables |
191 | 0 | void DisableJITVars(uint64_t parser_id) { m_jit_vars.erase(parser_id); } |
192 | | |
193 | 45.3k | JITVars *GetJITVars(uint64_t parser_id) { |
194 | 45.3k | JITVarMap::iterator i = m_jit_vars.find(parser_id); |
195 | | |
196 | 45.3k | if (i == m_jit_vars.end()) |
197 | 6.05k | return nullptr; |
198 | 39.3k | else |
199 | 39.3k | return &i->second; |
200 | 45.3k | } |
201 | | |
202 | | TypeFromUser GetTypeFromUser(); |
203 | | |
204 | | /// Members |
205 | | ClangExpressionVariable(const ClangExpressionVariable &) = delete; |
206 | | const ClangExpressionVariable & |
207 | | operator=(const ClangExpressionVariable &) = delete; |
208 | | }; |
209 | | |
210 | | } // namespace lldb_private |
211 | | |
212 | | #endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGEXPRESSIONVARIABLE_H |