forked from OSchip/llvm-project
1519 lines
42 KiB
C++
1519 lines
42 KiB
C++
//===-- JavaASTContext.cpp --------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <sstream>
|
|
|
|
#include "lldb/Core/ArchSpec.h"
|
|
#include "lldb/Core/DataExtractor.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/PluginManager.h"
|
|
#include "lldb/Core/Stream.h"
|
|
#include "lldb/Core/StreamFile.h"
|
|
#include "lldb/Core/ValueObject.h"
|
|
#include "lldb/Expression/DWARFExpression.h"
|
|
#include "lldb/Symbol/CompilerType.h"
|
|
#include "lldb/Symbol/JavaASTContext.h"
|
|
#include "lldb/Symbol/SymbolFile.h"
|
|
#include "lldb/Symbol/Type.h"
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
namespace lldb_private
|
|
{
|
|
|
|
class JavaASTContext::JavaType
|
|
{
|
|
public:
|
|
enum LLVMCastKind
|
|
{
|
|
eKindPrimitive,
|
|
eKindObject,
|
|
eKindReference,
|
|
eKindArray,
|
|
kNumKinds
|
|
};
|
|
|
|
JavaType(LLVMCastKind kind) : m_kind(kind) {}
|
|
|
|
virtual ~JavaType() = default;
|
|
|
|
virtual ConstString
|
|
GetName() = 0;
|
|
|
|
virtual void
|
|
Dump(Stream *s) = 0;
|
|
|
|
virtual bool
|
|
IsCompleteType() = 0;
|
|
|
|
LLVMCastKind
|
|
getKind() const
|
|
{
|
|
return m_kind;
|
|
}
|
|
|
|
private:
|
|
LLVMCastKind m_kind;
|
|
};
|
|
|
|
} // end of namespace lldb_private
|
|
|
|
namespace
|
|
{
|
|
|
|
class JavaPrimitiveType : public JavaASTContext::JavaType
|
|
{
|
|
public:
|
|
enum TypeKind
|
|
{
|
|
eTypeByte,
|
|
eTypeShort,
|
|
eTypeInt,
|
|
eTypeLong,
|
|
eTypeFloat,
|
|
eTypeDouble,
|
|
eTypeBoolean,
|
|
eTypeChar,
|
|
};
|
|
|
|
JavaPrimitiveType(TypeKind type_kind) : JavaType(JavaType::eKindPrimitive), m_type_kind(type_kind) {}
|
|
|
|
ConstString
|
|
GetName() override
|
|
{
|
|
switch (m_type_kind)
|
|
{
|
|
case eTypeByte:
|
|
return ConstString("byte");
|
|
case eTypeShort:
|
|
return ConstString("short");
|
|
case eTypeInt:
|
|
return ConstString("int");
|
|
case eTypeLong:
|
|
return ConstString("long");
|
|
case eTypeFloat:
|
|
return ConstString("float");
|
|
case eTypeDouble:
|
|
return ConstString("double");
|
|
case eTypeBoolean:
|
|
return ConstString("boolean");
|
|
case eTypeChar:
|
|
return ConstString("char");
|
|
}
|
|
return ConstString();
|
|
}
|
|
|
|
TypeKind
|
|
GetTypeKind()
|
|
{
|
|
return m_type_kind;
|
|
}
|
|
|
|
void
|
|
Dump(Stream *s) override
|
|
{
|
|
s->Printf("%s\n", GetName().GetCString());
|
|
}
|
|
|
|
bool
|
|
IsCompleteType() override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
static bool
|
|
classof(const JavaType *jt)
|
|
{
|
|
return jt->getKind() == JavaType::eKindPrimitive;
|
|
}
|
|
|
|
private:
|
|
const TypeKind m_type_kind;
|
|
};
|
|
|
|
class JavaObjectType : public JavaASTContext::JavaType
|
|
{
|
|
public:
|
|
struct Field
|
|
{
|
|
ConstString m_name;
|
|
CompilerType m_type;
|
|
uint32_t m_offset;
|
|
};
|
|
|
|
JavaObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
|
|
: JavaType(JavaType::eKindObject),
|
|
m_name(name),
|
|
m_linkage_name(linkage_name),
|
|
m_byte_size(byte_size),
|
|
m_base_class_offset(0),
|
|
m_is_complete(false),
|
|
m_dynamic_type_id(nullptr)
|
|
{
|
|
}
|
|
|
|
ConstString
|
|
GetName() override
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
ConstString
|
|
GetLinkageName() const
|
|
{
|
|
return m_linkage_name;
|
|
}
|
|
|
|
uint32_t
|
|
GetByteSize() const
|
|
{
|
|
return m_byte_size;
|
|
}
|
|
|
|
uint32_t
|
|
GetNumFields()
|
|
{
|
|
return m_fields.size();
|
|
}
|
|
|
|
void
|
|
Dump(Stream *s) override
|
|
{
|
|
if (m_base_class.IsValid())
|
|
s->Printf("%s : %s\n", GetName().GetCString(), m_base_class.GetTypeName().GetCString());
|
|
else
|
|
s->Printf("%s\n", GetName().GetCString());
|
|
|
|
s->IndentMore();
|
|
for (const Field &f : m_fields)
|
|
s->Printf("%s %s\n", f.m_type.GetTypeName().GetCString(), f.m_name.GetCString());
|
|
s->IndentLess();
|
|
}
|
|
|
|
Field *
|
|
GetFieldAtIndex(size_t idx)
|
|
{
|
|
if (idx < m_fields.size())
|
|
return &m_fields[idx];
|
|
return nullptr;
|
|
}
|
|
|
|
CompilerType
|
|
GetBaseClass()
|
|
{
|
|
return m_base_class;
|
|
}
|
|
|
|
uint32_t
|
|
GetBaseClassOffset()
|
|
{
|
|
return m_base_class_offset;
|
|
}
|
|
|
|
uint32_t
|
|
GetNumInterfaces()
|
|
{
|
|
return m_interfaces.size();
|
|
}
|
|
|
|
CompilerType
|
|
GetInterfaceAtIndex(uint32_t idx)
|
|
{
|
|
if (m_interfaces.size() < idx)
|
|
return m_interfaces[idx];
|
|
return CompilerType();
|
|
}
|
|
|
|
bool
|
|
IsCompleteType() override
|
|
{
|
|
return m_is_complete;
|
|
}
|
|
|
|
void
|
|
SetCompleteType(bool is_complete)
|
|
{
|
|
m_is_complete = is_complete;
|
|
if (m_byte_size == 0)
|
|
{
|
|
// Try to calcualte the size of the object based on it's values
|
|
for (const Field &field : m_fields)
|
|
{
|
|
uint32_t field_end = field.m_offset + field.m_type.GetByteSize(nullptr);
|
|
if (field_end > m_byte_size)
|
|
m_byte_size = field_end;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
AddBaseClass(const CompilerType &type, uint32_t offset)
|
|
{
|
|
// TODO: Check if type is an interface and add it to the interface list in that case
|
|
m_base_class = type;
|
|
m_base_class_offset = offset;
|
|
}
|
|
|
|
void
|
|
AddField(const ConstString &name, const CompilerType &type, uint32_t offset)
|
|
{
|
|
m_fields.push_back({name, type, offset});
|
|
}
|
|
|
|
void
|
|
SetDynamicTypeId(const DWARFExpression &type_id)
|
|
{
|
|
m_dynamic_type_id = type_id;
|
|
}
|
|
|
|
uint64_t
|
|
CalculateDynamicTypeId(ExecutionContext *exe_ctx, ValueObject &value_obj)
|
|
{
|
|
if (!m_dynamic_type_id.IsValid())
|
|
return UINT64_MAX;
|
|
|
|
Value obj_load_address = value_obj.GetValue();
|
|
obj_load_address.ResolveValue(exe_ctx);
|
|
obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
|
|
|
|
Value result;
|
|
if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), nullptr, nullptr, 0, &obj_load_address,
|
|
nullptr, result, nullptr))
|
|
{
|
|
Error error;
|
|
|
|
lldb::addr_t type_id_addr = result.GetScalar().UInt();
|
|
lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
|
|
if (process_sp)
|
|
return process_sp->ReadUnsignedIntegerFromMemory(type_id_addr, process_sp->GetAddressByteSize(),
|
|
UINT64_MAX, error);
|
|
}
|
|
|
|
return UINT64_MAX;
|
|
}
|
|
|
|
static bool
|
|
classof(const JavaType *jt)
|
|
{
|
|
return jt->getKind() == JavaType::eKindObject;
|
|
}
|
|
|
|
private:
|
|
ConstString m_name;
|
|
ConstString m_linkage_name;
|
|
uint32_t m_byte_size;
|
|
CompilerType m_base_class;
|
|
uint32_t m_base_class_offset;
|
|
std::vector<CompilerType> m_interfaces;
|
|
std::vector<Field> m_fields;
|
|
bool m_is_complete;
|
|
DWARFExpression m_dynamic_type_id;
|
|
};
|
|
|
|
class JavaReferenceType : public JavaASTContext::JavaType
|
|
{
|
|
public:
|
|
JavaReferenceType(CompilerType pointee_type) : JavaType(JavaType::eKindReference), m_pointee_type(pointee_type) {}
|
|
|
|
static bool
|
|
classof(const JavaType *jt)
|
|
{
|
|
return jt->getKind() == JavaType::eKindReference;
|
|
}
|
|
|
|
CompilerType
|
|
GetPointeeType()
|
|
{
|
|
return m_pointee_type;
|
|
}
|
|
|
|
ConstString
|
|
GetName() override
|
|
{
|
|
ConstString pointee_type_name = static_cast<JavaType *>(GetPointeeType().GetOpaqueQualType())->GetName();
|
|
return ConstString(std::string(pointee_type_name.AsCString()) + "&");
|
|
}
|
|
|
|
void
|
|
Dump(Stream *s) override
|
|
{
|
|
static_cast<JavaType *>(m_pointee_type.GetOpaqueQualType())->Dump(s);
|
|
}
|
|
|
|
bool
|
|
IsCompleteType() override
|
|
{
|
|
return m_pointee_type.IsCompleteType();
|
|
}
|
|
|
|
private:
|
|
CompilerType m_pointee_type;
|
|
};
|
|
|
|
class JavaArrayType : public JavaASTContext::JavaType
|
|
{
|
|
public:
|
|
JavaArrayType(CompilerType element_type, const DWARFExpression &length_expression, const lldb::addr_t data_offset)
|
|
: JavaType(JavaType::eKindArray),
|
|
m_element_type(element_type),
|
|
m_length_expression(length_expression)
|
|
{
|
|
}
|
|
|
|
static bool
|
|
classof(const JavaType *jt)
|
|
{
|
|
return jt->getKind() == JavaType::eKindArray;
|
|
}
|
|
|
|
CompilerType
|
|
GetElementType()
|
|
{
|
|
return m_element_type;
|
|
}
|
|
|
|
ConstString
|
|
GetName() override
|
|
{
|
|
ConstString element_type_name = static_cast<JavaType *>(GetElementType().GetOpaqueQualType())->GetName();
|
|
return ConstString(std::string(element_type_name.AsCString()) + "[]");
|
|
}
|
|
|
|
void
|
|
Dump(Stream *s) override
|
|
{
|
|
s->Printf("%s\n", GetName().GetCString());
|
|
}
|
|
|
|
bool
|
|
IsCompleteType() override
|
|
{
|
|
return m_length_expression.IsValid();
|
|
}
|
|
|
|
uint32_t
|
|
GetNumElements(const ValueObject *value_obj)
|
|
{
|
|
if (!m_length_expression.IsValid())
|
|
return false;
|
|
|
|
Value obj_load_address = value_obj->GetValue();
|
|
obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
|
|
|
|
Value result;
|
|
if (m_length_expression.Evaluate(nullptr, nullptr, nullptr, nullptr, 0, nullptr, &obj_load_address, result,
|
|
nullptr))
|
|
return result.GetScalar().UInt();
|
|
|
|
return 0;
|
|
}
|
|
|
|
private:
|
|
CompilerType m_element_type;
|
|
DWARFExpression m_length_expression;
|
|
};
|
|
|
|
} // end of anonymous namespace
|
|
|
|
ConstString
|
|
JavaASTContext::GetPluginNameStatic()
|
|
{
|
|
return ConstString("java");
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::GetPluginName()
|
|
{
|
|
return JavaASTContext::GetPluginNameStatic();
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetPluginVersion()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
lldb::TypeSystemSP
|
|
JavaASTContext::CreateInstance(lldb::LanguageType language, Module *module, Target *target)
|
|
{
|
|
if (language == eLanguageTypeJava)
|
|
{
|
|
if (module)
|
|
return std::make_shared<JavaASTContext>(module->GetArchitecture());
|
|
if (target)
|
|
return std::make_shared<JavaASTContext>(target->GetArchitecture());
|
|
assert(false && "Either a module or a target has to be specifed to create a JavaASTContext");
|
|
}
|
|
return lldb::TypeSystemSP();
|
|
}
|
|
|
|
void
|
|
JavaASTContext::EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
|
|
std::set<lldb::LanguageType> &languages_for_expressions)
|
|
{
|
|
static std::vector<lldb::LanguageType> s_languages_for_types({lldb::eLanguageTypeJava});
|
|
static std::vector<lldb::LanguageType> s_languages_for_expressions({});
|
|
|
|
languages_for_types.insert(s_languages_for_types.begin(), s_languages_for_types.end());
|
|
languages_for_expressions.insert(s_languages_for_expressions.begin(), s_languages_for_expressions.end());
|
|
}
|
|
|
|
void
|
|
JavaASTContext::Initialize()
|
|
{
|
|
PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", CreateInstance,
|
|
EnumerateSupportedLanguages);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::Terminate()
|
|
{
|
|
PluginManager::UnregisterPlugin(CreateInstance);
|
|
}
|
|
|
|
JavaASTContext::JavaASTContext(const ArchSpec &arch)
|
|
: TypeSystem(eKindJava), m_pointer_byte_size(arch.GetAddressByteSize())
|
|
{
|
|
}
|
|
|
|
JavaASTContext::~JavaASTContext()
|
|
{
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetPointerByteSize()
|
|
{
|
|
return m_pointer_byte_size;
|
|
}
|
|
|
|
DWARFASTParser *
|
|
JavaASTContext::GetDWARFParser()
|
|
{
|
|
if (!m_dwarf_ast_parser_ap)
|
|
m_dwarf_ast_parser_ap.reset(new DWARFASTParserJava(*this));
|
|
return m_dwarf_ast_parser_ap.get();
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::DeclGetName(void *opaque_decl)
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
lldb::VariableSP
|
|
JavaASTContext::DeclGetVariable(void *opaque_decl)
|
|
{
|
|
return lldb::VariableSP();
|
|
}
|
|
|
|
void
|
|
JavaASTContext::DeclLinkToObject(void *opaque_decl, std::shared_ptr<void> object)
|
|
{
|
|
}
|
|
|
|
std::vector<CompilerDecl>
|
|
JavaASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls)
|
|
{
|
|
return std::vector<CompilerDecl>();
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::DeclContextGetName(void *opaque_decl_ctx)
|
|
{
|
|
return ConstString();
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
|
|
bool *is_instance_method_ptr, ConstString *language_object_name_ptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::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;
|
|
|
|
if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
|
|
{
|
|
if (element_type)
|
|
*element_type = array->GetElementType();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsAggregateType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsCharType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
return ptype->GetTypeKind() == JavaPrimitiveType::eTypeChar;
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
|
|
{
|
|
is_complex = true;
|
|
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
count = 1;
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
count = 0;
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
|
|
{
|
|
if (is_variadic_ptr)
|
|
*is_variadic_ptr = false;
|
|
return false;
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
|
|
{
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
case JavaPrimitiveType::eTypeShort:
|
|
case JavaPrimitiveType::eTypeInt:
|
|
case JavaPrimitiveType::eTypeLong:
|
|
is_signed = true;
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
is_signed = false;
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type,
|
|
bool check_cplusplus, bool check_objc)
|
|
{
|
|
return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type));
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
|
|
{
|
|
if (pointee_type)
|
|
pointee_type->Clear();
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue)
|
|
{
|
|
if (is_rvalue)
|
|
*is_rvalue = false;
|
|
|
|
if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
{
|
|
if (pointee_type)
|
|
*pointee_type = ref->GetPointeeType();
|
|
return true;
|
|
}
|
|
|
|
if (pointee_type)
|
|
pointee_type->Clear();
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsScalarType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)) ||
|
|
llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type));
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsVoidType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return false; // TODO: Implement if we introduce the void type
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::SupportsLanguage(lldb::LanguageType language)
|
|
{
|
|
return language == lldb::eLanguageTypeJava;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
|
|
{
|
|
return IsPointerType(type, pointee_type) || IsReferenceType(type, pointee_type);
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length)
|
|
{
|
|
return false; // TODO: Implement it if we need it for string literals
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsTypedefType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::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
|
|
JavaASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return llvm::isa<JavaObjectType>(static_cast<JavaType *>(type));
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsCompleteType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return static_cast<JavaType *>(type)->IsCompleteType();
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsConst(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::IsDefined(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return type != nullptr;
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::GetCompleteType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (IsCompleteType(type))
|
|
return true;
|
|
|
|
if (JavaArrayType *array = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type)))
|
|
return GetCompleteType(array->GetElementType().GetOpaqueQualType());
|
|
|
|
if (JavaReferenceType *reference = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
return GetCompleteType(reference->GetPointeeType().GetOpaqueQualType());
|
|
|
|
if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
SymbolFile *symbol_file = GetSymbolFile();
|
|
if (!symbol_file)
|
|
return false;
|
|
|
|
CompilerType object_type(this, type);
|
|
return symbol_file->CompleteType(object_type);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::GetTypeName(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (type)
|
|
return static_cast<JavaType *>(type)->GetName();
|
|
return ConstString();
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::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;
|
|
|
|
if (IsReferenceType(type, pointee_or_element_compiler_type))
|
|
return eTypeHasChildren | eTypeHasValue | eTypeIsReference;
|
|
if (IsArrayType(type, pointee_or_element_compiler_type, nullptr, nullptr))
|
|
return eTypeHasChildren | eTypeIsArray;
|
|
if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
return eTypeHasChildren | eTypeIsClass;
|
|
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
case JavaPrimitiveType::eTypeShort:
|
|
case JavaPrimitiveType::eTypeInt:
|
|
case JavaPrimitiveType::eTypeLong:
|
|
return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | eTypeIsSigned;
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsFloat | eTypeIsSigned;
|
|
case JavaPrimitiveType::eTypeBoolean:
|
|
return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
|
|
case JavaPrimitiveType::eTypeChar:
|
|
return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
lldb::TypeClass
|
|
JavaASTContext::GetTypeClass(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (!type)
|
|
return eTypeClassInvalid;
|
|
if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
return eTypeClassReference;
|
|
if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
|
|
return eTypeClassArray;
|
|
if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
return eTypeClassClass;
|
|
if (llvm::isa<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
return eTypeClassBuiltin;
|
|
assert(false && "Java type with unhandled type class");
|
|
return eTypeClassInvalid;
|
|
}
|
|
|
|
lldb::LanguageType
|
|
JavaASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return lldb::eLanguageTypeJava;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride)
|
|
{
|
|
if (stride)
|
|
*stride = 0;
|
|
|
|
CompilerType element_type;
|
|
if (IsArrayType(type, &element_type, nullptr, nullptr))
|
|
return element_type;
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetPointeeType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
CompilerType pointee_type;
|
|
if (IsPointerType(type, &pointee_type))
|
|
return pointee_type;
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetPointerType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CompilerType(); // No pointer types in java
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CompilerType(this, type);
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CompilerType(this, type);
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
CompilerType pointee_type;
|
|
if (IsReferenceType(type, &pointee_type))
|
|
return pointee_type;
|
|
return CompilerType(this, type);
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
lldb::BasicType
|
|
JavaASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
return eBasicTypeOther;
|
|
case JavaPrimitiveType::eTypeShort:
|
|
return eBasicTypeShort;
|
|
case JavaPrimitiveType::eTypeInt:
|
|
return eBasicTypeInt;
|
|
case JavaPrimitiveType::eTypeLong:
|
|
return eBasicTypeLong;
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
return eBasicTypeFloat;
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
return eBasicTypeDouble;
|
|
case JavaPrimitiveType::eTypeBoolean:
|
|
return eBasicTypeBool;
|
|
case JavaPrimitiveType::eTypeChar:
|
|
return eBasicTypeChar;
|
|
}
|
|
}
|
|
return eBasicTypeInvalid;
|
|
}
|
|
|
|
uint64_t
|
|
JavaASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
|
|
{
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
return 8;
|
|
case JavaPrimitiveType::eTypeShort:
|
|
return 16;
|
|
case JavaPrimitiveType::eTypeInt:
|
|
return 32;
|
|
case JavaPrimitiveType::eTypeLong:
|
|
return 64;
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
return 32;
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
return 64;
|
|
case JavaPrimitiveType::eTypeBoolean:
|
|
return 1;
|
|
case JavaPrimitiveType::eTypeChar:
|
|
return 16;
|
|
}
|
|
}
|
|
else if (llvm::isa<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
{
|
|
return 32; // References are always 4 byte long in java
|
|
}
|
|
else if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
return obj->GetByteSize() * 8;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
lldb::Encoding
|
|
JavaASTContext::GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count)
|
|
{
|
|
count = 1;
|
|
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
case JavaPrimitiveType::eTypeShort:
|
|
case JavaPrimitiveType::eTypeInt:
|
|
case JavaPrimitiveType::eTypeLong:
|
|
return eEncodingSint;
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
return eEncodingIEEE754;
|
|
case JavaPrimitiveType::eTypeBoolean:
|
|
case JavaPrimitiveType::eTypeChar:
|
|
return eEncodingUint;
|
|
}
|
|
}
|
|
if (IsReferenceType(type))
|
|
return eEncodingUint;
|
|
return eEncodingInvalid;
|
|
}
|
|
|
|
lldb::Format
|
|
JavaASTContext::GetFormat(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaPrimitiveType *ptype = llvm::dyn_cast<JavaPrimitiveType>(static_cast<JavaType *>(type)))
|
|
{
|
|
switch (ptype->GetTypeKind())
|
|
{
|
|
case JavaPrimitiveType::eTypeByte:
|
|
case JavaPrimitiveType::eTypeShort:
|
|
case JavaPrimitiveType::eTypeInt:
|
|
case JavaPrimitiveType::eTypeLong:
|
|
return eFormatDecimal;
|
|
case JavaPrimitiveType::eTypeFloat:
|
|
case JavaPrimitiveType::eTypeDouble:
|
|
return eFormatFloat;
|
|
case JavaPrimitiveType::eTypeBoolean:
|
|
return eFormatBoolean;
|
|
case JavaPrimitiveType::eTypeChar:
|
|
return eFormatUnicode16;
|
|
}
|
|
}
|
|
if (IsReferenceType(type))
|
|
return eFormatHex;
|
|
return eFormatDefault;
|
|
}
|
|
|
|
unsigned
|
|
JavaASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst,
|
|
size_t dst_size)
|
|
{
|
|
assert(false && "Not implemented");
|
|
return 0;
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
return obj->GetNumFields();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::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 (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
|
|
if (!field)
|
|
return CompilerType();
|
|
name = field->m_name.AsCString();
|
|
if (bit_offset_ptr)
|
|
*bit_offset_ptr = field->m_offset * 8;
|
|
return field->m_type;
|
|
}
|
|
return CompilerType();
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes);
|
|
|
|
if (llvm::isa<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
return GetNumFields(type) + GetNumDirectBaseClasses(type);
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
return obj->GetNumInterfaces() + (obj->GetBaseClass() ? 1 : 0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
return obj->GetNumInterfaces();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
if (CompilerType base_class = obj->GetBaseClass())
|
|
{
|
|
if (idx == 0)
|
|
return base_class;
|
|
else
|
|
--idx;
|
|
}
|
|
return obj->GetInterfaceAtIndex(idx);
|
|
}
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
return obj->GetInterfaceAtIndex(idx);
|
|
}
|
|
return CompilerType();
|
|
}
|
|
|
|
void
|
|
JavaASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
|
|
const DataExtractor &data, lldb::offset_t data_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)
|
|
{
|
|
assert(false && "Not implemented");
|
|
}
|
|
|
|
bool
|
|
JavaASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
|
|
const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size,
|
|
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
|
|
ExecutionContextScope *exe_scope)
|
|
{
|
|
if (IsScalarType(type))
|
|
{
|
|
return data.Dump(s, data_offset, format, data_byte_size,
|
|
1, // count
|
|
UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
|
|
{
|
|
StreamFile s(stdout, false);
|
|
DumpTypeDescription(type, &s);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
|
|
{
|
|
static_cast<JavaType *>(type)->Dump(s);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::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)
|
|
{
|
|
assert(false && "Not implemented");
|
|
}
|
|
|
|
int
|
|
JavaASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CompilerType();
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TypeMemberFunctionImpl
|
|
JavaASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
|
|
{
|
|
return TypeMemberFunctionImpl();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::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;
|
|
|
|
ExecutionContextScope *exec_ctx_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
|
|
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
if (CompilerType base_class = obj->GetBaseClass())
|
|
{
|
|
if (idx == 0)
|
|
{
|
|
JavaType *base_class_type = static_cast<JavaType *>(base_class.GetOpaqueQualType());
|
|
child_name = base_class_type->GetName().GetCString();
|
|
child_byte_size = base_class.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
|
|
child_byte_offset = obj->GetBaseClassOffset();
|
|
child_is_base_class = true;
|
|
return base_class;
|
|
}
|
|
idx -= 1;
|
|
}
|
|
|
|
JavaObjectType::Field *field = obj->GetFieldAtIndex(idx);
|
|
if (!field)
|
|
return CompilerType();
|
|
|
|
child_name = field->m_name.AsCString();
|
|
child_byte_size = field->m_type.GetByteSize(exec_ctx_scope);
|
|
child_byte_offset = field->m_offset;
|
|
return field->m_type;
|
|
}
|
|
else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
{
|
|
CompilerType pointee_type = ref->GetPointeeType();
|
|
|
|
if (transparent_pointers)
|
|
return pointee_type.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);
|
|
|
|
if (idx != 0)
|
|
return CompilerType();
|
|
|
|
if (valobj && valobj->GetName())
|
|
child_name = valobj->GetName().GetCString();
|
|
child_is_deref_of_parent = true;
|
|
child_byte_offset = 0;
|
|
child_byte_size = pointee_type.GetByteSize(exec_ctx_scope);
|
|
return pointee_type;
|
|
}
|
|
return CompilerType();
|
|
}
|
|
|
|
uint32_t
|
|
JavaASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name,
|
|
bool omit_empty_base_classes)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
uint32_t index_offset = 0;
|
|
if (CompilerType base_class = obj->GetBaseClass())
|
|
{
|
|
if (base_class.GetTypeName() == ConstString(name))
|
|
return 0;
|
|
index_offset = 1;
|
|
}
|
|
for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
|
|
{
|
|
if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
|
|
return i + index_offset;
|
|
}
|
|
}
|
|
else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
{
|
|
return GetIndexOfChildWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes);
|
|
}
|
|
return UINT_MAX;
|
|
}
|
|
|
|
size_t
|
|
JavaASTContext::GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name,
|
|
bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes)
|
|
{
|
|
child_indexes.clear();
|
|
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
|
|
{
|
|
GetCompleteType(type);
|
|
|
|
uint32_t index_offset = 0;
|
|
if (CompilerType base_class = obj->GetBaseClass())
|
|
{
|
|
if (GetIndexOfChildMemberWithName(base_class.GetOpaqueQualType(), name, omit_empty_base_classes,
|
|
child_indexes) != 0)
|
|
{
|
|
child_indexes.insert(child_indexes.begin(), 0);
|
|
return child_indexes.size();
|
|
}
|
|
index_offset = 1;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < obj->GetNumFields(); ++i)
|
|
{
|
|
if (obj->GetFieldAtIndex(i)->m_name == ConstString(name))
|
|
{
|
|
child_indexes.push_back(i + index_offset);
|
|
return child_indexes.size();
|
|
}
|
|
}
|
|
}
|
|
else if (JavaReferenceType *ref = llvm::dyn_cast<JavaReferenceType>(static_cast<JavaType *>(type)))
|
|
{
|
|
return GetIndexOfChildMemberWithName(ref->GetPointeeType().GetOpaqueQualType(), name, omit_empty_base_classes,
|
|
child_indexes);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type)
|
|
{
|
|
return CreateReferenceType(CompilerType(this, type));
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx)
|
|
{
|
|
return GetTypeName(opaque_decl_ctx);
|
|
}
|
|
|
|
static void
|
|
AddPrimitiveType(JavaASTContext::JavaTypeMap &type_map, JavaPrimitiveType::TypeKind type_kind)
|
|
{
|
|
JavaPrimitiveType *type = new JavaPrimitiveType(type_kind);
|
|
type_map.emplace(type->GetName(), std::unique_ptr<JavaASTContext::JavaType>(type));
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::CreateBaseType(const ConstString &name)
|
|
{
|
|
if (m_base_type_map.empty())
|
|
{
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeByte);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeShort);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeInt);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeLong);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeFloat);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeDouble);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeBoolean);
|
|
AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeChar);
|
|
}
|
|
auto it = m_base_type_map.find(name);
|
|
if (it != m_base_type_map.end())
|
|
return CompilerType(this, it->second.get());
|
|
return CompilerType();
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
|
|
{
|
|
auto it = m_object_type_map.find(name);
|
|
if (it == m_object_type_map.end())
|
|
{
|
|
std::unique_ptr<JavaType> object_type(new JavaObjectType(name, linkage_name, byte_size));
|
|
it = m_object_type_map.emplace(name, std::move(object_type)).first;
|
|
}
|
|
return CompilerType(this, it->second.get());
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::CreateArrayType(const CompilerType &element_type, const DWARFExpression &length_expression,
|
|
const lldb::addr_t data_offset)
|
|
{
|
|
ConstString name = element_type.GetTypeName();
|
|
auto it = m_array_type_map.find(name);
|
|
if (it == m_array_type_map.end())
|
|
{
|
|
std::unique_ptr<JavaType> array_type(new JavaArrayType(element_type, length_expression, data_offset));
|
|
it = m_array_type_map.emplace(name, std::move(array_type)).first;
|
|
}
|
|
return CompilerType(this, it->second.get());
|
|
}
|
|
|
|
CompilerType
|
|
JavaASTContext::CreateReferenceType(const CompilerType &pointee_type)
|
|
{
|
|
ConstString name = pointee_type.GetTypeName();
|
|
auto it = m_reference_type_map.find(name);
|
|
if (it == m_reference_type_map.end())
|
|
it = m_reference_type_map.emplace(name, std::unique_ptr<JavaType>(new JavaReferenceType(pointee_type))).first;
|
|
return CompilerType(this, it->second.get());
|
|
}
|
|
|
|
void
|
|
JavaASTContext::CompleteObjectType(const CompilerType &object_type)
|
|
{
|
|
JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
|
|
assert(obj && "JavaASTContext::CompleteObjectType called with not a JavaObjectType");
|
|
obj->SetCompleteType(true);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type,
|
|
uint32_t member_offset)
|
|
{
|
|
JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
|
|
assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
|
|
obj->AddBaseClass(member_type, member_offset);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::AddMemberToObject(const CompilerType &object_type, const ConstString &name,
|
|
const CompilerType &member_type, uint32_t member_offset)
|
|
{
|
|
JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(object_type.GetOpaqueQualType()));
|
|
assert(obj && "JavaASTContext::AddMemberToObject called with not a JavaObjectType");
|
|
obj->AddField(name, member_type, member_offset);
|
|
}
|
|
|
|
void
|
|
JavaASTContext::SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id)
|
|
{
|
|
JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType()));
|
|
assert(obj && "JavaASTContext::SetDynamicTypeId called with not a JavaObjectType");
|
|
obj->SetDynamicTypeId(type_id);
|
|
}
|
|
|
|
uint64_t
|
|
JavaASTContext::CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
|
|
return obj->CalculateDynamicTypeId(exe_ctx, in_value);
|
|
return UINT64_MAX;
|
|
}
|
|
|
|
ConstString
|
|
JavaASTContext::GetLinkageName(const CompilerType &type)
|
|
{
|
|
if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
|
|
return obj->GetLinkageName();
|
|
return ConstString();
|
|
}
|