Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Format/AffectedRangeManager.cpp
Line
Count
Source
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
227k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
24
227k
  SmallVectorImpl<AnnotatedLine *>::iterator I = Lines.begin();
25
227k
  SmallVectorImpl<AnnotatedLine *>::iterator E = Lines.end();
26
227k
  bool SomeLineAffected = false;
27
227k
  const AnnotatedLine *PreviousLine = nullptr;
28
417k
  while (I != E) {
29
189k
    AnnotatedLine *Line = *I;
30
189k
    Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
31
32
    // If a line is part of a preprocessor directive, it needs to be formatted
33
    // if any token within the directive is affected.
34
189k
    if (Line->InPPDirective) {
35
11.2k
      FormatToken *Last = Line->Last;
36
11.2k
      SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
37
16.5k
      while (PPEnd != E && 
!(*PPEnd)->First->HasUnescapedNewline14.4k
) {
38
5.27k
        Last = (*PPEnd)->Last;
39
5.27k
        ++PPEnd;
40
5.27k
      }
41
42
11.2k
      if (affectsTokenRange(*Line->First, *Last,
43
11.2k
                            /*IncludeLeadingNewlines=*/false)) {
44
9.95k
        SomeLineAffected = true;
45
9.95k
        markAllAsAffected(I, PPEnd);
46
9.95k
      }
47
11.2k
      I = PPEnd;
48
11.2k
      continue;
49
11.2k
    }
50
51
178k
    if (nonPPLineAffected(Line, PreviousLine, Lines))
52
159k
      SomeLineAffected = true;
53
54
178k
    PreviousLine = Line;
55
178k
    ++I;
56
178k
  }
57
227k
  return SomeLineAffected;
58
227k
}
59
60
bool AffectedRangeManager::affectsCharSourceRange(
61
983k
    const CharSourceRange &Range) {
62
983k
  for (const CharSourceRange &R : Ranges)
63
1.02M
    if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), R.getBegin()) &&
64
1.02M
        
!SourceMgr.isBeforeInTranslationUnit(R.getEnd(), Range.getBegin())961k
)
65
872k
      return true;
66
110k
  return false;
67
983k
}
68
69
bool AffectedRangeManager::affectsTokenRange(const FormatToken &First,
70
                                             const FormatToken &Last,
71
793k
                                             bool IncludeLeadingNewlines) {
72
793k
  SourceLocation Start = First.WhitespaceRange.getBegin();
73
793k
  if (!IncludeLeadingNewlines)
74
192k
    Start = Start.getLocWithOffset(First.LastNewlineOffset);
75
793k
  SourceLocation End = Last.getStartOfNonWhitespace();
76
793k
  End = End.getLocWithOffset(Last.TokenText.size());
77
793k
  CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
78
793k
  return affectsCharSourceRange(Range);
79
793k
}
80
81
189k
bool AffectedRangeManager::affectsLeadingEmptyLines(const FormatToken &Tok) {
82
189k
  CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
83
189k
      Tok.WhitespaceRange.getBegin(),
84
189k
      Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
85
189k
  return affectsCharSourceRange(EmptyLineRange);
86
189k
}
87
88
void AffectedRangeManager::markAllAsAffected(
89
    SmallVectorImpl<AnnotatedLine *>::iterator I,
90
24.7k
    SmallVectorImpl<AnnotatedLine *>::iterator E) {
91
39.5k
  while (I != E) {
92
14.7k
    (*I)->Affected = true;
93
14.7k
    markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
94
14.7k
    ++I;
95
14.7k
  }
96
24.7k
}
97
98
bool AffectedRangeManager::nonPPLineAffected(
99
    AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
100
178k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
101
178k
  bool SomeLineAffected = false;
102
178k
  Line->ChildrenAffected = computeAffectedLines(Line->Children);
103
178k
  if (Line->ChildrenAffected)
104
2.29k
    SomeLineAffected = true;
105
106
  // Stores whether one of the line's tokens is directly affected.
107
178k
  bool SomeTokenAffected = false;
108
  // Stores whether we need to look at the leading newlines of the next token
109
  // in order to determine whether it was affected.
110
178k
  bool IncludeLeadingNewlines = false;
111
112
  // Stores whether the first child line of any of this line's tokens is
113
  // affected.
114
178k
  bool SomeFirstChildAffected = false;
115
116
960k
  for (FormatToken *Tok = Line->First; Tok; 
Tok = Tok->Next782k
) {
117
    // Determine whether 'Tok' was affected.
118
782k
    if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
119
697k
      SomeTokenAffected = true;
120
121
    // Determine whether the first child of 'Tok' was affected.
122
782k
    if (!Tok->Children.empty() && 
Tok->Children.front()->Affected2.41k
)
123
2.38k
      SomeFirstChildAffected = true;
124
125
782k
    IncludeLeadingNewlines = Tok->Children.empty();
126
782k
  }
127
128
  // Was this line moved, i.e. has it previously been on the same line as an
129
  // affected line?
130
178k
  bool LineMoved = PreviousLine && 
PreviousLine->Affected128k
&&
131
178k
                   
Line->First->NewlinesBefore == 0110k
;
132
133
178k
  bool IsContinuedComment =
134
178k
      Line->First->is(tok::comment) && 
Line->First->Next == nullptr3.95k
&&
135
178k
      
Line->First->NewlinesBefore < 23.08k
&&
PreviousLine2.65k
&&
136
178k
      
PreviousLine->Affected1.58k
&&
PreviousLine->Last->is(tok::comment)1.56k
;
137
138
178k
  bool IsAffectedClosingBrace =
139
178k
      Line->First->is(tok::r_brace) &&
140
178k
      
Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex28.9k
&&
141
178k
      
Lines[Line->MatchingOpeningBlockLineIndex]->Affected28.6k
;
142
143
178k
  if (SomeTokenAffected || 
SomeFirstChildAffected21.0k
||
LineMoved21.0k
||
144
178k
      
IsContinuedComment19.2k
||
IsAffectedClosingBrace19.2k
) {
145
159k
    Line->Affected = true;
146
159k
    SomeLineAffected = true;
147
159k
  }
148
178k
  return SomeLineAffected;
149
178k
}
150
151
} // namespace format
152
} // namespace clang