1 //===-- Type.h --------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_Type_h_
11 #define liblldb_Type_h_
12 
13 #include "lldb/Core/ClangForward.h"
14 #include "lldb/Symbol/CompilerDecl.h"
15 #include "lldb/Symbol/CompilerType.h"
16 #include "lldb/Symbol/Declaration.h"
17 #include "lldb/Utility/ConstString.h"
18 #include "lldb/Utility/UserID.h"
19 #include "lldb/lldb-private.h"
20 
21 #include "llvm/ADT/APSInt.h"
22 
23 #include <set>
24 
25 namespace lldb_private {
26 //----------------------------------------------------------------------
27 // CompilerContext allows an array of these items to be passed to perform
28 // detailed lookups in SymbolVendor and SymbolFile functions.
29 //----------------------------------------------------------------------
30 struct CompilerContext {
CompilerContextCompilerContext31   CompilerContext(CompilerContextKind t, const ConstString &n)
32       : type(t), name(n) {}
33 
34   bool operator==(const CompilerContext &rhs) const {
35     return type == rhs.type && name == rhs.name;
36   }
37 
38   void Dump() const;
39 
40   CompilerContextKind type;
41   ConstString name;
42 };
43 
44 class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
45                        public UserID {
46 public:
SymbolFileType(SymbolFile & symbol_file,lldb::user_id_t uid)47   SymbolFileType(SymbolFile &symbol_file, lldb::user_id_t uid)
48       : UserID(uid), m_symbol_file(symbol_file) {}
49 
50   SymbolFileType(SymbolFile &symbol_file, const lldb::TypeSP &type_sp);
51 
~SymbolFileType()52   ~SymbolFileType() {}
53 
54   Type *operator->() { return GetType(); }
55 
56   Type *GetType();
57 
58 protected:
59   SymbolFile &m_symbol_file;
60   lldb::TypeSP m_type_sp;
61 };
62 
63 class Type : public std::enable_shared_from_this<Type>, public UserID {
64 public:
65   typedef enum EncodingDataTypeTag {
66     eEncodingInvalid,
67     eEncodingIsUID,      ///< This type is the type whose UID is m_encoding_uid
68     eEncodingIsConstUID, ///< This type is the type whose UID is m_encoding_uid
69                          ///with the const qualifier added
70     eEncodingIsRestrictUID, ///< This type is the type whose UID is
71                             ///m_encoding_uid with the restrict qualifier added
72     eEncodingIsVolatileUID, ///< This type is the type whose UID is
73                             ///m_encoding_uid with the volatile qualifier added
74     eEncodingIsTypedefUID,  ///< This type is pointer to a type whose UID is
75                             ///m_encoding_uid
76     eEncodingIsPointerUID,  ///< This type is pointer to a type whose UID is
77                             ///m_encoding_uid
78     eEncodingIsLValueReferenceUID, ///< This type is L value reference to a type
79                                    ///whose UID is m_encoding_uid
80     eEncodingIsRValueReferenceUID, ///< This type is R value reference to a type
81                                    ///whose UID is m_encoding_uid
82     eEncodingIsSyntheticUID
83   } EncodingDataType;
84 
85   // We must force the underlying type of the enum to be unsigned here.  Not
86   // all compilers behave the same with regards to the default underlying type
87   // of an enum, but because this enum is used in an enum bitfield and integer
88   // comparisons are done with the value we need to guarantee that it's always
89   // unsigned so that, for example, eResolveStateFull doesn't compare less than
90   // eResolveStateUnresolved when used in a 2-bit bitfield.
91   typedef enum ResolveStateTag : unsigned {
92     eResolveStateUnresolved = 0,
93     eResolveStateForward = 1,
94     eResolveStateLayout = 2,
95     eResolveStateFull = 3
96   } ResolveState;
97 
98   Type(lldb::user_id_t uid, SymbolFile *symbol_file, const ConstString &name,
99        uint64_t byte_size, SymbolContextScope *context,
100        lldb::user_id_t encoding_uid, EncodingDataType encoding_uid_type,
101        const Declaration &decl, const CompilerType &compiler_qual_type,
102        ResolveState compiler_type_resolve_state);
103 
104   // This makes an invalid type.  Used for functions that return a Type when
105   // they get an error.
106   Type();
107 
108   Type(const Type &rhs);
109 
110   const Type &operator=(const Type &rhs);
111 
112   void Dump(Stream *s, bool show_context);
113 
114   void DumpTypeName(Stream *s);
115 
116   // Since Type instances only keep a "SymbolFile *" internally, other classes
117   // like TypeImpl need make sure the module is still around before playing
118   // with
119   // Type instances. They can store a weak pointer to the Module;
120   lldb::ModuleSP GetModule();
121 
122   void GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name);
123 
GetSymbolFile()124   SymbolFile *GetSymbolFile() { return m_symbol_file; }
GetSymbolFile()125   const SymbolFile *GetSymbolFile() const { return m_symbol_file; }
126 
127   TypeList *GetTypeList();
128 
129   const ConstString &GetName();
130 
131   uint64_t GetByteSize();
132 
133   uint32_t GetNumChildren(bool omit_empty_base_classes);
134 
135   bool IsAggregateType();
136 
IsValidType()137   bool IsValidType() { return m_encoding_uid_type != eEncodingInvalid; }
138 
IsTypedef()139   bool IsTypedef() { return m_encoding_uid_type == eEncodingIsTypedefUID; }
140 
141   lldb::TypeSP GetTypedefType();
142 
GetName()143   const ConstString &GetName() const { return m_name; }
144 
145   ConstString GetQualifiedName();
146 
147   void DumpValue(ExecutionContext *exe_ctx, Stream *s,
148                  const DataExtractor &data, uint32_t data_offset,
149                  bool show_type, bool show_summary, bool verbose,
150                  lldb::Format format = lldb::eFormatDefault);
151 
152   bool DumpValueInMemory(ExecutionContext *exe_ctx, Stream *s,
153                          lldb::addr_t address, AddressType address_type,
154                          bool show_types, bool show_summary, bool verbose);
155 
156   bool ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
157                       AddressType address_type, DataExtractor &data);
158 
159   bool WriteToMemory(ExecutionContext *exe_ctx, lldb::addr_t address,
160                      AddressType address_type, DataExtractor &data);
161 
162   bool GetIsDeclaration() const;
163 
164   void SetIsDeclaration(bool b);
165 
166   bool GetIsExternal() const;
167 
168   void SetIsExternal(bool b);
169 
170   lldb::Format GetFormat();
171 
172   lldb::Encoding GetEncoding(uint64_t &count);
173 
GetSymbolContextScope()174   SymbolContextScope *GetSymbolContextScope() { return m_context; }
GetSymbolContextScope()175   const SymbolContextScope *GetSymbolContextScope() const { return m_context; }
SetSymbolContextScope(SymbolContextScope * context)176   void SetSymbolContextScope(SymbolContextScope *context) {
177     m_context = context;
178   }
179 
180   const lldb_private::Declaration &GetDeclaration() const;
181 
182   // Get the clang type, and resolve definitions for any
183   // class/struct/union/enum types completely.
184   CompilerType GetFullCompilerType();
185 
186   // Get the clang type, and resolve definitions enough so that the type could
187   // have layout performed. This allows ptrs and refs to
188   // class/struct/union/enum types remain forward declarations.
189   CompilerType GetLayoutCompilerType();
190 
191   // Get the clang type and leave class/struct/union/enum types as forward
192   // declarations if they haven't already been fully defined.
193   CompilerType GetForwardCompilerType();
194 
195   static int Compare(const Type &a, const Type &b);
196 
197   // From a fully qualified typename, split the type into the type basename and
198   // the remaining type scope (namespaces/classes).
199   static bool GetTypeScopeAndBasename(const llvm::StringRef& name,
200                                       llvm::StringRef &scope,
201                                       llvm::StringRef &basename,
202                                       lldb::TypeClass &type_class);
SetEncodingType(Type * encoding_type)203   void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; }
204 
205   uint32_t GetEncodingMask();
206 
IsCompleteObjCClass()207   bool IsCompleteObjCClass() { return m_flags.is_complete_objc_class; }
208 
SetIsCompleteObjCClass(bool is_complete_objc_class)209   void SetIsCompleteObjCClass(bool is_complete_objc_class) {
210     m_flags.is_complete_objc_class = is_complete_objc_class;
211   }
212 
213 protected:
214   ConstString m_name;
215   SymbolFile *m_symbol_file;
216   SymbolContextScope
217       *m_context; // The symbol context in which this type is defined
218   Type *m_encoding_type;
219   lldb::user_id_t m_encoding_uid;
220   EncodingDataType m_encoding_uid_type;
221   uint64_t m_byte_size;
222   Declaration m_decl;
223   CompilerType m_compiler_type;
224 
225   struct Flags {
226 #ifdef __GNUC__
227     // using unsigned type here to work around a very noisy gcc warning
228     unsigned compiler_type_resolve_state : 2;
229 #else
230     ResolveState compiler_type_resolve_state : 2;
231 #endif
232     bool is_complete_objc_class : 1;
233   } m_flags;
234 
235   Type *GetEncodingType();
236 
237   bool ResolveClangType(ResolveState compiler_type_resolve_state);
238 };
239 
240 // these classes are used to back the SBType* objects
241 
242 class TypePair {
243 public:
TypePair()244   TypePair() : compiler_type(), type_sp() {}
245 
TypePair(CompilerType type)246   TypePair(CompilerType type) : compiler_type(type), type_sp() {}
247 
TypePair(lldb::TypeSP type)248   TypePair(lldb::TypeSP type) : compiler_type(), type_sp(type) {
249     compiler_type = type_sp->GetForwardCompilerType();
250   }
251 
IsValid()252   bool IsValid() const {
253     return compiler_type.IsValid() || (type_sp.get() != nullptr);
254   }
255 
256   explicit operator bool() const { return IsValid(); }
257 
258   bool operator==(const TypePair &rhs) const {
259     return compiler_type == rhs.compiler_type &&
260            type_sp.get() == rhs.type_sp.get();
261   }
262 
263   bool operator!=(const TypePair &rhs) const {
264     return compiler_type != rhs.compiler_type ||
265            type_sp.get() != rhs.type_sp.get();
266   }
267 
Clear()268   void Clear() {
269     compiler_type.Clear();
270     type_sp.reset();
271   }
272 
GetName()273   ConstString GetName() const {
274     if (type_sp)
275       return type_sp->GetName();
276     if (compiler_type)
277       return compiler_type.GetTypeName();
278     return ConstString();
279   }
280 
GetDisplayTypeName()281   ConstString GetDisplayTypeName() const {
282     if (type_sp)
283       return type_sp->GetForwardCompilerType().GetDisplayTypeName();
284     if (compiler_type)
285       return compiler_type.GetDisplayTypeName();
286     return ConstString();
287   }
288 
SetType(CompilerType type)289   void SetType(CompilerType type) {
290     type_sp.reset();
291     compiler_type = type;
292   }
293 
SetType(lldb::TypeSP type)294   void SetType(lldb::TypeSP type) {
295     type_sp = type;
296     if (type_sp)
297       compiler_type = type_sp->GetForwardCompilerType();
298     else
299       compiler_type.Clear();
300   }
301 
GetTypeSP()302   lldb::TypeSP GetTypeSP() const { return type_sp; }
303 
GetCompilerType()304   CompilerType GetCompilerType() const { return compiler_type; }
305 
GetPointerType()306   CompilerType GetPointerType() const {
307     if (type_sp)
308       return type_sp->GetForwardCompilerType().GetPointerType();
309     return compiler_type.GetPointerType();
310   }
311 
GetPointeeType()312   CompilerType GetPointeeType() const {
313     if (type_sp)
314       return type_sp->GetForwardCompilerType().GetPointeeType();
315     return compiler_type.GetPointeeType();
316   }
317 
GetReferenceType()318   CompilerType GetReferenceType() const {
319     if (type_sp)
320       return type_sp->GetForwardCompilerType().GetLValueReferenceType();
321     else
322       return compiler_type.GetLValueReferenceType();
323   }
324 
GetTypedefedType()325   CompilerType GetTypedefedType() const {
326     if (type_sp)
327       return type_sp->GetForwardCompilerType().GetTypedefedType();
328     else
329       return compiler_type.GetTypedefedType();
330   }
331 
GetDereferencedType()332   CompilerType GetDereferencedType() const {
333     if (type_sp)
334       return type_sp->GetForwardCompilerType().GetNonReferenceType();
335     else
336       return compiler_type.GetNonReferenceType();
337   }
338 
GetUnqualifiedType()339   CompilerType GetUnqualifiedType() const {
340     if (type_sp)
341       return type_sp->GetForwardCompilerType().GetFullyUnqualifiedType();
342     else
343       return compiler_type.GetFullyUnqualifiedType();
344   }
345 
GetCanonicalType()346   CompilerType GetCanonicalType() const {
347     if (type_sp)
348       return type_sp->GetForwardCompilerType().GetCanonicalType();
349     return compiler_type.GetCanonicalType();
350   }
351 
GetTypeSystem()352   TypeSystem *GetTypeSystem() const { return compiler_type.GetTypeSystem(); }
353 
GetModule()354   lldb::ModuleSP GetModule() const {
355     if (type_sp)
356       return type_sp->GetModule();
357     return lldb::ModuleSP();
358   }
359 
360 protected:
361   CompilerType compiler_type;
362   lldb::TypeSP type_sp;
363 };
364 
365 // the two classes here are used by the public API as a backend to the SBType
366 // and SBTypeList classes
367 
368 class TypeImpl {
369 public:
370   TypeImpl();
371 
~TypeImpl()372   ~TypeImpl() {}
373 
374   TypeImpl(const TypeImpl &rhs);
375 
376   TypeImpl(const lldb::TypeSP &type_sp);
377 
378   TypeImpl(const CompilerType &compiler_type);
379 
380   TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
381 
382   TypeImpl(const CompilerType &compiler_type, const CompilerType &dynamic);
383 
384   TypeImpl(const TypePair &pair, const CompilerType &dynamic);
385 
386   void SetType(const lldb::TypeSP &type_sp);
387 
388   void SetType(const CompilerType &compiler_type);
389 
390   void SetType(const lldb::TypeSP &type_sp, const CompilerType &dynamic);
391 
392   void SetType(const CompilerType &compiler_type, const CompilerType &dynamic);
393 
394   void SetType(const TypePair &pair, const CompilerType &dynamic);
395 
396   TypeImpl &operator=(const TypeImpl &rhs);
397 
398   bool operator==(const TypeImpl &rhs) const;
399 
400   bool operator!=(const TypeImpl &rhs) const;
401 
402   bool IsValid() const;
403 
404   explicit operator bool() const;
405 
406   void Clear();
407 
408   ConstString GetName() const;
409 
410   ConstString GetDisplayTypeName() const;
411 
412   TypeImpl GetPointerType() const;
413 
414   TypeImpl GetPointeeType() const;
415 
416   TypeImpl GetReferenceType() const;
417 
418   TypeImpl GetTypedefedType() const;
419 
420   TypeImpl GetDereferencedType() const;
421 
422   TypeImpl GetUnqualifiedType() const;
423 
424   TypeImpl GetCanonicalType() const;
425 
426   CompilerType GetCompilerType(bool prefer_dynamic);
427 
428   TypeSystem *GetTypeSystem(bool prefer_dynamic);
429 
430   bool GetDescription(lldb_private::Stream &strm,
431                       lldb::DescriptionLevel description_level);
432 
433 private:
434   bool CheckModule(lldb::ModuleSP &module_sp) const;
435 
436   lldb::ModuleWP m_module_wp;
437   TypePair m_static_type;
438   CompilerType m_dynamic_type;
439 };
440 
441 class TypeListImpl {
442 public:
TypeListImpl()443   TypeListImpl() : m_content() {}
444 
Append(const lldb::TypeImplSP & type)445   void Append(const lldb::TypeImplSP &type) { m_content.push_back(type); }
446 
447   class AppendVisitor {
448   public:
AppendVisitor(TypeListImpl & type_list)449     AppendVisitor(TypeListImpl &type_list) : m_type_list(type_list) {}
450 
operator()451     void operator()(const lldb::TypeImplSP &type) { m_type_list.Append(type); }
452 
453   private:
454     TypeListImpl &m_type_list;
455   };
456 
457   void Append(const lldb_private::TypeList &type_list);
458 
GetTypeAtIndex(size_t idx)459   lldb::TypeImplSP GetTypeAtIndex(size_t idx) {
460     lldb::TypeImplSP type_sp;
461     if (idx < GetSize())
462       type_sp = m_content[idx];
463     return type_sp;
464   }
465 
GetSize()466   size_t GetSize() { return m_content.size(); }
467 
468 private:
469   std::vector<lldb::TypeImplSP> m_content;
470 };
471 
472 class TypeMemberImpl {
473 public:
TypeMemberImpl()474   TypeMemberImpl()
475       : m_type_impl_sp(), m_bit_offset(0), m_name(), m_bitfield_bit_size(0),
476         m_is_bitfield(false)
477 
478   {}
479 
480   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset,
481                  const ConstString &name, uint32_t bitfield_bit_size = 0,
482                  bool is_bitfield = false)
m_type_impl_sp(type_impl_sp)483       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(name),
484         m_bitfield_bit_size(bitfield_bit_size), m_is_bitfield(is_bitfield) {}
485 
TypeMemberImpl(const lldb::TypeImplSP & type_impl_sp,uint64_t bit_offset)486   TypeMemberImpl(const lldb::TypeImplSP &type_impl_sp, uint64_t bit_offset)
487       : m_type_impl_sp(type_impl_sp), m_bit_offset(bit_offset), m_name(),
488         m_bitfield_bit_size(0), m_is_bitfield(false) {
489     if (m_type_impl_sp)
490       m_name = m_type_impl_sp->GetName();
491   }
492 
GetTypeImpl()493   const lldb::TypeImplSP &GetTypeImpl() { return m_type_impl_sp; }
494 
GetName()495   const ConstString &GetName() const { return m_name; }
496 
GetBitOffset()497   uint64_t GetBitOffset() const { return m_bit_offset; }
498 
GetBitfieldBitSize()499   uint32_t GetBitfieldBitSize() const { return m_bitfield_bit_size; }
500 
SetBitfieldBitSize(uint32_t bitfield_bit_size)501   void SetBitfieldBitSize(uint32_t bitfield_bit_size) {
502     m_bitfield_bit_size = bitfield_bit_size;
503   }
504 
GetIsBitfield()505   bool GetIsBitfield() const { return m_is_bitfield; }
506 
SetIsBitfield(bool is_bitfield)507   void SetIsBitfield(bool is_bitfield) { m_is_bitfield = is_bitfield; }
508 
509 protected:
510   lldb::TypeImplSP m_type_impl_sp;
511   uint64_t m_bit_offset;
512   ConstString m_name;
513   uint32_t m_bitfield_bit_size; // Bit size for bitfield members only
514   bool m_is_bitfield;
515 };
516 
517 ///
518 /// Sometimes you can find the name of the type corresponding to an object, but
519 /// we don't have debug
520 /// information for it.  If that is the case, you can return one of these
521 /// objects, and then if it
522 /// has a full type, you can use that, but if not at least you can print the
523 /// name for informational
524 /// purposes.
525 ///
526 
527 class TypeAndOrName {
528 public:
529   TypeAndOrName();
530   TypeAndOrName(lldb::TypeSP &type_sp);
531   TypeAndOrName(const CompilerType &compiler_type);
532   TypeAndOrName(const char *type_str);
533   TypeAndOrName(const TypeAndOrName &rhs);
534   TypeAndOrName(ConstString &type_const_string);
535 
536   TypeAndOrName &operator=(const TypeAndOrName &rhs);
537 
538   bool operator==(const TypeAndOrName &other) const;
539 
540   bool operator!=(const TypeAndOrName &other) const;
541 
542   ConstString GetName() const;
543 
GetTypeSP()544   lldb::TypeSP GetTypeSP() const { return m_type_pair.GetTypeSP(); }
545 
GetCompilerType()546   CompilerType GetCompilerType() const { return m_type_pair.GetCompilerType(); }
547 
548   void SetName(const ConstString &type_name);
549 
550   void SetName(const char *type_name_cstr);
551 
552   void SetTypeSP(lldb::TypeSP type_sp);
553 
554   void SetCompilerType(CompilerType compiler_type);
555 
556   bool IsEmpty() const;
557 
558   bool HasName() const;
559 
560   bool HasTypeSP() const;
561 
562   bool HasCompilerType() const;
563 
HasType()564   bool HasType() const { return HasTypeSP() || HasCompilerType(); }
565 
566   void Clear();
567 
568   explicit operator bool() { return !IsEmpty(); }
569 
570 private:
571   TypePair m_type_pair;
572   ConstString m_type_name;
573 };
574 
575 class TypeMemberFunctionImpl {
576 public:
TypeMemberFunctionImpl()577   TypeMemberFunctionImpl()
578       : m_type(), m_decl(), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) {
579   }
580 
TypeMemberFunctionImpl(const CompilerType & type,const CompilerDecl & decl,const std::string & name,const lldb::MemberFunctionKind & kind)581   TypeMemberFunctionImpl(const CompilerType &type, const CompilerDecl &decl,
582                          const std::string &name,
583                          const lldb::MemberFunctionKind &kind)
584       : m_type(type), m_decl(decl), m_name(name), m_kind(kind) {}
585 
586   bool IsValid();
587 
588   ConstString GetName() const;
589 
590   ConstString GetMangledName() const;
591 
592   CompilerType GetType() const;
593 
594   CompilerType GetReturnType() const;
595 
596   size_t GetNumArguments() const;
597 
598   CompilerType GetArgumentAtIndex(size_t idx) const;
599 
600   lldb::MemberFunctionKind GetKind() const;
601 
602   bool GetDescription(Stream &stream);
603 
604 protected:
605   std::string GetPrintableTypeName();
606 
607 private:
608   CompilerType m_type;
609   CompilerDecl m_decl;
610   ConstString m_name;
611   lldb::MemberFunctionKind m_kind;
612 };
613 
614 class TypeEnumMemberImpl {
615 public:
TypeEnumMemberImpl()616   TypeEnumMemberImpl()
617       : m_integer_type_sp(), m_name("<invalid>"), m_value(), m_valid(false) {}
618 
619   TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp,
620                      const ConstString &name, const llvm::APSInt &value);
621 
TypeEnumMemberImpl(const TypeEnumMemberImpl & rhs)622   TypeEnumMemberImpl(const TypeEnumMemberImpl &rhs)
623       : m_integer_type_sp(rhs.m_integer_type_sp), m_name(rhs.m_name),
624         m_value(rhs.m_value), m_valid(rhs.m_valid) {}
625 
626   TypeEnumMemberImpl &operator=(const TypeEnumMemberImpl &rhs);
627 
IsValid()628   bool IsValid() { return m_valid; }
629 
GetName()630   const ConstString &GetName() const { return m_name; }
631 
GetIntegerType()632   const lldb::TypeImplSP &GetIntegerType() const { return m_integer_type_sp; }
633 
GetValueAsUnsigned()634   uint64_t GetValueAsUnsigned() const { return m_value.getZExtValue(); }
635 
GetValueAsSigned()636   int64_t GetValueAsSigned() const { return m_value.getSExtValue(); }
637 
638 protected:
639   lldb::TypeImplSP m_integer_type_sp;
640   ConstString m_name;
641   llvm::APSInt m_value;
642   bool m_valid;
643 };
644 
645 class TypeEnumMemberListImpl {
646 public:
TypeEnumMemberListImpl()647   TypeEnumMemberListImpl() : m_content() {}
648 
Append(const lldb::TypeEnumMemberImplSP & type)649   void Append(const lldb::TypeEnumMemberImplSP &type) {
650     m_content.push_back(type);
651   }
652 
653   void Append(const lldb_private::TypeEnumMemberListImpl &type_list);
654 
GetTypeEnumMemberAtIndex(size_t idx)655   lldb::TypeEnumMemberImplSP GetTypeEnumMemberAtIndex(size_t idx) {
656     lldb::TypeEnumMemberImplSP enum_member;
657     if (idx < GetSize())
658       enum_member = m_content[idx];
659     return enum_member;
660   }
661 
GetSize()662   size_t GetSize() { return m_content.size(); }
663 
664 private:
665   std::vector<lldb::TypeEnumMemberImplSP> m_content;
666 };
667 
668 } // namespace lldb_private
669 
670 #endif // liblldb_Type_h_
671