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 (line)
122         s->Printf(", line = %u", line);
123     if (column)
124         s->Printf(", column = %u", column);
125     if (show_file)
126     {
127         *s << ", file = " << file;
128     }
129     if (is_start_of_statement)
130         *s << ", is_start_of_statement = TRUE";
131 
132     if (is_start_of_basic_block)
133         *s << ", is_start_of_basic_block = TRUE";
134 
135     if (is_prologue_end)
136         *s << ", is_prologue_end = TRUE";
137 
138     if (is_epilogue_begin)
139         *s << ", is_epilogue_begin = TRUE";
140 
141     if (is_terminal_entry)
142         *s << ", is_terminal_entry = TRUE";
143     return true;
144 }
145 
146 bool
147 LineEntry::GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Process *process) const
148 {
149 
150     if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull)
151     {
152         // Show address only
153         range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
154 
155         if (file)
156             *s << ' ' << file;
157 
158         if (line)
159         {
160             s->Printf(":%u", line);
161             if (column)
162                 s->Printf(":%u", column);
163         }
164 
165         if (level == lldb::eDescriptionLevelFull)
166         {
167             if (is_start_of_statement)
168                 *s << ", is_start_of_statement = TRUE";
169 
170             if (is_start_of_basic_block)
171                 *s << ", is_start_of_basic_block = TRUE";
172 
173             if (is_prologue_end)
174                 *s << ", is_prologue_end = TRUE";
175 
176             if (is_epilogue_begin)
177                 *s << ", is_epilogue_begin = TRUE";
178 
179             if (is_terminal_entry)
180                 *s << ", is_terminal_entry = TRUE";
181         }
182         else
183         {
184             if (is_terminal_entry)
185                 s->EOL();
186         }
187     }
188     else
189     {
190         return Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
191     }
192     return true;
193 }
194 
195 
196 bool
197 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
198 {
199     return LineEntry::Compare (a, b) < 0;
200 }
201 
202 int
203 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
204 {
205     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
206     if (result != 0)
207         return result;
208 
209     const lldb::addr_t a_byte_size = a.range.GetByteSize();
210     const lldb::addr_t b_byte_size = b.range.GetByteSize();
211 
212     if (a_byte_size < b_byte_size)
213         return -1;
214     if (a_byte_size > b_byte_size)
215         return +1;
216 
217     // Check for an end sequence entry mismatch after we have determined
218     // that the address values are equal. If one of the items is an end
219     // sequence, we don't care about the line, file, or column info.
220     if (a.is_terminal_entry > b.is_terminal_entry)
221         return -1;
222     if (a.is_terminal_entry < b.is_terminal_entry)
223         return +1;
224 
225     if (a.line < b.line)
226         return -1;
227     if (a.line > b.line)
228         return +1;
229 
230     if (a.column < b.column)
231         return -1;
232     if (a.column > b.column)
233         return +1;
234 
235     return FileSpec::Compare (a.file, b.file, true);
236 }
237 
238