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