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