diff options
| -rw-r--r-- | lldb/include/lldb/API/SBFunction.h | 3 | ||||
| -rw-r--r-- | lldb/include/lldb/Core/FormatEntity.h | 1 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/CompileUnit.h | 27 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/Function.h | 18 | ||||
| -rw-r--r-- | lldb/scripts/interface/SBFunction.i | 10 | ||||
| -rw-r--r-- | lldb/source/API/SBFunction.cpp | 11 | ||||
| -rw-r--r-- | lldb/source/Core/Debugger.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Core/FormatEntity.cpp | 14 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 8 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 3 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Symbol/CompileUnit.cpp | 16 | ||||
| -rw-r--r-- | lldb/source/Symbol/Function.cpp | 15 |
13 files changed, 119 insertions, 11 deletions
diff --git a/lldb/include/lldb/API/SBFunction.h b/lldb/include/lldb/API/SBFunction.h index 86cfeb49bb5..8fb24c453b1 100644 --- a/lldb/include/lldb/API/SBFunction.h +++ b/lldb/include/lldb/API/SBFunction.h @@ -66,6 +66,9 @@ public: GetLanguage (); bool + GetIsOptimized (); + + bool operator == (const lldb::SBFunction &rhs) const; bool diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h index db4f5913283..d3a0b0c5d4a 100644 --- a/lldb/include/lldb/Core/FormatEntity.h +++ b/lldb/include/lldb/Core/FormatEntity.h @@ -81,6 +81,7 @@ namespace lldb_private FunctionPCOffset, FunctionInitial, FunctionChanged, + FunctionIsOptimized, LineEntryFile, LineEntryLineNumber, LineEntryStartAddress, diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h index e0c069352bf..85f446ddd00 100644 --- a/lldb/include/lldb/Symbol/CompileUnit.h +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -66,9 +66,12 @@ public: /// A language enumeration type that describes the main language /// of this compile unit. /// + /// @param[in] is_optimized + /// true if this compile unit was compiled with optimization. + /// /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language); + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized); //------------------------------------------------------------------ /// Construct with a module, file spec, UID and language. @@ -98,9 +101,12 @@ public: /// A language enumeration type that describes the main language /// of this compile unit. /// + /// @param[in] is_optimized + /// true if this compile unit was compiled with optimization. + /// /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language); + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized); //------------------------------------------------------------------ /// Destructor @@ -406,6 +412,22 @@ public: SymbolContextList &sc_list); + //------------------------------------------------------------------ + /// Get whether compiler optimizations were enabled for this compile unit + /// + /// "optimized" means that the debug experience may be difficult + /// for the user to understand. Variables may not be available when + /// the developer would expect them, stepping through the source lines + /// in the function may appear strange, etc. + /// + /// @return + /// Returns 'true' if this compile unit was compiled with + /// optimization. 'false' indicates that either the optimization + /// is unknown, or this compile unit was built without optimization. + //------------------------------------------------------------------ + bool + GetIsOptimized (); + protected: void *m_user_data; ///< User data for the SymbolFile parser to store information into. lldb::LanguageType m_language; ///< The programming language enumeration value. @@ -417,6 +439,7 @@ protected: FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations. std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand. lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand. + bool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization. private: enum diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h index 30c8f168e5f..7b7c5411730 100644 --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -616,6 +616,24 @@ public: size_t MemorySize () const; + //------------------------------------------------------------------ + /// Get whether compiler optimizations were enabled for this function + /// + /// The debug information may provide information about whether this + /// function was compiled with optimization or not. In this case, + /// "optimized" means that the debug experience may be difficult + /// for the user to understand. Variables may not be available when + /// the developer would expect them, stepping through the source lines + /// in the function may appear strange, etc. + /// + /// @return + /// Returns 'true' if this function was compiled with + /// optimization. 'false' indicates that either the optimization + /// is unknown, or this function was built without optimization. + //------------------------------------------------------------------ + bool + GetIsOptimized (); + lldb::DisassemblerSP GetInstructions (const ExecutionContext &exe_ctx, const char *flavor, diff --git a/lldb/scripts/interface/SBFunction.i b/lldb/scripts/interface/SBFunction.i index 346237583e8..df8fb8836d5 100644 --- a/lldb/scripts/interface/SBFunction.i +++ b/lldb/scripts/interface/SBFunction.i @@ -89,6 +89,16 @@ public: lldb::LanguageType GetLanguage (); + %feature("docstring", " + Returns true if the function was compiled with optimization. + Optimization, in this case, is meant to indicate that the debugger + experience may be confusing for the user -- variables optimized away, + stepping jumping between source lines -- and the driver may want to + provide some guidance to the user about this. + Returns false if unoptimized, or unknown.") GetIsOptimized; + bool + GetIsOptimized(); + bool GetDescription (lldb::SBStream &description); diff --git a/lldb/source/API/SBFunction.cpp b/lldb/source/API/SBFunction.cpp index 2ec6072b51e..795a726a183 100644 --- a/lldb/source/API/SBFunction.cpp +++ b/lldb/source/API/SBFunction.cpp @@ -258,4 +258,13 @@ SBFunction::GetLanguage () return lldb::eLanguageTypeUnknown; } - +bool +SBFunction::GetIsOptimized () +{ + if (m_opaque_ptr) + { + if (m_opaque_ptr->GetCompileUnit()) + return m_opaque_ptr->GetCompileUnit()->GetIsOptimized(); + } + return false; +} diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index cd41e5d6510..55324f15c5e 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -105,6 +105,7 @@ g_language_enumerators[] = #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" +#define IS_OPTIMIZED "{${function.is-optimized} [opt]}" #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ "{, ${frame.pc}}"\ @@ -122,6 +123,7 @@ g_language_enumerators[] = #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ MODULE_WITH_FUNC\ FILE_AND_LINE\ + IS_OPTIMIZED\ "\\n" // Three parts to this disassembly format specification: diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index b960007251f..19889ce4775 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -98,7 +98,8 @@ static FormatEntity::Entry::Definition g_function_child_entries[] = ENTRY ("line-offset" , FunctionLineOffset , UInt64), ENTRY ("pc-offset" , FunctionPCOffset , UInt64), ENTRY ("initial-function" , FunctionInitial , None), - ENTRY ("changed" , FunctionChanged , None) + ENTRY ("changed" , FunctionChanged , None), + ENTRY ("is-optimized" , FunctionIsOptimized , None) }; static FormatEntity::Entry::Definition g_line_child_entries[] = @@ -343,6 +344,7 @@ FormatEntity::Entry::TypeToCString (Type t) ENUM_TO_CSTR(FunctionPCOffset); ENUM_TO_CSTR(FunctionInitial); ENUM_TO_CSTR(FunctionChanged); + ENUM_TO_CSTR(FunctionIsOptimized); ENUM_TO_CSTR(LineEntryFile); ENUM_TO_CSTR(LineEntryLineNumber); ENUM_TO_CSTR(LineEntryStartAddress); @@ -1870,6 +1872,16 @@ FormatEntity::Format (const Entry &entry, case Entry::Type::FunctionChanged: return function_changed == true; + case Entry::Type::FunctionIsOptimized: + { + bool is_optimized = false; + if (sc->function && sc->function->GetIsOptimized()) + { + is_optimized = true; + } + return is_optimized; + } + case Entry::Type::FunctionInitial: return initial_function == true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index b18628f7b19..564b2dd2853 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1034,11 +1034,17 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); + bool is_optimized = false; + if (cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_APPLE_optimized, 0) == 1) + { + is_optimized = true; + } cu_sp.reset(new CompileUnit (module_sp, dwarf_cu, cu_file_spec, MakeUserID(dwarf_cu->GetOffset()), - cu_language)); + cu_language, + is_optimized)); if (cu_sp) { // If we just created a compile unit with an invalid file spec, try and get the diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index de972acd7ed..1e973b0ac68 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -660,7 +660,8 @@ SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) NULL, so_file_spec, cu_id, - eLanguageTypeUnknown)); + eLanguageTypeUnknown, + false)); if (m_compile_unit_infos[cu_idx].compile_unit_sp) { diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 09b91978260..d535078c189 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -161,7 +161,7 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); if (cu_symbol) - cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown)); + cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown, false)); } return cu_sp; } diff --git a/lldb/source/Symbol/CompileUnit.cpp b/lldb/source/Symbol/CompileUnit.cpp index d43ef44a137..29ee9952205 100644 --- a/lldb/source/Symbol/CompileUnit.cpp +++ b/lldb/source/Symbol/CompileUnit.cpp @@ -17,7 +17,7 @@ using namespace lldb; using namespace lldb_private; -CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) : +CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) : ModuleChild(module_sp), FileSpec (pathname, false), UserID(cu_sym_id), @@ -27,14 +27,15 @@ CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, cons m_functions (), m_support_files (), m_line_table_ap (), - m_variables() + m_variables(), + m_is_optimized (is_optimized) { if (language != eLanguageTypeUnknown) m_flags.Set(flagsParsedLanguage); assert(module_sp); } -CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language) : +CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &fspec, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, bool is_optimized) : ModuleChild(module_sp), FileSpec (fspec), UserID(cu_sym_id), @@ -44,7 +45,8 @@ CompileUnit::CompileUnit (const lldb::ModuleSP &module_sp, void *user_data, cons m_functions (), m_support_files (), m_line_table_ap (), - m_variables() + m_variables(), + m_is_optimized (is_optimized) { if (language != eLanguageTypeUnknown) m_flags.Set(flagsParsedLanguage); @@ -430,6 +432,12 @@ CompileUnit::ResolveSymbolContext return sc_list.GetSize() - prev_size; } +bool +CompileUnit::GetIsOptimized () +{ + return m_is_optimized; +} + void CompileUnit::SetVariableList(VariableListSP &variables) { diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp index 77448d4f2a2..be51925fc30 100644 --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -466,6 +466,21 @@ Function::MemorySize () const return mem_size; } +bool +Function::GetIsOptimized () +{ + bool result = false; + + // Currently optimization is only indicted by the + // vendor extension DW_AT_APPLE_optimized which + // is set on a compile unit level. + if (m_comp_unit) + { + result = m_comp_unit->GetIsOptimized(); + } + return result; +} + ConstString Function::GetDisplayName () const { |

