Coverage Report

Created: 2022-05-17 06:19

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Format/AffectedRangeManager.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- AffectedRangeManager.cpp - Format C++ code -----------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file implements AffectRangeManager class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "AffectedRangeManager.h"
15
16
#include "FormatToken.h"
17
#include "TokenAnnotator.h"
18
19
namespace clang {
20
namespace format {
21
22
bool AffectedRangeManager::computeAffectedLines(
23
291k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
24
291k
  SmallVectorImpl<AnnotatedLine *>::iterator I = Lines.begin();
25
291k
  SmallVectorImpl<AnnotatedLine *>::iterator E = Lines.end();
26
291k
  bool SomeLineAffected = false;
27
291k
  const AnnotatedLine *PreviousLine = nullptr;
28
531k
  while (I != E) {
29
240k
    AnnotatedLine *Line = *I;
30
240k
    assert(Line->First);
31
0
    Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
32
33
    // If a line is part of a preprocessor directive, it needs to be formatted
34
    // if any token within the directive is affected.
35
240k
    if (Line->InPPDirective) {
36
13.2k
      FormatToken *Last = Line->Last;
37
13.2k
      SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
38
20.0k
      while (PPEnd != E && 
!(*PPEnd)->First->HasUnescapedNewline17.2k
) {
39
6.83k
        Last = (*PPEnd)->Last;
40
6.83k
        ++PPEnd;
41
6.83k
      }
42
43
13.2k
      if (affectsTokenRange(*Line->First, *Last,
44
13.2k
                            /*IncludeLeadingNewlines=*/false)) {
45
11.9k
        SomeLineAffected = true;
46
11.9k
        markAllAsAffected(I, PPEnd);
47
11.9k
      }
48
13.2k
      I = PPEnd;
49
13.2k
      continue;
50
13.2k
    }
51
52
227k
    if (nonPPLineAffected(Line, PreviousLine, Lines))
53
208k
      SomeLineAffected = true;
54
55
227k
    PreviousLine = Line;
56
227k
    ++I;
57
227k
  }
58
291k
  return SomeLineAffected;
59
291k
}
60
61
bool AffectedRangeManager::affectsCharSourceRange(
62
1.28M
    const CharSourceRange &Range) {
63
1.28M
  for (const CharSourceRange &R : Ranges)
64
1.32M
    if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), R.getBegin()) &&
65
1.32M
        
!SourceMgr.isBeforeInTranslationUnit(R.getEnd(), Range.getBegin())1.25M
)
66
1.16M
      return true;
67
110k
  return false;
68
1.28M
}
69
70
bool AffectedRangeManager::affectsTokenRange(const FormatToken &First,
71
                                             const FormatToken &Last,
72
1.03M
                                             bool IncludeLeadingNewlines) {
73
1.03M
  SourceLocation Start = First.WhitespaceRange.getBegin();
74
1.03M
  if (!IncludeLeadingNewlines)
75
244k
    Start = Start.getLocWithOffset(First.LastNewlineOffset);
76
1.03M
  SourceLocation End = Last.getStartOfNonWhitespace();
77
1.03M
  End = End.getLocWithOffset(Last.TokenText.size());
78
1.03M
  CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
79
1.03M
  return affectsCharSourceRange(Range);
80
1.03M
}
81
82
240k
bool AffectedRangeManager::affectsLeadingEmptyLines(const FormatToken &Tok) {
83
240k
  CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
84
240k
      Tok.WhitespaceRange.getBegin(),
85
240k
      Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
86
240k
  return affectsCharSourceRange(EmptyLineRange);
87
240k
}
88
89
void AffectedRangeManager::markAllAsAffected(
90
    SmallVectorImpl<AnnotatedLine *>::iterator I,
91
30.2k
    SmallVectorImpl<AnnotatedLine *>::iterator E) {
92
48.6k
  while (I != E) {
93
18.3k
    (*I)->Affected = true;
94
18.3k
    markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
95
18.3k
    ++I;
96
18.3k
  }
97
30.2k
}
98
99
bool AffectedRangeManager::nonPPLineAffected(
100
    AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
101
227k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
102
227k
  bool SomeLineAffected = false;
103
227k
  Line->ChildrenAffected = computeAffectedLines(Line->Children);
104
227k
  if (Line->ChildrenAffected)
105
3.69k
    SomeLineAffected = true;
106
107
  // Stores whether one of the line's tokens is directly affected.
108
227k
  bool SomeTokenAffected = false;
109
  // Stores whether we need to look at the leading newlines of the next token
110
  // in order to determine whether it was affected.
111
227k
  bool IncludeLeadingNewlines = false;
112
113
  // Stores whether the first child line of any of this line's tokens is
114
  // affected.
115
227k
  bool SomeFirstChildAffected = false;
116
117
227k
  assert(Line->First);
118
1.25M
  for (FormatToken *Tok = Line->First; Tok; 
Tok = Tok->Next1.02M
) {
119
    // Determine whether 'Tok' was affected.
120
1.02M
    if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
121
941k
      SomeTokenAffected = true;
122
123
    // Determine whether the first child of 'Tok' was affected.
124
1.02M
    if (!Tok->Children.empty() && 
Tok->Children.front()->Affected3.95k
)
125
3.92k
      SomeFirstChildAffected = true;
126
127
1.02M
    IncludeLeadingNewlines = Tok->Children.empty();
128
1.02M
  }
129
130
  // Was this line moved, i.e. has it previously been on the same line as an
131
  // affected line?
132
227k
  bool LineMoved = PreviousLine && 
PreviousLine->Affected161k
&&
133
227k
                   
Line->First->NewlinesBefore == 0143k
;
134
135
227k
  bool IsContinuedComment =
136
227k
      Line->First->is(tok::comment) && 
Line->First->Next == nullptr4.95k
&&
137
227k
      
Line->First->NewlinesBefore < 23.82k
&&
PreviousLine3.23k
&&
138
227k
      
PreviousLine->Affected1.95k
&&
PreviousLine->Last->is(tok::comment)1.93k
;
139
140
227k
  bool IsAffectedClosingBrace =
141
227k
      Line->First->is(tok::r_brace) &&
142
227k
      
Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex35.9k
&&
143
227k
      
Lines[Line->MatchingOpeningBlockLineIndex]->Affected35.6k
;
144
145
227k
  if (SomeTokenAffected || 
SomeFirstChildAffected21.0k
||
LineMoved21.0k
||
146
227k
      
IsContinuedComment19.2k
||
IsAffectedClosingBrace19.2k
) {
147
208k
    Line->Affected = true;
148
208k
    SomeLineAffected = true;
149
208k
  }
150
227k
  return SomeLineAffected;
151
227k
}
152
153
} // namespace format
154
} // namespace clang