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/Symbol/TypeList.h"
16 #include "lldb/Symbol/TypeMap.h"
17 #include "lldb/Symbol/TypeSystem.h"
18 #include "lldb/Utility/ConstString.h"
19 #include "lldb/Utility/UserID.h"
20 #include "lldb/lldb-private.h"
21
22 #include "llvm/ADT/APSInt.h"
23 #include "llvm/ADT/DenseSet.h"
24 #include "llvm/ADT/STLForwardCompat.h"
25 #include "llvm/Support/raw_ostream.h"
26
27 #include <optional>
28 #include <set>
29
30 namespace lldb_private {
31 class SymbolFileCommon;
32
33 /// A SmallBitVector that represents a set of source languages (\p
34 /// lldb::LanguageType). Each lldb::LanguageType is represented by
35 /// the bit with the position of its enumerator. The largest
36 /// LanguageType is < 64, so this is space-efficient and on 64-bit
37 /// architectures a LanguageSet can be completely stack-allocated.
38 struct LanguageSet {
39 llvm::SmallBitVector bitvector;
40 LanguageSet();
41
42 /// If the set contains a single language only, return it.
43 std::optional<lldb::LanguageType> GetSingularLanguage();
44 void Insert(lldb::LanguageType language);
45 bool Empty() const;
46 size_t Size() const;
47 bool operator[](unsigned i) const;
48 };
49
50 /// CompilerContext allows an array of these items to be passed to perform
51 /// detailed lookups in SymbolVendor and SymbolFile functions.
52 struct CompilerContext {
CompilerContextCompilerContext53 CompilerContext(CompilerContextKind t, ConstString n) : kind(t), name(n) {}
54
55 bool operator==(const CompilerContext &rhs) const {
56 return kind == rhs.kind && name == rhs.name;
57 }
58 bool operator!=(const CompilerContext &rhs) const { return !(*this == rhs); }
59
60 void Dump(Stream &s) const;
61
62 CompilerContextKind kind;
63 ConstString name;
64 };
65 llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
66 const CompilerContext &rhs);
67
FLAGS_ENUM(TypeQueryOptions)68 FLAGS_ENUM(TypeQueryOptions){
69 e_none = 0u,
70 /// If set, TypeQuery::m_context contains an exact context that must match
71 /// the full context. If not set, TypeQuery::m_context can contain a partial
72 /// type match where the full context isn't fully specified.
73 e_exact_match = (1u << 0),
74 /// If set, TypeQuery::m_context is a clang module compiler context. If not
75 /// set TypeQuery::m_context is normal type lookup context.
76 e_module_search = (1u << 1),
77 /// If set, the query will ignore all Module entries in the type context,
78 /// even for exact matches.
79 e_ignore_modules = (1u << 2),
80 /// If set, all anonymous namespaces in the context must be matched exactly
81 /// by the pattern. Otherwise, superfluous namespaces are skipped.
82 e_strict_namespaces = (1u << 3),
83 /// When true, the find types call should stop the query as soon as a single
84 /// matching type is found. When false, the type query should find all
85 /// matching types.
86 e_find_one = (1u << 4),
87 // If set, treat TypeQuery::m_name as a mangled name that should be
88 // searched.
89 e_search_by_mangled_name = (1u << 5),
90 };
LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)91 LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
92
93 /// A class that contains all state required for type lookups.
94 ///
95 /// Using a TypeQuery class for matching types simplifies the internal APIs we
96 /// need to implement type lookups in LLDB. Type lookups can fully specify the
97 /// exact typename by filling out a complete or partial CompilerContext array.
98 /// This technique allows for powerful searches and also allows the SymbolFile
99 /// classes to use the m_context array to lookup types by basename, then
100 /// eliminate potential matches without having to resolve types into each
101 /// TypeSystem. This makes type lookups vastly more efficient and allows the
102 /// SymbolFile objects to stop looking up types when the type matching is
103 /// complete, like if we are looking for only a single type in our search.
104 class TypeQuery {
105 public:
106 TypeQuery() = delete;
107
108 /// Construct a type match object using a fully- or partially-qualified name.
109 ///
110 /// The specified \a type_name will be chopped up and the m_context will be
111 /// populated by separating the string by looking for "::". We do this because
112 /// symbol files have indexes that contain only the type's basename. This also
113 /// allows symbol files to efficiently not realize types that don't match the
114 /// specified context. Example of \a type_name values that can be specified
115 /// include:
116 /// "foo": Look for any type whose basename matches "foo".
117 /// If \a exact_match is true, then the type can't be contained in any
118 /// declaration context like a namespace, class, or other containing
119 /// scope.
120 /// If \a exact match is false, then we will find all matches including
121 /// ones that are contained in other declaration contexts, including top
122 /// level types.
123 /// "foo::bar": Look for any type whose basename matches "bar" but make sure
124 /// its parent declaration context is any named declaration context
125 /// (namespace, class, struct, etc) whose name matches "foo".
126 /// If \a exact_match is true, then the "foo" declaration context must
127 /// appear at the source file level or inside of a function.
128 /// If \a exact match is false, then the "foo" declaration context can
129 /// be contained in any other declaration contexts.
130 /// "class foo": Only match types that are classes whose basename matches
131 /// "foo".
132 /// "struct foo": Only match types that are structures whose basename
133 /// matches "foo".
134 /// "class foo::bar": Only match types that are classes whose basename
135 /// matches "bar" and that are contained in any named declaration context
136 /// named "foo".
137 ///
138 /// \param[in] type_name
139 /// A fully- or partially-qualified type name. This name will be parsed and
140 /// broken up and the m_context will be populated with the various parts of
141 /// the name. This typename can be prefixed with "struct ", "class ",
142 /// "union", "enum " or "typedef " before the actual type name to limit the
143 /// results of the types that match. The declaration context can be
144 /// specified with the "::" string. For example, "a::b::my_type".
145 ///
146 /// \param[in] options A set of boolean enumeration flags from the
147 /// TypeQueryOptions enumerations. \see TypeQueryOptions.
148 TypeQuery(llvm::StringRef name, TypeQueryOptions options = e_none);
149
150 /// Construct a type-match object that matches a type basename that exists
151 /// in the specified declaration context.
152 ///
153 /// This allows the m_context to be first populated using a declaration
154 /// context to exactly identify the containing declaration context of a type.
155 /// This can be used when you have a forward declaration to a type and you
156 /// need to search for its complete type.
157 ///
158 /// \param[in] decl_ctx
159 /// A declaration context object that comes from a TypeSystem plug-in. This
160 /// object will be asked to populate the array of CompilerContext objects
161 /// by adding the top most declaration context first into the array and then
162 /// adding any containing declaration contexts.
163 ///
164 /// \param[in] type_basename
165 /// The basename of the type to lookup in the specified declaration context.
166 ///
167 /// \param[in] options A set of boolean enumeration flags from the
168 /// TypeQueryOptions enumerations. \see TypeQueryOptions.
169 TypeQuery(const CompilerDeclContext &decl_ctx, ConstString type_basename,
170 TypeQueryOptions options = e_none);
171 /// Construct a type-match object using a compiler declaration that specifies
172 /// a typename and a declaration context to use when doing exact type lookups.
173 ///
174 /// This allows the m_context to be first populated using a type declaration.
175 /// The type declaration might have a declaration context and each TypeSystem
176 /// plug-in can populate the declaration context needed to perform an exact
177 /// lookup for a type.
178 /// This can be used when you have a forward declaration to a type and you
179 /// need to search for its complete type.
180 ///
181 /// \param[in] decl
182 /// A type declaration context object that comes from a TypeSystem plug-in.
183 /// This object will be asked to full the array of CompilerContext objects
184 /// by adding the top most declaration context first into the array and then
185 /// adding any containing declaration contexts, and ending with the exact
186 /// typename and the kind of type it is (class, struct, union, enum, etc).
187 ///
188 /// \param[in] options A set of boolean enumeration flags from the
189 /// TypeQueryOptions enumerations. \see TypeQueryOptions.
190 TypeQuery(const CompilerDecl &decl, TypeQueryOptions options = e_none);
191
192 /// Construct a type-match object using a CompilerContext array.
193 ///
194 /// Clients can manually create compiler contexts and use these to find
195 /// matches when searching for types. There are two types of contexts that
196 /// are supported when doing type searchs: type contexts and clang module
197 /// contexts. Type contexts have contexts that specify the type and its
198 /// containing declaration context like namespaces and classes. Clang module
199 /// contexts specify contexts more completely to find exact matches within
200 /// clang module debug information. They will include the modules that the
201 /// type is included in and any functions that the type might be defined in.
202 /// This allows very fine-grained type resolution.
203 ///
204 /// \param[in] context The compiler context to use when doing the search.
205 ///
206 /// \param[in] options A set of boolean enumeration flags from the
207 /// TypeQueryOptions enumerations. \see TypeQueryOptions.
208 TypeQuery(const llvm::ArrayRef<lldb_private::CompilerContext> &context,
209 TypeQueryOptions options = e_none);
210
211 /// Construct a type-match object that duplicates all matching criterea,
212 /// but not any searched symbol files or the type map for matches. This allows
213 /// the m_context to be modified prior to performing another search.
214 TypeQuery(const TypeQuery &rhs) = default;
215 /// Assign a type-match object that duplicates all matching criterea,
216 /// but not any searched symbol files or the type map for matches. This allows
217 /// the m_context to be modified prior to performing another search.
218 TypeQuery &operator=(const TypeQuery &rhs) = default;
219
220 /// Check of a CompilerContext array from matching type from a symbol file
221 /// matches the \a m_context.
222 ///
223 /// \param[in] context
224 /// A fully qualified CompilerContext array for a potential match that is
225 /// created by the symbol file prior to trying to actually resolve a type.
226 ///
227 /// \returns
228 /// True if the context matches, false if it doesn't. If e_exact_match
229 /// is set in m_options, then \a context must exactly match \a m_context. If
230 /// e_exact_match is not set, then the bottom m_context.size() objects in
231 /// \a context must match. This allows SymbolFile objects the fill in a
232 /// potential type basename match from the index into \a context, and see if
233 /// it matches prior to having to resolve a lldb_private::Type object for
234 /// the type from the index. This allows type parsing to be as efficient as
235 /// possible and only realize the types that match the query.
236 bool
237 ContextMatches(llvm::ArrayRef<lldb_private::CompilerContext> context) const;
238
239 /// Get the type basename to use when searching the type indexes in each
240 /// SymbolFile object.
241 ///
242 /// Debug information indexes often contain indexes that track the basename
243 /// of types only, not a fully qualified path. This allows the indexes to be
244 /// smaller and allows for efficient lookups.
245 ///
246 /// \returns
247 /// The type basename to use when doing lookups as a constant string.
248 ConstString GetTypeBasename() const;
249
250 /// Returns true if any matching languages have been specified in this type
251 /// matching object.
252 bool HasLanguage() const { return m_languages.has_value(); }
253
254 /// Add a language family to the list of languages that should produce a
255 /// match.
256 void AddLanguage(lldb::LanguageType language);
257
258 /// Set the list of languages that should produce a match to only the ones
259 /// specified in \ref languages.
260 void SetLanguages(LanguageSet languages);
261
262 /// Check if the language matches any languages that have been added to this
263 /// match object.
264 ///
265 /// \returns
266 /// True if no language have been specified, or if some language have been
267 /// added using AddLanguage(...) and they match. False otherwise.
268 bool LanguageMatches(lldb::LanguageType language) const;
269
270 bool GetExactMatch() const { return (m_options & e_exact_match) != 0; }
271
272 bool GetIgnoreModules() const { return (m_options & e_ignore_modules) != 0; }
273 void SetIgnoreModules(bool b) {
274 if (b)
275 m_options |= e_ignore_modules;
276 else
277 m_options &= ~e_ignore_modules;
278 }
279
280 bool GetStrictNamespaces() const {
281 return (m_options & e_strict_namespaces) != 0;
282 }
283 void SetStrictNamespaces(bool b) {
284 if (b)
285 m_options |= e_strict_namespaces;
286 else
287 m_options &= ~e_strict_namespaces;
288 }
289
290 /// The \a m_context can be used in two ways: normal types searching with
291 /// the context containing a stanadard declaration context for a type, or
292 /// with the context being more complete for exact matches in clang modules.
293 /// Set this to true if you wish to search for a type in clang module.
294 bool GetModuleSearch() const { return (m_options & e_module_search) != 0; }
295
296 /// Returns true if the type query is supposed to find only a single matching
297 /// type. Returns false if the type query should find all matches.
298 bool GetFindOne() const { return (m_options & e_find_one) != 0; }
299 void SetFindOne(bool b) {
300 if (b)
301 m_options |= e_find_one;
302 else
303 m_options &= ~e_find_one;
304 }
305
306 /// Returns true if the type query is supposed to treat the name to be
307 /// searched as a mangled name.
308 bool GetSearchByMangledName() const {
309 return (m_options & e_search_by_mangled_name) != 0;
310 }
311
312 void SetSearchByMangledName(bool b) {
313 if (b)
314 m_options |= e_search_by_mangled_name;
315 else
316 m_options &= ~e_search_by_mangled_name;
317 }
318
319 /// Access the internal compiler context array.
320 ///
321 /// Clients can use this to populate the context manually.
322 std::vector<lldb_private::CompilerContext> &GetContextRef() {
323 return m_context;
324 }
325
326 protected:
327 /// A full or partial compiler context array where the parent declaration
328 /// contexts appear at the top of the array starting at index zero and the
329 /// last entry contains the type and name of the type we are looking for.
330 std::vector<lldb_private::CompilerContext> m_context;
331 /// An options bitmask that contains enabled options for the type query.
332 /// \see TypeQueryOptions.
333 TypeQueryOptions m_options;
334 /// If this variable has a value, then the language family must match at least
335 /// one of the specified languages. If this variable has no value, then the
336 /// language of the type doesn't need to match any types that are searched.
337 std::optional<LanguageSet> m_languages;
338 };
339
340 /// This class tracks the state and results of a \ref TypeQuery.
341 ///
342 /// Any mutable state required for type lookups and the results are tracked in
343 /// this object.
344 class TypeResults {
345 public:
346 /// Construct a type results object
347 TypeResults() = default;
348
349 /// When types that match a TypeQuery are found, this API is used to insert
350 /// the matching types.
351 ///
352 /// \return
353 /// True if the type was added, false if the \a type_sp was already in the
354 /// results.
355 bool InsertUnique(const lldb::TypeSP &type_sp);
356
357 /// Check if the type matching has found all of the matches that it needs.
358 bool Done(const TypeQuery &query) const;
359
360 /// Check if a SymbolFile object has already been searched by this type match
361 /// object.
362 ///
363 /// This function will add \a sym_file to the set of SymbolFile objects if it
364 /// isn't already in the set and return \a false. Returns true if \a sym_file
365 /// was already in the set and doesn't need to be searched.
366 ///
367 /// Any clients that search for types should first check that the symbol file
368 /// has not already been searched. If this function returns true, the type
369 /// search function should early return to avoid duplicating type searchihng
370 /// efforts.
371 ///
372 /// \param[in] sym_file
373 /// A SymbolFile pointer that will be used to track which symbol files have
374 /// already been searched.
375 ///
376 /// \returns
377 /// True if the symbol file has been search already, false otherwise.
378 bool AlreadySearched(lldb_private::SymbolFile *sym_file);
379
380 /// Access the set of searched symbol files.
GetSearchedSymbolFiles()381 llvm::DenseSet<lldb_private::SymbolFile *> &GetSearchedSymbolFiles() {
382 return m_searched_symbol_files;
383 }
384
GetFirstType()385 lldb::TypeSP GetFirstType() const { return m_type_map.FirstType(); }
GetTypeMap()386 TypeMap &GetTypeMap() { return m_type_map; }
GetTypeMap()387 const TypeMap &GetTypeMap() const { return m_type_map; }
388
389 private:
390 /// Matching types get added to this map as type search continues.
391 TypeMap m_type_map;
392 /// This set is used to track and make sure we only perform lookups in a
393 /// symbol file one time.
394 llvm::DenseSet<lldb_private::SymbolFile *> m_searched_symbol_files;
395 };
396
397 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
398 public UserID {
399 public:
SymbolFileType(SymbolFile & symbol_file,lldb::user_id_t uid)400 SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
401 : UserID(uid), m_symbol_file(symbol_file) {}
402
403 SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp);
404
405 ~SymbolFileType() = default;
406
407 Type *operator->() { return GetType(); }
408
409 Type *GetType();
GetSymbolFile()410 SymbolFile &GetSymbolFile() const { return m_symbol_file; }
411
412 protected:
413 SymbolFile &m_symbol_file;
414 lldb::TypeSP m_type_sp;
415 };
416
417 class Type : public std::enable_shared_from_this<Type>, public UserID {
418 public:
419 enum EncodingDataType {
420 /// Invalid encoding.
421 eEncodingInvalid,
422 /// This type is the type whose UID is m_encoding_uid.
423 eEncodingIsUID,
424 /// This type is the type whose UID is m_encoding_uid with the const
425 /// qualifier added.
426 eEncodingIsConstUID,
427 /// This type is the type whose UID is m_encoding_uid with the restrict
428 /// qualifier added.
429 eEncodingIsRestrictUID,
430 /// This type is the type whose UID is m_encoding_uid with the volatile
431 /// qualifier added.
432 eEncodingIsVolatileUID,
433 /// This type is alias to a type whose UID is m_encoding_uid.
434 eEncodingIsTypedefUID,
435 /// This type is pointer to a type whose UID is m_encoding_uid.
436 eEncodingIsPointerUID,
437 /// This type is L value reference to a type whose UID is m_encoding_uid.
438 eEncodingIsLValueReferenceUID,
439 /// This type is R value reference to a type whose UID is m_encoding_uid.
440 eEncodingIsRValueReferenceUID,
441 /// This type is the type whose UID is m_encoding_uid as an atomic type.
442 eEncodingIsAtomicUID,
443 /// This type is the synthetic type whose UID is m_encoding_uid.
444 eEncodingIsSyntheticUID,
445 /// This type is a signed pointer.
446 eEncodingIsLLVMPtrAuthUID
447 };
448
449 enum class ResolveState : unsigned char {
450 Unresolved = 0,
451 Forward = 1,
452 Layout = 2,
453 Full = 3
454 };
455
456 void Dump(Stream *s, bool show_context,
457 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
458
459 void DumpTypeName(Stream *s);
460
461 /// Since Type instances only keep a "SymbolFile *" internally, other classes
462 /// like TypeImpl need make sure the module is still around before playing
463 /// with
464 /// Type instances. They can store a weak pointer to the Module;
465 lldb::ModuleSP GetModule();
466
467 /// GetModule may return module for compile unit's object file.
468 /// GetExeModule returns module for executable object file that contains
469 /// compile unit where type was actually defined.
470 /// GetModule and GetExeModule may return the same value.
471 lldb::ModuleSP GetExeModule();
472
473 void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name,
474 ExecutionContextScope *exe_scope);
475
GetSymbolFile()476 SymbolFile *GetSymbolFile() { return m_symbol_file; }
GetSymbolFile()477 const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
478
479 ConstString GetName();
480
481 ConstString GetBaseName();
482
483 llvm::Expected<uint64_t> GetByteSize(ExecutionContextScope *exe_scope);
484
485 llvm::Expected<uint32_t> GetNumChildren(bool omit_empty_base_classes);
486
487 bool IsAggregateType();
488
489 // Returns if the type is a templated decl. Does not look through typedefs.
490 bool IsTemplateType();
491
IsValidType()492 bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; }
493
IsTypedef()494 bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; }
495
496 lldb::TypeSP GetTypedefType();
497
GetName()498 ConstString GetName() const { return m_name; }
499
500 ConstString GetQualifiedName();
501
502 bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
503 AddressType address_type, DataExtractor &data);
504
505 bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
506 AddressType address_type, DataExtractor &data);
507
508 lldb::Format GetFormat();
509
510 lldb::Encoding GetEncoding(uint64_t &count);
511
GetSymbolContextScope()512 SymbolContextScope *GetSymbolContextScope() { return m_context; }
GetSymbolContextScope()513 const SymbolContextScope *GetSymbolContextScope() const { return m_context; }
SetSymbolContextScope(SymbolContextScope * context)514 void SetSymbolContextScope(SymbolContextScope *context) {
515 m_context = context;
516 }
517
518 const lldb_private::Declaration &GetDeclaration() const;
519
520 // Get the clang type, and resolve definitions for any
521 // class/struct/union/enum types completely.
522 CompilerType GetFullCompilerType();
523
524 // Get the clang type, and resolve definitions enough so that the type could
525 // have layout performed. This allows ptrs and refs to
526 // class/struct/union/enum types remain forward declarations.
527 CompilerType GetLayoutCompilerType();
528
529 // Get the clang type and leave class/struct/union/enum types as forward
530 // declarations if they haven't already been fully defined.
531 CompilerType GetForwardCompilerType();
532
533 static int Compare(const Type &a, const Type &b);
534
535 // Represents a parsed type name coming out of GetTypeScopeAndBasename. The
536 // structure holds StringRefs pointing to portions of the original name, and
537 // so must not be used after the name is destroyed.
538 struct ParsedName {
539 lldb::TypeClass type_class = lldb::eTypeClassAny;
540
541 // Scopes of the type, starting with the outermost. Absolute type references
542 // have a "::" as the first scope.
543 llvm::SmallVector<llvm::StringRef> scope;
544
545 llvm::StringRef basename;
546
547 friend bool operator==(const ParsedName &lhs, const ParsedName &rhs) {
548 return lhs.type_class == rhs.type_class && lhs.scope == rhs.scope &&
549 lhs.basename == rhs.basename;
550 }
551
552 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
553 const ParsedName &name) {
554 return os << llvm::formatv(
555 "Type::ParsedName({0:x}, [{1}], {2})",
556 llvm::to_underlying(name.type_class),
557 llvm::make_range(name.scope.begin(), name.scope.end()),
558 name.basename);
559 }
560 };
561 // From a fully qualified typename, split the type into the type basename and
562 // the remaining type scope (namespaces/classes).
563 static std::optional<ParsedName>
564 GetTypeScopeAndBasename(llvm::StringRef name);
565
SetEncodingType(Type * encoding_type)566 void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }
567
568 uint32_t GetEncodingMask();
569
570 typedef uint32_t Payload;
571 /// Return the language-specific payload.
GetPayload()572 Payload GetPayload() { return m_payload; }
573 /// Return the language-specific payload.
SetPayload(Payload opaque_payload)574 void SetPayload(Payload opaque_payload) { m_payload = opaque_payload; }
575
576 protected:
577 ConstString m_name;
578 SymbolFile *m_symbol_file = nullptr;
579 /// The symbol context in which this type is defined.
580 SymbolContextScope *m_context = nullptr;
581 Type *m_encoding_type = nullptr;
582 lldb::user_id_t m_encoding_uid = LLDB_INVALID_UID;
583 EncodingDataType m_encoding_uid_type = eEncodingInvalid;
584 uint64_t m_byte_size : 63;
585 uint64_t m_byte_size_has_value : 1;
586 Declaration m_decl;
587 CompilerType m_compiler_type;
588 ResolveState m_compiler_type_resolve_state = ResolveState::Unresolved;
589 /// Language-specific flags.
590 Payload m_payload;
591
592 Type *GetEncodingType();
593
594 bool ResolveCompilerType(ResolveState compiler_type_resolve_state);
595 private:
596 /// Only allow Symbol File to create types, as they should own them by keeping
597 /// them in their TypeList. \see SymbolFileCommon::MakeType() reference in the
598 /// header documentation here so users will know what function to use if the
599 /// get a compile error.
600 friend class lldb_private::SymbolFileCommon;
601
602 Type(lldb::user_id_t uid, SymbolFile *symbol_file, ConstString name,
603 std::optional<uint64_t> byte_size, SymbolContextScope *context,
604 lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type,
605 const Declaration &decl, const CompilerType &compiler_qual_type,
606 ResolveState compiler_type_resolve_state, uint32_t opaque_payload = 0);
607
608 // This makes an invalid type. Used for functions that return a Type when
609 // they get an error.
610 Type();
611
612 Type(Type &t) = default;
613
614 Type(Type &&t) = default;
615
616 Type &operator=(const Type &t) = default;
617
618 Type &operator=(Type &&t) = default;
619 };
620
621 // the two classes here are used by the public API as a backend to the SBType
622 // and SBTypeList classes
623
624 class TypeImpl {
625 public:
626 TypeImpl() = default;
627
628 ~TypeImpl() = default;
629
630 TypeImpl(const lldb::TypeSP &type_sp);
631
632 TypeImpl(const CompilerType &compiler_type);
633
634 TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
635
636 TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic);
637
638 void SetType(const lldb::TypeSP &type_sp);
639
640 void SetType(const CompilerType &compiler_type);
641
642 void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
643
644 void SetType(const CompilerType &compiler_type, const CompilerType &dynamic);
645
646 bool operator==(const TypeImpl &rhs) const;
647
648 bool operator!=(const TypeImpl &rhs) const;
649
650 bool IsValid() const;
651
652 explicit operator bool() const;
653
654 void Clear();
655
656 lldb::ModuleSP GetModule() const;
657
658 ConstString GetName() const;
659
660 ConstString GetDisplayTypeName() const;
661
662 TypeImpl GetPointerType() const;
663
664 TypeImpl GetPointeeType() const;
665
666 TypeImpl GetReferenceType() const;
667
668 TypeImpl GetTypedefedType() const;
669
670 TypeImpl GetDereferencedType() const;
671
672 TypeImpl GetUnqualifiedType() const;
673
674 TypeImpl GetCanonicalType() const;
675
676 CompilerType GetCompilerType(bool prefer_dynamic);
677
678 CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic);
679
680 bool GetDescription(lldb_private::Stream &strm,
681 lldb::DescriptionLevel description_level);
682
683 CompilerType FindDirectNestedType(llvm::StringRef name);
684
685 private:
686 bool CheckModule(lldb::ModuleSP &module_sp) const;
687 bool CheckExeModule(lldb::ModuleSP &module_sp) const;
688 bool CheckModuleCommon(const lldb::ModuleWP &input_module_wp,
689 lldb::ModuleSP &module_sp) const;
690
691 lldb::ModuleWP m_module_wp;
692 lldb::ModuleWP m_exe_module_wp;
693 CompilerType m_static_type;
694 CompilerType m_dynamic_type;
695 };
696
697 class TypeListImpl {
698 public:
699 TypeListImpl() = default;
700
Append(const lldb::TypeImplSP & type)701 void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); }
702
703 class AppendVisitor {
704 public:
AppendVisitor(TypeListImpl & type_list)705 AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
706
operator()707 void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); }
708
709 private:
710 TypeListImpl &m_type_list;
711 };
712
713 void Append(const lldb_private::TypeList &type_list);
714
GetTypeAtIndex(size_t idx)715 lldb::TypeImplSP GetTypeAtIndex(size_t idx) {
716 lldb::TypeImplSP type_sp;
717 if (idx < GetSize())
718 type_sp = m_content[idx];
719 return type_sp;
720 }
721
GetSize()722 size_t GetSize() { return m_content.size(); }
723
724 private:
725 std::vector<lldb::TypeImplSP> m_content;
726 };
727
728 class TypeMemberImpl {
729 public:
730 TypeMemberImpl() = default;
731
732 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset,
733 ConstString name, uint32_t bitfield_bit_size = 0,
734 bool is_bitfield = false)
m_type_impl_sp(type_impl_sp)735 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name),
736 m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {}
737
TypeMemberImpl(const lldb::TypeImplSP & type_impl_sp,uint64_t bit_offset)738 TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset)
739 : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset),
740 m_bitfield_bit_size(0), m_is_bitfield(false) {
741 if (m_type_impl_sp)
742 m_name = m_type_impl_sp->GetName();
743 }
744
GetTypeImpl()745 const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; }
746
GetName()747 ConstString GetName() const { return m_name; }
748
GetBitOffset()749 uint64_t GetBitOffset() const { return m_bit_offset; }
750
GetBitfieldBitSize()751 uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; }
752
SetBitfieldBitSize(uint32_t bitfield_bit_size)753 void SetBitfieldBitSize(uint32_t bitfield_bit_size) {
754 m_bitfield_bit_size = bitfield_bit_size;
755 }
756
GetIsBitfield()757 bool GetIsBitfield() const { return m_is_bitfield; }
758
SetIsBitfield(bool is_bitfield)759 void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; }
760
761 protected:
762 lldb::TypeImplSP m_type_impl_sp;
763 uint64_t m_bit_offset = 0;
764 ConstString m_name;
765 uint32_t m_bitfield_bit_size = 0; // Bit size for bitfield members only
766 bool m_is_bitfield = false;
767 };
768
769 ///
770 /// Sometimes you can find the name of the type corresponding to an object, but
771 /// we don't have debug
772 /// information for it. If that is the case, you can return one of these
773 /// objects, and then if it
774 /// has a full type, you can use that, but if not at least you can print the
775 /// name for informational
776 /// purposes.
777 ///
778
779 class TypeAndOrName {
780 public:
781 TypeAndOrName() = default;
782 TypeAndOrName(lldb::TypeSP &type_sp);
783 TypeAndOrName(const CompilerType &compiler_type);
784 TypeAndOrName(const char *type_str);
785 TypeAndOrName(ConstString &type_const_string);
786
787 bool operator==(const TypeAndOrName &other) const;
788
789 bool operator!=(const TypeAndOrName &other) const;
790
791 ConstString GetName() const;
792
GetCompilerType()793 CompilerType GetCompilerType() const { return m_compiler_type; }
794
795 void SetName(ConstString type_name);
796
797 void SetName(const char *type_name_cstr);
798
799 void SetName(llvm::StringRef name);
800
801 void SetTypeSP(lldb::TypeSP type_sp);
802
803 void SetCompilerType(CompilerType compiler_type);
804
805 bool IsEmpty() const;
806
807 bool HasName() const;
808
809 bool HasCompilerType() const;
810
HasType()811 bool HasType() const { return HasCompilerType(); }
812
813 void Clear();
814
815 explicit operator bool() { return !IsEmpty(); }
816
817 private:
818 CompilerType m_compiler_type;
819 ConstString m_type_name;
820 };
821
822 class TypeMemberFunctionImpl {
823 public:
824 TypeMemberFunctionImpl() = default;
825
TypeMemberFunctionImpl(const CompilerType & type,const CompilerDecl & decl,const std::string & name,const lldb::MemberFunctionKind & kind)826 TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl,
827 const std::string &name,
828 const lldb::MemberFunctionKind &kind)
829 : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {}
830
831 bool IsValid();
832
833 ConstString GetName() const;
834
835 ConstString GetMangledName() const;
836
837 CompilerType GetType() const;
838
839 CompilerType GetReturnType() const;
840
841 size_t GetNumArguments() const;
842
843 CompilerType GetArgumentAtIndex(size_t idx) const;
844
845 lldb::MemberFunctionKind GetKind() const;
846
847 bool GetDescription(Stream &stream);
848
849 protected:
850 std::string GetPrintableTypeName();
851
852 private:
853 CompilerType m_type;
854 CompilerDecl m_decl;
855 ConstString m_name;
856 lldb::MemberFunctionKind m_kind = lldb::eMemberFunctionKindUnknown;
857 };
858
859 class TypeEnumMemberImpl {
860 public:
TypeEnumMemberImpl()861 TypeEnumMemberImpl() : m_name("<invalid>") {}
862
863 TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, ConstString name,
864 const llvm::APSInt &value);
865
866 TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs) = default;
867
868 TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs);
869
IsValid()870 bool IsValid() { return m_valid; }
871
GetName()872 ConstString GetName() const { return m_name; }
873
GetIntegerType()874 const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; }
875
GetValueAsUnsigned()876 uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); }
877
GetValueAsSigned()878 int64_t GetValueAsSigned() const { return m_value.getSExtValue(); }
879
880 protected:
881 lldb::TypeImplSP m_integer_type_sp;
882 ConstString m_name;
883 llvm::APSInt m_value;
884 bool m_valid = false;
885 };
886
887 class TypeEnumMemberListImpl {
888 public:
889 TypeEnumMemberListImpl() = default;
890
Append(const lldb::TypeEnumMemberImplSP & type)891 void Append(const lldb::TypeEnumMemberImplSP &type) {
892 m_content.push_back(type);
893 }
894
895 void Append(const lldb_private::TypeEnumMemberListImpl &type_list);
896
GetTypeEnumMemberAtIndex(size_t idx)897 lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) {
898 lldb::TypeEnumMemberImplSP enum_member;
899 if (idx < GetSize())
900 enum_member = m_content[idx];
901 return enum_member;
902 }
903
GetSize()904 size_t GetSize() { return m_content.size(); }
905
906 private:
907 std::vector<lldb::TypeEnumMemberImplSP> m_content;
908 };
909
910 } // namespace lldb_private
911
912 #endif // LLDB_SYMBOL_TYPE_H
913