diff options
Diffstat (limited to 'source/Symbol/GoASTContext.cpp')
| -rw-r--r-- | source/Symbol/GoASTContext.cpp | 1444 |
1 files changed, 0 insertions, 1444 deletions
diff --git a/source/Symbol/GoASTContext.cpp b/source/Symbol/GoASTContext.cpp deleted file mode 100644 index da5c82b2cb55..000000000000 --- a/source/Symbol/GoASTContext.cpp +++ /dev/null @@ -1,1444 +0,0 @@ -//===-- GoASTContext.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <mutex> -#include <utility> -#include <vector> - -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/GoASTContext.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Target.h" - -#include "llvm/Support/Threading.h" - -#include "Plugins/ExpressionParser/Go/GoUserExpression.h" -#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h" - -using namespace lldb; - -namespace lldb_private { -class GoArray; -class GoFunction; -class GoStruct; - -class GoType { -public: - enum { - KIND_BOOL = 1, - KIND_INT = 2, - KIND_INT8 = 3, - KIND_INT16 = 4, - KIND_INT32 = 5, - KIND_INT64 = 6, - KIND_UINT = 7, - KIND_UINT8 = 8, - KIND_UINT16 = 9, - KIND_UINT32 = 10, - KIND_UINT64 = 11, - KIND_UINTPTR = 12, - KIND_FLOAT32 = 13, - KIND_FLOAT64 = 14, - KIND_COMPLEX64 = 15, - KIND_COMPLEX128 = 16, - KIND_ARRAY = 17, - KIND_CHAN = 18, - KIND_FUNC = 19, - KIND_INTERFACE = 20, - KIND_MAP = 21, - KIND_PTR = 22, - KIND_SLICE = 23, - KIND_STRING = 24, - KIND_STRUCT = 25, - KIND_UNSAFEPOINTER = 26, - KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime. - KIND_MASK = (1 << 5) - 1, - KIND_DIRECT_IFACE = 1 << 5 - }; - GoType(int kind, const ConstString &name) - : m_kind(kind & KIND_MASK), m_name(name) { - if (m_kind == KIND_FUNC) - m_kind = KIND_FUNC; - } - virtual ~GoType() {} - - int GetGoKind() const { return m_kind; } - const ConstString &GetName() const { return m_name; } - virtual CompilerType GetElementType() const { return CompilerType(); } - - bool IsTypedef() const { - switch (m_kind) { - case KIND_CHAN: - case KIND_MAP: - case KIND_INTERFACE: - return true; - default: - return false; - } - } - - GoArray *GetArray(); - GoFunction *GetFunction(); - GoStruct *GetStruct(); - -private: - int m_kind; - ConstString m_name; - GoType(const GoType &) = delete; - const GoType &operator=(const GoType &) = delete; -}; - -class GoElem : public GoType { -public: - GoElem(int kind, const ConstString &name, const CompilerType &elem) - : GoType(kind, name), m_elem(elem) {} - virtual CompilerType GetElementType() const { return m_elem; } - -private: - // TODO: should we store this differently? - CompilerType m_elem; - - GoElem(const GoElem &) = delete; - const GoElem &operator=(const GoElem &) = delete; -}; - -class GoArray : public GoElem { -public: - GoArray(const ConstString &name, uint64_t length, const CompilerType &elem) - : GoElem(KIND_ARRAY, name, elem), m_length(length) {} - - uint64_t GetLength() const { return m_length; } - -private: - uint64_t m_length; - GoArray(const GoArray &) = delete; - const GoArray &operator=(const GoArray &) = delete; -}; - -class GoFunction : public GoType { -public: - GoFunction(const ConstString &name, bool is_variadic) - : GoType(KIND_FUNC, name), m_is_variadic(is_variadic) {} - - bool IsVariadic() const { return m_is_variadic; } - -private: - bool m_is_variadic; - GoFunction(const GoFunction &) = delete; - const GoFunction &operator=(const GoFunction &) = delete; -}; - -class GoStruct : public GoType { -public: - struct Field { - Field(const ConstString &name, const CompilerType &type, uint64_t offset) - : m_name(name), m_type(type), m_byte_offset(offset) {} - ConstString m_name; - CompilerType m_type; - uint64_t m_byte_offset; - }; - - GoStruct(int kind, const ConstString &name, int64_t byte_size) - : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false), - m_byte_size(byte_size) {} - - uint32_t GetNumFields() const { return m_fields.size(); } - - const Field *GetField(uint32_t i) const { - if (i < m_fields.size()) - return &m_fields[i]; - return nullptr; - } - - void AddField(const ConstString &name, const CompilerType &type, - uint64_t offset) { - m_fields.push_back(Field(name, type, offset)); - } - - bool IsComplete() const { return m_is_complete; } - - void SetComplete() { m_is_complete = true; } - - int64_t GetByteSize() const { return m_byte_size; } - -private: - bool m_is_complete; - int64_t m_byte_size; - std::vector<Field> m_fields; - - GoStruct(const GoStruct &) = delete; - const GoStruct &operator=(const GoStruct &) = delete; -}; - -GoArray *GoType::GetArray() { - if (m_kind == KIND_ARRAY) { - return static_cast<GoArray *>(this); - } - return nullptr; -} - -GoFunction *GoType::GetFunction() { - if (m_kind == KIND_FUNC) { - return static_cast<GoFunction *>(this); - } - return nullptr; -} - -GoStruct *GoType::GetStruct() { - switch (m_kind) { - case KIND_STRING: - case KIND_STRUCT: - case KIND_SLICE: - return static_cast<GoStruct *>(this); - } - return nullptr; -} -} // namespace lldb_private -using namespace lldb_private; - -GoASTContext::GoASTContext() - : TypeSystem(eKindGo), m_pointer_byte_size(0), m_int_byte_size(0), - m_types(new TypeMap) {} -GoASTContext::~GoASTContext() {} - -//------------------------------------------------------------------ -// PluginInterface functions -//------------------------------------------------------------------ - -ConstString GoASTContext::GetPluginNameStatic() { return ConstString("go"); } - -ConstString GoASTContext::GetPluginName() { - return GoASTContext::GetPluginNameStatic(); -} - -uint32_t GoASTContext::GetPluginVersion() { return 1; } - -lldb::TypeSystemSP GoASTContext::CreateInstance(lldb::LanguageType language, - Module *module, - Target *target) { - if (language == eLanguageTypeGo) { - ArchSpec arch; - std::shared_ptr<GoASTContext> go_ast_sp; - if (module) { - arch = module->GetArchitecture(); - go_ast_sp = std::shared_ptr<GoASTContext>(new GoASTContext); - } else if (target) { - arch = target->GetArchitecture(); - go_ast_sp = std::shared_ptr<GoASTContextForExpr>( - new GoASTContextForExpr(target->shared_from_this())); - } - - if (arch.IsValid()) { - go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize()); - return go_ast_sp; - } - } - return lldb::TypeSystemSP(); -} - -void GoASTContext::EnumerateSupportedLanguages( - std::set<lldb::LanguageType> &languages_for_types, - std::set<lldb::LanguageType> &languages_for_expressions) { - static std::vector<lldb::LanguageType> s_supported_languages_for_types( - {lldb::eLanguageTypeGo}); - - static std::vector<lldb::LanguageType> s_supported_languages_for_expressions( - {}); - - languages_for_types.insert(s_supported_languages_for_types.begin(), - s_supported_languages_for_types.end()); - languages_for_expressions.insert( - s_supported_languages_for_expressions.begin(), - s_supported_languages_for_expressions.end()); -} - -void GoASTContext::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", - CreateInstance, EnumerateSupportedLanguages); -} - -void GoASTContext::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -//---------------------------------------------------------------------- -// Tests -//---------------------------------------------------------------------- - -bool GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - if (is_incomplete) - *is_incomplete = false; - GoArray *array = static_cast<GoType *>(type)->GetArray(); - if (array) { - if (size) - *size = array->GetLength(); - if (element_type) - *element_type = array->GetElementType(); - return true; - } - return false; -} - -bool GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - return false; -} - -bool GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { - int kind = static_cast<GoType *>(type)->GetGoKind(); - if (kind < GoType::KIND_ARRAY) - return false; - if (kind == GoType::KIND_PTR) - return false; - if (kind == GoType::KIND_CHAN) - return false; - if (kind == GoType::KIND_MAP) - return false; - if (kind == GoType::KIND_STRING) - return false; - if (kind == GoType::KIND_UNSAFEPOINTER) - return false; - return true; -} - -bool GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsCharType(lldb::opaque_compiler_type_t type) { - // Go's DWARF doesn't distinguish between rune and int32. - return false; -} - -bool GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - GoType *t = static_cast<GoType *>(type); - if (GoStruct *s = t->GetStruct()) - return s->IsComplete(); - if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR) - return t->GetElementType().IsCompleteType(); - return true; -} - -bool GoASTContext::IsConst(lldb::opaque_compiler_type_t type) { return false; } - -bool GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) { - return false; -} - -bool GoASTContext::IsDefined(lldb::opaque_compiler_type_t type) { - return type != nullptr; -} - -bool GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, - uint32_t &count, bool &is_complex) { - int kind = static_cast<GoType *>(type)->GetGoKind(); - if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128) { - if (kind >= GoType::KIND_COMPLEX64) { - is_complex = true; - count = 2; - } else { - is_complex = false; - count = 1; - } - return true; - } - count = 0; - is_complex = false; - return false; -} - -bool GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr) { - GoFunction *func = static_cast<GoType *>(type)->GetFunction(); - if (func) { - if (is_variadic_ptr) - *is_variadic_ptr = func->IsVariadic(); - return true; - } - if (is_variadic_ptr) - *is_variadic_ptr = false; - return false; -} - -uint32_t GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) { - return false; -} - -size_t -GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) { - return 0; -} - -CompilerType -GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) { - return CompilerType(); -} - -bool GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { - return IsFunctionType(type); -} - -bool GoASTContext::IsBlockPointerType(lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) { - return false; -} - -bool GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) { - is_signed = false; - // TODO: Is bool an integer? - if (type) { - int kind = static_cast<GoType *>(type)->GetGoKind(); - if (kind <= GoType::KIND_UINTPTR) { - is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64); - return true; - } - } - return false; -} - -bool GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsPossibleDynamicType( - lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass NULL - bool check_cplusplus, bool check_objc) { - if (target_type) - target_type->Clear(); - if (type) - return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE; - return false; -} - -bool GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - if (!type) - return false; - GoType *t = static_cast<GoType *>(type); - if (pointee_type) { - *pointee_type = t->GetElementType(); - } - switch (t->GetGoKind()) { - case GoType::KIND_PTR: - case GoType::KIND_UNSAFEPOINTER: - case GoType::KIND_CHAN: - case GoType::KIND_MAP: - // TODO: is function a pointer? - return true; - default: - return false; - } -} - -bool GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - return IsPointerType(type, pointee_type); -} - -bool GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type, - bool *is_rvalue) { - return false; -} - -bool GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type) { - return !IsAggregateType(type); -} - -bool GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast<GoType *>(type)->IsTypedef(); - return false; -} - -bool GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID; -} - -bool GoASTContext::SupportsLanguage(lldb::LanguageType language) { - return language == eLanguageTypeGo; -} - -//---------------------------------------------------------------------- -// Type Completion -//---------------------------------------------------------------------- - -bool GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - GoType *t = static_cast<GoType *>(type); - if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray()) - return t->GetElementType().GetCompleteType(); - if (GoStruct *s = t->GetStruct()) { - if (s->IsComplete()) - return true; - CompilerType compiler_type(this, s); - SymbolFile *symbols = GetSymbolFile(); - return symbols && symbols->CompleteType(compiler_type); - } - return true; -} - -//---------------------------------------------------------------------- -// AST related queries -//---------------------------------------------------------------------- - -uint32_t GoASTContext::GetPointerByteSize() { return m_pointer_byte_size; } - -//---------------------------------------------------------------------- -// Accessors -//---------------------------------------------------------------------- - -ConstString GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast<GoType *>(type)->GetName(); - return ConstString(); -} - -uint32_t -GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type) { - if (pointee_or_element_compiler_type) - pointee_or_element_compiler_type->Clear(); - if (!type) - return 0; - GoType *t = static_cast<GoType *>(type); - if (pointee_or_element_compiler_type) - *pointee_or_element_compiler_type = t->GetElementType(); - int kind = t->GetGoKind(); - if (kind == GoType::KIND_ARRAY) - return eTypeHasChildren | eTypeIsArray; - if (kind < GoType::KIND_ARRAY) { - uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; - if (kind < GoType::KIND_FLOAT32) { - builtin_type_flags |= eTypeIsInteger | eTypeIsScalar; - if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64) - builtin_type_flags |= eTypeIsSigned; - } else { - builtin_type_flags |= eTypeIsFloat; - if (kind < GoType::KIND_COMPLEX64) - builtin_type_flags |= eTypeIsComplex; - else - builtin_type_flags |= eTypeIsScalar; - } - return builtin_type_flags; - } - if (kind == GoType::KIND_STRING) - return eTypeHasValue | eTypeIsBuiltIn; - if (kind == GoType::KIND_FUNC) - return eTypeIsFuncPrototype | eTypeHasValue; - if (IsPointerType(type)) - return eTypeIsPointer | eTypeHasValue | eTypeHasChildren; - if (kind == GoType::KIND_LLDB_VOID) - return 0; - return eTypeHasChildren | eTypeIsStructUnion; -} - -lldb::TypeClass GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { - if (!type) - return eTypeClassInvalid; - int kind = static_cast<GoType *>(type)->GetGoKind(); - if (kind == GoType::KIND_FUNC) - return eTypeClassFunction; - if (IsPointerType(type)) - return eTypeClassPointer; - if (kind < GoType::KIND_COMPLEX64) - return eTypeClassBuiltin; - if (kind <= GoType::KIND_COMPLEX128) - return eTypeClassComplexFloat; - if (kind == GoType::KIND_LLDB_VOID) - return eTypeClassInvalid; - return eTypeClassStruct; -} - -lldb::BasicType -GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { - ConstString name = GetTypeName(type); - if (name) { - typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; - static TypeNameToBasicTypeMap g_type_map; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - // "void" - g_type_map.Append(ConstString("void"), eBasicTypeVoid); - // "int" - g_type_map.Append(ConstString("int"), eBasicTypeInt); - g_type_map.Append(ConstString("uint"), eBasicTypeUnsignedInt); - - // Miscellaneous - g_type_map.Append(ConstString("bool"), eBasicTypeBool); - - // Others. Should these map to C types? - g_type_map.Append(ConstString("byte"), eBasicTypeOther); - g_type_map.Append(ConstString("uint8"), eBasicTypeOther); - g_type_map.Append(ConstString("uint16"), eBasicTypeOther); - g_type_map.Append(ConstString("uint32"), eBasicTypeOther); - g_type_map.Append(ConstString("uint64"), eBasicTypeOther); - g_type_map.Append(ConstString("int8"), eBasicTypeOther); - g_type_map.Append(ConstString("int16"), eBasicTypeOther); - g_type_map.Append(ConstString("int32"), eBasicTypeOther); - g_type_map.Append(ConstString("int64"), eBasicTypeOther); - g_type_map.Append(ConstString("float32"), eBasicTypeOther); - g_type_map.Append(ConstString("float64"), eBasicTypeOther); - g_type_map.Append(ConstString("uintptr"), eBasicTypeOther); - - g_type_map.Sort(); - }); - - return g_type_map.Find(name, eBasicTypeInvalid); - } - return eBasicTypeInvalid; -} - -lldb::LanguageType -GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { - return lldb::eLanguageTypeGo; -} - -unsigned GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { - return 0; -} - -//---------------------------------------------------------------------- -// Creating related types -//---------------------------------------------------------------------- - -CompilerType -GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride) { - GoArray *array = static_cast<GoType *>(type)->GetArray(); - if (array) { - if (stride) { - *stride = array->GetElementType().GetByteSize(nullptr); - } - return array->GetElementType(); - } - return CompilerType(); -} - -CompilerType GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) { - GoType *t = static_cast<GoType *>(type); - if (t->IsTypedef()) - return t->GetElementType(); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -// Returns -1 if this isn't a function of if the function doesn't have a -// prototype Returns a value >= 0 if there is a prototype. -int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) { - return GetNumberOfFunctionArguments(type); -} - -CompilerType -GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return GetFunctionArgumentAtIndex(type, idx); -} - -CompilerType -GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { - CompilerType result; - if (type) { - GoType *t = static_cast<GoType *>(type); - if (t->GetGoKind() == GoType::KIND_FUNC) - result = t->GetElementType(); - } - return result; -} - -size_t GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { - return 0; -} - -TypeMemberFunctionImpl -GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return TypeMemberFunctionImpl(); -} - -CompilerType -GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) { - if (!type) - return CompilerType(); - return static_cast<GoType *>(type)->GetElementType(); -} - -CompilerType GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { - if (!type) - return CompilerType(); - ConstString type_name = GetTypeName(type); - ConstString pointer_name(std::string("*") + type_name.GetCString()); - GoType *pointer = (*m_types)[pointer_name].get(); - if (pointer == nullptr) { - pointer = - new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type)); - (*m_types)[pointer_name].reset(pointer); - } - return CompilerType(this, pointer); -} - -// If the current object represents a typedef type, get the underlying type -CompilerType GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { - if (IsTypedefType(type)) - return static_cast<GoType *>(type)->GetElementType(); - return CompilerType(); -} - -//---------------------------------------------------------------------- -// Create related types using the current type's AST -//---------------------------------------------------------------------- -CompilerType GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { - return CompilerType(); -} - -CompilerType -GoASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) { - return CompilerType(); -} - -//---------------------------------------------------------------------- -// Exploring the type -//---------------------------------------------------------------------- - -uint64_t GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) { - if (!type) - return 0; - if (!GetCompleteType(type)) - return 0; - GoType *t = static_cast<GoType *>(type); - GoArray *array = nullptr; - switch (t->GetGoKind()) { - case GoType::KIND_BOOL: - case GoType::KIND_INT8: - case GoType::KIND_UINT8: - return 8; - case GoType::KIND_INT16: - case GoType::KIND_UINT16: - return 16; - case GoType::KIND_INT32: - case GoType::KIND_UINT32: - case GoType::KIND_FLOAT32: - return 32; - case GoType::KIND_INT64: - case GoType::KIND_UINT64: - case GoType::KIND_FLOAT64: - case GoType::KIND_COMPLEX64: - return 64; - case GoType::KIND_COMPLEX128: - return 128; - case GoType::KIND_INT: - case GoType::KIND_UINT: - return m_int_byte_size * 8; - case GoType::KIND_UINTPTR: - case GoType::KIND_FUNC: // I assume this is a pointer? - case GoType::KIND_CHAN: - case GoType::KIND_PTR: - case GoType::KIND_UNSAFEPOINTER: - case GoType::KIND_MAP: - return m_pointer_byte_size * 8; - case GoType::KIND_ARRAY: - array = t->GetArray(); - return array->GetLength() * array->GetElementType().GetBitSize(exe_scope); - case GoType::KIND_INTERFACE: - return t->GetElementType().GetBitSize(exe_scope); - case GoType::KIND_SLICE: - case GoType::KIND_STRING: - case GoType::KIND_STRUCT: - return t->GetStruct()->GetByteSize() * 8; - default: - assert(false); - } - return 0; -} - -lldb::Encoding GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) { - count = 1; - bool is_signed; - if (IsIntegerType(type, is_signed)) - return is_signed ? lldb::eEncodingSint : eEncodingUint; - bool is_complex; - uint32_t complex_count; - if (IsFloatingPointType(type, complex_count, is_complex)) { - count = complex_count; - return eEncodingIEEE754; - } - if (IsPointerType(type)) - return eEncodingUint; - return eEncodingInvalid; -} - -lldb::Format GoASTContext::GetFormat(lldb::opaque_compiler_type_t type) { - if (!type) - return eFormatDefault; - switch (static_cast<GoType *>(type)->GetGoKind()) { - case GoType::KIND_BOOL: - return eFormatBoolean; - case GoType::KIND_INT: - case GoType::KIND_INT8: - case GoType::KIND_INT16: - case GoType::KIND_INT32: - case GoType::KIND_INT64: - return eFormatDecimal; - case GoType::KIND_UINT: - case GoType::KIND_UINT8: - case GoType::KIND_UINT16: - case GoType::KIND_UINT32: - case GoType::KIND_UINT64: - return eFormatUnsigned; - case GoType::KIND_FLOAT32: - case GoType::KIND_FLOAT64: - return eFormatFloat; - case GoType::KIND_COMPLEX64: - case GoType::KIND_COMPLEX128: - return eFormatComplexFloat; - case GoType::KIND_UINTPTR: - case GoType::KIND_CHAN: - case GoType::KIND_PTR: - case GoType::KIND_MAP: - case GoType::KIND_UNSAFEPOINTER: - return eFormatHex; - case GoType::KIND_STRING: - return eFormatCString; - case GoType::KIND_ARRAY: - case GoType::KIND_INTERFACE: - case GoType::KIND_SLICE: - case GoType::KIND_STRUCT: - default: - // Don't know how to display this. - return eFormatBytes; - } -} - -size_t GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) { - return 0; -} - -uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return 0; - GoType *t = static_cast<GoType *>(type); - if (t->GetGoKind() == GoType::KIND_PTR) { - CompilerType elem = t->GetElementType(); - if (elem.IsAggregateType()) - return elem.GetNumChildren(omit_empty_base_classes); - return 1; - } else if (GoArray *array = t->GetArray()) { - return array->GetLength(); - } else if (t->IsTypedef()) { - return t->GetElementType().GetNumChildren(omit_empty_base_classes); - } - - return GetNumFields(type); -} - -uint32_t GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { - if (!type || !GetCompleteType(type)) - return 0; - GoType *t = static_cast<GoType *>(type); - if (t->IsTypedef()) - return t->GetElementType().GetNumFields(); - GoStruct *s = t->GetStruct(); - if (s) - return s->GetNumFields(); - return 0; -} - -CompilerType GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, std::string &name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - if (bitfield_bit_size_ptr) - *bitfield_bit_size_ptr = 0; - if (is_bitfield_ptr) - *is_bitfield_ptr = false; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - GoType *t = static_cast<GoType *>(type); - if (t->IsTypedef()) - return t->GetElementType().GetFieldAtIndex( - idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - - GoStruct *s = t->GetStruct(); - if (s) { - const auto *field = s->GetField(idx); - if (field) { - name = field->m_name.GetStringRef(); - if (bit_offset_ptr) - *bit_offset_ptr = field->m_byte_offset * 8; - return field->m_type; - } - } - return CompilerType(); -} - -CompilerType GoASTContext::GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) { - child_name.clear(); - child_byte_size = 0; - child_byte_offset = 0; - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - child_is_deref_of_parent = false; - language_flags = 0; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - GoType *t = static_cast<GoType *>(type); - if (t->GetStruct()) { - uint64_t bit_offset; - CompilerType ret = - GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr); - child_byte_size = ret.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - child_byte_offset = bit_offset / 8; - return ret; - } else if (t->GetGoKind() == GoType::KIND_PTR) { - CompilerType pointee = t->GetElementType(); - if (!pointee.IsValid() || pointee.IsVoidType()) - return CompilerType(); - if (transparent_pointers && pointee.IsAggregateType()) { - bool tmp_child_is_deref_of_parent = false; - return pointee.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, tmp_child_is_deref_of_parent, valobj, - language_flags); - } else { - child_is_deref_of_parent = true; - const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL; - if (parent_name) { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0 && pointee.GetCompleteType()) { - child_byte_size = pointee.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = 0; - return pointee; - } - } - } else if (GoArray *a = t->GetArray()) { - if (ignore_array_bounds || idx < a->GetLength()) { - CompilerType element_type = a->GetElementType(); - if (element_type.GetCompleteType()) { - char element_name[64]; - ::snprintf(element_name, sizeof(element_name), "[%zu]", idx); - child_name.assign(element_name); - child_byte_size = element_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return element_type; - } - } - } else if (t->IsTypedef()) { - return t->GetElementType().GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } - return CompilerType(); -} - -// Lookup a child given a name. This function will match base class names and -// member member names in "clang_type" only, not descendants. -uint32_t -GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return UINT_MAX; - - GoType *t = static_cast<GoType *>(type); - GoStruct *s = t->GetStruct(); - if (s) { - for (uint32_t i = 0; i < s->GetNumFields(); ++i) { - const GoStruct::Field *f = s->GetField(i); - if (f->m_name.GetStringRef() == name) - return i; - } - } else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef()) { - return t->GetElementType().GetIndexOfChildWithName(name, - omit_empty_base_classes); - } - return UINT_MAX; -} - -// Lookup a child member given a name. This function will match member names -// only and will descend into "clang_type" children in search for the first -// member in this class, or any base class that matches "name". -// TODO: Return all matches for a given name by returning a -// vector<vector<uint32_t>> -// so we catch all names that match a given child name, not just the first. -size_t GoASTContext::GetIndexOfChildMemberWithName( - lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) { - uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes); - if (index == UINT_MAX) - return 0; - child_indexes.push_back(index); - return 1; -} - -// Converts "s" to a floating point value and place resulting floating point -// bytes in the "dst" buffer. -size_t -GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) { - assert(false); - return 0; -} -//---------------------------------------------------------------------- -// Dumping types -//---------------------------------------------------------------------- -#define DEPTH_INCREMENT 2 - -void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, bool show_types, - bool show_summary, bool verbose, uint32_t depth) { - if (IsTypedefType(type)) - type = GetTypedefedType(type).GetOpaqueQualType(); - if (!type) - return; - GoType *t = static_cast<GoType *>(type); - - if (GoStruct *st = t->GetStruct()) { - if (GetCompleteType(type)) { - uint32_t field_idx = 0; - for (auto *field = st->GetField(field_idx); field != nullptr; - field_idx++) { - // Print the starting squiggly bracket (if this is the first member) or - // comma (for member 2 and beyond) for the struct/union/class member. - if (field_idx == 0) - s->PutChar('{'); - else - s->PutChar(','); - - // Indent - s->Printf("\n%*s", depth + DEPTH_INCREMENT, ""); - - // Print the member type if requested - if (show_types) { - ConstString field_type_name = field->m_type.GetTypeName(); - s->Printf("(%s) ", field_type_name.AsCString()); - } - // Print the member name and equal sign - s->Printf("%s = ", field->m_name.AsCString()); - - // Dump the value of the member - CompilerType field_type = field->m_type; - field_type.DumpValue( - exe_ctx, - s, // Stream to dump to - field_type - .GetFormat(), // The format with which to display the member - data, // Data buffer containing all bytes for this type - data_byte_offset + field->m_byte_offset, // Offset into "data" where - // to grab value from - field->m_type.GetByteSize( - exe_ctx->GetBestExecutionContextScope()), // Size of this type - // in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable - // types - show_summary, // Boolean indicating if we should show a summary for - // the current type - verbose, // Verbose output? - depth + DEPTH_INCREMENT); // Scope depth for any types that have - // children - } - - // Indent the trailing squiggly bracket - if (field_idx > 0) - s->Printf("\n%*s}", depth, ""); - } - } - - if (GoArray *a = t->GetArray()) { - CompilerType element_clang_type = a->GetElementType(); - lldb::Format element_format = element_clang_type.GetFormat(); - uint32_t element_byte_size = - element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope()); - - uint64_t element_idx; - for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) { - // Print the starting squiggly bracket (if this is the first member) or - // comman (for member 2 and beyong) for the struct/union/class member. - if (element_idx == 0) - s->PutChar('{'); - else - s->PutChar(','); - - // Indent and print the index - s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "", - element_idx); - - // Figure out the field offset within the current struct/union/class type - uint64_t element_offset = element_idx * element_byte_size; - - // Dump the value of the member - element_clang_type.DumpValue( - exe_ctx, - s, // Stream to dump to - element_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset + - element_offset, // Offset into "data" where to grab value from - element_byte_size, // Size of this type in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for - // the current type - verbose, // Verbose output? - depth + - DEPTH_INCREMENT); // Scope depth for any types that have children - } - - // Indent the trailing squiggly bracket - if (element_idx > 0) - s->Printf("\n%*s}", depth, ""); - } - - if (show_summary) - DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size); -} - -bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t byte_offset, size_t byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) { - if (!type) - return false; - if (IsAggregateType(type)) { - return false; - } else { - GoType *t = static_cast<GoType *>(type); - if (t->IsTypedef()) { - CompilerType typedef_compiler_type = t->GetElementType(); - if (format == eFormatDefault) - format = typedef_compiler_type.GetFormat(); - uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope); - - return typedef_compiler_type.DumpTypeValue( - s, - format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - byte_offset, // Offset into "data" where to grab value from - typedef_byte_size, // Size of this type in bytes - bitfield_bit_size, // Size in bits of a bitfield value, if zero don't - // treat as a bitfield - bitfield_bit_offset, // Offset in bits of a bitfield value if - // bitfield_bit_size != 0 - exe_scope); - } - - uint32_t item_count = 1; - // A few formats, we might need to modify our size and count for depending - // on how we are trying to display the value... - switch (format) { - default: - case eFormatBoolean: - case eFormatBinary: - case eFormatComplex: - case eFormatCString: // NULL terminated C strings - case eFormatDecimal: - case eFormatEnum: - case eFormatHex: - case eFormatHexUppercase: - case eFormatFloat: - case eFormatOctal: - case eFormatOSType: - case eFormatUnsigned: - case eFormatPointer: - case eFormatVectorOfChar: - case eFormatVectorOfSInt8: - case eFormatVectorOfUInt8: - case eFormatVectorOfSInt16: - case eFormatVectorOfUInt16: - case eFormatVectorOfSInt32: - case eFormatVectorOfUInt32: - case eFormatVectorOfSInt64: - case eFormatVectorOfUInt64: - case eFormatVectorOfFloat32: - case eFormatVectorOfFloat64: - case eFormatVectorOfUInt128: - break; - - case eFormatChar: - case eFormatCharPrintable: - case eFormatCharArray: - case eFormatBytes: - case eFormatBytesWithASCII: - item_count = byte_size; - byte_size = 1; - break; - - case eFormatUnicode16: - item_count = byte_size / 2; - byte_size = 2; - break; - - case eFormatUnicode32: - item_count = byte_size / 4; - byte_size = 4; - break; - } - return DumpDataExtractor(data, s, byte_offset, format, byte_size, - item_count, UINT32_MAX, LLDB_INVALID_ADDRESS, - bitfield_bit_size, bitfield_bit_offset, exe_scope); - } - return 0; -} - -void GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) { - if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind()) { - // TODO(ribrdb): read length and data - } -} - -void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { - // Dump to stdout - StreamFile s(stdout, false); - DumpTypeDescription(type, &s); -} - -void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) { - if (!type) - return; - ConstString name = GetTypeName(type); - GoType *t = static_cast<GoType *>(type); - - if (GoStruct *st = t->GetStruct()) { - if (GetCompleteType(type)) { - if (NULL == strchr(name.AsCString(), '{')) - s->Printf("type %s ", name.AsCString()); - s->PutCString("struct {"); - if (st->GetNumFields() == 0) { - s->PutChar('}'); - return; - } - s->IndentMore(); - uint32_t field_idx = 0; - for (auto *field = st->GetField(field_idx); field != nullptr; - field_idx++) { - s->PutChar('\n'); - s->Indent(); - s->Printf("%s %s", field->m_name.AsCString(), - field->m_type.GetTypeName().AsCString()); - } - s->IndentLess(); - s->PutChar('\n'); - s->Indent("}"); - return; - } - } - - s->PutCString(name.AsCString()); -} - -CompilerType GoASTContext::CreateArrayType(const ConstString &name, - const CompilerType &element_type, - uint64_t length) { - GoType *type = new GoArray(name, length, element_type); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType GoASTContext::CreateBaseType(int go_kind, - const lldb_private::ConstString &name, - uint64_t byte_size) { - if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT) - m_int_byte_size = byte_size; - GoType *type = new GoType(go_kind, name); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType GoASTContext::CreateTypedefType(int kind, const ConstString &name, - CompilerType impl) { - GoType *type = new GoElem(kind, name, impl); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::CreateVoidType(const lldb_private::ConstString &name) { - GoType *type = new GoType(GoType::KIND_LLDB_VOID, name); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name, - uint32_t byte_size) { - GoType *type = new GoStruct(kind, name, byte_size); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -void GoASTContext::AddFieldToStruct( - const lldb_private::CompilerType &struct_type, - const lldb_private::ConstString &name, - const lldb_private::CompilerType &field_type, uint32_t byte_offset) { - if (!struct_type) - return; - GoASTContext *ast = - llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem()); - if (!ast) - return; - GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType()); - if (GoStruct *s = type->GetStruct()) - s->AddField(name, field_type, byte_offset); -} - -void GoASTContext::CompleteStructType( - const lldb_private::CompilerType &struct_type) { - if (!struct_type) - return; - GoASTContext *ast = - llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem()); - if (!ast) - return; - GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType()); - if (GoStruct *s = type->GetStruct()) - s->SetComplete(); -} - -CompilerType -GoASTContext::CreateFunctionType(const lldb_private::ConstString &name, - CompilerType *params, size_t params_count, - bool is_variadic) { - GoType *type = new GoFunction(name, is_variadic); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -bool GoASTContext::IsGoString(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem())) - return false; - return GoType::KIND_STRING == - static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsGoSlice(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem())) - return false; - return GoType::KIND_SLICE == - static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsGoInterface(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem())) - return false; - return GoType::KIND_INTERFACE == - static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsPointerKind(uint8_t kind) { - return (kind & GoType::KIND_MASK) == GoType::KIND_PTR; -} - -bool GoASTContext::IsDirectIface(uint8_t kind) { - return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE; -} - -DWARFASTParser *GoASTContext::GetDWARFParser() { - if (!m_dwarf_ast_parser_ap) - m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this)); - return m_dwarf_ast_parser_ap.get(); -} - -UserExpression *GoASTContextForExpr::GetUserExpression( - llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) { - TargetSP target = m_target_wp.lock(); - if (target) - return new GoUserExpression(*target, expr, prefix, language, desired_type, - options); - return nullptr; -} |
