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

source code of lldb/include/lldb/Symbol/Type.h