Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/AST/CommentBriefParser.cpp
Line
Count
Source
1
//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
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
#include "clang/AST/CommentBriefParser.h"
10
#include "clang/AST/CommentCommandTraits.h"
11
12
namespace clang {
13
namespace comments {
14
15
namespace {
16
16.5k
inline bool isWhitespace(char C) {
17
16.5k
  return C == ' ' || 
C == '\n'12.5k
||
C == '\r'12.5k
||
18
16.5k
         
C == '\t'12.5k
||
C == '\f'12.5k
||
C == '\v'12.5k
;
19
16.5k
}
20
21
/// Convert all whitespace into spaces, remove leading and trailing spaces,
22
/// compress multiple spaces into one.
23
1.10k
void cleanupBrief(std::string &S) {
24
1.10k
  bool PrevWasSpace = true;
25
1.10k
  std::string::iterator O = S.begin();
26
1.10k
  for (std::string::iterator I = S.begin(), E = S.end();
27
16.5k
       I != E; 
++I15.4k
) {
28
15.4k
    const char C = *I;
29
15.4k
    if (isWhitespace(C)) {
30
3.15k
      if (!PrevWasSpace) {
31
1.83k
        *O++ = ' ';
32
1.83k
        PrevWasSpace = true;
33
1.83k
      }
34
3.15k
      continue;
35
12.3k
    } else {
36
12.3k
      *O++ = C;
37
12.3k
      PrevWasSpace = false;
38
12.3k
    }
39
15.4k
  }
40
1.10k
  if (O != S.begin() && 
*(O - 1) == ' '659
)
41
659
    --O;
42
1.10k
43
1.10k
  S.resize(O - S.begin());
44
1.10k
}
45
46
638
bool isWhitespace(StringRef Text) {
47
638
  for (StringRef::const_iterator I = Text.begin(), E = Text.end();
48
1.56k
       I != E; 
++I922
) {
49
1.12k
    if (!isWhitespace(*I))
50
201
      return false;
51
1.12k
  }
52
638
  
return true437
;
53
638
}
54
} // unnamed namespace
55
56
BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
57
859
    L(L), Traits(Traits) {
58
859
  // Get lookahead token.
59
859
  ConsumeToken();
60
859
}
61
62
859
std::string BriefParser::Parse() {
63
859
  std::string FirstParagraphOrBrief;
64
859
  std::string ReturnsParagraph;
65
859
  bool InFirstParagraph = true;
66
859
  bool InBrief = false;
67
859
  bool InReturns = false;
68
859
69
4.89k
  while (Tok.isNot(tok::eof)) {
70
4.26k
    if (Tok.is(tok::text)) {
71
1.54k
      if (InFirstParagraph || 
InBrief464
)
72
1.09k
        FirstParagraphOrBrief += Tok.getText();
73
450
      else if (InReturns)
74
72
        ReturnsParagraph += Tok.getText();
75
1.54k
      ConsumeToken();
76
1.54k
      continue;
77
1.54k
    }
78
2.72k
79
2.72k
    if (Tok.is(tok::backslash_command) || 
Tok.is(tok::at_command)2.05k
) {
80
693
      const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
81
693
      if (Info->IsBriefCommand) {
82
250
        FirstParagraphOrBrief.clear();
83
250
        InBrief = true;
84
250
        ConsumeToken();
85
250
        continue;
86
250
      }
87
443
      if (Info->IsReturnsCommand) {
88
72
        InReturns = true;
89
72
        InBrief = false;
90
72
        InFirstParagraph = false;
91
72
        ReturnsParagraph += "Returns ";
92
72
        ConsumeToken();
93
72
        continue;
94
72
      }
95
371
      // Block commands implicitly start a new paragraph.
96
371
      if (Info->IsBlockCommand) {
97
346
        // We found an implicit paragraph end.
98
346
        InFirstParagraph = false;
99
346
        if (InBrief)
100
57
          break;
101
2.34k
      }
102
371
    }
103
2.34k
104
2.34k
    if (Tok.is(tok::newline)) {
105
1.57k
      if (InFirstParagraph || 
InBrief478
)
106
1.11k
        FirstParagraphOrBrief += ' ';
107
459
      else if (InReturns)
108
72
        ReturnsParagraph += ' ';
109
1.57k
      ConsumeToken();
110
1.57k
111
1.57k
      // If the next token is a whitespace only text, ignore it.  Thus we allow
112
1.57k
      // two paragraphs to be separated by line that has only whitespace in it.
113
1.57k
      //
114
1.57k
      // We don't need to add a space to the parsed text because we just added
115
1.57k
      // a space for the newline.
116
1.57k
      if (Tok.is(tok::text)) {
117
526
        if (isWhitespace(Tok.getText()))
118
423
          ConsumeToken();
119
526
      }
120
1.57k
121
1.57k
      if (Tok.is(tok::newline)) {
122
345
        ConsumeToken();
123
345
        // We found a paragraph end.  This ends the brief description if
124
345
        // \command or its equivalent was explicitly used.
125
345
        // Stop scanning text because an explicit \paragraph is the
126
345
        // preffered one.
127
345
        if (InBrief)
128
169
          break;
129
176
        // End first paragraph if we found some non-whitespace text.
130
176
        if (InFirstParagraph && 
!isWhitespace(FirstParagraphOrBrief)112
)
131
98
          InFirstParagraph = false;
132
176
        // End the \\returns paragraph because we found the paragraph end.
133
176
        InReturns = false;
134
176
      }
135
1.57k
      
continue1.40k
;
136
769
    }
137
769
138
769
    // We didn't handle this token, so just drop it.
139
769
    ConsumeToken();
140
769
  }
141
859
142
859
  cleanupBrief(FirstParagraphOrBrief);
143
859
  if (!FirstParagraphOrBrief.empty())
144
612
    return FirstParagraphOrBrief;
145
247
146
247
  cleanupBrief(ReturnsParagraph);
147
247
  return ReturnsParagraph;
148
247
}
149
150
} // end namespace comments
151
} // end namespace clang
152
153