已合并
[feature]根据断点位置自动下发软硬断点 #130
wiyr0创建于 5月8日
[feature]根据断点位置自动下发软硬断点 #130
已合并
wiyr0创建于 5月8日
13 个文件变更+163-8
Mlldb/include/lldb/Symbol/Function.h+15-0
@@ -426,9 +426,15 @@ public:
426 ///426 ///
427 /// \param[in] range427 /// \param[in] range
428 /// The section offset based address for this function.428 /// The section offset based address for this function.
429+#ifndef MS_DEBUGGER
429 Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,430 Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
430 lldb::user_id_t func_type_uid, const Mangled &mangled,431 lldb::user_id_t func_type_uid, const Mangled &mangled,
431 Type *func_type, const AddressRange &range);432 Type *func_type, const AddressRange &range);
433+#else
434+ Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
435+ lldb::user_id_t func_type_uid, const Mangled &mangled,
436+ Type *func_type, const AddressRange &range, uint32_t function_class = 0);
437+#endif
432 438 
433 /// Destructor.439 /// Destructor.
434 ~Function() override;440 ~Function() override;
@@ -446,6 +452,11 @@ public:
446 452 
447 const AddressRange &GetAddressRange() { return m_range; }453 const AddressRange &GetAddressRange() { return m_range; }
448 454 
455+#ifdef MS_DEBUGGER
456+ uint32_t GetFunctionClass() const { return m_function_class; }
457+ void SetFunctionClass(uint32_t function_class) { m_function_class = function_class; }
458+#endif
459+ 
449 lldb::LanguageType GetLanguage() const;460 lldb::LanguageType GetLanguage() const;
450 /// Find the file and line number of the source location of the start of the461 /// Find the file and line number of the source location of the start of the
451 /// function. This will use the declaration if present and fall back on the462 /// function. This will use the declaration if present and fall back on the
@@ -672,6 +683,10 @@ protected:
672 /// Outgoing call edges.683 /// Outgoing call edges.
673 std::vector<std::unique_ptr<CallEdge>> m_call_edges;684 std::vector<std::unique_ptr<CallEdge>> m_call_edges;
674 685 
686+#ifdef MS_DEBUGGER
687+ uint32_t m_function_class;
688+#endif
689+ 
675private:690private:
676 Function(const Function &) = delete;691 Function(const Function &) = delete;
677 const Function &operator=(const Function &) = delete;692 const Function &operator=(const Function &) = delete;
Mlldb/include/lldb/Target/Target.h+8-0
@@ -1530,6 +1530,14 @@ public:
1530 /// Print all the signals set in this target.1530 /// Print all the signals set in this target.
1531 void PrintDummySignals(Stream &strm, Args &signals);1531 void PrintDummySignals(Stream &strm, Args &signals);
1532 1532 
1533+#ifdef MS_DEBUGGER
1534+ void UpdateBreakpoints(const lldb::ModuleSP &old_module_sp,
1535+ const lldb::ModuleSP &new_module_sp) {
1536+ ModuleList module_list;
1537+ return NotifyModuleUpdated(module_list, old_module_sp, new_module_sp);
1538+ }
1539+#endif
1540+ 
1533protected:1541protected:
1534 /// Implementing of ModuleList::Notifier.1542 /// Implementing of ModuleList::Notifier.
1535 1543 
Mlldb/include/lldb/lldb-private-enumerations.h+14-0
@@ -58,6 +58,20 @@ enum class AddressClass {
58};58};
59 59 
60#ifdef MS_DEBUGGER60#ifdef MS_DEBUGGER
61+enum class DeviceFunctionClass {
62+ NONE = 0U,
63+ HOST = 1U << 0,
64+ KERNEL = 1U << 1,
65+ AICORE = 1U << 2,
66+ AICPU = 1U << 3,
67+ AICUBE = 1U << 4,
68+ AIVEC = 1U << 5,
69+ SIMT_ENTRY = 1U << 6, // simt vector function
70+ SIMT_CALLEE = 1U << 7, // function called by simt vector function
71+ SIMD_ENTRY = 1U << 8, // simd vector function
72+ SIMD_CALLEE = 1U << 9 // function called by simd vector function
73+};
74+ 
61enum class DeviceAddressClass {75enum class DeviceAddressClass {
62 NONE = 0U,76 NONE = 0U,
63 GM = 1U << 0,77 GM = 1U << 0,
Mlldb/source/Breakpoint/Breakpoint.cpp+14-0
@@ -250,6 +250,20 @@ bool Breakpoint::IsInternal() const { return LLDB_BREAK_ID_IS_INTERNAL(m_bid); }
250 250 
251BreakpointLocationSP Breakpoint::AddLocation(const Address &addr,251BreakpointLocationSP Breakpoint::AddLocation(const Address &addr,
252 bool *new_location) {252 bool *new_location) {
253+#ifdef MS_DEBUGGER
254+ Log *log = GetLog(LLDBLog::Breakpoints);
255+ const auto *function = addr.CalculateSymbolContextFunction();
256+ LLDB_LOG(log, "Detect function_calss={0:x}", function->GetFunctionClass());
257+ if (function && (function->GetFunctionClass() &
258+ (static_cast<uint32_t>(DeviceFunctionClass::SIMD_CALLEE) |
259+ static_cast<uint32_t>(DeviceFunctionClass::SIMT_CALLEE) |
260+ static_cast<uint32_t>(DeviceFunctionClass::SIMT_ENTRY) |
261+ static_cast<uint32_t>(DeviceFunctionClass::SIMT_ENTRY)))) {
262+ m_hardware = true;
263+ LLDB_LOG(log, "Simt/Simd function only support hardware breakpoint, auto "
264+ "change breakpoint type to hardware");
265+ }
266+#endif
253 return m_locations.AddLocation(addr, m_resolve_indirect_symbols,267 return m_locations.AddLocation(addr, m_resolve_indirect_symbols,
254 new_location);268 new_location);
255}269}
Mlldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp+11-7
@@ -491,11 +491,14 @@ void DynamicLoaderPOSIXDYLD::RefreshDeviceModules() {
491 // remove this module from loaded modules if any one of these conditions below are met:491 // remove this module from loaded modules if any one of these conditions below are met:
492 // 1. it is a hiipu64-module and we need to reset all device binary.492 // 1. it is a hiipu64-module and we need to reset all device binary.
493 // 2. it is a duplicate module. we replace the old one with it in loaded modules.493 // 2. it is a duplicate module. we replace the old one with it in loaded modules.
494- if ((reset_all_device_binary &&494+ if (reset_all_device_binary &&
495- module_sp->GetArchitecture().GetTriple().getArch() == llvm::Triple::hiipu64) ||495+ module_sp->GetArchitecture().GetTriple().getArch() ==
496- (!reset_all_device_binary &&496+ llvm::Triple::hiipu64) {
497- module_sp && module_sp->GetUUID() == device_module->GetUUID())) {
498 old_modules.Append(module_sp);497 old_modules.Append(module_sp);
498+ } else if (!reset_all_device_binary && module_sp &&
499+ module_sp->GetUUID() == device_module->GetUUID()) {
500+ old_modules.Append(module_sp);
501+ m_process->GetTarget().UpdateBreakpoints(module_sp, device_module);
499 }502 }
500 }503 }
501 504 
@@ -504,7 +507,7 @@ void DynamicLoaderPOSIXDYLD::RefreshDeviceModules() {
504 UnloadSections(module_sp);507 UnloadSections(module_sp);
505 }508 }
506 loaded_modules.Remove(old_modules);509 loaded_modules.Remove(old_modules);
507- m_process->GetTarget().ModulesDidUnload(old_modules, false);510+ m_process->GetTarget().ModulesDidUnload(old_modules, true);
508 511 
509 // added new modules512 // added new modules
510 new_modules.Append(device_module);513 new_modules.Append(device_module);
@@ -558,9 +561,10 @@ void DynamicLoaderPOSIXDYLD::AddRendezvousVFCallBreakpoint(ModuleSP device_modul
558 uint64_t break_addr = par.first;561 uint64_t break_addr = par.first;
559 auto dyld_break = target.CreateBreakpoint(break_addr + base_pc + smallest_instr_bytes, true, false);562 auto dyld_break = target.CreateBreakpoint(break_addr + base_pc + smallest_instr_bytes, true, false);
560 if (dyld_break->GetNumResolvedLocations() != 1) {563 if (dyld_break->GetNumResolvedLocations() != 1) {
561- LLDB_LOG(log, "Rendezvoud vf_call breakpoint has abnormal number of"564+ LLDB_LOG(log,
565+ "Rendezvoud vf_call breakpoint has abnormal number of"
562 " resolved locations {0}. It's supposed to be exactly 1",566 " resolved locations {0}. It's supposed to be exactly 1",
563- dyld_break->GetNumResolvedLocations()); 567+ dyld_break->GetNumResolvedLocations());
564 target.RemoveBreakpointByID(dyld_break->GetID());568 target.RemoveBreakpointByID(dyld_break->GetID());
565 continue;569 continue;
566 }570 }
Mlldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp+15-0
@@ -2402,9 +2402,16 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2402 if (tag != DW_TAG_subprogram)2402 if (tag != DW_TAG_subprogram)
2403 return nullptr;2403 return nullptr;
2404 2404 
2405+#ifndef MS_DEBUGGER
2405 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,2406 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
2406 decl_column, call_file, call_line, call_column,2407 decl_column, call_file, call_line, call_column,
2407 &frame_base)) {2408 &frame_base)) {
2409+#else
2410+ std::optional<int> function_class;
2411+ if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
2412+ decl_column, call_file, call_line, call_column,
2413+ function_class, &frame_base)) {
2414+#endif
2408 Mangled func_name;2415 Mangled func_name;
2409 if (mangled)2416 if (mangled)
2410 func_name.SetValue(ConstString(mangled));2417 func_name.SetValue(ConstString(mangled));
@@ -2436,11 +2443,19 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2436 assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);2443 assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
2437 2444 
2438 const user_id_t func_user_id = die.GetID();2445 const user_id_t func_user_id = die.GetID();
2446+#ifndef MS_DEBUGGER
2439 func_sp =2447 func_sp =
2440 std::make_shared<Function>(&comp_unit,2448 std::make_shared<Function>(&comp_unit,
2441 func_user_id, // UserID is the DIE offset2449 func_user_id, // UserID is the DIE offset
2442 func_user_id, func_name, func_type,2450 func_user_id, func_name, func_type,
2443 func_range); // first address range2451 func_range); // first address range
2452+#else
2453+ func_sp =
2454+ std::make_shared<Function>(&comp_unit,
2455+ func_user_id, // UserID is the DIE offset
2456+ func_user_id, func_name, func_type,
2457+ func_range, function_class ? function_class.value() : 0); // first address range
2458+#endif
2444 2459 
2445 if (func_sp.get() != nullptr) {2460 if (func_sp.get() != nullptr) {
2446 if (frame_base.IsValid())2461 if (frame_base.IsValid())
Mlldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp+17-0
@@ -574,6 +574,7 @@ bool DWARFDIE::IsMethod() const {
574 return false;574 return false;
575}575}
576 576 
577+#ifndef MS_DEBUGGER
577bool DWARFDIE::GetDIENamesAndRanges(578bool DWARFDIE::GetDIENamesAndRanges(
578 const char *&name, const char *&mangled, DWARFRangeList &ranges,579 const char *&name, const char *&mangled, DWARFRangeList &ranges,
579 std::optional<int> &decl_file, std::optional<int> &decl_line,580 std::optional<int> &decl_file, std::optional<int> &decl_line,
@@ -587,6 +588,22 @@ bool DWARFDIE::GetDIENamesAndRanges(
587 } else588 } else
588 return false;589 return false;
589}590}
591+#else
592+bool DWARFDIE::GetDIENamesAndRanges(
593+ const char *&name, const char *&mangled, DWARFRangeList &ranges,
594+ std::optional<int> &decl_file, std::optional<int> &decl_line,
595+ std::optional<int> &decl_column, std::optional<int> &call_file,
596+ std::optional<int> &call_line, std::optional<int> &call_column,
597+ std::optional<int> &function_class,
598+ lldb_private::DWARFExpressionList *frame_base) const {
599+ if (IsValid()) {
600+ return m_die->GetDIENamesAndRanges(
601+ GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,
602+ call_file, call_line, call_column, function_class, frame_base);
603+ } else
604+ return false;
605+}
606+#endif
590 607 
591llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const {608llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const {
592 return llvm::make_range(child_iterator(*this), child_iterator());609 return llvm::make_range(child_iterator(*this), child_iterator());
Mlldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h+9-0
@@ -96,12 +96,21 @@ public:
96 DWARFDIE96 DWARFDIE
97 GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;97 GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
98 98 
99+#ifndef MS_DEBUGGER
99 bool GetDIENamesAndRanges(100 bool GetDIENamesAndRanges(
100 const char *&name, const char *&mangled, DWARFRangeList &ranges,101 const char *&name, const char *&mangled, DWARFRangeList &ranges,
101 std::optional<int> &decl_file, std::optional<int> &decl_line,102 std::optional<int> &decl_file, std::optional<int> &decl_line,
102 std::optional<int> &decl_column, std::optional<int> &call_file,103 std::optional<int> &decl_column, std::optional<int> &call_file,
103 std::optional<int> &call_line, std::optional<int> &call_column,104 std::optional<int> &call_line, std::optional<int> &call_column,
104 DWARFExpressionList *frame_base) const;105 DWARFExpressionList *frame_base) const;
106+#else
107+ bool GetDIENamesAndRanges(
108+ const char *&name, const char *&mangled, DWARFRangeList &ranges,
109+ std::optional<int> &decl_file, std::optional<int> &decl_line,
110+ std::optional<int> &decl_column, std::optional<int> &call_file,
111+ std::optional<int> &call_line, std::optional<int> &call_column,
112+ std::optional<int> &function_class, DWARFExpressionList *frame_base) const;
113+#endif
105 114 
106 /// The range of all the children of this DIE.115 /// The range of all the children of this DIE.
107 llvm::iterator_range<child_iterator> children() const;116 llvm::iterator_range<child_iterator> children() const;
Mlldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp+22-0
@@ -116,12 +116,21 @@ static void ExtractAttrAndFormValue(
116//116//
117// Gets the valid address ranges for a given DIE by looking for a117// Gets the valid address ranges for a given DIE by looking for a
118// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.118// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
119+#ifndef MS_DEBUGGER
119bool DWARFDebugInfoEntry::GetDIENamesAndRanges(120bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
120 DWARFUnit *cu, const char *&name, const char *&mangled,121 DWARFUnit *cu, const char *&name, const char *&mangled,
121 DWARFRangeList &ranges, std::optional<int> &decl_file,122 DWARFRangeList &ranges, std::optional<int> &decl_file,
122 std::optional<int> &decl_line, std::optional<int> &decl_column,123 std::optional<int> &decl_line, std::optional<int> &decl_column,
123 std::optional<int> &call_file, std::optional<int> &call_line,124 std::optional<int> &call_file, std::optional<int> &call_line,
124 std::optional<int> &call_column, DWARFExpressionList *frame_base) const {125 std::optional<int> &call_column, DWARFExpressionList *frame_base) const {
126+#else
127+bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
128+ DWARFUnit *cu, const char *&name, const char *&mangled,
129+ DWARFRangeList &ranges, std::optional<int> &decl_file,
130+ std::optional<int> &decl_line, std::optional<int> &decl_column,
131+ std::optional<int> &call_file, std::optional<int> &call_line,
132+ std::optional<int> &call_column, std::optional<int> &function_class, DWARFExpressionList *frame_base) const {
133+#endif
125 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;134 dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
126 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;135 dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
127 std::vector<DWARFDIE> dies;136 std::vector<DWARFDIE> dies;
@@ -252,6 +261,12 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
252 }261 }
253 }262 }
254 break;263 break;
264+#ifdef MS_DEBUGGER
265+ case DW_AT_function_class:
266+ if (!function_class) {
267+ function_class = form_value.Unsigned();
268+ }
269+#endif
255 270 
256 default:271 default:
257 break;272 break;
@@ -278,9 +293,16 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
278 if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {293 if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
279 for (const DWARFDIE &die : dies) {294 for (const DWARFDIE &die : dies) {
280 if (die) {295 if (die) {
296+#ifndef MS_DEBUGGER
281 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,297 die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
282 decl_file, decl_line, decl_column,298 decl_file, decl_line, decl_column,
283 call_file, call_line, call_column);299 call_file, call_line, call_column);
300+#else
301+ std::optional<int> function_class;
302+ die.GetDIE()->GetDIENamesAndRanges(die.GetCU(), name, mangled, ranges,
303+ decl_file, decl_line, decl_column,
304+ call_file, call_line, call_column, function_class);
305+#endif
284 }306 }
285 }307 }
286 }308 }
Mlldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h+13-0
@@ -106,6 +106,7 @@ public:
106 106 
107 const char *GetPubname(const DWARFUnit *cu) const;107 const char *GetPubname(const DWARFUnit *cu) const;
108 108 
109+#ifndef MS_DEBUGGER
109 bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,110 bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,
110 const char *&mangled, DWARFRangeList &rangeList,111 const char *&mangled, DWARFRangeList &rangeList,
111 std::optional<int> &decl_file,112 std::optional<int> &decl_file,
@@ -115,6 +116,18 @@ public:
115 std::optional<int> &call_line,116 std::optional<int> &call_line,
116 std::optional<int> &call_column,117 std::optional<int> &call_column,
117 DWARFExpressionList *frame_base = nullptr) const;118 DWARFExpressionList *frame_base = nullptr) const;
119+#else
120+ bool GetDIENamesAndRanges(DWARFUnit *cu, const char *&name,
121+ const char *&mangled, DWARFRangeList &rangeList,
122+ std::optional<int> &decl_file,
123+ std::optional<int> &decl_line,
124+ std::optional<int> &decl_column,
125+ std::optional<int> &call_file,
126+ std::optional<int> &call_line,
127+ std::optional<int> &call_column,
128+ std::optional<int> &function_class,
129+ DWARFExpressionList *frame_base = nullptr) const;
130+#endif
118 131 
119 const llvm::DWARFAbbreviationDeclaration *132 const llvm::DWARFAbbreviationDeclaration *
120 GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;133 GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;
Mlldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp+9-1
@@ -1368,9 +1368,17 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(
1368 std::optional<int> call_file;1368 std::optional<int> call_file;
1369 std::optional<int> call_line;1369 std::optional<int> call_line;
1370 std::optional<int> call_column;1370 std::optional<int> call_column;
1371+ 
1372+#ifndef MS_DEBUGGER
1371 if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,1373 if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1372 decl_line, decl_column, call_file, call_line,1374 decl_line, decl_column, call_file, call_line,
1373 call_column, nullptr)) {1375 call_column, nullptr)) {
1376+#else
1377+ std::optional<int> function_class;
1378+ if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1379+ decl_line, decl_column, call_file, call_line,
1380+ call_column, function_class, nullptr)) {
1381+#endif
1374 if (tag == DW_TAG_subprogram) {1382 if (tag == DW_TAG_subprogram) {
1375 assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);1383 assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
1376 subprogram_low_pc = ranges.GetMinRangeBase(0);1384 subprogram_low_pc = ranges.GetMinRangeBase(0);
@@ -1773,7 +1781,7 @@ SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) {
1773 // We have a SymbolFileDWARFDebugMap, so let it find the right file1781 // We have a SymbolFileDWARFDebugMap, so let it find the right file
1774 if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())1782 if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
1775 return debug_map->GetSymbolFileByOSOIndex(*file_index);1783 return debug_map->GetSymbolFileByOSOIndex(*file_index);
1776- 1784+ 
1777 // Handle the .dwp file case correctly1785 // Handle the .dwp file case correctly
1778 if (*file_index == DIERef::k_file_index_mask)1786 if (*file_index == DIERef::k_file_index_mask)
1779 return GetDwpSymbolFile().get(); // DWP case1787 return GetDwpSymbolFile().get(); // DWP case
Mlldb/source/Symbol/Function.cpp+13-0
@@ -255,6 +255,7 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images,
255/// @}255/// @}
256 256 
257//257//
258+#ifndef MS_DEBUGGER
258Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,259Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
259 lldb::user_id_t type_uid, const Mangled &mangled, Type *type,260 lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
260 const AddressRange &range)261 const AddressRange &range)
@@ -265,6 +266,18 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
265 assert(comp_unit != nullptr);266 assert(comp_unit != nullptr);
266}267}
267 268 
269+#else
270+Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
271+ lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
272+ const AddressRange &range, uint32_t function_class)
273+ : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
274+ m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range),
275+ m_frame_base(), m_flags(), m_prologue_byte_size(0), m_function_class(function_class) {
276+ m_block.SetParentScope(this);
277+ assert(comp_unit != nullptr);
278+}
279+#endif
280+ 
268Function::~Function() = default;281Function::~Function() = default;
269 282 
270void Function::GetStartLineSourceInfo(FileSpec &source_file,283void Function::GetStartLineSourceInfo(FileSpec &source_file,
Mllvm/include/llvm/BinaryFormat/Dwarf.def+3-0
@@ -410,6 +410,9 @@ HANDLE_DW_AT(0x89, export_symbols, 5, DWARF)
410HANDLE_DW_AT(0x8a, deleted, 5, DWARF)410HANDLE_DW_AT(0x8a, deleted, 5, DWARF)
411HANDLE_DW_AT(0x8b, defaulted, 5, DWARF)411HANDLE_DW_AT(0x8b, defaulted, 5, DWARF)
412HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF)412HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF)
413+// MS_DEBUGGER
414+HANDLE_DW_AT(0x8d, function_class, 5, DWARF)
415+// MS_DEBUGGER
413 416 
414// Vendor extensions:417// Vendor extensions:
415HANDLE_DW_AT(0x806, GHS_namespace_alias, 0, GHS)418HANDLE_DW_AT(0x806, GHS_namespace_alias, 0, GHS)