LineEntry.cpp revision 72b7158235500ae6d4b69ed378cbc36bf6e5cbe1
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
14using namespace lldb_private;
15
16LineEntry::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
29LineEntry::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
55void
56LineEntry::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
70bool
71LineEntry::IsValid() const
72{
73    return range.GetBaseAddress().IsValid() && line != 0;
74}
75
76bool
77LineEntry::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
99bool
100LineEntry::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
148bool
149LineEntry::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
207bool
208lldb_private::operator< (const LineEntry& a, const LineEntry& b)
209{
210    return LineEntry::Compare (a, b) < 0;
211}
212
213int
214LineEntry::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