LCOV - code coverage report
Current view: top level - lib/Support - LineIterator.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 33 33 100.0 %
Date: 2018-06-17 00:07:59 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- LineIterator.cpp - Implementation of line iteration ----------------===//
       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 "llvm/Support/LineIterator.h"
      11             : #include "llvm/Support/MemoryBuffer.h"
      12             : 
      13             : using namespace llvm;
      14             : 
      15             : static bool isAtLineEnd(const char *P) {
      16    16333121 :   if (*P == '\n')
      17             :     return true;
      18    15836451 :   if (*P == '\r' && *(P + 1) == '\n')
      19             :     return true;
      20             :   return false;
      21             : }
      22             : 
      23             : static bool skipIfAtLineEnd(const char *&P) {
      24      827142 :   if (*P == '\n') {
      25      437199 :     ++P;
      26             :     return true;
      27             :   }
      28      389943 :   if (*P == '\r' && *(P + 1) == '\n') {
      29           2 :     P += 2;
      30             :     return true;
      31             :   }
      32             :   return false;
      33             : }
      34             : 
      35        6361 : line_iterator::line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks,
      36        6361 :                              char CommentMarker)
      37       12722 :     : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr),
      38             :       CommentMarker(CommentMarker), SkipBlanks(SkipBlanks), LineNumber(1),
      39        6361 :       CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr,
      40       12722 :                   0) {
      41             :   // Ensure that if we are constructed on a non-empty memory buffer that it is
      42             :   // a null terminated buffer.
      43       12722 :   if (Buffer.getBufferSize()) {
      44             :     assert(Buffer.getBufferEnd()[0] == '\0');
      45             :     // Make sure we don't skip a leading newline if we're keeping blanks
      46        6327 :     if (SkipBlanks || !isAtLineEnd(Buffer.getBufferStart()))
      47        6324 :       advance();
      48             :   }
      49        6361 : }
      50             : 
      51      442243 : void line_iterator::advance() {
      52             :   assert(Buffer && "Cannot advance past the end!");
      53             : 
      54             :   const char *Pos = CurrentLine.end();
      55             :   assert(Pos == Buffer->getBufferStart() || isAtLineEnd(Pos) || *Pos == '\0');
      56             : 
      57             :   if (skipIfAtLineEnd(Pos))
      58      435935 :     ++LineNumber;
      59      442243 :   if (!SkipBlanks && isAtLineEnd(Pos)) {
      60             :     // Nothing to do for a blank line.
      61      383634 :   } else if (CommentMarker == '\0') {
      62             :     // If we're not stripping comments, this is simpler.
      63          12 :     while (skipIfAtLineEnd(Pos))
      64          12 :       ++LineNumber;
      65             :   } else {
      66             :     // Skip comments and count line numbers, which is a bit more complex.
      67             :     for (;;) {
      68        1525 :       if (isAtLineEnd(Pos) && !SkipBlanks)
      69             :         break;
      70        4198 :       if (*Pos == CommentMarker)
      71             :         do {
      72       29728 :           ++Pos;
      73       29728 :         } while (*Pos != '\0' && !isAtLineEnd(Pos));
      74        4198 :       if (!skipIfAtLineEnd(Pos))
      75             :         break;
      76        1254 :       ++LineNumber;
      77             :     }
      78             :   }
      79             : 
      80      442243 :   if (*Pos == '\0') {
      81             :     // We've hit the end of the buffer, reset ourselves to the end state.
      82        5434 :     Buffer = nullptr;
      83        5434 :     CurrentLine = StringRef();
      84             :     return;
      85             :   }
      86             : 
      87             :   // Measure the line.
      88             :   size_t Length = 0;
      89    31271125 :   while (Pos[Length] != '\0' && !isAtLineEnd(&Pos[Length])) {
      90    15417158 :     ++Length;
      91             :   }
      92             : 
      93      436809 :   CurrentLine = StringRef(Pos, Length);
      94             : }

Generated by: LCOV version 1.13