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