|  | //===-- BreakpointResolverFileLine.cpp --------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lldb/Breakpoint/BreakpointResolverFileLine.h" | 
|  |  | 
|  | // C Includes | 
|  | // C++ Includes | 
|  | // Other libraries and framework includes | 
|  | // Project includes | 
|  | #include "lldb/Breakpoint/BreakpointLocation.h" | 
|  | #include "lldb/Core/Log.h" | 
|  | #include "lldb/Core/Module.h" | 
|  | #include "lldb/Core/StreamString.h" | 
|  | #include "lldb/Symbol/CompileUnit.h" | 
|  | #include "lldb/Symbol/Function.h" | 
|  |  | 
|  | using namespace lldb; | 
|  | using namespace lldb_private; | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | // BreakpointResolverFileLine: | 
|  | //---------------------------------------------------------------------- | 
|  | BreakpointResolverFileLine::BreakpointResolverFileLine | 
|  | ( | 
|  | Breakpoint *bkpt, | 
|  | const FileSpec &file_spec, | 
|  | uint32_t line_no, | 
|  | bool check_inlines, | 
|  | bool skip_prologue, | 
|  | bool exact_match | 
|  | ) : | 
|  | BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), | 
|  | m_file_spec (file_spec), | 
|  | m_line_number (line_no), | 
|  | m_inlines (check_inlines), | 
|  | m_skip_prologue(skip_prologue), | 
|  | m_exact_match(exact_match) | 
|  | { | 
|  | } | 
|  |  | 
|  | BreakpointResolverFileLine::~BreakpointResolverFileLine () | 
|  | { | 
|  | } | 
|  |  | 
|  | Searcher::CallbackReturn | 
|  | BreakpointResolverFileLine::SearchCallback | 
|  | ( | 
|  | SearchFilter &filter, | 
|  | SymbolContext &context, | 
|  | Address *addr, | 
|  | bool containing | 
|  | ) | 
|  | { | 
|  | SymbolContextList sc_list; | 
|  |  | 
|  | assert (m_breakpoint != NULL); | 
|  |  | 
|  | // There is a tricky bit here.  You can have two compilation units that #include the same file, and | 
|  | // in one of them the function at m_line_number is used (and so code and a line entry for it is generated) but in the | 
|  | // other it isn't.  If we considered the CU's independently, then in the second inclusion, we'd move the breakpoint | 
|  | // to the next function that actually generated code in the header file.  That would end up being confusing. | 
|  | // So instead, we do the CU iterations by hand here, then scan through the complete list of matches, and figure out | 
|  | // the closest line number match, and only set breakpoints on that match. | 
|  |  | 
|  | // Note also that if file_spec only had a file name and not a directory, there may be many different file spec's in | 
|  | // the resultant list.  The closest line match for one will not be right for some totally different file. | 
|  | // So we go through the match list and pull out the sets that have the same file spec in their line_entry | 
|  | // and treat each set separately. | 
|  |  | 
|  | const size_t num_comp_units = context.module_sp->GetNumCompileUnits(); | 
|  | for (size_t i = 0; i < num_comp_units; i++) | 
|  | { | 
|  | CompUnitSP cu_sp (context.module_sp->GetCompileUnitAtIndex (i)); | 
|  | if (cu_sp) | 
|  | { | 
|  | if (filter.CompUnitPasses(*cu_sp)) | 
|  | cu_sp->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, m_exact_match, eSymbolContextEverything, sc_list); | 
|  | } | 
|  | } | 
|  | StreamString s; | 
|  | s.Printf ("for %s:%d ", | 
|  | m_file_spec.GetFilename().AsCString("<Unknown>"), | 
|  | m_line_number); | 
|  |  | 
|  | SetSCMatchesByLine (filter, sc_list, m_skip_prologue, s.GetData()); | 
|  |  | 
|  | return Searcher::eCallbackReturnContinue; | 
|  | } | 
|  |  | 
|  | Searcher::Depth | 
|  | BreakpointResolverFileLine::GetDepth() | 
|  | { | 
|  | return Searcher::eDepthModule; | 
|  | } | 
|  |  | 
|  | void | 
|  | BreakpointResolverFileLine::GetDescription (Stream *s) | 
|  | { | 
|  | s->Printf ("file = '%s', line = %u, exact_match = %d", m_file_spec.GetPath().c_str(), m_line_number, m_exact_match); | 
|  | } | 
|  |  | 
|  | void | 
|  | BreakpointResolverFileLine::Dump (Stream *s) const | 
|  | { | 
|  |  | 
|  | } | 
|  |  | 
|  | lldb::BreakpointResolverSP | 
|  | BreakpointResolverFileLine::CopyForBreakpoint (Breakpoint &breakpoint) | 
|  | { | 
|  | lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine(&breakpoint, | 
|  | m_file_spec, | 
|  | m_line_number, | 
|  | m_inlines, | 
|  | m_skip_prologue, | 
|  | m_exact_match)); | 
|  |  | 
|  | return ret_sp; | 
|  | } |