/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- TypeSystem.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_SYMBOL_TYPESYSTEM_H |
10 | | #define LLDB_SYMBOL_TYPESYSTEM_H |
11 | | |
12 | | #include <functional> |
13 | | #include <mutex> |
14 | | #include <optional> |
15 | | #include <string> |
16 | | |
17 | | #include "llvm/ADT/APFloat.h" |
18 | | #include "llvm/ADT/APSInt.h" |
19 | | #include "llvm/ADT/DenseMap.h" |
20 | | #include "llvm/ADT/SmallBitVector.h" |
21 | | #include "llvm/Support/Casting.h" |
22 | | #include "llvm/Support/Error.h" |
23 | | #include "llvm/Support/JSON.h" |
24 | | |
25 | | #include "lldb/Core/PluginInterface.h" |
26 | | #include "lldb/Expression/Expression.h" |
27 | | #include "lldb/Symbol/CompilerDecl.h" |
28 | | #include "lldb/Symbol/CompilerDeclContext.h" |
29 | | #include "lldb/lldb-private.h" |
30 | | |
31 | | class DWARFDIE; |
32 | | class DWARFASTParser; |
33 | | class PDBASTParser; |
34 | | |
35 | | namespace lldb_private { |
36 | | namespace npdb { |
37 | | class PdbAstBuilder; |
38 | | } // namespace npdb |
39 | | |
40 | | /// A SmallBitVector that represents a set of source languages (\p |
41 | | /// lldb::LanguageType). Each lldb::LanguageType is represented by |
42 | | /// the bit with the position of its enumerator. The largest |
43 | | /// LanguageType is < 64, so this is space-efficient and on 64-bit |
44 | | /// architectures a LanguageSet can be completely stack-allocated. |
45 | | struct LanguageSet { |
46 | | llvm::SmallBitVector bitvector; |
47 | | LanguageSet(); |
48 | | |
49 | | /// If the set contains a single language only, return it. |
50 | | std::optional<lldb::LanguageType> GetSingularLanguage(); |
51 | | void Insert(lldb::LanguageType language); |
52 | | bool Empty() const; |
53 | | size_t Size() const; |
54 | | bool operator[](unsigned i) const; |
55 | | }; |
56 | | |
57 | | /// Interface for representing a type system. |
58 | | /// |
59 | | /// Implemented by language plugins to define the type system for a given |
60 | | /// language. |
61 | | /// |
62 | | /// This interface extensively used opaque pointers to prevent that generic |
63 | | /// LLDB code has dependencies on language plugins. The type and semantics of |
64 | | /// these opaque pointers are defined by the TypeSystem implementation inside |
65 | | /// the respective language plugin. Opaque pointers from one TypeSystem |
66 | | /// instance should never be passed to a different TypeSystem instance (even |
67 | | /// when the language plugin for both TypeSystem instances is the same). |
68 | | /// |
69 | | /// Most of the functions in this class should not be called directly but only |
70 | | /// called by their respective counterparts in CompilerType, CompilerDecl and |
71 | | /// CompilerDeclContext. |
72 | | /// |
73 | | /// \see lldb_private::CompilerType |
74 | | /// \see lldb_private::CompilerDecl |
75 | | /// \see lldb_private::CompilerDeclContext |
76 | | class TypeSystem : public PluginInterface, |
77 | | public std::enable_shared_from_this<TypeSystem> { |
78 | | public: |
79 | | // Constructors and Destructors |
80 | | TypeSystem(); |
81 | | ~TypeSystem() override; |
82 | | |
83 | | // LLVM RTTI support |
84 | | virtual bool isA(const void *ClassID) const = 0; |
85 | | |
86 | | static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, |
87 | | Module *module); |
88 | | |
89 | | static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, |
90 | | Target *target); |
91 | | |
92 | | /// Free up any resources associated with this TypeSystem. Done before |
93 | | /// removing all the TypeSystems from the TypeSystemMap. |
94 | 0 | virtual void Finalize() {} |
95 | | |
96 | 0 | virtual DWARFASTParser *GetDWARFParser() { return nullptr; } |
97 | 0 | virtual PDBASTParser *GetPDBParser() { return nullptr; } |
98 | 0 | virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; } |
99 | | |
100 | 48.2k | virtual SymbolFile *GetSymbolFile() const { return m_sym_file; } |
101 | | |
102 | 578k | virtual void SetSymbolFile(SymbolFile *sym_file) { m_sym_file = sym_file; } |
103 | | |
104 | | // CompilerDecl functions |
105 | | virtual ConstString DeclGetName(void *opaque_decl) = 0; |
106 | | |
107 | | virtual ConstString DeclGetMangledName(void *opaque_decl); |
108 | | |
109 | | virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl); |
110 | | |
111 | | virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl); |
112 | | |
113 | | virtual size_t DeclGetFunctionNumArguments(void *opaque_decl); |
114 | | |
115 | | virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl, |
116 | | size_t arg_idx); |
117 | | |
118 | | virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0; |
119 | | |
120 | | // CompilerDeclContext functions |
121 | | |
122 | | virtual std::vector<CompilerDecl> |
123 | | DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, |
124 | | const bool ignore_imported_decls); |
125 | | |
126 | | virtual ConstString DeclContextGetName(void *opaque_decl_ctx) = 0; |
127 | | |
128 | | virtual ConstString |
129 | | DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) = 0; |
130 | | |
131 | | virtual bool DeclContextIsClassMethod(void *opaque_decl_ctx) = 0; |
132 | | |
133 | | virtual bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, |
134 | | void *other_opaque_decl_ctx) = 0; |
135 | | |
136 | | virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0; |
137 | | |
138 | | // Tests |
139 | | #ifndef NDEBUG |
140 | | /// Verify the integrity of the type to catch CompilerTypes that mix |
141 | | /// and match invalid TypeSystem/Opaque type pairs. |
142 | | virtual bool Verify(lldb::opaque_compiler_type_t type) = 0; |
143 | | #endif |
144 | | |
145 | | virtual bool IsArrayType(lldb::opaque_compiler_type_t type, |
146 | | CompilerType *element_type, uint64_t *size, |
147 | | bool *is_incomplete) = 0; |
148 | | |
149 | | virtual bool IsAggregateType(lldb::opaque_compiler_type_t type) = 0; |
150 | | |
151 | | virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type); |
152 | | |
153 | | virtual bool IsCharType(lldb::opaque_compiler_type_t type) = 0; |
154 | | |
155 | | virtual bool IsCompleteType(lldb::opaque_compiler_type_t type) = 0; |
156 | | |
157 | | virtual bool IsDefined(lldb::opaque_compiler_type_t type) = 0; |
158 | | |
159 | | virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type, |
160 | | uint32_t &count, bool &is_complex) = 0; |
161 | | |
162 | | virtual bool IsFunctionType(lldb::opaque_compiler_type_t type) = 0; |
163 | | |
164 | | virtual size_t |
165 | | GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0; |
166 | | |
167 | | virtual CompilerType |
168 | | GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, |
169 | | const size_t index) = 0; |
170 | | |
171 | | virtual bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; |
172 | | |
173 | | virtual bool |
174 | | IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; |
175 | | |
176 | | virtual bool IsBlockPointerType(lldb::opaque_compiler_type_t type, |
177 | | CompilerType *function_pointer_type_ptr) = 0; |
178 | | |
179 | | virtual bool IsIntegerType(lldb::opaque_compiler_type_t type, |
180 | | bool &is_signed) = 0; |
181 | | |
182 | | virtual bool IsEnumerationType(lldb::opaque_compiler_type_t type, |
183 | 0 | bool &is_signed) { |
184 | 0 | is_signed = false; |
185 | 0 | return false; |
186 | 0 | } |
187 | | |
188 | | virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0; |
189 | | |
190 | | virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, |
191 | | CompilerType *target_type, // Can pass NULL |
192 | | bool check_cplusplus, bool check_objc) = 0; |
193 | | |
194 | | virtual bool IsPointerType(lldb::opaque_compiler_type_t type, |
195 | | CompilerType *pointee_type) = 0; |
196 | | |
197 | | virtual bool IsScalarType(lldb::opaque_compiler_type_t type) = 0; |
198 | | |
199 | | virtual bool IsVoidType(lldb::opaque_compiler_type_t type) = 0; |
200 | | |
201 | | virtual bool CanPassInRegisters(const CompilerType &type) = 0; |
202 | | |
203 | | // TypeSystems can support more than one language |
204 | | virtual bool SupportsLanguage(lldb::LanguageType language) = 0; |
205 | | |
206 | | // Type Completion |
207 | | |
208 | | virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; |
209 | | |
210 | 0 | virtual bool IsForcefullyCompleted(lldb::opaque_compiler_type_t type) { |
211 | 0 | return false; |
212 | 0 | } |
213 | | |
214 | | // AST related queries |
215 | | |
216 | | virtual uint32_t GetPointerByteSize() = 0; |
217 | | |
218 | | // Accessors |
219 | | |
220 | | virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type, |
221 | | bool BaseOnly) = 0; |
222 | | |
223 | | virtual ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) = 0; |
224 | | |
225 | | virtual uint32_t |
226 | | GetTypeInfo(lldb::opaque_compiler_type_t type, |
227 | | CompilerType *pointee_or_element_compiler_type) = 0; |
228 | | |
229 | | virtual lldb::LanguageType |
230 | | GetMinimumLanguage(lldb::opaque_compiler_type_t type) = 0; |
231 | | |
232 | | virtual lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) = 0; |
233 | | |
234 | | // Creating related types |
235 | | |
236 | | virtual CompilerType |
237 | | GetArrayElementType(lldb::opaque_compiler_type_t type, |
238 | | ExecutionContextScope *exe_scope) = 0; |
239 | | |
240 | | virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type, |
241 | | uint64_t size); |
242 | | |
243 | | virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0; |
244 | | |
245 | | virtual CompilerType |
246 | | GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) = 0; |
247 | | |
248 | | // Returns -1 if this isn't a function of if the function doesn't have a |
249 | | // prototype Returns a value >= 0 if there is a prototype. |
250 | | virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0; |
251 | | |
252 | | virtual CompilerType |
253 | | GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, |
254 | | size_t idx) = 0; |
255 | | |
256 | | virtual CompilerType |
257 | | GetFunctionReturnType(lldb::opaque_compiler_type_t type) = 0; |
258 | | |
259 | | virtual size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) = 0; |
260 | | |
261 | | virtual TypeMemberFunctionImpl |
262 | | GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) = 0; |
263 | | |
264 | | virtual CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) = 0; |
265 | | |
266 | | virtual CompilerType GetPointerType(lldb::opaque_compiler_type_t type) = 0; |
267 | | |
268 | | virtual CompilerType |
269 | | GetLValueReferenceType(lldb::opaque_compiler_type_t type); |
270 | | |
271 | | virtual CompilerType |
272 | | GetRValueReferenceType(lldb::opaque_compiler_type_t type); |
273 | | |
274 | | virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type); |
275 | | |
276 | | virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type); |
277 | | |
278 | | virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type); |
279 | | |
280 | | virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type); |
281 | | |
282 | | /// \param opaque_payload The m_payload field of Type, which may |
283 | | /// carry TypeSystem-specific extra information. |
284 | | virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, |
285 | | const char *name, |
286 | | const CompilerDeclContext &decl_ctx, |
287 | | uint32_t opaque_payload); |
288 | | |
289 | | // Exploring the type |
290 | | |
291 | | virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0; |
292 | | |
293 | | virtual std::optional<uint64_t> |
294 | | GetBitSize(lldb::opaque_compiler_type_t type, |
295 | | ExecutionContextScope *exe_scope) = 0; |
296 | | |
297 | | virtual lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, |
298 | | uint64_t &count) = 0; |
299 | | |
300 | | virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; |
301 | | |
302 | | virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, |
303 | | bool omit_empty_base_classes, |
304 | | const ExecutionContext *exe_ctx) = 0; |
305 | | |
306 | | virtual CompilerType GetBuiltinTypeByName(ConstString name); |
307 | | |
308 | | virtual lldb::BasicType |
309 | | GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) = 0; |
310 | | |
311 | | virtual void ForEachEnumerator( |
312 | | lldb::opaque_compiler_type_t type, |
313 | | std::function<bool(const CompilerType &integer_type, |
314 | | ConstString name, |
315 | 0 | const llvm::APSInt &value)> const &callback) {} |
316 | | |
317 | | virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type) = 0; |
318 | | |
319 | | virtual CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, |
320 | | size_t idx, std::string &name, |
321 | | uint64_t *bit_offset_ptr, |
322 | | uint32_t *bitfield_bit_size_ptr, |
323 | | bool *is_bitfield_ptr) = 0; |
324 | | |
325 | | virtual uint32_t |
326 | | GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) = 0; |
327 | | |
328 | | virtual uint32_t |
329 | | GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) = 0; |
330 | | |
331 | | virtual CompilerType |
332 | | GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, |
333 | | uint32_t *bit_offset_ptr) = 0; |
334 | | |
335 | | virtual CompilerType |
336 | | GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, |
337 | | uint32_t *bit_offset_ptr) = 0; |
338 | | |
339 | | virtual CompilerType GetChildCompilerTypeAtIndex( |
340 | | lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, |
341 | | bool transparent_pointers, bool omit_empty_base_classes, |
342 | | bool ignore_array_bounds, std::string &child_name, |
343 | | uint32_t &child_byte_size, int32_t &child_byte_offset, |
344 | | uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, |
345 | | bool &child_is_base_class, bool &child_is_deref_of_parent, |
346 | | ValueObject *valobj, uint64_t &language_flags) = 0; |
347 | | |
348 | | // Lookup a child given a name. This function will match base class names and |
349 | | // member member names in "clang_type" only, not descendants. |
350 | | virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, |
351 | | llvm::StringRef name, |
352 | | bool omit_empty_base_classes) = 0; |
353 | | |
354 | | // Lookup a child member given a name. This function will match member names |
355 | | // only and will descend into "clang_type" children in search for the first |
356 | | // member in this class, or any base class that matches "name". |
357 | | // TODO: Return all matches for a given name by returning a |
358 | | // vector<vector<uint32_t>> |
359 | | // so we catch all names that match a given child name, not just the first. |
360 | | virtual size_t GetIndexOfChildMemberWithName( |
361 | | lldb::opaque_compiler_type_t type, llvm::StringRef name, |
362 | | bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) = 0; |
363 | | |
364 | | virtual bool IsTemplateType(lldb::opaque_compiler_type_t type); |
365 | | |
366 | | virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type, |
367 | | bool expand_pack); |
368 | | |
369 | | virtual lldb::TemplateArgumentKind |
370 | | GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx, |
371 | | bool expand_pack); |
372 | | virtual CompilerType |
373 | | GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, |
374 | | bool expand_pack); |
375 | | virtual std::optional<CompilerType::IntegralTemplateArgument> |
376 | | GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, |
377 | | bool expand_pack); |
378 | | |
379 | | // Dumping types |
380 | | |
381 | | #ifndef NDEBUG |
382 | | /// Convenience LLVM-style dump method for use in the debugger only. |
383 | | LLVM_DUMP_METHOD virtual void |
384 | | dump(lldb::opaque_compiler_type_t type) const = 0; |
385 | | #endif |
386 | | |
387 | | virtual void DumpValue(lldb::opaque_compiler_type_t type, |
388 | | ExecutionContext *exe_ctx, Stream &s, |
389 | | lldb::Format format, const DataExtractor &data, |
390 | | lldb::offset_t data_offset, size_t data_byte_size, |
391 | | uint32_t bitfield_bit_size, |
392 | | uint32_t bitfield_bit_offset, bool show_types, |
393 | | bool show_summary, bool verbose, uint32_t depth) = 0; |
394 | | |
395 | | virtual bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream &s, |
396 | | lldb::Format format, const DataExtractor &data, |
397 | | lldb::offset_t data_offset, size_t data_byte_size, |
398 | | uint32_t bitfield_bit_size, |
399 | | uint32_t bitfield_bit_offset, |
400 | | ExecutionContextScope *exe_scope) = 0; |
401 | | |
402 | | /// Dump the type to stdout. |
403 | | virtual void DumpTypeDescription( |
404 | | lldb::opaque_compiler_type_t type, |
405 | | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; |
406 | | |
407 | | /// Print a description of the type to a stream. The exact implementation |
408 | | /// varies, but the expectation is that eDescriptionLevelFull returns a |
409 | | /// source-like representation of the type, whereas eDescriptionLevelVerbose |
410 | | /// does a dump of the underlying AST if applicable. |
411 | | virtual void DumpTypeDescription( |
412 | | lldb::opaque_compiler_type_t type, Stream &s, |
413 | | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; |
414 | | |
415 | | /// Dump a textual representation of the internal TypeSystem state to the |
416 | | /// given stream. |
417 | | /// |
418 | | /// This should not modify the state of the TypeSystem if possible. |
419 | | virtual void Dump(llvm::raw_ostream &output) = 0; |
420 | | |
421 | | // TODO: These methods appear unused. Should they be removed? |
422 | | |
423 | | virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0; |
424 | | |
425 | | virtual void DumpSummary(lldb::opaque_compiler_type_t type, |
426 | | ExecutionContext *exe_ctx, Stream &s, |
427 | | const DataExtractor &data, |
428 | | lldb::offset_t data_offset, |
429 | | size_t data_byte_size) = 0; |
430 | | |
431 | | // TODO: Determine if these methods should move to TypeSystemClang. |
432 | | |
433 | | virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, |
434 | | CompilerType *pointee_type) = 0; |
435 | | |
436 | | virtual unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) = 0; |
437 | | |
438 | | virtual bool IsCStringType(lldb::opaque_compiler_type_t type, |
439 | | uint32_t &length) = 0; |
440 | | |
441 | | virtual std::optional<size_t> |
442 | | GetTypeBitAlign(lldb::opaque_compiler_type_t type, |
443 | | ExecutionContextScope *exe_scope) = 0; |
444 | | |
445 | | virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0; |
446 | | |
447 | | virtual CompilerType |
448 | | GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, |
449 | | size_t bit_size) = 0; |
450 | | |
451 | | virtual bool IsBeingDefined(lldb::opaque_compiler_type_t type) = 0; |
452 | | |
453 | | virtual bool IsConst(lldb::opaque_compiler_type_t type) = 0; |
454 | | |
455 | | virtual uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, |
456 | | CompilerType *base_type_ptr) = 0; |
457 | | |
458 | | virtual bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) = 0; |
459 | | |
460 | | virtual bool IsTypedefType(lldb::opaque_compiler_type_t type) = 0; |
461 | | |
462 | | // If the current object represents a typedef type, get the underlying type |
463 | | virtual CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) = 0; |
464 | | |
465 | | virtual bool IsVectorType(lldb::opaque_compiler_type_t type, |
466 | | CompilerType *element_type, uint64_t *size) = 0; |
467 | | |
468 | | virtual CompilerType |
469 | | GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) = 0; |
470 | | |
471 | | virtual CompilerType |
472 | | GetNonReferenceType(lldb::opaque_compiler_type_t type) = 0; |
473 | | |
474 | | virtual bool IsReferenceType(lldb::opaque_compiler_type_t type, |
475 | | CompilerType *pointee_type, bool *is_rvalue) = 0; |
476 | | |
477 | | virtual bool |
478 | 44.9k | ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) { |
479 | 44.9k | return IsPointerOrReferenceType(type, nullptr); |
480 | 44.9k | } |
481 | | |
482 | | virtual UserExpression * |
483 | | GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, |
484 | | lldb::LanguageType language, |
485 | | Expression::ResultType desired_type, |
486 | | const EvaluateExpressionOptions &options, |
487 | 0 | ValueObject *ctx_obj) { |
488 | 0 | return nullptr; |
489 | 0 | } |
490 | | |
491 | | virtual FunctionCaller *GetFunctionCaller(const CompilerType &return_type, |
492 | | const Address &function_address, |
493 | | const ValueList &arg_value_list, |
494 | 0 | const char *name) { |
495 | 0 | return nullptr; |
496 | 0 | } |
497 | | |
498 | | virtual std::unique_ptr<UtilityFunction> |
499 | | CreateUtilityFunction(std::string text, std::string name); |
500 | | |
501 | 0 | virtual PersistentExpressionState *GetPersistentExpressionState() { |
502 | 0 | return nullptr; |
503 | 0 | } |
504 | | |
505 | | virtual CompilerType GetTypeForFormatters(void *type); |
506 | | |
507 | | virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj); |
508 | | |
509 | | // Type systems can have types that are placeholder types, which are meant to |
510 | | // indicate the presence of a type, but offer no actual information about |
511 | | // said types, and leave the burden of actually figuring type information out |
512 | | // to dynamic type resolution. For instance a language with a generics |
513 | | // system, can use placeholder types to indicate "type argument goes here", |
514 | | // without promising uniqueness of the placeholder, nor attaching any |
515 | | // actually idenfiable information to said placeholder. This API allows type |
516 | | // systems to tell LLDB when such a type has been encountered In response, |
517 | | // the debugger can react by not using this type as a cache entry in any |
518 | | // type-specific way For instance, LLDB will currently not cache any |
519 | | // formatters that are discovered on such a type as attributable to the |
520 | | // meaningless type itself, instead preferring to use the dynamic type |
521 | | virtual bool IsMeaninglessWithoutDynamicResolution(void *type); |
522 | | |
523 | | virtual std::optional<llvm::json::Value> ReportStatistics(); |
524 | | |
525 | 14 | bool GetHasForcefullyCompletedTypes() const { |
526 | 14 | return m_has_forcefully_completed_types; |
527 | 14 | } |
528 | | protected: |
529 | | SymbolFile *m_sym_file = nullptr; |
530 | | /// Used for reporting statistics. |
531 | | bool m_has_forcefully_completed_types = false; |
532 | | }; |
533 | | |
534 | | class TypeSystemMap { |
535 | | public: |
536 | | TypeSystemMap(); |
537 | | ~TypeSystemMap(); |
538 | | |
539 | | // Clear calls Finalize on all the TypeSystems managed by this map, and then |
540 | | // empties the map. |
541 | | void Clear(); |
542 | | |
543 | | // Iterate through all of the type systems that are created. Return true from |
544 | | // callback to keep iterating, false to stop iterating. |
545 | | void ForEach(std::function<bool(lldb::TypeSystemSP)> const &callback); |
546 | | |
547 | | llvm::Expected<lldb::TypeSystemSP> |
548 | | GetTypeSystemForLanguage(lldb::LanguageType language, Module *module, |
549 | | bool can_create); |
550 | | |
551 | | llvm::Expected<lldb::TypeSystemSP> |
552 | | GetTypeSystemForLanguage(lldb::LanguageType language, Target *target, |
553 | | bool can_create); |
554 | | |
555 | | /// Check all type systems in the map to see if any have forcefully completed |
556 | | /// types; |
557 | | bool GetHasForcefullyCompletedTypes() const; |
558 | | protected: |
559 | | typedef llvm::DenseMap<uint16_t, lldb::TypeSystemSP> collection; |
560 | | mutable std::mutex m_mutex; ///< A mutex to keep this object happy in |
561 | | /// multi-threaded environments. |
562 | | collection m_map; |
563 | | bool m_clear_in_progress = false; |
564 | | |
565 | | private: |
566 | | typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback; |
567 | | /// Finds the type system for the given language. If no type system could be |
568 | | /// found for a language and a CreateCallback was provided, the value |
569 | | /// returned by the callback will be treated as the TypeSystem for the |
570 | | /// language. |
571 | | /// |
572 | | /// \param language The language for which the type system should be found. |
573 | | /// \param create_callback A callback that will be called if no previously |
574 | | /// created TypeSystem that fits the given language |
575 | | /// could found. Can be omitted if a non-existent |
576 | | /// type system should be treated as an error |
577 | | /// instead. |
578 | | /// \return The found type system or an error. |
579 | | llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage( |
580 | | lldb::LanguageType language, |
581 | | std::optional<CreateCallback> create_callback = std::nullopt); |
582 | | }; |
583 | | |
584 | | } // namespace lldb_private |
585 | | |
586 | | #endif // LLDB_SYMBOL_TYPESYSTEM_H |