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 
14 using namespace lldb_private;
15 
16 LineEntry::LineEntry() :
17     range(),
18     file(),
19     line(0),
20     column(0),
21     is_start_of_statement(0),
22     is_start_of_basic_block(0),
23     is_prologue_end(0),
24     is_epilogue_begin(0),
25     is_terminal_entry(0)
26 {
27 }
28 
29 LineEntry::LineEntry
30 (
31     lldb_private::Section *section,
32     lldb::addr_t section_offset,
33     lldb::addr_t byte_size,
34     const FileSpec &_file,
35     uint32_t _line,
36     uint16_t _column,
37     bool _is_start_of_statement,
38     bool _is_start_of_basic_block,
39     bool _is_prologue_end,
40     bool _is_epilogue_begin,
41     bool _is_terminal_entry
42 ) :
43     range(section, section_offset, byte_size),
44     file(_file),
45     line(_line),
46     column(_column),
47     is_start_of_statement(_is_start_of_statement),
48     is_start_of_basic_block(_is_start_of_basic_block),
49     is_prologue_end(_is_prologue_end),
50     is_epilogue_begin(_is_epilogue_begin),
51     is_terminal_entry(_is_terminal_entry)
52 {
53 }
54 
55 void
56 LineEntry::Clear()
57 {
58     range.Clear();
59     file.Clear();
60     line = 0;
61     column = 0;
62     is_start_of_statement = 0;
63     is_start_of_basic_block = 0;
64     is_prologue_end = 0;
65     is_epilogue_begin = 0;
66     is_terminal_entry = 0;
67 }
68 
69 
70 bool
71 LineEntry::IsValid() const
72 {
73     return range.GetBaseAddress().IsValid() && line != 0;
74 }
75 
76 bool
77 LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const
78 {
79     bool result = false;
80     if (file)
81     {
82         if (show_fullpaths)
83             file.Dump (s);
84         else
85             file.GetFilename().Dump (s);
86 
87         if (line)
88             s->PutChar(':');
89         result = true;
90     }
91     if (line)
92         s->Printf ("%u", line);
93     else
94         result = false;
95 
96     return result;
97 }
98 
99 bool
100 LineEntry::Dump
101 (
102     Stream *s,
103     Process *process,
104     bool show_file,
105     Address::DumpStyle style,
106     Address::DumpStyle fallback_style,
107     bool show_range
108 ) const
109 {
110     if (show_range)
111     {
112         // Show address range
113         if (!range.Dump(s, process, style, fallback_style))
114             return false;
115     }
116     else
117     {
118         // Show address only
119         if (!range.GetBaseAddress().Dump(s,
120                                          process,
121                                          style,
122                                          fallback_style))
123             return false;
124     }
125     if (show_file)
126         *s << ", file = " << file;
127     if (line)
128         s->Printf(", line = %u", line);
129     if (column)
130         s->Printf(", column = %u", column);
131     if (is_start_of_statement)
132         *s << ", is_start_of_statement = TRUE";
133 
134     if (is_start_of_basic_block)
135         *s << ", is_start_of_basic_block = TRUE";
136 
137     if (is_prologue_end)
138         *s << ", is_prologue_end = TRUE";
139 
140     if (is_epilogue_begin)
141         *s << ", is_epilogue_begin = TRUE";
142 
143     if (is_terminal_entry)
144         *s << ", is_terminal_entry = TRUE";
145     return true;
146 }
147 
148 bool
149 LineEntry::GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Process *process, bool show_address_only) const
150 {
151 
152     if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull)
153     {
154         // Show address only
155         if (show_address_only)
156         {
157             s->PutCString ("address = ");
158             range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
159         }
160         else
161         {
162             s->PutCString ("range = ");
163             range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
164         }
165 
166         if (file)
167             *s << ' ' << file;
168 
169         if (line)
170         {
171             s->Printf(":%u", line);
172             if (column)
173                 s->Printf(":%u", column);
174         }
175 
176         if (level == lldb::eDescriptionLevelFull)
177         {
178             if (is_start_of_statement)
179                 *s << ", is_start_of_statement = TRUE";
180 
181             if (is_start_of_basic_block)
182                 *s << ", is_start_of_basic_block = TRUE";
183 
184             if (is_prologue_end)
185                 *s << ", is_prologue_end = TRUE";
186 
187             if (is_epilogue_begin)
188                 *s << ", is_epilogue_begin = TRUE";
189 
190             if (is_terminal_entry)
191                 *s << ", is_terminal_entry = TRUE";
192         }
193         else
194         {
195             if (is_terminal_entry)
196                 s->EOL();
197         }
198     }
199     else
200     {
201         return Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
202     }
203     return true;
204 }
205 
206 
207 bool
208 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
209 {
210     return LineEntry::Compare (a, b) < 0;
211 }
212 
213 int
214 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
215 {
216     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
217     if (result != 0)
218         return result;
219 
220     const lldb::addr_t a_byte_size = a.range.GetByteSize();
221     const lldb::addr_t b_byte_size = b.range.GetByteSize();
222 
223     if (a_byte_size < b_byte_size)
224         return -1;
225     if (a_byte_size > b_byte_size)
226         return +1;
227 
228     // Check for an end sequence entry mismatch after we have determined
229     // that the address values are equal. If one of the items is an end
230     // sequence, we don't care about the line, file, or column info.
231     if (a.is_terminal_entry > b.is_terminal_entry)
232         return -1;
233     if (a.is_terminal_entry < b.is_terminal_entry)
234         return +1;
235 
236     if (a.line < b.line)
237         return -1;
238     if (a.line > b.line)
239         return +1;
240 
241     if (a.column < b.column)
242         return -1;
243     if (a.column > b.column)
244         return +1;
245 
246     return FileSpec::Compare (a.file, b.file, true);
247 }
248 
249