LineEntry.cpp revision c67b7d13cffeb2c9454635e8a11d65350bce61ad
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        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
204bool
205lldb_private::operator< (const LineEntry& a, const LineEntry& b)
206{
207    return LineEntry::Compare (a, b) < 0;
208}
209
210int
211LineEntry::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