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