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_terminal_entry(0),
24     is_prologue_end(0),
25     is_epilogue_begin(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) const
78 {
79     bool result = false;
80     if (file)
81     {
82         file.Dump (s);
83         if (line)
84             s->PutChar(':');
85         result = true;
86     }
87     if (line)
88         s->Printf ("%u", line);
89     else
90         result = false;
91 
92     return result;
93 }
94 
95 bool
96 LineEntry::Dump
97 (
98     Stream *s,
99     Process *process,
100     bool show_file,
101     Address::DumpStyle style,
102     Address::DumpStyle fallback_style,
103     bool show_range
104 ) const
105 {
106     if (show_range)
107     {
108         // Show address range
109         if (!range.Dump(s, process, style, fallback_style))
110             return false;
111     }
112     else
113     {
114         // Show address only
115         if (!range.GetBaseAddress().Dump(s,
116                                          process,
117                                          style,
118                                          fallback_style))
119             return false;
120     }
121     if (show_file)
122         *s << ", file = " << file;
123     if (line)
124         s->Printf(", line = %u", line);
125     if (column)
126         s->Printf(", column = %u", column);
127     if (is_start_of_statement)
128         *s << ", is_start_of_statement = TRUE";
129 
130     if (is_start_of_basic_block)
131         *s << ", is_start_of_basic_block = TRUE";
132 
133     if (is_prologue_end)
134         *s << ", is_prologue_end = TRUE";
135 
136     if (is_epilogue_begin)
137         *s << ", is_epilogue_begin = TRUE";
138 
139     if (is_terminal_entry)
140         *s << ", is_terminal_entry = TRUE";
141     return true;
142 }
143 
144 bool
145 LineEntry::GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Process *process, bool show_address_only) const
146 {
147 
148     if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull)
149     {
150         // Show address only
151         if (show_address_only)
152         {
153             s->PutCString ("address = ");
154             range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
155         }
156         else
157         {
158             s->PutCString ("range = ");
159             range.Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
160         }
161 
162         if (file)
163             *s << ' ' << file;
164 
165         if (line)
166         {
167             s->Printf(":%u", line);
168             if (column)
169                 s->Printf(":%u", column);
170         }
171 
172         if (level == lldb::eDescriptionLevelFull)
173         {
174             if (is_start_of_statement)
175                 *s << ", is_start_of_statement = TRUE";
176 
177             if (is_start_of_basic_block)
178                 *s << ", is_start_of_basic_block = TRUE";
179 
180             if (is_prologue_end)
181                 *s << ", is_prologue_end = TRUE";
182 
183             if (is_epilogue_begin)
184                 *s << ", is_epilogue_begin = TRUE";
185 
186             if (is_terminal_entry)
187                 *s << ", is_terminal_entry = TRUE";
188         }
189         else
190         {
191             if (is_terminal_entry)
192                 s->EOL();
193         }
194     }
195     else
196     {
197         return Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
198     }
199     return true;
200 }
201 
202 
203 bool
204 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
205 {
206     return LineEntry::Compare (a, b) < 0;
207 }
208 
209 int
210 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
211 {
212     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
213     if (result != 0)
214         return result;
215 
216     const lldb::addr_t a_byte_size = a.range.GetByteSize();
217     const lldb::addr_t b_byte_size = b.range.GetByteSize();
218 
219     if (a_byte_size < b_byte_size)
220         return -1;
221     if (a_byte_size > b_byte_size)
222         return +1;
223 
224     // Check for an end sequence entry mismatch after we have determined
225     // that the address values are equal. If one of the items is an end
226     // sequence, we don't care about the line, file, or column info.
227     if (a.is_terminal_entry > b.is_terminal_entry)
228         return -1;
229     if (a.is_terminal_entry < b.is_terminal_entry)
230         return +1;
231 
232     if (a.line < b.line)
233         return -1;
234     if (a.line > b.line)
235         return +1;
236 
237     if (a.column < b.column)
238         return -1;
239     if (a.column > b.column)
240         return +1;
241 
242     return FileSpec::Compare (a.file, b.file, true);
243 }
244 
245