forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			1334 lines
		
	
	
		
			43 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			1334 lines
		
	
	
		
			43 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/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/JavaASTContext.h"
 | |
| #include "lldb/Symbol/SymbolFile.h"
 | |
| #include "lldb/Symbol/Type.h"
 | |
| #include "lldb/Target/Target.h"
 | |
| #include "lldb/Utility/Stream.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 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(),
 | |
|                                    nullptr, nullptr, 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, nullptr, nullptr, 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;
 | |
| }
 | |
| 
 | |
| 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 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();
 | |
| }
 |