LCOV - code coverage report
Current view: top level - lib/DebugInfo/Symbolize - DIPrinter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 45 54 83.3 %
Date: 2017-09-14 15:23:50 Functions: 3 5 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
       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             : // This file defines the DIPrinter class, which is responsible for printing
      11             : // structures defined in DebugInfo/DIContext.h
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "llvm/DebugInfo/Symbolize/DIPrinter.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/DebugInfo/DIContext.h"
      18             : #include "llvm/Support/ErrorOr.h"
      19             : #include "llvm/Support/Format.h"
      20             : #include "llvm/Support/LineIterator.h"
      21             : #include "llvm/Support/MemoryBuffer.h"
      22             : #include "llvm/Support/raw_ostream.h"
      23             : #include <algorithm>
      24             : #include <cmath>
      25             : #include <cstddef>
      26             : #include <cstdint>
      27             : #include <memory>
      28             : #include <string>
      29             : 
      30             : namespace llvm {
      31             : namespace symbolize {
      32             : 
      33             : // By default, DILineInfo contains "<invalid>" for function/filename it
      34             : // cannot fetch. We replace it to "??" to make our output closer to addr2line.
      35             : static const char kDILineInfoBadString[] = "<invalid>";
      36             : static const char kBadString[] = "??";
      37             : 
      38             : // Prints source code around in the FileName the Line.
      39         517 : void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
      40         517 :   if (PrintSourceContext <= 0)
      41         516 :     return;
      42             : 
      43             :   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
      44           2 :       MemoryBuffer::getFile(FileName);
      45           1 :   if (!BufOrErr)
      46             :     return;
      47             : 
      48           3 :   std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
      49             :   int64_t FirstLine =
      50           2 :       std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
      51           1 :   int64_t LastLine = FirstLine + PrintSourceContext;
      52           1 :   size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
      53             : 
      54           1 :   for (line_iterator I = line_iterator(*Buf, false);
      55          14 :        !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
      56           6 :     int64_t L = I.line_number();
      57           6 :     if (L >= FirstLine && L <= LastLine) {
      58          12 :       OS << format_decimal(L, MaxLineNumberWidth);
      59           6 :       if (L == Line)
      60           1 :         OS << " >: ";
      61             :       else
      62           5 :         OS << "  : ";
      63           6 :       OS << *I << "\n";
      64             :     }
      65             :   }
      66             : }
      67             : 
      68         529 : void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
      69         529 :   if (PrintFunctionNames) {
      70        1587 :     std::string FunctionName = Info.FunctionName;
      71         529 :     if (FunctionName == kDILineInfoBadString)
      72             :       FunctionName = kBadString;
      73             : 
      74        1058 :     StringRef Delimiter = PrintPretty ? " at " : "\n";
      75        1058 :     StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
      76        1058 :     OS << Prefix << FunctionName << Delimiter;
      77             :   }
      78        1070 :   std::string Filename = Info.FileName;
      79         529 :   if (Filename == kDILineInfoBadString)
      80             :     Filename = kBadString;
      81         529 :   if (!Verbose) {
      82        2068 :     OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
      83         517 :     printContext(Filename, Info.Line);
      84         517 :     return;
      85             :   }
      86          24 :   OS << "  Filename: " << Filename << "\n";
      87          12 :   if (Info.StartLine)
      88          24 :     OS << "Function start line: " << Info.StartLine << "\n";
      89          24 :   OS << "  Line: " << Info.Line << "\n";
      90          24 :   OS << "  Column: " << Info.Column << "\n";
      91          12 :   if (Info.Discriminator)
      92          14 :     OS << "  Discriminator: " << Info.Discriminator << "\n";
      93             : }
      94             : 
      95           0 : DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
      96           0 :   print(Info, false);
      97           0 :   return *this;
      98             : }
      99             : 
     100         390 : DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
     101         390 :   uint32_t FramesNum = Info.getNumberOfFrames();
     102         390 :   if (FramesNum == 0) {
     103           2 :     print(DILineInfo(), false);
     104           2 :     return *this;
     105             :   }
     106        1442 :   for (uint32_t i = 0; i < FramesNum; i++)
     107        1054 :     print(Info.getFrame(i), i > 0);
     108             :   return *this;
     109             : }
     110             : 
     111           0 : DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
     112           0 :   std::string Name = Global.Name;
     113           0 :   if (Name == kDILineInfoBadString)
     114             :     Name = kBadString;
     115           0 :   OS << Name << "\n";
     116           0 :   OS << Global.Start << " " << Global.Size << "\n";
     117           0 :   return *this;
     118             : }
     119             : 
     120             : } // end namespace symbolize
     121             : } // end namespace llvm

Generated by: LCOV version 1.13