130fdc8d8SChris Lattner //===-- LineTable.h ---------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 9cdc514e4SJonas Devlieghere #ifndef LLDB_SYMBOL_LINETABLE_H 10cdc514e4SJonas Devlieghere #define LLDB_SYMBOL_LINETABLE_H 1130fdc8d8SChris Lattner 12b0ad73a2SAdrian Prantl #include "lldb/Core/Address.h" 1330fdc8d8SChris Lattner #include "lldb/Core/ModuleChild.h" 14b9c1b51eSKate Stone #include "lldb/Core/Section.h" 153e2ed744SMed Ismail Bennani #include "lldb/Core/SourceLocationSpec.h" 16b9c1b51eSKate Stone #include "lldb/Symbol/LineEntry.h" 17b8093314SPavel Labath #include "lldb/Utility/RangeMap.h" 18b9c1b51eSKate Stone #include "lldb/lldb-private.h" 19b8093314SPavel Labath #include <vector> 2030fdc8d8SChris Lattner 2130fdc8d8SChris Lattner namespace lldb_private { 2230fdc8d8SChris Lattner 23f05b42e9SAdrian Prantl /// \class LineSequence LineTable.h "lldb/Symbol/LineTable.h" An abstract base 24d8f460e8SAdrian Prantl /// class used during symbol table creation. 25b9c1b51eSKate Stone class LineSequence { 26c740150fSAndrew Kaylor public: 27c740150fSAndrew Kaylor LineSequence(); 28c740150fSAndrew Kaylor 29b9c1b51eSKate Stone virtual ~LineSequence() = default; 30c740150fSAndrew Kaylor 31b9c1b51eSKate Stone virtual void Clear() = 0; 32c740150fSAndrew Kaylor 33c740150fSAndrew Kaylor private: 34eaebcbc6SKonrad Kleine LineSequence(const LineSequence &) = delete; 35eaebcbc6SKonrad Kleine const LineSequence &operator=(const LineSequence &) = delete; 36c740150fSAndrew Kaylor }; 37c740150fSAndrew Kaylor 38f05b42e9SAdrian Prantl /// \class LineTable LineTable.h "lldb/Symbol/LineTable.h" 39d8f460e8SAdrian Prantl /// A line table class. 40b9c1b51eSKate Stone class LineTable { 4130fdc8d8SChris Lattner public: 4230fdc8d8SChris Lattner /// Construct with compile unit. 4330fdc8d8SChris Lattner /// 44f05b42e9SAdrian Prantl /// \param[in] comp_unit 4530fdc8d8SChris Lattner /// The compile unit to which this line table belongs. 4630fdc8d8SChris Lattner LineTable(CompileUnit *comp_unit); 4730fdc8d8SChris Lattner 4839f13354SUnnar Freyr Erlendsson /// Construct with entries found in \a sequences. 4939f13354SUnnar Freyr Erlendsson /// 5039f13354SUnnar Freyr Erlendsson /// \param[in] sequences 5139f13354SUnnar Freyr Erlendsson /// Unsorted list of line sequences. 5218a96fd5SPavel Labath LineTable(CompileUnit *comp_unit, 5318a96fd5SPavel Labath std::vector<std::unique_ptr<LineSequence>> &&sequences); 5439f13354SUnnar Freyr Erlendsson 5530fdc8d8SChris Lattner /// Destructor. 5630fdc8d8SChris Lattner ~LineTable(); 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner /// Adds a new line entry to this line table. 5930fdc8d8SChris Lattner /// 6030fdc8d8SChris Lattner /// All line entries are maintained in file address order. 6130fdc8d8SChris Lattner /// 62f05b42e9SAdrian Prantl /// \param[in] line_entry 6330fdc8d8SChris Lattner /// A const reference to a new line_entry to add to this line 6430fdc8d8SChris Lattner /// table. 6530fdc8d8SChris Lattner /// 66f05b42e9SAdrian Prantl /// \see Address::DumpStyle 6730fdc8d8SChris Lattner // void 6830fdc8d8SChris Lattner // AddLineEntry (const LineEntry& line_entry); 6930fdc8d8SChris Lattner 7030fdc8d8SChris Lattner // Called when you can't guarantee the addresses are in increasing order 71b9c1b51eSKate Stone void InsertLineEntry(lldb::addr_t file_addr, uint32_t line, uint16_t column, 72b9c1b51eSKate Stone uint16_t file_idx, bool is_start_of_statement, 73b9c1b51eSKate Stone bool is_start_of_basic_block, bool is_prologue_end, 74b9c1b51eSKate Stone bool is_epilogue_begin, bool is_terminal_entry); 7530fdc8d8SChris Lattner 76d93c4a33SBruce Mitchener // Used to instantiate the LineSequence helper class 7718a96fd5SPavel Labath static std::unique_ptr<LineSequence> CreateLineSequenceContainer(); 78c740150fSAndrew Kaylor 79c740150fSAndrew Kaylor // Append an entry to a caller-provided collection that will later be 80c740150fSAndrew Kaylor // inserted in this line table. 8139f13354SUnnar Freyr Erlendsson static void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr, 82b9c1b51eSKate Stone uint32_t line, uint16_t column, 83b9c1b51eSKate Stone uint16_t file_idx, bool is_start_of_statement, 84c740150fSAndrew Kaylor bool is_start_of_basic_block, 85b9c1b51eSKate Stone bool is_prologue_end, bool is_epilogue_begin, 86c740150fSAndrew Kaylor bool is_terminal_entry); 87c740150fSAndrew Kaylor 88c740150fSAndrew Kaylor // Insert a sequence of entries into this line table. 89b9c1b51eSKate Stone void InsertSequence(LineSequence *sequence); 90c740150fSAndrew Kaylor 9130fdc8d8SChris Lattner /// Dump all line entries in this line table to the stream \a s. 9230fdc8d8SChris Lattner /// 93f05b42e9SAdrian Prantl /// \param[in] s 94d93c4a33SBruce Mitchener /// The stream to which to dump the object description. 9530fdc8d8SChris Lattner /// 96f05b42e9SAdrian Prantl /// \param[in] style 9730fdc8d8SChris Lattner /// The display style for the address. 9830fdc8d8SChris Lattner /// 99f05b42e9SAdrian Prantl /// \see Address::DumpStyle 100b9c1b51eSKate Stone void Dump(Stream *s, Target *target, Address::DumpStyle style, 101b9c1b51eSKate Stone Address::DumpStyle fallback_style, bool show_line_ranges); 10230fdc8d8SChris Lattner 103b9c1b51eSKate Stone void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level); 10430fdc8d8SChris Lattner 105d8f460e8SAdrian Prantl /// Find a line entry that contains the section offset address \a so_addr. 10630fdc8d8SChris Lattner /// 107f05b42e9SAdrian Prantl /// \param[in] so_addr 10830fdc8d8SChris Lattner /// A section offset address object containing the address we 10930fdc8d8SChris Lattner /// are searching for. 11030fdc8d8SChris Lattner /// 111f05b42e9SAdrian Prantl /// \param[out] line_entry 11230fdc8d8SChris Lattner /// A copy of the line entry that was found if \b true is 11330fdc8d8SChris Lattner /// returned, otherwise \a entry is left unmodified. 11430fdc8d8SChris Lattner /// 115f05b42e9SAdrian Prantl /// \param[out] index_ptr 11630fdc8d8SChris Lattner /// A pointer to a 32 bit integer that will get the actual line 117ecf34922SEugene Zelenko /// entry index if it is not nullptr. 11830fdc8d8SChris Lattner /// 119f05b42e9SAdrian Prantl /// \return 12030fdc8d8SChris Lattner /// Returns \b true if \a so_addr is contained in a line entry 12130fdc8d8SChris Lattner /// in this line table, \b false otherwise. 122b9c1b51eSKate Stone bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry, 123b9c1b51eSKate Stone uint32_t *index_ptr = nullptr); 12430fdc8d8SChris Lattner 125d8f460e8SAdrian Prantl /// Find a line entry index that has a matching file index and source line 126d8f460e8SAdrian Prantl /// number. 12730fdc8d8SChris Lattner /// 128d8f460e8SAdrian Prantl /// Finds the next line entry that has a matching \a file_idx and source 129d8f460e8SAdrian Prantl /// line number \a line starting at the \a start_idx entries into the line 130d8f460e8SAdrian Prantl /// entry collection. 13130fdc8d8SChris Lattner /// 132f05b42e9SAdrian Prantl /// \param[in] start_idx 13330fdc8d8SChris Lattner /// The number of entries to skip when starting the search. 13430fdc8d8SChris Lattner /// 135f05b42e9SAdrian Prantl /// \param[out] file_idx 13630fdc8d8SChris Lattner /// The file index to search for that should be found prior 13730fdc8d8SChris Lattner /// to calling this function using the following functions: 13830fdc8d8SChris Lattner /// CompileUnit::GetSupportFiles() 13930fdc8d8SChris Lattner /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const 14030fdc8d8SChris Lattner /// 1413e2ed744SMed Ismail Bennani /// \param[in] src_location_spec 1423e2ed744SMed Ismail Bennani /// The source location specifier to match. 14330fdc8d8SChris Lattner /// 144ad882774SJonas Devlieghere /// \param[out] line_entry_ptr 145ad882774SJonas Devlieghere /// A pointer to a line entry object that will get a copy of 14630fdc8d8SChris Lattner /// the line entry if \b true is returned, otherwise \a 14730fdc8d8SChris Lattner /// line_entry is left untouched. 14830fdc8d8SChris Lattner /// 149f05b42e9SAdrian Prantl /// \return 15030fdc8d8SChris Lattner /// Returns \b true if a matching line entry is found in this 15130fdc8d8SChris Lattner /// line table, \b false otherwise. 15230fdc8d8SChris Lattner /// 153f05b42e9SAdrian Prantl /// \see CompileUnit::GetSupportFiles() 154f05b42e9SAdrian Prantl /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const 1553e2ed744SMed Ismail Bennani uint32_t 1563e2ed744SMed Ismail Bennani FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx, 1573e2ed744SMed Ismail Bennani const SourceLocationSpec &src_location_spec, 158176761e5SGreg Clayton LineEntry *line_entry_ptr); 15930fdc8d8SChris Lattner 160b9c1b51eSKate Stone uint32_t FindLineEntryIndexByFileIndex( 16135ecfda0SMed Ismail Bennani uint32_t start_idx, const std::vector<uint32_t> &file_idx, 1623e2ed744SMed Ismail Bennani const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr); 163fd269157SGreg Clayton 164b9c1b51eSKate Stone size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append, 165176761e5SGreg Clayton SymbolContextList &sc_list); 166176761e5SGreg Clayton 16730fdc8d8SChris Lattner /// Get the line entry from the line table at index \a idx. 16830fdc8d8SChris Lattner /// 169f05b42e9SAdrian Prantl /// \param[in] idx 17030fdc8d8SChris Lattner /// An index into the line table entry collection. 17130fdc8d8SChris Lattner /// 172f05b42e9SAdrian Prantl /// \return 17330fdc8d8SChris Lattner /// A valid line entry if \a idx is a valid index, or an invalid 17430fdc8d8SChris Lattner /// line entry if \a idx is not valid. 17530fdc8d8SChris Lattner /// 176f05b42e9SAdrian Prantl /// \see LineTable::GetSize() 177f05b42e9SAdrian Prantl /// \see LineEntry::IsValid() const 178b9c1b51eSKate Stone bool GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry); 17930fdc8d8SChris Lattner 18030fdc8d8SChris Lattner /// Gets the size of the line table in number of line table entries. 18130fdc8d8SChris Lattner /// 182f05b42e9SAdrian Prantl /// \return 18330fdc8d8SChris Lattner /// The number of line table entries in this line table. 184b9c1b51eSKate Stone uint32_t GetSize() const; 18530fdc8d8SChris Lattner 186b807a287SPavel Labath typedef lldb_private::RangeVector<lldb::addr_t, lldb::addr_t, 32> 187b9c1b51eSKate Stone FileAddressRanges; 1886ab80139SGreg Clayton 1896ab80139SGreg Clayton /// Gets all contiguous file address ranges for the entire line table. 1906ab80139SGreg Clayton /// 191f05b42e9SAdrian Prantl /// \param[out] file_ranges 1926ab80139SGreg Clayton /// A collection of file address ranges that will be filled in 1936ab80139SGreg Clayton /// by this function. 1946ab80139SGreg Clayton /// 195f05b42e9SAdrian Prantl /// \param[out] append 1966ab80139SGreg Clayton /// If \b true, then append to \a file_ranges, otherwise clear 1976ab80139SGreg Clayton /// \a file_ranges prior to adding any ranges. 1986ab80139SGreg Clayton /// 199f05b42e9SAdrian Prantl /// \return 2006ab80139SGreg Clayton /// The number of address ranges added to \a file_ranges 201b9c1b51eSKate Stone size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges, 202b9c1b51eSKate Stone bool append); 2036ab80139SGreg Clayton 204b9c1b51eSKate Stone typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> 205b9c1b51eSKate Stone FileRangeMap; 2069422dd64SGreg Clayton 207b9c1b51eSKate Stone LineTable *LinkLineTable(const FileRangeMap &file_range_map); 2089422dd64SGreg Clayton 209b9c1b51eSKate Stone struct Entry { EntryEntry210b9c1b51eSKate Stone Entry() 2119494c510SJonas Devlieghere : line(0), is_start_of_statement(false), is_start_of_basic_block(false), 212b9c1b51eSKate Stone is_prologue_end(false), is_epilogue_begin(false), 2139494c510SJonas Devlieghere is_terminal_entry(false) {} 21430fdc8d8SChris Lattner EntryEntry215b9c1b51eSKate Stone Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column, 216b9c1b51eSKate Stone uint16_t _file_idx, bool _is_start_of_statement, 217b9c1b51eSKate Stone bool _is_start_of_basic_block, bool _is_prologue_end, 218b9c1b51eSKate Stone bool _is_epilogue_begin, bool _is_terminal_entry) 2194b4aa665SPavel Labath : file_addr(_file_addr), line(_line), 2204b4aa665SPavel Labath is_start_of_statement(_is_start_of_statement), 22130fdc8d8SChris Lattner is_start_of_basic_block(_is_start_of_basic_block), 22230fdc8d8SChris Lattner is_prologue_end(_is_prologue_end), 22330fdc8d8SChris Lattner is_epilogue_begin(_is_epilogue_begin), 2244b4aa665SPavel Labath is_terminal_entry(_is_terminal_entry), column(_column), 2254b4aa665SPavel Labath file_idx(_file_idx) {} 22630fdc8d8SChris Lattner 227b9c1b51eSKate Stone int bsearch_compare(const void *key, const void *arrmem); 22830fdc8d8SChris Lattner ClearEntry229b9c1b51eSKate Stone void Clear() { 2309422dd64SGreg Clayton file_addr = LLDB_INVALID_ADDRESS; 23130fdc8d8SChris Lattner line = 0; 23230fdc8d8SChris Lattner column = 0; 23330fdc8d8SChris Lattner file_idx = 0; 23430fdc8d8SChris Lattner is_start_of_statement = false; 23530fdc8d8SChris Lattner is_start_of_basic_block = false; 23630fdc8d8SChris Lattner is_prologue_end = false; 23730fdc8d8SChris Lattner is_epilogue_begin = false; 23830fdc8d8SChris Lattner is_terminal_entry = false; 23930fdc8d8SChris Lattner } 24030fdc8d8SChris Lattner CompareEntry241b9c1b51eSKate Stone static int Compare(const Entry &lhs, const Entry &rhs) { 24230fdc8d8SChris Lattner // Compare the sections before calling 243b9c1b51eSKate Stone #define SCALAR_COMPARE(a, b) \ 244b9c1b51eSKate Stone if (a < b) \ 245b9c1b51eSKate Stone return -1; \ 246b9c1b51eSKate Stone if (a > b) \ 247b9c1b51eSKate Stone return +1 2489422dd64SGreg Clayton SCALAR_COMPARE(lhs.file_addr, rhs.file_addr); 24930fdc8d8SChris Lattner SCALAR_COMPARE(lhs.line, rhs.line); 25030fdc8d8SChris Lattner SCALAR_COMPARE(lhs.column, rhs.column); 25130fdc8d8SChris Lattner SCALAR_COMPARE(lhs.is_start_of_statement, rhs.is_start_of_statement); 25230fdc8d8SChris Lattner SCALAR_COMPARE(lhs.is_start_of_basic_block, rhs.is_start_of_basic_block); 25330fdc8d8SChris Lattner // rhs and lhs reversed on purpose below. 25430fdc8d8SChris Lattner SCALAR_COMPARE(rhs.is_prologue_end, lhs.is_prologue_end); 25530fdc8d8SChris Lattner SCALAR_COMPARE(lhs.is_epilogue_begin, rhs.is_epilogue_begin); 25630fdc8d8SChris Lattner // rhs and lhs reversed on purpose below. 25730fdc8d8SChris Lattner SCALAR_COMPARE(rhs.is_terminal_entry, lhs.is_terminal_entry); 25830fdc8d8SChris Lattner SCALAR_COMPARE(lhs.file_idx, rhs.file_idx); 2593c61077aSEli Friedman #undef SCALAR_COMPARE 26030fdc8d8SChris Lattner return 0; 26130fdc8d8SChris Lattner } 26230fdc8d8SChris Lattner 263b9c1b51eSKate Stone class LessThanBinaryPredicate { 26430fdc8d8SChris Lattner public: 26530fdc8d8SChris Lattner LessThanBinaryPredicate(LineTable *line_table); 2663c61077aSEli Friedman bool operator()(const LineTable::Entry &, const LineTable::Entry &) const; 26718a96fd5SPavel Labath bool operator()(const std::unique_ptr<LineSequence> &, 26818a96fd5SPavel Labath const std::unique_ptr<LineSequence> &) const; 269ecf34922SEugene Zelenko 27030fdc8d8SChris Lattner protected: 27130fdc8d8SChris Lattner LineTable *m_line_table; 27230fdc8d8SChris Lattner }; 27330fdc8d8SChris Lattner EntryAddressLessThanEntry274b9c1b51eSKate Stone static bool EntryAddressLessThan(const Entry &lhs, const Entry &rhs) { 2759422dd64SGreg Clayton return lhs.file_addr < rhs.file_addr; 27630fdc8d8SChris Lattner } 27730fdc8d8SChris Lattner 27830fdc8d8SChris Lattner // Member variables. 2795344cd6fSAdrian Prantl /// The file address for this line entry. 2809494c510SJonas Devlieghere lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; 2815344cd6fSAdrian Prantl /// The source line number, or zero if there is no line number 2825344cd6fSAdrian Prantl /// information. 2835344cd6fSAdrian Prantl uint32_t line : 27; 2845344cd6fSAdrian Prantl /// Indicates this entry is the beginning of a statement. 2855344cd6fSAdrian Prantl uint32_t is_start_of_statement : 1; 2865344cd6fSAdrian Prantl /// Indicates this entry is the beginning of a basic block. 2875344cd6fSAdrian Prantl uint32_t is_start_of_basic_block : 1; 2885344cd6fSAdrian Prantl /// Indicates this entry is one (of possibly many) where execution 2895344cd6fSAdrian Prantl /// should be suspended for an entry breakpoint of a function. 2905344cd6fSAdrian Prantl uint32_t is_prologue_end : 1; 2915344cd6fSAdrian Prantl /// Indicates this entry is one (of possibly many) where execution 2925344cd6fSAdrian Prantl /// should be suspended for an exit breakpoint of a function. 2935344cd6fSAdrian Prantl uint32_t is_epilogue_begin : 1; 2945344cd6fSAdrian Prantl /// Indicates this entry is that of the first byte after the end 2955344cd6fSAdrian Prantl /// of a sequence of target machine instructions. 2965344cd6fSAdrian Prantl uint32_t is_terminal_entry : 1; 2975344cd6fSAdrian Prantl /// The column number of the source line, or zero if there is no 2985344cd6fSAdrian Prantl /// column information. 2999494c510SJonas Devlieghere uint16_t column = 0; 3005344cd6fSAdrian Prantl /// The file index into CompileUnit's file table, or zero if there 3015344cd6fSAdrian Prantl /// is no file information. 3029494c510SJonas Devlieghere uint16_t file_idx = 0; 30330fdc8d8SChris Lattner }; 30430fdc8d8SChris Lattner 305f00cd23cSZequan Wu protected: 306b9c1b51eSKate Stone struct EntrySearchInfo { 30730fdc8d8SChris Lattner LineTable *line_table; 30830fdc8d8SChris Lattner lldb_private::Section *a_section; 30930fdc8d8SChris Lattner Entry *a_entry; 31030fdc8d8SChris Lattner }; 31130fdc8d8SChris Lattner 31230fdc8d8SChris Lattner // Types 313b9c1b51eSKate Stone typedef std::vector<lldb_private::Section *> 314b9c1b51eSKate Stone section_collection; ///< The collection type for the sections. 315b9c1b51eSKate Stone typedef std::vector<Entry> 316b9c1b51eSKate Stone entry_collection; ///< The collection type for the line entries. 31730fdc8d8SChris Lattner // Member variables. 318b9c1b51eSKate Stone CompileUnit 319b9c1b51eSKate Stone *m_comp_unit; ///< The compile unit that this line table belongs to. 320b9c1b51eSKate Stone entry_collection 321b9c1b51eSKate Stone m_entries; ///< The collection of line entries in this line table. 32230fdc8d8SChris Lattner 323c740150fSAndrew Kaylor // Helper class 324b9c1b51eSKate Stone class LineSequenceImpl : public LineSequence { 325c740150fSAndrew Kaylor public: 326ecf34922SEugene Zelenko LineSequenceImpl() = default; 327c740150fSAndrew Kaylor 328ecf34922SEugene Zelenko ~LineSequenceImpl() override = default; 329c740150fSAndrew Kaylor 330b9c1b51eSKate Stone void Clear() override; 331c740150fSAndrew Kaylor 332b9c1b51eSKate Stone entry_collection 333b9c1b51eSKate Stone m_entries; ///< The collection of line entries in this sequence. 334c740150fSAndrew Kaylor }; 335c740150fSAndrew Kaylor 336b9c1b51eSKate Stone bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry); 33730fdc8d8SChris Lattner 33830fdc8d8SChris Lattner private: 339eaebcbc6SKonrad Kleine LineTable(const LineTable &) = delete; 340eaebcbc6SKonrad Kleine const LineTable &operator=(const LineTable &) = delete; 34135ecfda0SMed Ismail Bennani 34235ecfda0SMed Ismail Bennani template <typename T> FindLineEntryIndexByFileIndexImpl(uint32_t start_idx,T file_idx,const SourceLocationSpec & src_location_spec,LineEntry * line_entry_ptr,std::function<bool (T,uint16_t)> file_idx_matcher)34335ecfda0SMed Ismail Bennani uint32_t FindLineEntryIndexByFileIndexImpl( 34435ecfda0SMed Ismail Bennani uint32_t start_idx, T file_idx, 34535ecfda0SMed Ismail Bennani const SourceLocationSpec &src_location_spec, LineEntry *line_entry_ptr, 34635ecfda0SMed Ismail Bennani std::function<bool(T, uint16_t)> file_idx_matcher) { 34735ecfda0SMed Ismail Bennani const size_t count = m_entries.size(); 34835ecfda0SMed Ismail Bennani size_t best_match = UINT32_MAX; 34935ecfda0SMed Ismail Bennani 35035ecfda0SMed Ismail Bennani if (!line_entry_ptr) 35135ecfda0SMed Ismail Bennani return best_match; 35235ecfda0SMed Ismail Bennani 353*aa88161bSKazu Hirata const uint32_t line = src_location_spec.GetLine().value_or(0); 35435ecfda0SMed Ismail Bennani const uint16_t column = 355*aa88161bSKazu Hirata src_location_spec.GetColumn().value_or(LLDB_INVALID_COLUMN_NUMBER); 35635ecfda0SMed Ismail Bennani const bool exact_match = src_location_spec.GetExactMatch(); 35735ecfda0SMed Ismail Bennani 35835ecfda0SMed Ismail Bennani for (size_t idx = start_idx; idx < count; ++idx) { 35935ecfda0SMed Ismail Bennani // Skip line table rows that terminate the previous row (is_terminal_entry 36035ecfda0SMed Ismail Bennani // is non-zero) 36135ecfda0SMed Ismail Bennani if (m_entries[idx].is_terminal_entry) 36235ecfda0SMed Ismail Bennani continue; 36335ecfda0SMed Ismail Bennani 36435ecfda0SMed Ismail Bennani if (!file_idx_matcher(file_idx, m_entries[idx].file_idx)) 36535ecfda0SMed Ismail Bennani continue; 36635ecfda0SMed Ismail Bennani 36735ecfda0SMed Ismail Bennani // Exact match always wins. Otherwise try to find the closest line > the 36835ecfda0SMed Ismail Bennani // desired line. 36935ecfda0SMed Ismail Bennani // FIXME: Maybe want to find the line closest before and the line closest 37035ecfda0SMed Ismail Bennani // after and if they're not in the same function, don't return a match. 37135ecfda0SMed Ismail Bennani 37235ecfda0SMed Ismail Bennani if (column == LLDB_INVALID_COLUMN_NUMBER) { 37335ecfda0SMed Ismail Bennani if (m_entries[idx].line < line) { 37435ecfda0SMed Ismail Bennani continue; 37535ecfda0SMed Ismail Bennani } else if (m_entries[idx].line == line) { 37635ecfda0SMed Ismail Bennani ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); 37735ecfda0SMed Ismail Bennani return idx; 37835ecfda0SMed Ismail Bennani } else if (!exact_match) { 37935ecfda0SMed Ismail Bennani if (best_match == UINT32_MAX || 38035ecfda0SMed Ismail Bennani m_entries[idx].line < m_entries[best_match].line) 38135ecfda0SMed Ismail Bennani best_match = idx; 38235ecfda0SMed Ismail Bennani } 38335ecfda0SMed Ismail Bennani } else { 38435ecfda0SMed Ismail Bennani if (m_entries[idx].line < line) { 38535ecfda0SMed Ismail Bennani continue; 38635ecfda0SMed Ismail Bennani } else if (m_entries[idx].line == line && 38735ecfda0SMed Ismail Bennani m_entries[idx].column == column) { 38835ecfda0SMed Ismail Bennani ConvertEntryAtIndexToLineEntry(idx, *line_entry_ptr); 38935ecfda0SMed Ismail Bennani return idx; 39035ecfda0SMed Ismail Bennani } else if (!exact_match) { 39135ecfda0SMed Ismail Bennani if (best_match == UINT32_MAX) 39235ecfda0SMed Ismail Bennani best_match = idx; 39335ecfda0SMed Ismail Bennani else if (m_entries[idx].line < m_entries[best_match].line) 39435ecfda0SMed Ismail Bennani best_match = idx; 39535ecfda0SMed Ismail Bennani else if (m_entries[idx].line == m_entries[best_match].line) 39635ecfda0SMed Ismail Bennani if (m_entries[idx].column && 39735ecfda0SMed Ismail Bennani m_entries[idx].column < m_entries[best_match].column) 39835ecfda0SMed Ismail Bennani best_match = idx; 39935ecfda0SMed Ismail Bennani } 40035ecfda0SMed Ismail Bennani } 40135ecfda0SMed Ismail Bennani } 40235ecfda0SMed Ismail Bennani 40335ecfda0SMed Ismail Bennani if (best_match != UINT32_MAX) { 40435ecfda0SMed Ismail Bennani if (line_entry_ptr) 40535ecfda0SMed Ismail Bennani ConvertEntryAtIndexToLineEntry(best_match, *line_entry_ptr); 40635ecfda0SMed Ismail Bennani return best_match; 40735ecfda0SMed Ismail Bennani } 40835ecfda0SMed Ismail Bennani return UINT32_MAX; 40935ecfda0SMed Ismail Bennani } 41030fdc8d8SChris Lattner }; 41130fdc8d8SChris Lattner 41230fdc8d8SChris Lattner } // namespace lldb_private 41330fdc8d8SChris Lattner 414cdc514e4SJonas Devlieghere #endif // LLDB_SYMBOL_LINETABLE_H 415