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