1 //===-- GoASTContext.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/StreamFile.h"
17 #include "lldb/Core/UniqueCStringMap.h"
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/DataFormatters/StringPrinter.h"
20 #include "lldb/Symbol/CompilerType.h"
21 #include "lldb/Symbol/GoASTContext.h"
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolFile.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Target/ExecutionContext.h"
26 #include "lldb/Target/Target.h"
28 #include "Plugins/ExpressionParser/Go/GoUserExpression.h"
29 #include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h"
33 namespace lldb_private {
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
71 GoType(int kind, const ConstString &name)
72 : m_kind(kind & KIND_MASK), m_name(name) {
73 if (m_kind == KIND_FUNC)
78 int GetGoKind() const { return m_kind; }
79 const ConstString &GetName() const { return m_name; }
80 virtual CompilerType GetElementType() const { return CompilerType(); }
82 bool IsTypedef() const {
94 GoFunction *GetFunction();
95 GoStruct *GetStruct();
100 GoType(const GoType &) = delete;
101 const GoType &operator=(const GoType &) = delete;
104 class GoElem : public GoType {
106 GoElem(int kind, const ConstString &name, const CompilerType &elem)
107 : GoType(kind, name), m_elem(elem) {}
108 virtual CompilerType GetElementType() const { return m_elem; }
111 // TODO: should we store this differently?
114 GoElem(const GoElem &) = delete;
115 const GoElem &operator=(const GoElem &) = delete;
118 class GoArray : public GoElem {
120 GoArray(const ConstString &name, uint64_t length, const CompilerType &elem)
121 : GoElem(KIND_ARRAY, name, elem), m_length(length) {}
123 uint64_t GetLength() const { return m_length; }
127 GoArray(const GoArray &) = delete;
128 const GoArray &operator=(const GoArray &) = delete;
131 class GoFunction : public GoType {
133 GoFunction(const ConstString &name, bool is_variadic)
134 : GoType(KIND_FUNC, name), m_is_variadic(is_variadic) {}
136 bool IsVariadic() const { return m_is_variadic; }
140 GoFunction(const GoFunction &) = delete;
141 const GoFunction &operator=(const GoFunction &) = delete;
144 class GoStruct : public GoType {
147 Field(const ConstString &name, const CompilerType &type, uint64_t offset)
148 : m_name(name), m_type(type), m_byte_offset(offset) {}
151 uint64_t m_byte_offset;
154 GoStruct(int kind, const ConstString &name, int64_t byte_size)
155 : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false),
156 m_byte_size(byte_size) {}
158 uint32_t GetNumFields() const { return m_fields.size(); }
160 const Field *GetField(uint32_t i) const {
161 if (i < m_fields.size())
166 void AddField(const ConstString &name, const CompilerType &type,
168 m_fields.push_back(Field(name, type, offset));
171 bool IsComplete() const { return m_is_complete; }
173 void SetComplete() { m_is_complete = true; }
175 int64_t GetByteSize() const { return m_byte_size; }
180 std::vector<Field> m_fields;
182 GoStruct(const GoStruct &) = delete;
183 const GoStruct &operator=(const GoStruct &) = delete;
186 GoArray *GoType::GetArray() {
187 if (m_kind == KIND_ARRAY) {
188 return static_cast<GoArray *>(this);
193 GoFunction *GoType::GetFunction() {
194 if (m_kind == KIND_FUNC) {
195 return static_cast<GoFunction *>(this);
200 GoStruct *GoType::GetStruct() {
205 return static_cast<GoStruct *>(this);
209 } // namespace lldb_private
210 using namespace lldb_private;
212 GoASTContext::GoASTContext()
213 : TypeSystem(eKindGo), m_pointer_byte_size(0), m_int_byte_size(0),
214 m_types(new TypeMap) {}
215 GoASTContext::~GoASTContext() {}
217 //------------------------------------------------------------------
218 // PluginInterface functions
219 //------------------------------------------------------------------
221 ConstString GoASTContext::GetPluginNameStatic() { return ConstString("go"); }
223 ConstString GoASTContext::GetPluginName() {
224 return GoASTContext::GetPluginNameStatic();
227 uint32_t GoASTContext::GetPluginVersion() { return 1; }
229 lldb::TypeSystemSP GoASTContext::CreateInstance(lldb::LanguageType language,
232 if (language == eLanguageTypeGo) {
234 std::shared_ptr<GoASTContext> go_ast_sp;
236 arch = module->GetArchitecture();
237 go_ast_sp = std::shared_ptr<GoASTContext>(new GoASTContext);
239 arch = target->GetArchitecture();
240 go_ast_sp = std::shared_ptr<GoASTContextForExpr>(
241 new GoASTContextForExpr(target->shared_from_this()));
244 if (arch.IsValid()) {
245 go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
249 return lldb::TypeSystemSP();
252 void GoASTContext::EnumerateSupportedLanguages(
253 std::set<lldb::LanguageType> &languages_for_types,
254 std::set<lldb::LanguageType> &languages_for_expressions) {
255 static std::vector<lldb::LanguageType> s_supported_languages_for_types(
256 {lldb::eLanguageTypeGo});
258 static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
261 languages_for_types.insert(s_supported_languages_for_types.begin(),
262 s_supported_languages_for_types.end());
263 languages_for_expressions.insert(
264 s_supported_languages_for_expressions.begin(),
265 s_supported_languages_for_expressions.end());
268 void GoASTContext::Initialize() {
269 PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in",
270 CreateInstance, EnumerateSupportedLanguages);
273 void GoASTContext::Terminate() {
274 PluginManager::UnregisterPlugin(CreateInstance);
277 //----------------------------------------------------------------------
279 //----------------------------------------------------------------------
281 bool GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
282 CompilerType *element_type, uint64_t *size,
283 bool *is_incomplete) {
285 element_type->Clear();
289 *is_incomplete = false;
290 GoArray *array = static_cast<GoType *>(type)->GetArray();
293 *size = array->GetLength();
295 *element_type = array->GetElementType();
301 bool GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
302 CompilerType *element_type, uint64_t *size) {
304 element_type->Clear();
310 bool GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
311 int kind = static_cast<GoType *>(type)->GetGoKind();
312 if (kind < GoType::KIND_ARRAY)
314 if (kind == GoType::KIND_PTR)
316 if (kind == GoType::KIND_CHAN)
318 if (kind == GoType::KIND_MAP)
320 if (kind == GoType::KIND_STRING)
322 if (kind == GoType::KIND_UNSAFEPOINTER)
327 bool GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
331 bool GoASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
332 // Go's DWARF doesn't distinguish between rune and int32.
336 bool GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
339 GoType *t = static_cast<GoType *>(type);
340 if (GoStruct *s = t->GetStruct())
341 return s->IsComplete();
342 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR)
343 return t->GetElementType().IsCompleteType();
347 bool GoASTContext::IsConst(lldb::opaque_compiler_type_t type) { return false; }
349 bool GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
354 bool GoASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
355 return type != nullptr;
358 bool GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
359 uint32_t &count, bool &is_complex) {
360 int kind = static_cast<GoType *>(type)->GetGoKind();
361 if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128) {
362 if (kind >= GoType::KIND_COMPLEX64) {
376 bool GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
377 bool *is_variadic_ptr) {
378 GoFunction *func = static_cast<GoType *>(type)->GetFunction();
381 *is_variadic_ptr = func->IsVariadic();
385 *is_variadic_ptr = false;
389 uint32_t GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
390 CompilerType *base_type_ptr) {
395 GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) {
400 GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
401 const size_t index) {
402 return CompilerType();
405 bool GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
406 return IsFunctionType(type);
409 bool GoASTContext::IsBlockPointerType(lldb::opaque_compiler_type_t type,
410 CompilerType *function_pointer_type_ptr) {
414 bool GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
417 // TODO: Is bool an integer?
419 int kind = static_cast<GoType *>(type)->GetGoKind();
420 if (kind <= GoType::KIND_UINTPTR) {
421 is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64);
428 bool GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
432 bool GoASTContext::IsPossibleDynamicType(
433 lldb::opaque_compiler_type_t type,
434 CompilerType *target_type, // Can pass NULL
435 bool check_cplusplus, bool check_objc) {
437 target_type->Clear();
439 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE;
443 bool GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) {
447 bool GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
448 CompilerType *pointee_type) {
451 GoType *t = static_cast<GoType *>(type);
453 *pointee_type = t->GetElementType();
455 switch (t->GetGoKind()) {
456 case GoType::KIND_PTR:
457 case GoType::KIND_UNSAFEPOINTER:
458 case GoType::KIND_CHAN:
459 case GoType::KIND_MAP:
460 // TODO: is function a pointer?
467 bool GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
468 CompilerType *pointee_type) {
469 return IsPointerType(type, pointee_type);
472 bool GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
473 CompilerType *pointee_type,
478 bool GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
479 return !IsAggregateType(type);
482 bool GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
484 return static_cast<GoType *>(type)->IsTypedef();
488 bool GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
491 return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID;
494 bool GoASTContext::SupportsLanguage(lldb::LanguageType language) {
495 return language == eLanguageTypeGo;
498 //----------------------------------------------------------------------
500 //----------------------------------------------------------------------
502 bool GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
505 GoType *t = static_cast<GoType *>(type);
506 if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray())
507 return t->GetElementType().GetCompleteType();
508 if (GoStruct *s = t->GetStruct()) {
511 CompilerType compiler_type(this, s);
512 SymbolFile *symbols = GetSymbolFile();
513 return symbols && symbols->CompleteType(compiler_type);
518 //----------------------------------------------------------------------
519 // AST related queries
520 //----------------------------------------------------------------------
522 uint32_t GoASTContext::GetPointerByteSize() { return m_pointer_byte_size; }
524 //----------------------------------------------------------------------
526 //----------------------------------------------------------------------
528 ConstString GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
530 return static_cast<GoType *>(type)->GetName();
531 return ConstString();
535 GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
536 CompilerType *pointee_or_element_compiler_type) {
537 if (pointee_or_element_compiler_type)
538 pointee_or_element_compiler_type->Clear();
541 GoType *t = static_cast<GoType *>(type);
542 if (pointee_or_element_compiler_type)
543 *pointee_or_element_compiler_type = t->GetElementType();
544 int kind = t->GetGoKind();
545 if (kind == GoType::KIND_ARRAY)
546 return eTypeHasChildren | eTypeIsArray;
547 if (kind < GoType::KIND_ARRAY) {
548 uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
549 if (kind < GoType::KIND_FLOAT32) {
550 builtin_type_flags |= eTypeIsInteger | eTypeIsScalar;
551 if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64)
552 builtin_type_flags |= eTypeIsSigned;
554 builtin_type_flags |= eTypeIsFloat;
555 if (kind < GoType::KIND_COMPLEX64)
556 builtin_type_flags |= eTypeIsComplex;
558 builtin_type_flags |= eTypeIsScalar;
560 return builtin_type_flags;
562 if (kind == GoType::KIND_STRING)
563 return eTypeHasValue | eTypeIsBuiltIn;
564 if (kind == GoType::KIND_FUNC)
565 return eTypeIsFuncPrototype | eTypeHasValue;
566 if (IsPointerType(type))
567 return eTypeIsPointer | eTypeHasValue | eTypeHasChildren;
568 if (kind == GoType::KIND_LLDB_VOID)
570 return eTypeHasChildren | eTypeIsStructUnion;
573 lldb::TypeClass GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
575 return eTypeClassInvalid;
576 int kind = static_cast<GoType *>(type)->GetGoKind();
577 if (kind == GoType::KIND_FUNC)
578 return eTypeClassFunction;
579 if (IsPointerType(type))
580 return eTypeClassPointer;
581 if (kind < GoType::KIND_COMPLEX64)
582 return eTypeClassBuiltin;
583 if (kind <= GoType::KIND_COMPLEX128)
584 return eTypeClassComplexFloat;
585 if (kind == GoType::KIND_LLDB_VOID)
586 return eTypeClassInvalid;
587 return eTypeClassStruct;
591 GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
592 ConstString name = GetTypeName(type);
594 typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
595 static TypeNameToBasicTypeMap g_type_map;
596 static std::once_flag g_once_flag;
597 std::call_once(g_once_flag, []() {
599 g_type_map.Append(ConstString("void").GetStringRef(), eBasicTypeVoid);
601 g_type_map.Append(ConstString("int").GetStringRef(), eBasicTypeInt);
602 g_type_map.Append(ConstString("uint").GetStringRef(),
603 eBasicTypeUnsignedInt);
606 g_type_map.Append(ConstString("bool").GetStringRef(), eBasicTypeBool);
608 // Others. Should these map to C types?
609 g_type_map.Append(ConstString("byte").GetStringRef(), eBasicTypeOther);
610 g_type_map.Append(ConstString("uint8").GetStringRef(), eBasicTypeOther);
611 g_type_map.Append(ConstString("uint16").GetStringRef(), eBasicTypeOther);
612 g_type_map.Append(ConstString("uint32").GetStringRef(), eBasicTypeOther);
613 g_type_map.Append(ConstString("uint64").GetStringRef(), eBasicTypeOther);
614 g_type_map.Append(ConstString("int8").GetStringRef(), eBasicTypeOther);
615 g_type_map.Append(ConstString("int16").GetStringRef(), eBasicTypeOther);
616 g_type_map.Append(ConstString("int32").GetStringRef(), eBasicTypeOther);
617 g_type_map.Append(ConstString("int64").GetStringRef(), eBasicTypeOther);
618 g_type_map.Append(ConstString("float32").GetStringRef(), eBasicTypeOther);
619 g_type_map.Append(ConstString("float64").GetStringRef(), eBasicTypeOther);
620 g_type_map.Append(ConstString("uintptr").GetStringRef(), eBasicTypeOther);
625 return g_type_map.Find(name.GetStringRef(), eBasicTypeInvalid);
627 return eBasicTypeInvalid;
631 GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
632 return lldb::eLanguageTypeGo;
635 unsigned GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
639 //----------------------------------------------------------------------
640 // Creating related types
641 //----------------------------------------------------------------------
644 GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
646 GoArray *array = static_cast<GoType *>(type)->GetArray();
649 *stride = array->GetElementType().GetByteSize(nullptr);
651 return array->GetElementType();
653 return CompilerType();
656 CompilerType GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
657 GoType *t = static_cast<GoType *>(type);
659 return t->GetElementType();
660 return CompilerType(this, type);
664 GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
665 return CompilerType(this, type);
668 // Returns -1 if this isn't a function of if the function doesn't have a
670 // Returns a value >= 0 if there is a prototype.
671 int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) {
672 return GetNumberOfFunctionArguments(type);
676 GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
678 return GetFunctionArgumentAtIndex(type, idx);
682 GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
685 GoType *t = static_cast<GoType *>(type);
686 if (t->GetGoKind() == GoType::KIND_FUNC)
687 result = t->GetElementType();
692 size_t GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
696 TypeMemberFunctionImpl
697 GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
699 return TypeMemberFunctionImpl();
703 GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
704 return CompilerType(this, type);
707 CompilerType GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
709 return CompilerType();
710 return static_cast<GoType *>(type)->GetElementType();
713 CompilerType GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
715 return CompilerType();
716 ConstString type_name = GetTypeName(type);
717 ConstString pointer_name(std::string("*") + type_name.GetCString());
718 GoType *pointer = (*m_types)[pointer_name].get();
719 if (pointer == nullptr) {
721 new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type));
722 (*m_types)[pointer_name].reset(pointer);
724 return CompilerType(this, pointer);
727 // If the current object represents a typedef type, get the underlying type
728 CompilerType GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
729 if (IsTypedefType(type))
730 return static_cast<GoType *>(type)->GetElementType();
731 return CompilerType();
734 //----------------------------------------------------------------------
735 // Create related types using the current type's AST
736 //----------------------------------------------------------------------
737 CompilerType GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
738 return CompilerType();
742 GoASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
744 return CompilerType();
747 //----------------------------------------------------------------------
748 // Exploring the type
749 //----------------------------------------------------------------------
751 uint64_t GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
752 ExecutionContextScope *exe_scope) {
755 if (!GetCompleteType(type))
757 GoType *t = static_cast<GoType *>(type);
758 GoArray *array = nullptr;
759 switch (t->GetGoKind()) {
760 case GoType::KIND_BOOL:
761 case GoType::KIND_INT8:
762 case GoType::KIND_UINT8:
764 case GoType::KIND_INT16:
765 case GoType::KIND_UINT16:
767 case GoType::KIND_INT32:
768 case GoType::KIND_UINT32:
769 case GoType::KIND_FLOAT32:
771 case GoType::KIND_INT64:
772 case GoType::KIND_UINT64:
773 case GoType::KIND_FLOAT64:
774 case GoType::KIND_COMPLEX64:
776 case GoType::KIND_COMPLEX128:
778 case GoType::KIND_INT:
779 case GoType::KIND_UINT:
780 return m_int_byte_size * 8;
781 case GoType::KIND_UINTPTR:
782 case GoType::KIND_FUNC: // I assume this is a pointer?
783 case GoType::KIND_CHAN:
784 case GoType::KIND_PTR:
785 case GoType::KIND_UNSAFEPOINTER:
786 case GoType::KIND_MAP:
787 return m_pointer_byte_size * 8;
788 case GoType::KIND_ARRAY:
789 array = t->GetArray();
790 return array->GetLength() * array->GetElementType().GetBitSize(exe_scope);
791 case GoType::KIND_INTERFACE:
792 return t->GetElementType().GetBitSize(exe_scope);
793 case GoType::KIND_SLICE:
794 case GoType::KIND_STRING:
795 case GoType::KIND_STRUCT:
796 return t->GetStruct()->GetByteSize() * 8;
803 lldb::Encoding GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
807 if (IsIntegerType(type, is_signed))
808 return is_signed ? lldb::eEncodingSint : eEncodingUint;
810 uint32_t complex_count;
811 if (IsFloatingPointType(type, complex_count, is_complex)) {
812 count = complex_count;
813 return eEncodingIEEE754;
815 if (IsPointerType(type))
816 return eEncodingUint;
817 return eEncodingInvalid;
820 lldb::Format GoASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
822 return eFormatDefault;
823 switch (static_cast<GoType *>(type)->GetGoKind()) {
824 case GoType::KIND_BOOL:
825 return eFormatBoolean;
826 case GoType::KIND_INT:
827 case GoType::KIND_INT8:
828 case GoType::KIND_INT16:
829 case GoType::KIND_INT32:
830 case GoType::KIND_INT64:
831 return eFormatDecimal;
832 case GoType::KIND_UINT:
833 case GoType::KIND_UINT8:
834 case GoType::KIND_UINT16:
835 case GoType::KIND_UINT32:
836 case GoType::KIND_UINT64:
837 return eFormatUnsigned;
838 case GoType::KIND_FLOAT32:
839 case GoType::KIND_FLOAT64:
841 case GoType::KIND_COMPLEX64:
842 case GoType::KIND_COMPLEX128:
843 return eFormatComplexFloat;
844 case GoType::KIND_UINTPTR:
845 case GoType::KIND_CHAN:
846 case GoType::KIND_PTR:
847 case GoType::KIND_MAP:
848 case GoType::KIND_UNSAFEPOINTER:
850 case GoType::KIND_STRING:
851 return eFormatCString;
852 case GoType::KIND_ARRAY:
853 case GoType::KIND_INTERFACE:
854 case GoType::KIND_SLICE:
855 case GoType::KIND_STRUCT:
857 // Don't know how to display this.
862 size_t GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
866 uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
867 bool omit_empty_base_classes) {
868 if (!type || !GetCompleteType(type))
870 GoType *t = static_cast<GoType *>(type);
871 if (t->GetGoKind() == GoType::KIND_PTR) {
872 CompilerType elem = t->GetElementType();
873 if (elem.IsAggregateType())
874 return elem.GetNumChildren(omit_empty_base_classes);
876 } else if (GoArray *array = t->GetArray()) {
877 return array->GetLength();
878 } else if (t->IsTypedef()) {
879 return t->GetElementType().GetNumChildren(omit_empty_base_classes);
882 return GetNumFields(type);
885 uint32_t GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
886 if (!type || !GetCompleteType(type))
888 GoType *t = static_cast<GoType *>(type);
890 return t->GetElementType().GetNumFields();
891 GoStruct *s = t->GetStruct();
893 return s->GetNumFields();
897 CompilerType GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
898 size_t idx, std::string &name,
899 uint64_t *bit_offset_ptr,
900 uint32_t *bitfield_bit_size_ptr,
901 bool *is_bitfield_ptr) {
904 if (bitfield_bit_size_ptr)
905 *bitfield_bit_size_ptr = 0;
907 *is_bitfield_ptr = false;
909 if (!type || !GetCompleteType(type))
910 return CompilerType();
912 GoType *t = static_cast<GoType *>(type);
914 return t->GetElementType().GetFieldAtIndex(
915 idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);
917 GoStruct *s = t->GetStruct();
919 const auto *field = s->GetField(idx);
921 name = field->m_name.GetStringRef();
923 *bit_offset_ptr = field->m_byte_offset * 8;
924 return field->m_type;
927 return CompilerType();
930 CompilerType GoASTContext::GetChildCompilerTypeAtIndex(
931 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
932 bool transparent_pointers, bool omit_empty_base_classes,
933 bool ignore_array_bounds, std::string &child_name,
934 uint32_t &child_byte_size, int32_t &child_byte_offset,
935 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
936 bool &child_is_base_class, bool &child_is_deref_of_parent,
937 ValueObject *valobj, uint64_t &language_flags) {
940 child_byte_offset = 0;
941 child_bitfield_bit_size = 0;
942 child_bitfield_bit_offset = 0;
943 child_is_base_class = false;
944 child_is_deref_of_parent = false;
947 if (!type || !GetCompleteType(type))
948 return CompilerType();
950 GoType *t = static_cast<GoType *>(type);
951 if (t->GetStruct()) {
954 GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
955 child_byte_size = ret.GetByteSize(
956 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
957 child_byte_offset = bit_offset / 8;
959 } else if (t->GetGoKind() == GoType::KIND_PTR) {
960 CompilerType pointee = t->GetElementType();
961 if (!pointee.IsValid() || pointee.IsVoidType())
962 return CompilerType();
963 if (transparent_pointers && pointee.IsAggregateType()) {
964 bool tmp_child_is_deref_of_parent = false;
965 return pointee.GetChildCompilerTypeAtIndex(
966 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
967 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
968 child_bitfield_bit_size, child_bitfield_bit_offset,
969 child_is_base_class, tmp_child_is_deref_of_parent, valobj,
972 child_is_deref_of_parent = true;
973 const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
975 child_name.assign(1, '*');
976 child_name += parent_name;
979 // We have a pointer to an simple type
980 if (idx == 0 && pointee.GetCompleteType()) {
981 child_byte_size = pointee.GetByteSize(
982 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
983 child_byte_offset = 0;
987 } else if (GoArray *a = t->GetArray()) {
988 if (ignore_array_bounds || idx < a->GetLength()) {
989 CompilerType element_type = a->GetElementType();
990 if (element_type.GetCompleteType()) {
991 char element_name[64];
992 ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
993 child_name.assign(element_name);
994 child_byte_size = element_type.GetByteSize(
995 exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
996 child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
1000 } else if (t->IsTypedef()) {
1001 return t->GetElementType().GetChildCompilerTypeAtIndex(
1002 exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
1003 ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
1004 child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
1005 child_is_deref_of_parent, valobj, language_flags);
1007 return CompilerType();
1010 // Lookup a child given a name. This function will match base class names
1011 // and member member names in "clang_type" only, not descendants.
1013 GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
1015 bool omit_empty_base_classes) {
1016 if (!type || !GetCompleteType(type))
1019 GoType *t = static_cast<GoType *>(type);
1020 GoStruct *s = t->GetStruct();
1022 for (uint32_t i = 0; i < s->GetNumFields(); ++i) {
1023 const GoStruct::Field *f = s->GetField(i);
1024 if (f->m_name.GetStringRef() == name)
1027 } else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef()) {
1028 return t->GetElementType().GetIndexOfChildWithName(name,
1029 omit_empty_base_classes);
1034 // Lookup a child member given a name. This function will match member names
1035 // only and will descend into "clang_type" children in search for the first
1036 // member in this class, or any base class that matches "name".
1037 // TODO: Return all matches for a given name by returning a
1038 // vector<vector<uint32_t>>
1039 // so we catch all names that match a given child name, not just the first.
1040 size_t GoASTContext::GetIndexOfChildMemberWithName(
1041 lldb::opaque_compiler_type_t type, const char *name,
1042 bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
1043 uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
1044 if (index == UINT_MAX)
1046 child_indexes.push_back(index);
1050 // Converts "s" to a floating point value and place resulting floating
1051 // point bytes in the "dst" buffer.
1053 GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
1054 const char *s, uint8_t *dst,
1059 //----------------------------------------------------------------------
1061 //----------------------------------------------------------------------
1062 #define DEPTH_INCREMENT 2
1064 void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type,
1065 ExecutionContext *exe_ctx, Stream *s,
1066 lldb::Format format, const DataExtractor &data,
1067 lldb::offset_t data_byte_offset,
1068 size_t data_byte_size, uint32_t bitfield_bit_size,
1069 uint32_t bitfield_bit_offset, bool show_types,
1070 bool show_summary, bool verbose, uint32_t depth) {
1071 if (IsTypedefType(type))
1072 type = GetTypedefedType(type).GetOpaqueQualType();
1075 GoType *t = static_cast<GoType *>(type);
1077 if (GoStruct *st = t->GetStruct()) {
1078 if (GetCompleteType(type)) {
1079 uint32_t field_idx = 0;
1080 for (auto *field = st->GetField(field_idx); field != nullptr;
1082 // Print the starting squiggly bracket (if this is the
1083 // first member) or comma (for member 2 and beyond) for
1084 // the struct/union/class member.
1091 s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
1093 // Print the member type if requested
1095 ConstString field_type_name = field->m_type.GetTypeName();
1096 s->Printf("(%s) ", field_type_name.AsCString());
1098 // Print the member name and equal sign
1099 s->Printf("%s = ", field->m_name.AsCString());
1101 // Dump the value of the member
1102 CompilerType field_type = field->m_type;
1103 field_type.DumpValue(
1105 s, // Stream to dump to
1107 .GetFormat(), // The format with which to display the member
1108 data, // Data buffer containing all bytes for this type
1109 data_byte_offset + field->m_byte_offset, // Offset into "data" where
1110 // to grab value from
1111 field->m_type.GetByteSize(
1112 exe_ctx->GetBestExecutionContextScope()), // Size of this type
1114 0, // Bitfield bit size
1115 0, // Bitfield bit offset
1116 show_types, // Boolean indicating if we should show the variable
1118 show_summary, // Boolean indicating if we should show a summary for
1120 verbose, // Verbose output?
1121 depth + DEPTH_INCREMENT); // Scope depth for any types that have
1125 // Indent the trailing squiggly bracket
1127 s->Printf("\n%*s}", depth, "");
1131 if (GoArray *a = t->GetArray()) {
1132 CompilerType element_clang_type = a->GetElementType();
1133 lldb::Format element_format = element_clang_type.GetFormat();
1134 uint32_t element_byte_size =
1135 element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());
1137 uint64_t element_idx;
1138 for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) {
1139 // Print the starting squiggly bracket (if this is the
1140 // first member) or comman (for member 2 and beyong) for
1141 // the struct/union/class member.
1142 if (element_idx == 0)
1147 // Indent and print the index
1148 s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "",
1151 // Figure out the field offset within the current struct/union/class type
1152 uint64_t element_offset = element_idx * element_byte_size;
1154 // Dump the value of the member
1155 element_clang_type.DumpValue(
1157 s, // Stream to dump to
1158 element_format, // The format with which to display the element
1159 data, // Data buffer containing all bytes for this type
1161 element_offset, // Offset into "data" where to grab value from
1162 element_byte_size, // Size of this type in bytes
1163 0, // Bitfield bit size
1164 0, // Bitfield bit offset
1165 show_types, // Boolean indicating if we should show the variable types
1166 show_summary, // Boolean indicating if we should show a summary for
1168 verbose, // Verbose output?
1170 DEPTH_INCREMENT); // Scope depth for any types that have children
1173 // Indent the trailing squiggly bracket
1174 if (element_idx > 0)
1175 s->Printf("\n%*s}", depth, "");
1179 DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
1182 bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
1183 lldb::Format format, const DataExtractor &data,
1184 lldb::offset_t byte_offset, size_t byte_size,
1185 uint32_t bitfield_bit_size,
1186 uint32_t bitfield_bit_offset,
1187 ExecutionContextScope *exe_scope) {
1190 if (IsAggregateType(type)) {
1193 GoType *t = static_cast<GoType *>(type);
1194 if (t->IsTypedef()) {
1195 CompilerType typedef_compiler_type = t->GetElementType();
1196 if (format == eFormatDefault)
1197 format = typedef_compiler_type.GetFormat();
1198 uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope);
1200 return typedef_compiler_type.DumpTypeValue(
1202 format, // The format with which to display the element
1203 data, // Data buffer containing all bytes for this type
1204 byte_offset, // Offset into "data" where to grab value from
1205 typedef_byte_size, // Size of this type in bytes
1206 bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
1207 // treat as a bitfield
1208 bitfield_bit_offset, // Offset in bits of a bitfield value if
1209 // bitfield_bit_size != 0
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...
1218 case eFormatBoolean:
1220 case eFormatComplex:
1221 case eFormatCString: // NULL terminated C strings
1222 case eFormatDecimal:
1225 case eFormatHexUppercase:
1229 case eFormatUnsigned:
1230 case eFormatPointer:
1231 case eFormatVectorOfChar:
1232 case eFormatVectorOfSInt8:
1233 case eFormatVectorOfUInt8:
1234 case eFormatVectorOfSInt16:
1235 case eFormatVectorOfUInt16:
1236 case eFormatVectorOfSInt32:
1237 case eFormatVectorOfUInt32:
1238 case eFormatVectorOfSInt64:
1239 case eFormatVectorOfUInt64:
1240 case eFormatVectorOfFloat32:
1241 case eFormatVectorOfFloat64:
1242 case eFormatVectorOfUInt128:
1246 case eFormatCharPrintable:
1247 case eFormatCharArray:
1249 case eFormatBytesWithASCII:
1250 item_count = byte_size;
1254 case eFormatUnicode16:
1255 item_count = byte_size / 2;
1259 case eFormatUnicode32:
1260 item_count = byte_size / 4;
1264 return data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX,
1265 LLDB_INVALID_ADDRESS, bitfield_bit_size,
1266 bitfield_bit_offset, exe_scope);
1271 void GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
1272 ExecutionContext *exe_ctx, Stream *s,
1273 const DataExtractor &data,
1274 lldb::offset_t data_offset,
1275 size_t data_byte_size) {
1276 if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind()) {
1277 // TODO(ribrdb): read length and data
1281 void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
1283 StreamFile s(stdout, false);
1284 DumpTypeDescription(type, &s);
1287 void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
1291 ConstString name = GetTypeName(type);
1292 GoType *t = static_cast<GoType *>(type);
1294 if (GoStruct *st = t->GetStruct()) {
1295 if (GetCompleteType(type)) {
1296 if (NULL == strchr(name.AsCString(), '{'))
1297 s->Printf("type %s ", name.AsCString());
1298 s->PutCString("struct {");
1299 if (st->GetNumFields() == 0) {
1304 uint32_t field_idx = 0;
1305 for (auto *field = st->GetField(field_idx); field != nullptr;
1309 s->Printf("%s %s", field->m_name.AsCString(),
1310 field->m_type.GetTypeName().AsCString());
1319 s->PutCString(name.AsCString());
1322 CompilerType GoASTContext::CreateArrayType(const ConstString &name,
1323 const CompilerType &element_type,
1325 GoType *type = new GoArray(name, length, element_type);
1326 (*m_types)[name].reset(type);
1327 return CompilerType(this, type);
1330 CompilerType GoASTContext::CreateBaseType(int go_kind,
1331 const lldb_private::ConstString &name,
1332 uint64_t byte_size) {
1333 if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT)
1334 m_int_byte_size = byte_size;
1335 GoType *type = new GoType(go_kind, name);
1336 (*m_types)[name].reset(type);
1337 return CompilerType(this, type);
1340 CompilerType GoASTContext::CreateTypedefType(int kind, const ConstString &name,
1341 CompilerType impl) {
1342 GoType *type = new GoElem(kind, name, impl);
1343 (*m_types)[name].reset(type);
1344 return CompilerType(this, type);
1348 GoASTContext::CreateVoidType(const lldb_private::ConstString &name) {
1349 GoType *type = new GoType(GoType::KIND_LLDB_VOID, name);
1350 (*m_types)[name].reset(type);
1351 return CompilerType(this, type);
1355 GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name,
1356 uint32_t byte_size) {
1357 GoType *type = new GoStruct(kind, name, byte_size);
1358 (*m_types)[name].reset(type);
1359 return CompilerType(this, type);
1362 void GoASTContext::AddFieldToStruct(
1363 const lldb_private::CompilerType &struct_type,
1364 const lldb_private::ConstString &name,
1365 const lldb_private::CompilerType &field_type, uint32_t byte_offset) {
1369 llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1372 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1373 if (GoStruct *s = type->GetStruct())
1374 s->AddField(name, field_type, byte_offset);
1377 void GoASTContext::CompleteStructType(
1378 const lldb_private::CompilerType &struct_type) {
1382 llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
1385 GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
1386 if (GoStruct *s = type->GetStruct())
1391 GoASTContext::CreateFunctionType(const lldb_private::ConstString &name,
1392 CompilerType *params, size_t params_count,
1394 GoType *type = new GoFunction(name, is_variadic);
1395 (*m_types)[name].reset(type);
1396 return CompilerType(this, type);
1399 bool GoASTContext::IsGoString(const lldb_private::CompilerType &type) {
1400 if (!type.IsValid() ||
1401 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1403 return GoType::KIND_STRING ==
1404 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1407 bool GoASTContext::IsGoSlice(const lldb_private::CompilerType &type) {
1408 if (!type.IsValid() ||
1409 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1411 return GoType::KIND_SLICE ==
1412 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1415 bool GoASTContext::IsGoInterface(const lldb_private::CompilerType &type) {
1416 if (!type.IsValid() ||
1417 !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
1419 return GoType::KIND_INTERFACE ==
1420 static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
1423 bool GoASTContext::IsPointerKind(uint8_t kind) {
1424 return (kind & GoType::KIND_MASK) == GoType::KIND_PTR;
1427 bool GoASTContext::IsDirectIface(uint8_t kind) {
1428 return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE;
1431 DWARFASTParser *GoASTContext::GetDWARFParser() {
1432 if (!m_dwarf_ast_parser_ap)
1433 m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this));
1434 return m_dwarf_ast_parser_ap.get();
1437 UserExpression *GoASTContextForExpr::GetUserExpression(
1438 llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
1439 Expression::ResultType desired_type,
1440 const EvaluateExpressionOptions &options) {
1441 TargetSP target = m_target_wp.lock();
1443 return new GoUserExpression(*target, expr, prefix, language, desired_type,