15ffd83dbSDimitry Andric //===-- FileLineResolver.cpp ----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Core/FileLineResolver.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
120b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
130b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h"
1406c3fb27SDimitry Andric #include "lldb/Utility/FileSpecList.h"
150b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include <string>
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace lldb_private {
200b57cec5SDimitry Andric class Address;
210b57cec5SDimitry Andric }
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric using namespace lldb;
240b57cec5SDimitry Andric using namespace lldb_private;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric // FileLineResolver:
FileLineResolver(const FileSpec & file_spec,uint32_t line_no,bool check_inlines)270b57cec5SDimitry Andric FileLineResolver::FileLineResolver(const FileSpec &file_spec, uint32_t line_no,
280b57cec5SDimitry Andric                                    bool check_inlines)
290b57cec5SDimitry Andric     : Searcher(), m_file_spec(file_spec), m_line_number(line_no),
300b57cec5SDimitry Andric       m_inlines(check_inlines) {}
310b57cec5SDimitry Andric 
32fe6060f1SDimitry Andric FileLineResolver::~FileLineResolver() = default;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric Searcher::CallbackReturn
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)350b57cec5SDimitry Andric FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context,
369dba64beSDimitry Andric                                  Address *addr) {
370b57cec5SDimitry Andric   CompileUnit *cu = context.comp_unit;
380b57cec5SDimitry Andric 
39480093f4SDimitry Andric   if (m_inlines || m_file_spec.Compare(cu->GetPrimaryFile(), m_file_spec,
40480093f4SDimitry Andric                                        (bool)m_file_spec.GetDirectory())) {
410b57cec5SDimitry Andric     uint32_t start_file_idx = 0;
420b57cec5SDimitry Andric     uint32_t file_idx =
430b57cec5SDimitry Andric         cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec, false);
440b57cec5SDimitry Andric     if (file_idx != UINT32_MAX) {
450b57cec5SDimitry Andric       LineTable *line_table = cu->GetLineTable();
460b57cec5SDimitry Andric       if (line_table) {
470b57cec5SDimitry Andric         if (m_line_number == 0) {
480b57cec5SDimitry Andric           // Match all lines in a file...
490b57cec5SDimitry Andric           const bool append = true;
500b57cec5SDimitry Andric           while (file_idx != UINT32_MAX) {
5106c3fb27SDimitry Andric             line_table->FindLineEntriesForFileIndex(file_idx, append,
520b57cec5SDimitry Andric                                                     m_sc_list);
530b57cec5SDimitry Andric             // Get the next file index in case we have multiple file entries
540b57cec5SDimitry Andric             // for the same file
550b57cec5SDimitry Andric             file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1,
560b57cec5SDimitry Andric                                                            m_file_spec, false);
570b57cec5SDimitry Andric           }
580b57cec5SDimitry Andric         } else {
590b57cec5SDimitry Andric           // Match a specific line in a file...
600b57cec5SDimitry Andric         }
610b57cec5SDimitry Andric       }
620b57cec5SDimitry Andric     }
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric   return Searcher::eCallbackReturnContinue;
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
GetDepth()670b57cec5SDimitry Andric lldb::SearchDepth FileLineResolver::GetDepth() {
680b57cec5SDimitry Andric   return lldb::eSearchDepthCompUnit;
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
GetDescription(Stream * s)710b57cec5SDimitry Andric void FileLineResolver::GetDescription(Stream *s) {
720b57cec5SDimitry Andric   s->Printf("File and line resolver for file: \"%s\" line: %u",
730b57cec5SDimitry Andric             m_file_spec.GetPath().c_str(), m_line_number);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
Clear()760b57cec5SDimitry Andric void FileLineResolver::Clear() {
770b57cec5SDimitry Andric   m_file_spec.Clear();
780b57cec5SDimitry Andric   m_line_number = UINT32_MAX;
790b57cec5SDimitry Andric   m_sc_list.Clear();
800b57cec5SDimitry Andric   m_inlines = true;
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
Reset(const FileSpec & file_spec,uint32_t line,bool check_inlines)830b57cec5SDimitry Andric void FileLineResolver::Reset(const FileSpec &file_spec, uint32_t line,
840b57cec5SDimitry Andric                              bool check_inlines) {
850b57cec5SDimitry Andric   m_file_spec = file_spec;
860b57cec5SDimitry Andric   m_line_number = line;
870b57cec5SDimitry Andric   m_sc_list.Clear();
880b57cec5SDimitry Andric   m_inlines = check_inlines;
890b57cec5SDimitry Andric }
90