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