blob: a7f93fc62e3acd90f36d4836fbc0b72775e13e5a [file] [log] [blame]
Ryan Brown57bee1e2015-09-14 22:45:11 +00001//===-- GoASTContext.cpp ----------------------------------------*- 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#include <mutex>
11#include <utility>
12#include <vector>
13
14#include "lldb/Core/UniqueCStringMap.h"
15#include "lldb/Core/ValueObject.h"
16#include "lldb/DataFormatters/StringPrinter.h"
17#include "lldb/Symbol/CompilerType.h"
18#include "lldb/Symbol/SymbolFile.h"
19#include "lldb/Symbol/GoASTContext.h"
20#include "lldb/Symbol/Type.h"
21#include "lldb/Target/ExecutionContext.h"
22
23#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h"
24
25using namespace lldb;
26
27namespace lldb_private
28{
29class GoArray;
30class GoFunction;
31class GoStruct;
32
33class GoType
34{
35 public:
36 enum
37 {
38 KIND_BOOL = 1,
39 KIND_INT = 2,
40 KIND_INT8 = 3,
41 KIND_INT16 = 4,
42 KIND_INT32 = 5,
43 KIND_INT64 = 6,
44 KIND_UINT = 7,
45 KIND_UINT8 = 8,
46 KIND_UINT16 = 9,
47 KIND_UINT32 = 10,
48 KIND_UINT64 = 11,
49 KIND_UINTPTR = 12,
50 KIND_FLOAT32 = 13,
51 KIND_FLOAT64 = 14,
52 KIND_COMPLEX64 = 15,
53 KIND_COMPLEX128 = 16,
54 KIND_ARRAY = 17,
55 KIND_CHAN = 18,
56 KIND_FUNC = 19,
57 KIND_INTERFACE = 20,
58 KIND_MAP = 21,
59 KIND_PTR = 22,
60 KIND_SLICE = 23,
61 KIND_STRING = 24,
62 KIND_STRUCT = 25,
63 KIND_UNSAFEPOINTER = 26,
64 KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime.
65 KIND_MASK = (1 << 5) - 1,
66 KIND_DIRECT_IFACE = 1 << 5
67 };
68 GoType(int kind, const ConstString &name)
69 : m_kind(kind & KIND_MASK)
70 , m_name(name)
71 {
72 if (m_kind == KIND_FUNC)
73 m_kind = KIND_FUNC;
74 }
75 virtual ~GoType() {}
76
77 int
78 GetGoKind() const
79 {
80 return m_kind;
81 }
82 const ConstString &
83 GetName() const
84 {
85 return m_name;
86 }
87 virtual CompilerType
88 GetElementType() const
89 {
90 return CompilerType();
91 }
92
93 bool
94 IsTypedef() const
95 {
96 switch (m_kind)
97 {
98 case KIND_CHAN:
99 case KIND_MAP:
100 case KIND_INTERFACE:
101 return true;
102 default:
103 return false;
104 }
105 }
106
107 GoArray *GetArray();
108 GoFunction *GetFunction();
109 GoStruct *GetStruct();
110
111 private:
112 int m_kind;
113 ConstString m_name;
114 GoType(const GoType &) = delete;
115 const GoType &operator=(const GoType &) = delete;
116};
117
118class GoElem : public GoType
119{
120 public:
121 GoElem(int kind, const ConstString &name, const CompilerType &elem)
122 : GoType(kind, name)
123 , m_elem(elem)
124 {
125 }
126 virtual CompilerType
127 GetElementType() const
128 {
129 return m_elem;
130 }
131
132 private:
133 // TODO: should we store this differently?
134 CompilerType m_elem;
135
136 GoElem(const GoElem &) = delete;
137 const GoElem &operator=(const GoElem &) = delete;
138};
139
140class GoArray : public GoElem
141{
142 public:
143 GoArray(const ConstString &name, int64_t length, const CompilerType &elem)
144 : GoElem(KIND_ARRAY, name, elem)
145 , m_length(length)
146 {
147 }
148
149 int64_t
150 GetLength() const
151 {
152 return m_length;
153 }
154
155 private:
156 int64_t m_length;
157 GoArray(const GoArray &) = delete;
158 const GoArray &operator=(const GoArray &) = delete;
159};
160
161class GoFunction : public GoType
162{
163 public:
164 GoFunction(const ConstString &name, bool is_variadic)
165 : GoType(KIND_FUNC, name)
166 , m_is_variadic(is_variadic)
167 {
168 }
169
170 bool
171 IsVariadic() const
172 {
173 return m_is_variadic;
174 }
175
176 private:
177 bool m_is_variadic;
178 GoFunction(const GoFunction &) = delete;
179 const GoFunction &operator=(const GoFunction &) = delete;
180};
181
182class GoStruct : public GoType
183{
184 public:
185 struct Field
186 {
187 Field(const ConstString &name, const CompilerType &type, uint64_t offset)
188 : m_name(name)
189 , m_type(type)
190 , m_byte_offset(offset)
191 {
192 }
193 ConstString m_name;
194 CompilerType m_type;
195 uint64_t m_byte_offset;
196 };
197
198 GoStruct(int kind, const ConstString &name, int64_t byte_size)
199 : GoType(kind, name)
200 , m_is_complete(false)
201 , m_byte_size(byte_size)
202 {
203 }
204
205 uint32_t
206 GetNumFields() const
207 {
208 return m_fields.size();
209 }
210
211 const Field *
212 GetField(uint32_t i) const
213 {
214 if (i < m_fields.size())
215 return &m_fields[i];
216 return nullptr;
217 }
218
219 void
220 AddField(const ConstString &name, const CompilerType &type, uint64_t offset)
221 {
222 m_fields.push_back(Field(name, type, offset));
223 }
224
225 bool
226 IsComplete() const
227 {
228 return m_is_complete;
229 }
230
231 void
232 SetComplete()
233 {
234 m_is_complete = true;
235 }
236
237 int64_t
238 GetByteSize() const
239 {
240 return m_byte_size;
241 }
242
243 private:
244 bool m_is_complete;
245 int64_t m_byte_size;
246 std::vector<Field> m_fields;
247
248 GoStruct(const GoStruct &) = delete;
249 const GoStruct &operator=(const GoStruct &) = delete;
250};
251
252GoArray *
253GoType::GetArray()
254{
255 if (m_kind == KIND_ARRAY)
256 {
257 return static_cast<GoArray *>(this);
258 }
259 return nullptr;
260}
261
262GoFunction *
263GoType::GetFunction()
264{
265 if (m_kind == KIND_FUNC)
266 {
267 return static_cast<GoFunction *>(this);
268 }
269 return nullptr;
270}
271
272GoStruct *
273GoType::GetStruct()
274{
275 switch (m_kind)
276 {
277 case KIND_STRING:
278 case KIND_STRUCT:
279 case KIND_SLICE:
280 return static_cast<GoStruct *>(this);
281 }
282 return nullptr;
283}
284} // namespace lldb_private
285using namespace lldb_private;
286
287GoASTContext::GoASTContext()
288 : TypeSystem(eKindGo)
289 , m_pointer_byte_size(0)
290 , m_int_byte_size(0)
291 , m_types(new TypeMap)
292{
293}
294GoASTContext::~GoASTContext()
295{
296}
297
298//----------------------------------------------------------------------
299// Tests
300//----------------------------------------------------------------------
301
302bool
303GoASTContext::IsArrayType(void *type, CompilerType *element_type, uint64_t *size, bool *is_incomplete)
304{
305 if (element_type)
306 element_type->Clear();
307 if (size)
308 *size = 0;
309 if (is_incomplete)
310 *is_incomplete = false;
311 GoArray *array = static_cast<GoType *>(type)->GetArray();
312 if (array)
313 {
314 if (array->GetLength() == -1)
315 {
316 if (is_incomplete)
317 {
318 *is_incomplete = true;
319 }
320 }
321 else if (size)
322 {
323 *size = array->GetLength();
324 }
325 if (element_type)
326 *element_type = array->GetElementType();
327 return true;
328 }
329 return false;
330}
331
332bool
333GoASTContext::IsVectorType(void *type, CompilerType *element_type, uint64_t *size)
334{
335 if (element_type)
336 element_type->Clear();
337 if (size)
338 *size = 0;
339 return false;
340}
341
342bool
343GoASTContext::IsAggregateType(void *type)
344{
345 int kind = static_cast<GoType *>(type)->GetGoKind();
346 if (kind < GoType::KIND_ARRAY)
347 return false;
348 if (kind == GoType::KIND_PTR)
349 return false;
350 if (kind == GoType::KIND_STRING)
351 return false;
352 if (kind == GoType::KIND_UNSAFEPOINTER)
353 return false;
354 return true;
355}
356
357bool
358GoASTContext::IsBeingDefined(void *type)
359{
360 return false;
361}
362
363bool
364GoASTContext::IsCharType(void *type)
365{
366 // Go's DWARF doesn't distinguish between rune and int32.
367 return false;
368}
369
370bool
371GoASTContext::IsCompleteType(void *type)
372{
373 if (!type)
374 return false;
375 GoType *t = static_cast<GoType *>(type);
376 if (GoStruct *s = t->GetStruct())
377 return s->IsComplete();
378 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR)
379 return t->GetElementType().IsCompleteType();
380 return true;
381}
382
383bool
384GoASTContext::IsConst(void *type)
385{
386 return false;
387}
388
389bool
390GoASTContext::IsCStringType(void *type, uint32_t &length)
391{
392 return false;
393}
394
395bool
396GoASTContext::IsDefined(void *type)
397{
398 return type != nullptr;
399}
400
401bool
402GoASTContext::IsFloatingPointType(void *type, uint32_t &count, bool &is_complex)
403{
404 int kind = static_cast<GoType *>(type)->GetGoKind();
405 if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128)
406 {
407 if (kind >= GoType::KIND_COMPLEX64)
408 {
409 is_complex = true;
410 count = 2;
411 }
412 else
413 {
414 is_complex = false;
415 count = 1;
416 }
417 return true;
418 }
419 count = 0;
420 is_complex = false;
421 return false;
422}
423
424bool
425GoASTContext::IsFunctionType(void *type, bool *is_variadic_ptr)
426{
427 GoFunction *func = static_cast<GoType *>(type)->GetFunction();
428 if (func)
429 {
430 if (is_variadic_ptr)
431 *is_variadic_ptr = func->IsVariadic();
432 return true;
433 }
434 if (is_variadic_ptr)
435 *is_variadic_ptr = false;
436 return false;
437}
438
439uint32_t
440GoASTContext::IsHomogeneousAggregate(void *type, CompilerType *base_type_ptr)
441{
442 return false;
443}
444
445size_t
446GoASTContext::GetNumberOfFunctionArguments(void *type)
447{
448 return 0;
449}
450
451CompilerType
452GoASTContext::GetFunctionArgumentAtIndex(void *type, const size_t index)
453{
454 return CompilerType();
455}
456
457bool
458GoASTContext::IsFunctionPointerType(void *type)
459{
460 return IsFunctionType(type);
461}
462
463bool
464GoASTContext::IsIntegerType(void *type, bool &is_signed)
465{
466 is_signed = false;
467 // TODO: Is bool an integer?
468 if (type)
469 {
470 int kind = static_cast<GoType *>(type)->GetGoKind();
471 if (kind <= GoType::KIND_UINTPTR)
472 {
473 is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64);
474 return true;
475 }
476 }
477 return false;
478}
479
480bool
481GoASTContext::IsPolymorphicClass(void *type)
482{
483 return false;
484}
485
486bool
487GoASTContext::IsPossibleDynamicType(void *type,
488 CompilerType *target_type, // Can pass NULL
489 bool check_cplusplus, bool check_objc)
490{
491 if (target_type)
492 target_type->Clear();
493 if (type)
494 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE;
495 return false;
496}
497
498bool
499GoASTContext::IsRuntimeGeneratedType(void *type)
500{
501 return false;
502}
503
504bool
505GoASTContext::IsPointerType(void *type, CompilerType *pointee_type)
506{
507 if (!type)
508 return false;
509 GoType *t = static_cast<GoType *>(type);
510 if (pointee_type)
511 {
512 *pointee_type = t->GetElementType();
513 }
514 switch (t->GetGoKind())
515 {
516 case GoType::KIND_PTR:
517 case GoType::KIND_UNSAFEPOINTER:
518 case GoType::KIND_CHAN:
519 // TODO: is map a pointer? string? function?
520 return true;
521 default:
522 return false;
523 }
524}
525
526bool
527GoASTContext::IsPointerOrReferenceType(void *type, CompilerType *pointee_type)
528{
529 return IsPointerType(type, pointee_type);
530}
531
532bool
533GoASTContext::IsReferenceType(void *type, CompilerType *pointee_type, bool *is_rvalue)
534{
535 return false;
536}
537
538bool
539GoASTContext::IsScalarType(void *type)
540{
541 return !IsAggregateType(type);
542}
543
544bool
545GoASTContext::IsTypedefType(void *type)
546{
547 if (type)
548 return static_cast<GoType *>(type)->IsTypedef();
549 return false;
550}
551
552bool
553GoASTContext::IsVoidType(void *type)
554{
555 if (!type)
556 return false;
557 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID;
558}
559
560//----------------------------------------------------------------------
561// Type Completion
562//----------------------------------------------------------------------
563
564bool
565GoASTContext::GetCompleteType(void *type)
566{
567 if (!type)
568 return false;
569 GoType *t = static_cast<GoType *>(type);
570 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray())
571 return t->GetElementType().GetCompleteType();
572 if (GoStruct *s = t->GetStruct())
573 {
574 if (s->IsComplete())
575 return true;
576 CompilerType compiler_type(this, s);
577 SymbolFile *symbols = GetSymbolFile();
578 return symbols && symbols->CompleteType(compiler_type);
579 }
580 return true;
581}
582
583//----------------------------------------------------------------------
584// AST related queries
585//----------------------------------------------------------------------
586
587uint32_t
588GoASTContext::GetPointerByteSize()
589{
590 return m_pointer_byte_size;
591}
592
593//----------------------------------------------------------------------
594// Accessors
595//----------------------------------------------------------------------
596
597ConstString
598GoASTContext::GetTypeName(void *type)
599{
600 if (type)
601 return static_cast<GoType *>(type)->GetName();
602 return ConstString();
603}
604
605uint32_t
606GoASTContext::GetTypeInfo(void *type, CompilerType *pointee_or_element_clang_type)
607{
608 if (pointee_or_element_clang_type)
609 pointee_or_element_clang_type->Clear();
610 if (!type)
611 return 0;
612 GoType *t = static_cast<GoType *>(type);
613 if (pointee_or_element_clang_type)
614 *pointee_or_element_clang_type = t->GetElementType();
615 int kind = t->GetGoKind();
616 if (kind == GoType::KIND_ARRAY)
617 return eTypeHasChildren | eTypeIsArray;
618 if (kind < GoType::KIND_ARRAY)
619 {
620 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
621 if (kind < GoType::KIND_FLOAT32)
622 {
623 builtin_type_flags |= eTypeIsInteger | eTypeIsScalar;
624 if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64)
625 builtin_type_flags |= eTypeIsSigned;
626 }
627 else
628 {
629 builtin_type_flags |= eTypeIsFloat;
630 if (kind < GoType::KIND_COMPLEX64)
631 builtin_type_flags |= eTypeIsComplex;
632 else
633 builtin_type_flags |= eTypeIsScalar;
634 }
635 return builtin_type_flags;
636 }
637 if (kind == GoType::KIND_STRING)
638 return eTypeHasValue | eTypeIsBuiltIn;
639 if (kind == GoType::KIND_FUNC)
640 return eTypeIsFuncPrototype | eTypeHasValue;
641 if (IsPointerType(type))
642 return eTypeIsPointer | eTypeHasValue | eTypeHasChildren;
643 if (kind == GoType::KIND_LLDB_VOID)
644 return 0;
645 return eTypeHasChildren | eTypeIsStructUnion;
646}
647
648lldb::TypeClass
649GoASTContext::GetTypeClass(void *type)
650{
651 if (!type)
652 return eTypeClassInvalid;
653 int kind = static_cast<GoType *>(type)->GetGoKind();
654 if (kind == GoType::KIND_FUNC)
655 return eTypeClassFunction;
656 if (IsPointerType(type))
657 return eTypeClassPointer;
658 if (kind < GoType::KIND_COMPLEX64)
659 return eTypeClassBuiltin;
660 if (kind <= GoType::KIND_COMPLEX128)
661 return eTypeClassComplexFloat;
662 if (kind == GoType::KIND_LLDB_VOID)
663 return eTypeClassInvalid;
664 return eTypeClassStruct;
665}
666
667lldb::BasicType
668GoASTContext::GetBasicTypeEnumeration(void *type)
669{
670 ConstString name = GetTypeName(type);
671 if (name)
672 {
673 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
674 static TypeNameToBasicTypeMap g_type_map;
675 static std::once_flag g_once_flag;
676 std::call_once(g_once_flag, [](){
677 // "void"
678 g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
679 // "int"
680 g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
681 g_type_map.Append(ConstString("uint").GetCString(), eBasicTypeUnsignedInt);
682
683 // Miscellaneous
684 g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
685
686 // Others. Should these map to C types?
687 g_type_map.Append(ConstString("byte").GetCString(), eBasicTypeOther);
688 g_type_map.Append(ConstString("uint8").GetCString(), eBasicTypeOther);
689 g_type_map.Append(ConstString("uint16").GetCString(), eBasicTypeOther);
690 g_type_map.Append(ConstString("uint32").GetCString(), eBasicTypeOther);
691 g_type_map.Append(ConstString("uint64").GetCString(), eBasicTypeOther);
692 g_type_map.Append(ConstString("int8").GetCString(), eBasicTypeOther);
693 g_type_map.Append(ConstString("int16").GetCString(), eBasicTypeOther);
694 g_type_map.Append(ConstString("int32").GetCString(), eBasicTypeOther);
695 g_type_map.Append(ConstString("int64").GetCString(), eBasicTypeOther);
696 g_type_map.Append(ConstString("float32").GetCString(), eBasicTypeOther);
697 g_type_map.Append(ConstString("float64").GetCString(), eBasicTypeOther);
698 g_type_map.Append(ConstString("uintptr").GetCString(), eBasicTypeOther);
699
700 g_type_map.Sort();
701 });
702
703 return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
704 }
705 return eBasicTypeInvalid;
706}
707
708lldb::LanguageType
709GoASTContext::GetMinimumLanguage(void *type)
710{
711 return lldb::eLanguageTypeGo;
712}
713
714unsigned
715GoASTContext::GetTypeQualifiers(void *type)
716{
717 return 0;
718}
719
720//----------------------------------------------------------------------
721// Creating related types
722//----------------------------------------------------------------------
723
724CompilerType
725GoASTContext::GetArrayElementType(void *type, uint64_t *stride)
726{
727 GoArray *array = static_cast<GoType *>(type)->GetArray();
728 if (array)
729 {
730 if (stride)
731 {
732 *stride = array->GetElementType().GetByteSize(nullptr);
733 }
734 return array->GetElementType();
735 }
736 return CompilerType();
737}
738
739CompilerType
740GoASTContext::GetCanonicalType(void *type)
741{
742 GoType *t = static_cast<GoType *>(type);
743 if (t->IsTypedef())
744 return t->GetElementType();
745 return CompilerType(this, type);
746}
747
748CompilerType
749GoASTContext::GetFullyUnqualifiedType(void *type)
750{
751 return CompilerType(this, type);
752}
753
754// Returns -1 if this isn't a function of if the function doesn't have a prototype
755// Returns a value >= 0 if there is a prototype.
756int
757GoASTContext::GetFunctionArgumentCount(void *type)
758{
759 return GetNumberOfFunctionArguments(type);
760}
761
762CompilerType
763GoASTContext::GetFunctionArgumentTypeAtIndex(void *type, size_t idx)
764{
765 return GetFunctionArgumentAtIndex(type, idx);
766}
767
768CompilerType
769GoASTContext::GetFunctionReturnType(void *type)
770{
771 CompilerType result;
772 if (type)
773 {
774 GoType *t = static_cast<GoType *>(type);
775 if (t->GetGoKind() == GoType::KIND_FUNC)
776 result = t->GetElementType();
777 }
778 return result;
779}
780
781size_t
782GoASTContext::GetNumMemberFunctions(void *type)
783{
784 return 0;
785}
786
787TypeMemberFunctionImpl
788GoASTContext::GetMemberFunctionAtIndex(void *type, size_t idx)
789{
790 return TypeMemberFunctionImpl();
791}
792
793CompilerType
794GoASTContext::GetNonReferenceType(void *type)
795{
796 return CompilerType(this, type);
797}
798
799CompilerType
800GoASTContext::GetPointeeType(void *type)
801{
802 if (!type)
803 return CompilerType();
804 return static_cast<GoType *>(type)->GetElementType();
805}
806
807CompilerType
808GoASTContext::GetPointerType(void *type)
809{
810 if (!type)
811 return CompilerType();
812 ConstString type_name = GetTypeName(type);
813 ConstString pointer_name(std::string("*") + type_name.GetCString());
814 GoType *pointer = (*m_types)[pointer_name].get();
815 if (pointer == nullptr)
816 {
817 pointer = new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type));
818 (*m_types)[pointer_name].reset(pointer);
819 }
820 return CompilerType(this, pointer);
821}
822
823// If the current object represents a typedef type, get the underlying type
824CompilerType
825GoASTContext::GetTypedefedType(void *type)
826{
827 if (IsTypedefType(type))
828 return static_cast<GoType *>(type)->GetElementType();
829 return CompilerType();
830}
831
832//----------------------------------------------------------------------
833// Create related types using the current type's AST
834//----------------------------------------------------------------------
835CompilerType
836GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
837{
838 return CompilerType();
839}
840
841CompilerType GoASTContext::GetIntTypeFromBitSize (size_t bit_size, bool is_signed)
842{
843 return CompilerType();
844}
845CompilerType GoASTContext::GetFloatTypeFromBitSize (size_t bit_size)
846{
847 return CompilerType();
848}
849
850
851//----------------------------------------------------------------------
852// Exploring the type
853//----------------------------------------------------------------------
854
855uint64_t
856GoASTContext::GetBitSize(void *type, ExecutionContextScope *exe_scope)
857{
858 if (!type)
859 return 0;
860 if (!GetCompleteType(type))
861 return 0;
862 GoType *t = static_cast<GoType *>(type);
863 GoArray *array = nullptr;
864 switch (t->GetGoKind())
865 {
866 case GoType::KIND_BOOL:
867 case GoType::KIND_INT8:
868 case GoType::KIND_UINT8:
869 return 8;
870 case GoType::KIND_INT16:
871 case GoType::KIND_UINT16:
872 return 16;
873 case GoType::KIND_INT32:
874 case GoType::KIND_UINT32:
875 case GoType::KIND_FLOAT32:
876 return 32;
877 case GoType::KIND_INT64:
878 case GoType::KIND_UINT64:
879 case GoType::KIND_FLOAT64:
880 case GoType::KIND_COMPLEX64:
881 return 64;
882 case GoType::KIND_COMPLEX128:
883 return 128;
884 case GoType::KIND_INT:
885 case GoType::KIND_UINT:
886 return m_int_byte_size * 8;
887 case GoType::KIND_UINTPTR:
888 case GoType::KIND_FUNC: // I assume this is a pointer?
889 case GoType::KIND_CHAN:
890 case GoType::KIND_PTR:
891 case GoType::KIND_UNSAFEPOINTER:
892 case GoType::KIND_MAP:
893 return m_pointer_byte_size * 8;
894 case GoType::KIND_ARRAY:
895 array = t->GetArray();
896 return array->GetLength() * array->GetElementType().GetBitSize(exe_scope);
897 case GoType::KIND_INTERFACE:
898 return t->GetElementType().GetBitSize(exe_scope);
899 case GoType::KIND_SLICE:
900 case GoType::KIND_STRING:
901 case GoType::KIND_STRUCT:
902 return t->GetStruct()->GetByteSize() * 8;
903 default:
904 assert(false);
905 }
906}
907
908lldb::Encoding
909GoASTContext::GetEncoding(void *type, uint64_t &count)
910{
911 count = 1;
912 bool is_signed;
913 if (IsIntegerType(type, is_signed))
914 return is_signed ? lldb::eEncodingSint : eEncodingUint;
915 bool is_complex;
916 uint32_t complex_count;
917 if (IsFloatingPointType(type, complex_count, is_complex))
918 {
919 count = complex_count;
920 return eEncodingIEEE754;
921 }
922 if (IsPointerType(type))
923 return eEncodingUint;
924 return eEncodingInvalid;
925}
926
927lldb::Format
928GoASTContext::GetFormat(void *type)
929{
930 if (!type)
931 return eFormatDefault;
932 switch (static_cast<GoType *>(type)->GetGoKind())
933 {
934 case GoType::KIND_BOOL:
935 return eFormatBoolean;
936 case GoType::KIND_INT:
937 case GoType::KIND_INT8:
938 case GoType::KIND_INT16:
939 case GoType::KIND_INT32:
940 case GoType::KIND_INT64:
941 return eFormatDecimal;
942 case GoType::KIND_UINT:
943 case GoType::KIND_UINT8:
944 case GoType::KIND_UINT16:
945 case GoType::KIND_UINT32:
946 case GoType::KIND_UINT64:
947 return eFormatUnsigned;
948 case GoType::KIND_FLOAT32:
949 case GoType::KIND_FLOAT64:
950 return eFormatFloat;
951 case GoType::KIND_COMPLEX64:
952 case GoType::KIND_COMPLEX128:
953 return eFormatComplexFloat;
954 case GoType::KIND_UINTPTR:
955 case GoType::KIND_CHAN:
956 case GoType::KIND_PTR:
957 case GoType::KIND_MAP:
958 case GoType::KIND_UNSAFEPOINTER:
959 return eFormatHex;
960 case GoType::KIND_STRING:
961 return eFormatCString;
962 case GoType::KIND_ARRAY:
963 case GoType::KIND_INTERFACE:
964 case GoType::KIND_SLICE:
965 case GoType::KIND_STRUCT:
966 default:
967 // Don't know how to display this.
968 return eFormatBytes;
969 }
970}
971
972size_t
973GoASTContext::GetTypeBitAlign(void *type)
974{
975 return 0;
976}
977
978uint32_t
979GoASTContext::GetNumChildren(void *type, bool omit_empty_base_classes)
980{
981 if (!type || !GetCompleteType(type))
982 return 0;
983 GoType *t = static_cast<GoType *>(type);
984 if (t->GetGoKind() == GoType::KIND_PTR)
985 {
986 CompilerType elem = t->GetElementType();
987 if (elem.IsAggregateType())
988 return elem.GetNumChildren(omit_empty_base_classes);
989 return 1;
990 }
991 else if (GoArray *array = t->GetArray())
992 {
993 return array->GetLength();
994 }
995 return GetNumFields(type);
996}
997
998uint32_t
999GoASTContext::GetNumFields(void *type)
1000{
1001 if (!type || !GetCompleteType(type))
1002 return 0;
1003 GoType *t = static_cast<GoType *>(type);
1004 if (t->IsTypedef())
1005 return t->GetElementType().GetNumFields();
1006 GoStruct *s = t->GetStruct();
1007 if (s)
1008 return s->GetNumFields();
1009 return 0;
1010}
1011
1012CompilerType
1013GoASTContext::GetFieldAtIndex(void *type, size_t idx, std::string &name, uint64_t *bit_offset_ptr,
1014 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr)
1015{
1016 if (bit_offset_ptr)
1017 *bit_offset_ptr = 0;
1018 if (bitfield_bit_size_ptr)
1019 *bitfield_bit_size_ptr = 0;
1020 if (is_bitfield_ptr)
1021 *is_bitfield_ptr = false;
1022
1023 if (!type || !GetCompleteType(type))
1024 return CompilerType();
1025
1026 GoType *t = static_cast<GoType *>(type);
1027 if (t->IsTypedef())
1028 return t->GetElementType().GetFieldAtIndex(idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
1029
1030 GoStruct *s = t->GetStruct();
1031 if (s)
1032 {
1033 const auto *field = s->GetField(idx);
1034 if (field)
1035 {
1036 name = field->m_name.GetStringRef();
1037 if (bit_offset_ptr)
1038 *bit_offset_ptr = field->m_byte_offset * 8;
1039 return field->m_type;
1040 }
1041 }
1042 return CompilerType();
1043}
1044
1045CompilerType
1046GoASTContext::GetChildClangTypeAtIndex(void *type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
1047 bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name,
1048 uint32_t &child_byte_size, int32_t &child_byte_offset,
1049 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
1050 bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj)
1051{
1052 child_name.clear();
1053 child_byte_size = 0;
1054 child_byte_offset = 0;
1055 child_bitfield_bit_size = 0;
1056 child_bitfield_bit_offset = 0;
1057 child_is_base_class = false;
1058 child_is_deref_of_parent = false;
1059
1060 if (!type || !GetCompleteType(type))
1061 return CompilerType();
1062
1063 GoType *t = static_cast<GoType *>(type);
1064 if (t->GetStruct())
1065 {
1066 uint64_t bit_offset;
1067 CompilerType ret = GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
1068 child_byte_size = ret.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
1069 child_byte_offset = bit_offset / 8;
1070 return ret;
1071 }
1072 else if (t->GetGoKind() == GoType::KIND_PTR)
1073 {
1074 CompilerType pointee = t->GetElementType();
1075 if (!pointee.IsValid() || pointee.IsVoidType())
1076 return CompilerType();
1077 if (transparent_pointers && pointee.IsAggregateType())
1078 {
1079 bool tmp_child_is_deref_of_parent = false;
1080 return pointee.GetChildClangTypeAtIndex(exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
1081 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
1082 child_bitfield_bit_size, child_bitfield_bit_offset,
1083 child_is_base_class, tmp_child_is_deref_of_parent, valobj);
1084 }
1085 else
1086 {
1087 child_is_deref_of_parent = true;
1088 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
1089 if (parent_name)
1090 {
1091 child_name.assign(1, '*');
1092 child_name += parent_name;
1093 }
1094
1095 // We have a pointer to an simple type
1096 if (idx == 0 && pointee.GetCompleteType())
1097 {
1098 child_byte_size = pointee.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1099 child_byte_offset = 0;
1100 return pointee;
1101 }
1102 }
1103 }
1104 else if (GoArray *a = t->GetArray())
1105 {
1106 if (ignore_array_bounds || idx < a->GetLength())
1107 {
1108 CompilerType element_type = a->GetElementType();
1109 if (element_type.GetCompleteType())
1110 {
1111 char element_name[64];
1112 ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
1113 child_name.assign(element_name);
1114 child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
1115 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
1116 return element_type;
1117 }
1118 }
1119 }
1120 else if (t->IsTypedef())
1121 {
1122 return t->GetElementType().GetChildClangTypeAtIndex(
1123 exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name,
1124 child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
1125 child_is_deref_of_parent, valobj);
1126 }
1127 return CompilerType();
1128}
1129
1130// Lookup a child given a name. This function will match base class names
1131// and member member names in "clang_type" only, not descendants.
1132uint32_t
1133GoASTContext::GetIndexOfChildWithName(void *type, const char *name, bool omit_empty_base_classes)
1134{
1135 GoType *t = static_cast<GoType *>(type);
1136 GoStruct *s = t->GetStruct();
1137 if (s)
1138 {
1139 for (uint32_t i = 0; i < s->GetNumFields(); ++i)
1140 {
1141 const GoStruct::Field *f = s->GetField(i);
1142 if (f->m_name.GetStringRef() == name)
1143 return i;
1144 }
1145 }
1146 else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef())
1147 {
1148 return t->GetElementType().GetIndexOfChildWithName(name, omit_empty_base_classes);
1149 }
1150 return UINT_MAX;
1151}
1152
1153// Lookup a child member given a name. This function will match member names
1154// only and will descend into "clang_type" children in search for the first
1155// member in this class, or any base class that matches "name".
1156// TODO: Return all matches for a given name by returning a vector<vector<uint32_t>>
1157// so we catch all names that match a given child name, not just the first.
1158size_t
1159GoASTContext::GetIndexOfChildMemberWithName(void *type, const char *name, bool omit_empty_base_classes,
1160 std::vector<uint32_t> &child_indexes)
1161{
1162 uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
1163 if (index == UINT_MAX)
1164 return 0;
1165 child_indexes.push_back(index);
1166 return 1;
1167}
1168
1169// Converts "s" to a floating point value and place resulting floating
1170// point bytes in the "dst" buffer.
1171size_t
1172GoASTContext::ConvertStringToFloatValue(void *type, const char *s, uint8_t *dst, size_t dst_size)
1173{
1174 assert(false);
1175}
1176//----------------------------------------------------------------------
1177// Dumping types
1178//----------------------------------------------------------------------
1179void
1180GoASTContext::DumpValue(void *type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
1181 const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
1182 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
1183 bool verbose, uint32_t depth)
1184{
1185 assert(false);
1186}
1187
1188bool
1189GoASTContext::DumpTypeValue(void *type, Stream *s, lldb::Format format, const DataExtractor &data,
1190 lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_size,
1191 uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope)
1192{
1193 if (!type)
1194 return false;
1195 if (IsAggregateType(type))
1196 {
1197 return false;
1198 }
1199 else
1200 {
1201 GoType *t = static_cast<GoType *>(type);
1202 if (t->IsTypedef())
1203 {
1204 CompilerType typedef_clang_type = t->GetElementType();
1205 if (format == eFormatDefault)
1206 format = typedef_clang_type.GetFormat();
1207 uint64_t typedef_byte_size = typedef_clang_type.GetByteSize(exe_scope);
1208
1209 return typedef_clang_type.DumpTypeValue(
1210 s,
1211 format, // The format with which to display the element
1212 data, // Data buffer containing all bytes for this type
1213 byte_offset, // Offset into "data" where to grab value from
1214 typedef_byte_size, // Size of this type in bytes
1215 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't treat as a bitfield
1216 bitfield_bit_offset, // Offset in bits of a bitfield value if bitfield_bit_size != 0
1217 exe_scope);
1218 }
1219
1220 uint32_t item_count = 1;
1221 // A few formats, we might need to modify our size and count for depending
1222 // on how we are trying to display the value...
1223 switch (format)
1224 {
1225 default:
1226 case eFormatBoolean:
1227 case eFormatBinary:
1228 case eFormatComplex:
1229 case eFormatCString: // NULL terminated C strings
1230 case eFormatDecimal:
1231 case eFormatEnum:
1232 case eFormatHex:
1233 case eFormatHexUppercase:
1234 case eFormatFloat:
1235 case eFormatOctal:
1236 case eFormatOSType:
1237 case eFormatUnsigned:
1238 case eFormatPointer:
1239 case eFormatVectorOfChar:
1240 case eFormatVectorOfSInt8:
1241 case eFormatVectorOfUInt8:
1242 case eFormatVectorOfSInt16:
1243 case eFormatVectorOfUInt16:
1244 case eFormatVectorOfSInt32:
1245 case eFormatVectorOfUInt32:
1246 case eFormatVectorOfSInt64:
1247 case eFormatVectorOfUInt64:
1248 case eFormatVectorOfFloat32:
1249 case eFormatVectorOfFloat64:
1250 case eFormatVectorOfUInt128:
1251 break;
1252
1253 case eFormatChar:
1254 case eFormatCharPrintable:
1255 case eFormatCharArray:
1256 case eFormatBytes:
1257 case eFormatBytesWithASCII:
1258 item_count = byte_size;
1259 byte_size = 1;
1260 break;
1261
1262 case eFormatUnicode16:
1263 item_count = byte_size / 2;
1264 byte_size = 2;
1265 break;
1266
1267 case eFormatUnicode32:
1268 item_count = byte_size / 4;
1269 byte_size = 4;
1270 break;
1271 }
1272 return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
1273 bitfield_bit_size, bitfield_bit_offset, exe_scope);
1274 }
1275 return 0;
1276}
1277
1278void
1279GoASTContext::DumpSummary(void *type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data,
1280 lldb::offset_t data_offset, size_t data_byte_size)
1281{
1282 assert(false);
1283}
1284
1285void
1286GoASTContext::DumpTypeDescription(void *type)
1287{
1288 assert(false);
1289} // Dump to stdout
1290
1291void
1292GoASTContext::DumpTypeDescription(void *type, Stream *s)
1293{
1294 assert(false);
1295}
1296
1297CompilerType
1298GoASTContext::CreateArrayType(const ConstString &name, const CompilerType &element_type, int64_t length)
1299{
1300 GoType *type = new GoArray(name, length, element_type);
1301 (*m_types)[name].reset(type);
1302 return CompilerType(this, type);
1303}
1304
1305CompilerType
1306GoASTContext::CreateBaseType(int go_kind, const lldb_private::ConstString &name, uint64_t byte_size)
1307{
1308 if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT)
1309 m_int_byte_size = byte_size;
1310 GoType *type = new GoType(go_kind, name);
1311 (*m_types)[name].reset(type);
1312 return CompilerType(this, type);
1313}
1314
1315CompilerType
1316GoASTContext::CreateTypedef(int kind, const ConstString &name, CompilerType impl)
1317{
1318 GoType *type = new GoElem(kind, name, impl);
1319 (*m_types)[name].reset(type);
1320 return CompilerType(this, type);
1321}
1322
1323CompilerType
1324GoASTContext::CreateVoidType(const lldb_private::ConstString &name)
1325{
1326 GoType *type = new GoType(GoType::KIND_LLDB_VOID, name);
1327 (*m_types)[name].reset(type);
1328 return CompilerType(this, type);
1329}
1330
1331CompilerType
1332GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name, uint32_t byte_size)
1333{
1334 GoType *type = new GoStruct(kind, name, byte_size);
1335 (*m_types)[name].reset(type);
1336 return CompilerType(this, type);
1337}
1338
1339void
1340GoASTContext::AddFieldToStruct(const lldb_private::CompilerType &struct_type, const lldb_private::ConstString &name,
1341 const lldb_private::CompilerType &field_type, uint32_t byte_offset)
1342{
1343 if (!struct_type)
1344 return;
1345 GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1346 if (!ast)
1347 return;
1348 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1349 if (GoStruct *s = type->GetStruct())
1350 s->AddField(name, field_type, byte_offset);
1351}
1352
1353void
1354GoASTContext::CompleteStructType(const lldb_private::CompilerType &struct_type)
1355{
1356 if (!struct_type)
1357 return;
1358 GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1359 if (!ast)
1360 return;
1361 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1362 if (GoStruct *s = type->GetStruct())
1363 s->SetComplete();
1364}
1365
1366CompilerType
1367GoASTContext::CreateFunctionType(const lldb_private::ConstString &name, CompilerType *params, size_t params_count,
1368 bool is_variadic)
1369{
1370 GoType *type = new GoFunction(name, is_variadic);
1371 (*m_types)[name].reset(type);
1372 return CompilerType(this, type);
1373}
1374
1375bool
1376GoASTContext::IsGoString(const lldb_private::CompilerType &type)
1377{
1378 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1379 return false;
1380 return GoType::KIND_STRING == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1381}
1382
1383bool
1384GoASTContext::IsGoSlice(const lldb_private::CompilerType &type)
1385{
1386 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1387 return false;
1388 return GoType::KIND_SLICE == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1389}
1390
1391bool
1392GoASTContext::IsGoInterface(const lldb_private::CompilerType &type)
1393{
1394 if (!type.IsValid() || !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1395 return false;
1396 return GoType::KIND_INTERFACE == static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1397}
1398
1399bool
1400GoASTContext::IsPointerKind(uint8_t kind)
1401{
1402 return (kind & GoType::KIND_MASK) == GoType::KIND_PTR;
1403}
1404
1405bool
1406GoASTContext::IsDirectIface(uint8_t kind)
1407{
1408 return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE;
1409}
1410
1411DWARFASTParser *
1412GoASTContext::GetDWARFParser()
1413{
1414 if (!m_dwarf_ast_parser_ap)
1415 m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this));
1416 return m_dwarf_ast_parser_ap.get();
1417}