/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Symbol/Type.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- Type.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_TYPE_H |
10 | | #define LLDB_SYMBOL_TYPE_H |
11 | | |
12 | | #include "lldb/Core/Declaration.h" |
13 | | #include "lldb/Symbol/CompilerDecl.h" |
14 | | #include "lldb/Symbol/CompilerType.h" |
15 | | #include "lldb/Utility/ConstString.h" |
16 | | #include "lldb/Utility/UserID.h" |
17 | | #include "lldb/lldb-private.h" |
18 | | |
19 | | #include "llvm/ADT/APSInt.h" |
20 | | |
21 | | #include <optional> |
22 | | #include <set> |
23 | | |
24 | | namespace lldb_private { |
25 | | class SymbolFileCommon; |
26 | | |
27 | | /// CompilerContext allows an array of these items to be passed to perform |
28 | | /// detailed lookups in SymbolVendor and SymbolFile functions. |
29 | | struct CompilerContext { |
30 | 325 | CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {} |
31 | | |
32 | 172 | bool operator==(const CompilerContext &rhs) const { |
33 | 172 | return kind == rhs.kind && name == rhs.name159 ; |
34 | 172 | } |
35 | 172 | bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); } |
36 | | |
37 | | void Dump() const; |
38 | | |
39 | | CompilerContextKind kind; |
40 | | ConstString name; |
41 | | }; |
42 | | |
43 | | /// Match \p context_chain against \p pattern, which may contain "Any" |
44 | | /// kinds. The \p context_chain should *not* contain any "Any" kinds. |
45 | | bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain, |
46 | | llvm::ArrayRef<CompilerContext> pattern); |
47 | | |
48 | | class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>, |
49 | | public UserID { |
50 | | public: |
51 | | SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid) |
52 | 18.2k | : UserID(uid), m_symbol_file(symbol_file) {} |
53 | | |
54 | | SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp); |
55 | | |
56 | 17.6k | ~SymbolFileType() = default; |
57 | | |
58 | 0 | Type *operator->() { return GetType(); } |
59 | | |
60 | | Type *GetType(); |
61 | 0 | SymbolFile &GetSymbolFile() const { return m_symbol_file; } |
62 | | |
63 | | protected: |
64 | | SymbolFile &m_symbol_file; |
65 | | lldb::TypeSP m_type_sp; |
66 | | }; |
67 | | |
68 | | class Type : public std::enable_shared_from_this<Type>, public UserID { |
69 | | public: |
70 | | enum EncodingDataType { |
71 | | /// Invalid encoding. |
72 | | eEncodingInvalid, |
73 | | /// This type is the type whose UID is m_encoding_uid. |
74 | | eEncodingIsUID, |
75 | | /// This type is the type whose UID is m_encoding_uid with the const |
76 | | /// qualifier added. |
77 | | eEncodingIsConstUID, |
78 | | /// This type is the type whose UID is m_encoding_uid with the restrict |
79 | | /// qualifier added. |
80 | | eEncodingIsRestrictUID, |
81 | | /// This type is the type whose UID is m_encoding_uid with the volatile |
82 | | /// qualifier added. |
83 | | eEncodingIsVolatileUID, |
84 | | /// This type is alias to a type whose UID is m_encoding_uid. |
85 | | eEncodingIsTypedefUID, |
86 | | /// This type is pointer to a type whose UID is m_encoding_uid. |
87 | | eEncodingIsPointerUID, |
88 | | /// This type is L value reference to a type whose UID is m_encoding_uid. |
89 | | eEncodingIsLValueReferenceUID, |
90 | | /// This type is R value reference to a type whose UID is m_encoding_uid. |
91 | | eEncodingIsRValueReferenceUID, |
92 | | /// This type is the type whose UID is m_encoding_uid as an atomic type. |
93 | | eEncodingIsAtomicUID, |
94 | | /// This type is the synthetic type whose UID is m_encoding_uid. |
95 | | eEncodingIsSyntheticUID |
96 | | }; |
97 | | |
98 | | enum class ResolveState : unsigned char { |
99 | | Unresolved = 0, |
100 | | Forward = 1, |
101 | | Layout = 2, |
102 | | Full = 3 |
103 | | }; |
104 | | |
105 | | void Dump(Stream *s, bool show_context, |
106 | | lldb::DescriptionLevel level = lldb::eDescriptionLevelFull); |
107 | | |
108 | | void DumpTypeName(Stream *s); |
109 | | |
110 | | /// Since Type instances only keep a "SymbolFile *" internally, other classes |
111 | | /// like TypeImpl need make sure the module is still around before playing |
112 | | /// with |
113 | | /// Type instances. They can store a weak pointer to the Module; |
114 | | lldb::ModuleSP GetModule(); |
115 | | |
116 | | /// GetModule may return module for compile unit's object file. |
117 | | /// GetExeModule returns module for executable object file that contains |
118 | | /// compile unit where type was actually defined. |
119 | | /// GetModule and GetExeModule may return the same value. |
120 | | lldb::ModuleSP GetExeModule(); |
121 | | |
122 | | void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name, |
123 | | ExecutionContextScope *exe_scope); |
124 | | |
125 | 329k | SymbolFile *GetSymbolFile() { return m_symbol_file; } |
126 | 0 | const SymbolFile *GetSymbolFile() const { return m_symbol_file; } |
127 | | |
128 | | ConstString GetName(); |
129 | | |
130 | | ConstString GetBaseName(); |
131 | | |
132 | | std::optional<uint64_t> GetByteSize(ExecutionContextScope *exe_scope); |
133 | | |
134 | | uint32_t GetNumChildren(bool omit_empty_base_classes); |
135 | | |
136 | | bool IsAggregateType(); |
137 | | |
138 | | // Returns if the type is a templated decl. Does not look through typedefs. |
139 | | bool IsTemplateType(); |
140 | | |
141 | 0 | bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; } |
142 | | |
143 | 178 | bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; } |
144 | | |
145 | | lldb::TypeSP GetTypedefType(); |
146 | | |
147 | 0 | ConstString GetName() const { return m_name; } |
148 | | |
149 | | ConstString GetQualifiedName(); |
150 | | |
151 | | void DumpValue(ExecutionContext *exe_ctx, Stream *s, |
152 | | const DataExtractor &data, uint32_t data_offset, |
153 | | bool show_type, bool show_summary, bool verbose, |
154 | | lldb::Format format = lldb::eFormatDefault); |
155 | | |
156 | | bool DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s, |
157 | | lldb::addr_t address, AddressType address_type, |
158 | | bool show_types, bool show_summary, bool verbose); |
159 | | |
160 | | bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address, |
161 | | AddressType address_type, DataExtractor &data); |
162 | | |
163 | | bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address, |
164 | | AddressType address_type, DataExtractor &data); |
165 | | |
166 | | lldb::Format GetFormat(); |
167 | | |
168 | | lldb::Encoding GetEncoding(uint64_t &count); |
169 | | |
170 | 1.11k | SymbolContextScope *GetSymbolContextScope() { return m_context; } |
171 | 0 | const SymbolContextScope *GetSymbolContextScope() const { return m_context; } |
172 | 101k | void SetSymbolContextScope(SymbolContextScope *context) { |
173 | 101k | m_context = context; |
174 | 101k | } |
175 | | |
176 | | const lldb_private::Declaration &GetDeclaration() const; |
177 | | |
178 | | // Get the clang type, and resolve definitions for any |
179 | | // class/struct/union/enum types completely. |
180 | | CompilerType GetFullCompilerType(); |
181 | | |
182 | | // Get the clang type, and resolve definitions enough so that the type could |
183 | | // have layout performed. This allows ptrs and refs to |
184 | | // class/struct/union/enum types remain forward declarations. |
185 | | CompilerType GetLayoutCompilerType(); |
186 | | |
187 | | // Get the clang type and leave class/struct/union/enum types as forward |
188 | | // declarations if they haven't already been fully defined. |
189 | | CompilerType GetForwardCompilerType(); |
190 | | |
191 | | static int Compare(const Type &a, const Type &b); |
192 | | |
193 | | // From a fully qualified typename, split the type into the type basename and |
194 | | // the remaining type scope (namespaces/classes). |
195 | | static bool GetTypeScopeAndBasename(llvm::StringRef name, |
196 | | llvm::StringRef &scope, |
197 | | llvm::StringRef &basename, |
198 | | lldb::TypeClass &type_class); |
199 | 890 | void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } |
200 | | |
201 | | uint32_t GetEncodingMask(); |
202 | | |
203 | | typedef uint32_t Payload; |
204 | | /// Return the language-specific payload. |
205 | 183 | Payload GetPayload() { return m_payload; } |
206 | | /// Return the language-specific payload. |
207 | 0 | void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; } |
208 | | |
209 | | protected: |
210 | | ConstString m_name; |
211 | | SymbolFile *m_symbol_file = nullptr; |
212 | | /// The symbol context in which this type is defined. |
213 | | SymbolContextScope *m_context = nullptr; |
214 | | Type *m_encoding_type = nullptr; |
215 | | lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID; |
216 | | EncodingDataType m_encoding_uid_type = eEncodingInvalid; |
217 | | uint64_t m_byte_size : 63; |
218 | | uint64_t m_byte_size_has_value : 1; |
219 | | Declaration m_decl; |
220 | | CompilerType m_compiler_type; |
221 | | ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved; |
222 | | /// Language-specific flags. |
223 | | Payload m_payload; |
224 | | |
225 | | Type *GetEncodingType(); |
226 | | |
227 | | bool ResolveCompilerType(ResolveState compiler_type_resolve_state); |
228 | | private: |
229 | | /// Only allow Symbol File to create types, as they should own them by keeping |
230 | | /// them in their TypeList. \see SymbolFileCommon::MakeType() reference in the |
231 | | /// header documentation here so users will know what function to use if the |
232 | | /// get a compile error. |
233 | | friend class lldb_private::SymbolFileCommon; |
234 | | |
235 | | Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name, |
236 | | std::optional<uint64_t> byte_size, SymbolContextScope *context, |
237 | | lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type, |
238 | | const Declaration &decl, const CompilerType &compiler_qual_type, |
239 | | ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0); |
240 | | |
241 | | // This makes an invalid type. Used for functions that return a Type when |
242 | | // they get an error. |
243 | | Type(); |
244 | | |
245 | 0 | Type(Type &t) = default; |
246 | | |
247 | | Type(Type &&t) = default; |
248 | | |
249 | | Type &operator=(const Type &t) = default; |
250 | | |
251 | | Type &operator=(Type &&t) = default; |
252 | | }; |
253 | | |
254 | | // the two classes here are used by the public API as a backend to the SBType |
255 | | // and SBTypeList classes |
256 | | |
257 | | class TypeImpl { |
258 | | public: |
259 | 1.68k | TypeImpl() = default; |
260 | | |
261 | 3.66M | ~TypeImpl() = default; |
262 | | |
263 | | TypeImpl(const lldb::TypeSP &type_sp); |
264 | | |
265 | | TypeImpl(const CompilerType &compiler_type); |
266 | | |
267 | | TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic); |
268 | | |
269 | | TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic); |
270 | | |
271 | | void SetType(const lldb::TypeSP &type_sp); |
272 | | |
273 | | void SetType(const CompilerType &compiler_type); |
274 | | |
275 | | void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic); |
276 | | |
277 | | void SetType(const CompilerType &compiler_type, const CompilerType &dynamic); |
278 | | |
279 | | bool operator==(const TypeImpl &rhs) const; |
280 | | |
281 | | bool operator!=(const TypeImpl &rhs) const; |
282 | | |
283 | | bool IsValid() const; |
284 | | |
285 | | explicit operator bool() const; |
286 | | |
287 | | void Clear(); |
288 | | |
289 | | lldb::ModuleSP GetModule() const; |
290 | | |
291 | | ConstString GetName() const; |
292 | | |
293 | | ConstString GetDisplayTypeName() const; |
294 | | |
295 | | TypeImpl GetPointerType() const; |
296 | | |
297 | | TypeImpl GetPointeeType() const; |
298 | | |
299 | | TypeImpl GetReferenceType() const; |
300 | | |
301 | | TypeImpl GetTypedefedType() const; |
302 | | |
303 | | TypeImpl GetDereferencedType() const; |
304 | | |
305 | | TypeImpl GetUnqualifiedType() const; |
306 | | |
307 | | TypeImpl GetCanonicalType() const; |
308 | | |
309 | | CompilerType GetCompilerType(bool prefer_dynamic); |
310 | | |
311 | | CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic); |
312 | | |
313 | | bool GetDescription(lldb_private::Stream &strm, |
314 | | lldb::DescriptionLevel description_level); |
315 | | |
316 | | private: |
317 | | bool CheckModule(lldb::ModuleSP &module_sp) const; |
318 | | bool CheckExeModule(lldb::ModuleSP &module_sp) const; |
319 | | bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp, |
320 | | lldb::ModuleSP &module_sp) const; |
321 | | |
322 | | lldb::ModuleWP m_module_wp; |
323 | | lldb::ModuleWP m_exe_module_wp; |
324 | | CompilerType m_static_type; |
325 | | CompilerType m_dynamic_type; |
326 | | }; |
327 | | |
328 | | class TypeListImpl { |
329 | | public: |
330 | 117 | TypeListImpl() = default; |
331 | | |
332 | 102 | void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); } |
333 | | |
334 | | class AppendVisitor { |
335 | | public: |
336 | 0 | AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {} |
337 | | |
338 | 0 | void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); } |
339 | | |
340 | | private: |
341 | | TypeListImpl &m_type_list; |
342 | | }; |
343 | | |
344 | | void Append(const lldb_private::TypeList &type_list); |
345 | | |
346 | 80 | lldb::TypeImplSP GetTypeAtIndex(size_t idx) { |
347 | 80 | lldb::TypeImplSP type_sp; |
348 | 80 | if (idx < GetSize()) |
349 | 80 | type_sp = m_content[idx]; |
350 | 80 | return type_sp; |
351 | 80 | } |
352 | | |
353 | 174 | size_t GetSize() { return m_content.size(); } |
354 | | |
355 | | private: |
356 | | std::vector<lldb::TypeImplSP> m_content; |
357 | | }; |
358 | | |
359 | | class TypeMemberImpl { |
360 | | public: |
361 | 0 | TypeMemberImpl() = default; |
362 | | |
363 | | TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset, |
364 | | ConstString name, uint32_t bitfield_bit_size = 0, |
365 | | bool is_bitfield = false) |
366 | 28 | : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name), |
367 | 28 | m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {} |
368 | | |
369 | | TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset) |
370 | 46 | : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), |
371 | 46 | m_bitfield_bit_size(0), m_is_bitfield(false) { |
372 | 46 | if (m_type_impl_sp) |
373 | 46 | m_name = m_type_impl_sp->GetName(); |
374 | 46 | } |
375 | | |
376 | 36 | const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; } |
377 | | |
378 | 72 | ConstString GetName() const { return m_name; } |
379 | | |
380 | 4 | uint64_t GetBitOffset() const { return m_bit_offset; } |
381 | | |
382 | 0 | uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; } |
383 | | |
384 | 0 | void SetBitfieldBitSize(uint32_t bitfield_bit_size) { |
385 | 0 | m_bitfield_bit_size = bitfield_bit_size; |
386 | 0 | } |
387 | | |
388 | 0 | bool GetIsBitfield() const { return m_is_bitfield; } |
389 | | |
390 | 0 | void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; } |
391 | | |
392 | | protected: |
393 | | lldb::TypeImplSP m_type_impl_sp; |
394 | | uint64_t m_bit_offset = 0; |
395 | | ConstString m_name; |
396 | | uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only |
397 | | bool m_is_bitfield = false; |
398 | | }; |
399 | | |
400 | | /// |
401 | | /// Sometimes you can find the name of the type corresponding to an object, but |
402 | | /// we don't have debug |
403 | | /// information for it. If that is the case, you can return one of these |
404 | | /// objects, and then if it |
405 | | /// has a full type, you can use that, but if not at least you can print the |
406 | | /// name for informational |
407 | | /// purposes. |
408 | | /// |
409 | | |
410 | | class TypeAndOrName { |
411 | | public: |
412 | 3.42k | TypeAndOrName() = default; |
413 | | TypeAndOrName(lldb::TypeSP &type_sp); |
414 | | TypeAndOrName(const CompilerType &compiler_type); |
415 | | TypeAndOrName(const char *type_str); |
416 | | TypeAndOrName(ConstString &type_const_string); |
417 | | |
418 | | bool operator==(const TypeAndOrName &other) const; |
419 | | |
420 | | bool operator!=(const TypeAndOrName &other) const; |
421 | | |
422 | | ConstString GetName() const; |
423 | | |
424 | 4.42k | CompilerType GetCompilerType() const { return m_compiler_type; } |
425 | | |
426 | | void SetName(ConstString type_name); |
427 | | |
428 | | void SetName(const char *type_name_cstr); |
429 | | |
430 | | void SetTypeSP(lldb::TypeSP type_sp); |
431 | | |
432 | | void SetCompilerType(CompilerType compiler_type); |
433 | | |
434 | | bool IsEmpty() const; |
435 | | |
436 | | bool HasName() const; |
437 | | |
438 | | bool HasCompilerType() const; |
439 | | |
440 | 36.8k | bool HasType() const { return HasCompilerType(); } |
441 | | |
442 | | void Clear(); |
443 | | |
444 | 3.04k | explicit operator bool() { return !IsEmpty(); } |
445 | | |
446 | | private: |
447 | | CompilerType m_compiler_type; |
448 | | ConstString m_type_name; |
449 | | }; |
450 | | |
451 | | class TypeMemberFunctionImpl { |
452 | | public: |
453 | 0 | TypeMemberFunctionImpl() = default; |
454 | | |
455 | | TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl, |
456 | | const std::string &name, |
457 | | const lldb::MemberFunctionKind &kind) |
458 | 44 | : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {} |
459 | | |
460 | | bool IsValid(); |
461 | | |
462 | | ConstString GetName() const; |
463 | | |
464 | | ConstString GetMangledName() const; |
465 | | |
466 | | CompilerType GetType() const; |
467 | | |
468 | | CompilerType GetReturnType() const; |
469 | | |
470 | | size_t GetNumArguments() const; |
471 | | |
472 | | CompilerType GetArgumentAtIndex(size_t idx) const; |
473 | | |
474 | | lldb::MemberFunctionKind GetKind() const; |
475 | | |
476 | | bool GetDescription(Stream &stream); |
477 | | |
478 | | protected: |
479 | | std::string GetPrintableTypeName(); |
480 | | |
481 | | private: |
482 | | CompilerType m_type; |
483 | | CompilerDecl m_decl; |
484 | | ConstString m_name; |
485 | | lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown; |
486 | | }; |
487 | | |
488 | | class TypeEnumMemberImpl { |
489 | | public: |
490 | 0 | TypeEnumMemberImpl() : m_name("<invalid>") {} |
491 | | |
492 | | TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name, |
493 | | const llvm::APSInt &value); |
494 | | |
495 | 284 | TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default; |
496 | | |
497 | | TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs); |
498 | | |
499 | 0 | bool IsValid() { return m_valid; } |
500 | | |
501 | 136 | ConstString GetName() const { return m_name; } |
502 | | |
503 | 4 | const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; } |
504 | | |
505 | 32 | uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); } |
506 | | |
507 | 32 | int64_t GetValueAsSigned() const { return m_value.getSExtValue(); } |
508 | | |
509 | | protected: |
510 | | lldb::TypeImplSP m_integer_type_sp; |
511 | | ConstString m_name; |
512 | | llvm::APSInt m_value; |
513 | | bool m_valid = false; |
514 | | }; |
515 | | |
516 | | class TypeEnumMemberListImpl { |
517 | | public: |
518 | 24 | TypeEnumMemberListImpl() = default; |
519 | | |
520 | 108 | void Append(const lldb::TypeEnumMemberImplSP &type) { |
521 | 108 | m_content.push_back(type); |
522 | 108 | } |
523 | | |
524 | | void Append(const lldb_private::TypeEnumMemberListImpl &type_list); |
525 | | |
526 | 196 | lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) { |
527 | 196 | lldb::TypeEnumMemberImplSP enum_member; |
528 | 196 | if (idx < GetSize()) |
529 | 196 | enum_member = m_content[idx]; |
530 | 196 | return enum_member; |
531 | 196 | } |
532 | | |
533 | 248 | size_t GetSize() { return m_content.size(); } |
534 | | |
535 | | private: |
536 | | std::vector<lldb::TypeEnumMemberImplSP> m_content; |
537 | | }; |
538 | | |
539 | | } // namespace lldb_private |
540 | | |
541 | | #endif // LLDB_SYMBOL_TYPE_H |