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         if (show_address_only)
155         {
156             range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
157         }
158         else
159         {
160             range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
161         }
162 
163         *s << ": " << file;
164 
165         if (line)
166         {
167             s->Printf(":%u", line);
168             if (column)
169                 s->Printf(":%u", column);
170         }
171 
172 
173         if (level == lldb::eDescriptionLevelFull)
174         {
175             if (is_start_of_statement)
176                 *s << ", is_start_of_statement = TRUE";
177 
178             if (is_start_of_basic_block)
179                 *s << ", is_start_of_basic_block = TRUE";
180 
181             if (is_prologue_end)
182                 *s << ", is_prologue_end = TRUE";
183 
184             if (is_epilogue_begin)
185                 *s << ", is_epilogue_begin = TRUE";
186 
187             if (is_terminal_entry)
188                 *s << ", is_terminal_entry = TRUE";
189         }
190         else
191         {
192             if (is_terminal_entry)
193                 s->EOL();
194         }
195     }
196     else
197     {
198         return Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
199     }
200     return true;
201 }
202 
203 
204 bool
205 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
206 {
207     return LineEntry::Compare (a, b) < 0;
208 }
209 
210 int
211 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
212 {
213     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
214     if (result != 0)
215         return result;
216 
217     const lldb::addr_t a_byte_size = a.range.GetByteSize();
218     const lldb::addr_t b_byte_size = b.range.GetByteSize();
219 
220     if (a_byte_size < b_byte_size)
221         return -1;
222     if (a_byte_size > b_byte_size)
223         return +1;
224 
225     // Check for an end sequence entry mismatch after we have determined
226     // that the address values are equal. If one of the items is an end
227     // sequence, we don't care about the line, file, or column info.
228     if (a.is_terminal_entry > b.is_terminal_entry)
229         return -1;
230     if (a.is_terminal_entry < b.is_terminal_entry)
231         return +1;
232 
233     if (a.line < b.line)
234         return -1;
235     if (a.line > b.line)
236         return +1;
237 
238     if (a.column < b.column)
239         return -1;
240     if (a.column > b.column)
241         return +1;
242 
243     return FileSpec::Compare (a.file, b.file, true);
244 }
245 
246