]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/LineEntry.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / LineEntry.cpp
1 //===-- LineEntry.cpp -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Symbol/LineEntry.h"
11 #include "lldb/Symbol/CompileUnit.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14
15 using namespace lldb_private;
16
17 LineEntry::LineEntry()
18     : range(), file(), line(LLDB_INVALID_LINE_NUMBER), column(0),
19       is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0),
20       is_epilogue_begin(0), is_terminal_entry(0) {}
21
22 LineEntry::LineEntry(const lldb::SectionSP &section_sp,
23                      lldb::addr_t section_offset, lldb::addr_t byte_size,
24                      const FileSpec &_file, uint32_t _line, uint16_t _column,
25                      bool _is_start_of_statement, bool _is_start_of_basic_block,
26                      bool _is_prologue_end, bool _is_epilogue_begin,
27                      bool _is_terminal_entry)
28     : range(section_sp, section_offset, byte_size), file(_file),
29       original_file(_file), line(_line), column(_column),
30       is_start_of_statement(_is_start_of_statement),
31       is_start_of_basic_block(_is_start_of_basic_block),
32       is_prologue_end(_is_prologue_end), is_epilogue_begin(_is_epilogue_begin),
33       is_terminal_entry(_is_terminal_entry) {}
34
35 void LineEntry::Clear() {
36   range.Clear();
37   file.Clear();
38   original_file.Clear();
39   line = LLDB_INVALID_LINE_NUMBER;
40   column = 0;
41   is_start_of_statement = 0;
42   is_start_of_basic_block = 0;
43   is_prologue_end = 0;
44   is_epilogue_begin = 0;
45   is_terminal_entry = 0;
46 }
47
48 bool LineEntry::IsValid() const {
49   return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;
50 }
51
52 bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {
53   if (file) {
54     if (show_fullpaths)
55       file.Dump(s);
56     else
57       file.GetFilename().Dump(s);
58
59     if (line)
60       s->PutChar(':');
61   }
62   if (line) {
63     s->Printf("%u", line);
64     if (column) {
65       s->PutChar(':');
66       s->Printf("%u", column);
67     }
68   }
69   return file || line;
70 }
71
72 bool LineEntry::Dump(Stream *s, Target *target, bool show_file,
73                      Address::DumpStyle style,
74                      Address::DumpStyle fallback_style, bool show_range) const {
75   if (show_range) {
76     // Show address range
77     if (!range.Dump(s, target, style, fallback_style))
78       return false;
79   } else {
80     // Show address only
81     if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))
82       return false;
83   }
84   if (show_file)
85     *s << ", file = " << file;
86   if (line)
87     s->Printf(", line = %u", line);
88   if (column)
89     s->Printf(", column = %u", column);
90   if (is_start_of_statement)
91     *s << ", is_start_of_statement = TRUE";
92
93   if (is_start_of_basic_block)
94     *s << ", is_start_of_basic_block = TRUE";
95
96   if (is_prologue_end)
97     *s << ", is_prologue_end = TRUE";
98
99   if (is_epilogue_begin)
100     *s << ", is_epilogue_begin = TRUE";
101
102   if (is_terminal_entry)
103     *s << ", is_terminal_entry = TRUE";
104   return true;
105 }
106
107 bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,
108                                CompileUnit *cu, Target *target,
109                                bool show_address_only) const {
110
111   if (level == lldb::eDescriptionLevelBrief ||
112       level == lldb::eDescriptionLevelFull) {
113     if (show_address_only) {
114       range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,
115                                   Address::DumpStyleFileAddress);
116     } else {
117       range.Dump(s, target, Address::DumpStyleLoadAddress,
118                  Address::DumpStyleFileAddress);
119     }
120
121     *s << ": " << file;
122
123     if (line) {
124       s->Printf(":%u", line);
125       if (column)
126         s->Printf(":%u", column);
127     }
128
129     if (level == lldb::eDescriptionLevelFull) {
130       if (is_start_of_statement)
131         *s << ", is_start_of_statement = TRUE";
132
133       if (is_start_of_basic_block)
134         *s << ", is_start_of_basic_block = TRUE";
135
136       if (is_prologue_end)
137         *s << ", is_prologue_end = TRUE";
138
139       if (is_epilogue_begin)
140         *s << ", is_epilogue_begin = TRUE";
141
142       if (is_terminal_entry)
143         *s << ", is_terminal_entry = TRUE";
144     } else {
145       if (is_terminal_entry)
146         s->EOL();
147     }
148   } else {
149     return Dump(s, target, true, Address::DumpStyleLoadAddress,
150                 Address::DumpStyleModuleWithFileAddress, true);
151   }
152   return true;
153 }
154
155 bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {
156   return LineEntry::Compare(a, b) < 0;
157 }
158
159 int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
160   int result = Address::CompareFileAddress(a.range.GetBaseAddress(),
161                                            b.range.GetBaseAddress());
162   if (result != 0)
163     return result;
164
165   const lldb::addr_t a_byte_size = a.range.GetByteSize();
166   const lldb::addr_t b_byte_size = b.range.GetByteSize();
167
168   if (a_byte_size < b_byte_size)
169     return -1;
170   if (a_byte_size > b_byte_size)
171     return +1;
172
173   // Check for an end sequence entry mismatch after we have determined that the
174   // address values are equal. If one of the items is an end sequence, we don't
175   // care about the line, file, or column info.
176   if (a.is_terminal_entry > b.is_terminal_entry)
177     return -1;
178   if (a.is_terminal_entry < b.is_terminal_entry)
179     return +1;
180
181   if (a.line < b.line)
182     return -1;
183   if (a.line > b.line)
184     return +1;
185
186   if (a.column < b.column)
187     return -1;
188   if (a.column > b.column)
189     return +1;
190
191   return FileSpec::Compare(a.file, b.file, true);
192 }
193
194 AddressRange LineEntry::GetSameLineContiguousAddressRange() const {
195   // Add each LineEntry's range to complete_line_range until we find a
196   // different file / line number.
197   AddressRange complete_line_range = range;
198
199   while (true) {
200     SymbolContext next_line_sc;
201     Address range_end(complete_line_range.GetBaseAddress());
202     range_end.Slide(complete_line_range.GetByteSize());
203     range_end.CalculateSymbolContext(&next_line_sc,
204                                      lldb::eSymbolContextLineEntry);
205
206     if (next_line_sc.line_entry.IsValid() &&
207         next_line_sc.line_entry.range.GetByteSize() > 0 &&
208         original_file == next_line_sc.line_entry.original_file) {
209       // Include any line 0 entries - they indicate that this is compiler-
210       // generated code that does not correspond to user source code.
211       if (next_line_sc.line_entry.line == 0) {
212         complete_line_range.SetByteSize(
213             complete_line_range.GetByteSize() +
214             next_line_sc.line_entry.range.GetByteSize());
215         continue;
216       }
217
218       if (line == next_line_sc.line_entry.line) {
219         // next_line_sc is the same file & line as this LineEntry, so extend
220         // our AddressRange by its size and continue to see if there are more
221         // LineEntries that we can combine.
222         complete_line_range.SetByteSize(
223             complete_line_range.GetByteSize() +
224             next_line_sc.line_entry.range.GetByteSize());
225         continue;
226       }
227     }
228     break;
229   }
230   return complete_line_range;
231 }
232
233 void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {
234   if (target_sp) {
235     // Apply any file remappings to our file
236     FileSpec new_file_spec;
237     if (target_sp->GetSourcePathMap().FindFile(original_file, new_file_spec))
238       file = new_file_spec;
239   }
240 }