| //===-- 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 "lldb/Symbol/JavaASTContext.h" |
| #include "lldb/Core/DumpDataExtractor.h" |
| #include "lldb/Core/Module.h" |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Core/StreamFile.h" |
| #include "lldb/Core/ValueObject.h" |
| #include "lldb/Expression/DWARFExpression.h" |
| #include "lldb/Symbol/CompilerType.h" |
| #include "lldb/Symbol/SymbolFile.h" |
| #include "lldb/Symbol/Type.h" |
| #include "lldb/Target/Target.h" |
| #include "lldb/Utility/ArchSpec.h" |
| #include "lldb/Utility/Stream.h" |
| #include <sstream> |
| |
| #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 JavaDynamicType : public JavaASTContext::JavaType { |
| public: |
| JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name) |
| : JavaType(kind), m_linkage_name(linkage_name), |
| m_dynamic_type_id(nullptr) {} |
| |
| ConstString GetLinkageName() const { return m_linkage_name; } |
| |
| 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(), 0, |
| &obj_load_address, nullptr, result, |
| nullptr)) { |
| Status 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; |
| } |
| |
| public: |
| ConstString m_linkage_name; |
| DWARFExpression m_dynamic_type_id; |
| }; |
| |
| class JavaObjectType : public JavaDynamicType { |
| 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) |
| : JavaDynamicType(JavaType::eKindObject, linkage_name), m_name(name), |
| m_byte_size(byte_size), m_base_class_offset(0), m_is_complete(false) {} |
| |
| ConstString GetName() override { return m_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}); |
| } |
| |
| static bool classof(const JavaType *jt) { |
| return jt->getKind() == JavaType::eKindObject; |
| } |
| |
| private: |
| ConstString m_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; |
| }; |
| |
| 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 JavaDynamicType { |
| public: |
| JavaArrayType(const ConstString &linkage_name, CompilerType element_type, |
| const DWARFExpression &length_expression, |
| lldb::addr_t data_offset) |
| : JavaDynamicType(JavaType::eKindArray, linkage_name), |
| m_element_type(element_type), m_length_expression(length_expression), |
| m_data_offset(data_offset) {} |
| |
| 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(ValueObject *value_obj) { |
| if (!m_length_expression.IsValid()) |
| return UINT32_MAX; |
| |
| Status error; |
| ValueObjectSP address_obj = value_obj->AddressOf(error); |
| if (error.Fail()) |
| return UINT32_MAX; |
| |
| Value obj_load_address = address_obj->GetValue(); |
| obj_load_address.SetValueType(Value::eValueTypeLoadAddress); |
| |
| Value result; |
| ExecutionContextScope *exec_ctx_scope = value_obj->GetExecutionContextRef() |
| .Lock(true) |
| .GetBestExecutionContextScope(); |
| if (m_length_expression.Evaluate(exec_ctx_scope, 0, nullptr, |
| &obj_load_address, result, nullptr)) |
| return result.GetScalar().UInt(); |
| |
| return UINT32_MAX; |
| } |
| |
| uint64_t GetElementOffset(size_t idx) { |
| return m_data_offset + idx * m_element_type.GetByteSize(nullptr); |
| } |
| |
| private: |
| CompilerType m_element_type; |
| DWARFExpression m_length_expression; |
| lldb::addr_t m_data_offset; |
| }; |
| |
| } // 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(); |
| } |
| |
| 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::IsBlockPointerType( |
| lldb::opaque_compiler_type_t type, |
| CompilerType *function_pointer_type_ptr) { |
| 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 (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type))) { |
| return 64; |
| } 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; |
| } |
| |
| 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 DumpDataExtractor(data, 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 ConstString &linkage_name, 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( |
| linkage_name, 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); |
| if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>( |
| static_cast<JavaType *>(type.GetOpaqueQualType()))) |
| return arr->CalculateDynamicTypeId(exe_ctx, in_value); |
| return UINT64_MAX; |
| } |
| |
| uint32_t JavaASTContext::CalculateArraySize(const CompilerType &type, |
| ValueObject &in_value) { |
| if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>( |
| static_cast<JavaType *>(type.GetOpaqueQualType()))) |
| return arr->GetNumElements(&in_value); |
| return UINT32_MAX; |
| } |
| |
| uint64_t JavaASTContext::CalculateArrayElementOffset(const CompilerType &type, |
| size_t index) { |
| if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>( |
| static_cast<JavaType *>(type.GetOpaqueQualType()))) |
| return arr->GetElementOffset(index); |
| 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(); |
| } |