Home | History | Annotate | Download | only in Symbol
      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 #include "lldb/Target/Target.h"
     14 
     15 using namespace lldb_private;
     16 
     17 LineEntry::LineEntry() :
     18     range(),
     19     file(),
     20     line(0),
     21     column(0),
     22     is_start_of_statement(0),
     23     is_start_of_basic_block(0),
     24     is_prologue_end(0),
     25     is_epilogue_begin(0),
     26     is_terminal_entry(0)
     27 {
     28 }
     29 
     30 LineEntry::LineEntry
     31 (
     32     const lldb::SectionSP &section_sp,
     33     lldb::addr_t section_offset,
     34     lldb::addr_t byte_size,
     35     const FileSpec &_file,
     36     uint32_t _line,
     37     uint16_t _column,
     38     bool _is_start_of_statement,
     39     bool _is_start_of_basic_block,
     40     bool _is_prologue_end,
     41     bool _is_epilogue_begin,
     42     bool _is_terminal_entry
     43 ) :
     44     range(section_sp, section_offset, byte_size),
     45     file(_file),
     46     line(_line),
     47     column(_column),
     48     is_start_of_statement(_is_start_of_statement),
     49     is_start_of_basic_block(_is_start_of_basic_block),
     50     is_prologue_end(_is_prologue_end),
     51     is_epilogue_begin(_is_epilogue_begin),
     52     is_terminal_entry(_is_terminal_entry)
     53 {
     54 }
     55 
     56 void
     57 LineEntry::Clear()
     58 {
     59     range.Clear();
     60     file.Clear();
     61     line = 0;
     62     column = 0;
     63     is_start_of_statement = 0;
     64     is_start_of_basic_block = 0;
     65     is_prologue_end = 0;
     66     is_epilogue_begin = 0;
     67     is_terminal_entry = 0;
     68 }
     69 
     70 
     71 bool
     72 LineEntry::IsValid() const
     73 {
     74     return range.GetBaseAddress().IsValid() && line != 0;
     75 }
     76 
     77 bool
     78 LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const
     79 {
     80     bool result = false;
     81     if (file)
     82     {
     83         if (show_fullpaths)
     84             file.Dump (s);
     85         else
     86             file.GetFilename().Dump (s);
     87 
     88         if (line)
     89             s->PutChar(':');
     90         result = true;
     91     }
     92     if (line)
     93         s->Printf ("%u", line);
     94     else
     95         result = false;
     96 
     97     return result;
     98 }
     99 
    100 bool
    101 LineEntry::Dump
    102 (
    103     Stream *s,
    104     Target *target,
    105     bool show_file,
    106     Address::DumpStyle style,
    107     Address::DumpStyle fallback_style,
    108     bool show_range
    109 ) const
    110 {
    111     if (show_range)
    112     {
    113         // Show address range
    114         if (!range.Dump(s, target, style, fallback_style))
    115             return false;
    116     }
    117     else
    118     {
    119         // Show address only
    120         if (!range.GetBaseAddress().Dump(s,
    121                                          target,
    122                                          style,
    123                                          fallback_style))
    124             return false;
    125     }
    126     if (show_file)
    127         *s << ", file = " << file;
    128     if (line)
    129         s->Printf(", line = %u", line);
    130     if (column)
    131         s->Printf(", column = %u", column);
    132     if (is_start_of_statement)
    133         *s << ", is_start_of_statement = TRUE";
    134 
    135     if (is_start_of_basic_block)
    136         *s << ", is_start_of_basic_block = TRUE";
    137 
    138     if (is_prologue_end)
    139         *s << ", is_prologue_end = TRUE";
    140 
    141     if (is_epilogue_begin)
    142         *s << ", is_epilogue_begin = TRUE";
    143 
    144     if (is_terminal_entry)
    145         *s << ", is_terminal_entry = TRUE";
    146     return true;
    147 }
    148 
    149 bool
    150 LineEntry::GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Target *target, bool show_address_only) const
    151 {
    152 
    153     if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull)
    154     {
    155         if (show_address_only)
    156         {
    157             range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
    158         }
    159         else
    160         {
    161             range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
    162         }
    163 
    164         *s << ": " << file;
    165 
    166         if (line)
    167         {
    168             s->Printf(":%u", line);
    169             if (column)
    170                 s->Printf(":%u", column);
    171         }
    172 
    173 
    174         if (level == lldb::eDescriptionLevelFull)
    175         {
    176             if (is_start_of_statement)
    177                 *s << ", is_start_of_statement = TRUE";
    178 
    179             if (is_start_of_basic_block)
    180                 *s << ", is_start_of_basic_block = TRUE";
    181 
    182             if (is_prologue_end)
    183                 *s << ", is_prologue_end = TRUE";
    184 
    185             if (is_epilogue_begin)
    186                 *s << ", is_epilogue_begin = TRUE";
    187 
    188             if (is_terminal_entry)
    189                 *s << ", is_terminal_entry = TRUE";
    190         }
    191         else
    192         {
    193             if (is_terminal_entry)
    194                 s->EOL();
    195         }
    196     }
    197     else
    198     {
    199         return Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
    200     }
    201     return true;
    202 }
    203 
    204 
    205 bool
    206 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
    207 {
    208     return LineEntry::Compare (a, b) < 0;
    209 }
    210 
    211 int
    212 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
    213 {
    214     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
    215     if (result != 0)
    216         return result;
    217 
    218     const lldb::addr_t a_byte_size = a.range.GetByteSize();
    219     const lldb::addr_t b_byte_size = b.range.GetByteSize();
    220 
    221     if (a_byte_size < b_byte_size)
    222         return -1;
    223     if (a_byte_size > b_byte_size)
    224         return +1;
    225 
    226     // Check for an end sequence entry mismatch after we have determined
    227     // that the address values are equal. If one of the items is an end
    228     // sequence, we don't care about the line, file, or column info.
    229     if (a.is_terminal_entry > b.is_terminal_entry)
    230         return -1;
    231     if (a.is_terminal_entry < b.is_terminal_entry)
    232         return +1;
    233 
    234     if (a.line < b.line)
    235         return -1;
    236     if (a.line > b.line)
    237         return +1;
    238 
    239     if (a.column < b.column)
    240         return -1;
    241     if (a.column > b.column)
    242         return +1;
    243 
    244     return FileSpec::Compare (a.file, b.file, true);
    245 }
    246 
    247