コード例 #1
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();
}
コード例 #2
0
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);
}
コード例 #3
0
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;
}
コード例 #4
0
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;
}
コード例 #5
0
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;
}
コード例 #6
0
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();
}
コード例 #7
0
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);
}
コード例 #8
0
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;
}
コード例 #9
0
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;
}
コード例 #10
0
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;
    }
}
コード例 #11
0
// 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;
}
コード例 #12
0
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;
}
コード例 #13
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);
}
コード例 #14
0
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,
                            bool is_base_class)
{
    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,
                is_base_class);
        }

        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 data.Dump(s, byte_offset, format, byte_size, item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
                         bitfield_bit_size, bitfield_bit_offset, exe_scope);
    }
    return 0;
}
コード例 #15
0
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();
}