1 //===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
3 #include "DWARFASTParserOCaml.h"
5 #include "lldb/Core/Module.h"
6 #include "lldb/Symbol/CompileUnit.h"
7 #include "lldb/Symbol/Function.h"
8 #include "lldb/Symbol/ObjectFile.h"
9 #include "lldb/Symbol/Type.h"
10 #include "lldb/Symbol/TypeList.h"
11 #include "lldb/Utility/Log.h"
12 #include "lldb/Utility/Status.h"
15 using namespace lldb_private;
17 DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {}
19 DWARFASTParserOCaml::~DWARFASTParserOCaml() {}
21 TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) {
22 SymbolFileDWARF *dwarf = die.GetDWARF();
23 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
25 ConstString type_name;
26 uint64_t byte_size = 0;
28 DWARFAttributes attributes;
29 const size_t num_attributes = die.GetAttributes(attributes);
30 for (uint32_t i = 0; i < num_attributes; ++i) {
31 DWARFFormValue form_value;
32 dw_attr_t attr = attributes.AttributeAtIndex(i);
33 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
36 type_name.SetCString(form_value.AsCString());
39 byte_size = form_value.Unsigned();
44 assert(false && "Unsupported attribute for DW_TAG_base_type");
50 CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size);
51 return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
52 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
53 decl, compiler_type, Type::eResolveStateFull);
56 lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
59 bool *type_is_new_ptr) {
61 *type_is_new_ptr = false;
66 SymbolFileDWARF *dwarf = die.GetDWARF();
68 Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
69 if (type_ptr == DIE_IS_BEING_PARSED)
71 if (type_ptr != nullptr)
72 return type_ptr->shared_from_this();
76 *type_is_new_ptr = true;
79 case DW_TAG_base_type: {
80 type_sp = ParseBaseTypeFromDIE(die);
83 case DW_TAG_array_type: {
86 case DW_TAG_class_type: {
89 case DW_TAG_reference_type: {
97 DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
98 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
100 SymbolContextScope *symbol_context_scope = nullptr;
101 if (sc_parent_tag == DW_TAG_compile_unit ||
102 sc_parent_tag == DW_TAG_partial_unit) {
103 symbol_context_scope = sc.comp_unit;
104 } else if (sc.function != nullptr && sc_parent_die) {
105 symbol_context_scope =
106 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
107 if (symbol_context_scope == nullptr)
108 symbol_context_scope = sc.function;
111 if (symbol_context_scope != nullptr)
112 type_sp->SetSymbolContextScope(symbol_context_scope);
114 dwarf->GetTypeList()->Insert(type_sp);
115 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
120 Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc,
121 const DWARFDIE &die) {
122 DWARFRangeList func_ranges;
123 const char *name = NULL;
124 const char *mangled = NULL;
131 DWARFExpression frame_base(die.GetCU());
133 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
136 SymbolFileDWARF *dwarf = die.GetDWARF();
138 dwarf->GetObjectFile()->GetModule()->LogMessage(
139 log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s "
141 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
145 assert(die.Tag() == DW_TAG_subprogram);
147 if (die.Tag() != DW_TAG_subprogram)
150 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
151 decl_column, call_file, call_line, call_column,
153 AddressRange func_range;
154 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
155 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
156 if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
157 lowest_func_addr <= highest_func_addr) {
158 ModuleSP module_sp(die.GetModule());
159 func_range.GetBaseAddress().ResolveAddressUsingFileSections(
160 lowest_func_addr, module_sp->GetSectionList());
161 if (func_range.GetBaseAddress().IsValid())
162 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
165 if (func_range.GetBaseAddress().IsValid()) {
168 func_name.SetValue(ConstString(name), true);
171 std::unique_ptr<Declaration> decl_ap;
172 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
173 decl_ap.reset(new Declaration(
174 sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
175 decl_line, decl_column));
177 SymbolFileDWARF *dwarf = die.GetDWARF();
178 Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
180 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
182 if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
183 const user_id_t func_user_id = die.GetID();
184 func_sp.reset(new Function(sc.comp_unit,
185 func_user_id, // UserID is the DIE offset
186 func_user_id, func_name, func_type,
187 func_range)); // first address range
189 if (func_sp.get() != NULL) {
190 if (frame_base.IsValid())
191 func_sp->GetFrameBaseExpression() = frame_base;
192 sc.comp_unit->AddFunction(func_sp);
193 return func_sp.get();
202 lldb_private::CompilerDeclContext
203 DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
204 return CompilerDeclContext();
207 lldb_private::CompilerDeclContext
208 DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
209 return CompilerDeclContext();