Skip to content

Commit 9eb681d

Browse files
committed
Parse only the space-delimited word after @throw
This is in response to a request by upstream to simplify the parser previously developed.
1 parent 421f585 commit 9eb681d

File tree

3 files changed

+9
-419
lines changed

3 files changed

+9
-419
lines changed

clang/include/clang/AST/CommentParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class Parser {
100100
ArrayRef<Comment::Argument>
101101
parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
102102

103+
/// Parse arguments for \\throws command supported args are in form of class
104+
/// or template.
103105
ArrayRef<Comment::Argument>
104106
parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
105107

clang/lib/AST/CommentParser.cpp

Lines changed: 4 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -75,25 +75,6 @@ class TextTokenRetokenizer {
7575
return *Pos.BufferPtr;
7676
}
7777

78-
char peekNext(unsigned offset) const {
79-
assert(!isEnd());
80-
assert(Pos.BufferPtr != Pos.BufferEnd);
81-
if (Pos.BufferPtr + offset < Pos.BufferEnd) {
82-
return *(Pos.BufferPtr + offset);
83-
} else {
84-
return '\0';
85-
}
86-
}
87-
88-
void peekNextToken(SmallString<32> &WordText) const {
89-
unsigned offset = 1;
90-
char C = peekNext(offset++);
91-
while (!isWhitespace(C) && C != '\0') {
92-
WordText.push_back(C);
93-
C = peekNext(offset++);
94-
}
95-
}
96-
9778
void consumeChar() {
9879
assert(!isEnd());
9980
assert(Pos.BufferPtr != Pos.BufferEnd);
@@ -108,65 +89,6 @@ class TextTokenRetokenizer {
10889
}
10990
}
11091

111-
bool shouldContinueLexingIntegralType(SmallString<32> &NextToken) {
112-
return NextToken.ends_with(StringRef("char")) ||
113-
NextToken.ends_with(StringRef("int")) ||
114-
NextToken.ends_with(StringRef("char*")) ||
115-
NextToken.ends_with(StringRef("int*")) ||
116-
NextToken.ends_with(StringRef("char&")) ||
117-
NextToken.ends_with(StringRef("int&"));
118-
}
119-
120-
/// Lex an integral type, such as unsigned long long, etc.
121-
bool lexIntegral(SmallString<32> &WordText, SmallString<32> &NextToken) {
122-
unsigned LongCounter = (WordText.ends_with(StringRef("long"))) ? 1 : 0;
123-
bool IsLexingComplete = false;
124-
125-
while (!isEnd()) {
126-
const char C = peek();
127-
if (!isWhitespace(C)) {
128-
WordText.push_back(C);
129-
consumeChar();
130-
} else {
131-
NextToken.clear();
132-
peekNextToken(NextToken);
133-
134-
if (WordText.ends_with(StringRef("long"))) {
135-
LongCounter++;
136-
// Use the next token to determine if we should continue parsing
137-
if (shouldContinueLexingIntegralType(NextToken)) {
138-
WordText.push_back(C);
139-
consumeChar();
140-
IsLexingComplete = true;
141-
continue;
142-
}
143-
// Maximum number of consecutive "long" is 2, so we can return if
144-
// we've hit that.
145-
if (LongCounter == 2) {
146-
return true;
147-
}
148-
}
149-
150-
// If current word doesn't end with long, check if we should exit early
151-
else {
152-
if (IsLexingComplete || shouldContinueLexingIntegralType(WordText)) {
153-
return true;
154-
}
155-
}
156-
157-
// If next token ends with long then we consume it and continue parsing
158-
if (NextToken.ends_with(StringRef("long"))) {
159-
WordText.push_back(C);
160-
consumeChar();
161-
} else {
162-
return true;
163-
}
164-
}
165-
}
166-
167-
return false;
168-
}
169-
17092
/// Extract a template type
17193
bool lexTemplate(SmallString<32> &WordText) {
17294
unsigned IncrementCounter = 0;
@@ -192,35 +114,6 @@ class TextTokenRetokenizer {
192114
return false;
193115
}
194116

195-
bool isTypeQualifier(SmallString<32> &WordText) {
196-
return WordText.ends_with(StringRef("const")) ||
197-
WordText.ends_with(StringRef("volatile")) ||
198-
WordText.ends_with(StringRef("short")) ||
199-
WordText.ends_with(StringRef("restrict")) ||
200-
WordText.ends_with(StringRef("auto")) ||
201-
WordText.ends_with(StringRef("register")) ||
202-
WordText.ends_with(StringRef("static")) ||
203-
WordText.ends_with(StringRef("extern")) ||
204-
WordText.ends_with(StringRef("struct")) ||
205-
WordText.ends_with(StringRef("typedef")) ||
206-
WordText.ends_with(StringRef("union")) ||
207-
WordText.ends_with(StringRef("void"));
208-
}
209-
210-
bool isScopeResolutionOperator(SmallString<32> &WordText) {
211-
return WordText.ends_with(StringRef("::"));
212-
}
213-
214-
bool isIntegral(SmallString<32> &WordText) {
215-
return WordText.ends_with(StringRef("unsigned")) ||
216-
WordText.ends_with(StringRef("long")) ||
217-
WordText.ends_with(StringRef("signed"));
218-
}
219-
220-
bool continueParsing(SmallString<32> &WordText) {
221-
return isTypeQualifier(WordText) || isScopeResolutionOperator(WordText);
222-
}
223-
224117
/// Add a token.
225118
/// Returns true on success, false if there are no interesting tokens to
226119
/// fetch from lexer.
@@ -292,14 +185,9 @@ class TextTokenRetokenizer {
292185

293186
// Consume any leading whitespace.
294187
consumeWhitespace();
295-
SmallString<32> NextToken;
296188
SmallString<32> WordText;
297189
const char *WordBegin = Pos.BufferPtr;
298190
SourceLocation Loc = getSourceLocation();
299-
StringRef ConstVal = StringRef("const");
300-
StringRef PointerVal = StringRef("*");
301-
StringRef ReferenceVal = StringRef("&");
302-
bool IsTypeConstPointerOrRef = false;
303191

304192
while (!isEnd()) {
305193
const char C = peek();
@@ -313,62 +201,9 @@ class TextTokenRetokenizer {
313201
WordText.push_back(C);
314202
consumeChar();
315203
}
316-
}
317-
// For whitespace, we start inspecting the constructed word
318-
else {
319-
// If we encounter a pointer/reference, we can stop parsing since we're
320-
// only parsing expressions.
321-
if (IsTypeConstPointerOrRef) {
322-
consumeChar();
323-
break;
324-
}
325-
// Parse out integral types
326-
if (isIntegral(WordText)) {
327-
WordText.push_back(C);
328-
consumeChar();
329-
if (!lexIntegral(WordText, NextToken))
330-
return false;
331-
}
332-
// Certain types, like qualified names or types with CVR to name a few,
333-
// may have whitespace inside of the typename, so we need to check and
334-
// continue parsing if that's the case
335-
if (continueParsing(WordText)) {
336-
WordText.push_back(C);
337-
consumeChar();
338-
}
339-
// Handles cases without qualified names or type qualifiers
340-
else {
341-
NextToken.clear();
342-
peekNextToken(NextToken);
343-
// Check for pointer/ref vals, and mark the type as a pointer/ref for
344-
// the rest of the lex
345-
if (WordText.ends_with(PointerVal) ||
346-
WordText.ends_with(ReferenceVal)) {
347-
if (NextToken.equals(ConstVal)) {
348-
IsTypeConstPointerOrRef = true;
349-
WordText.push_back(C);
350-
consumeChar();
351-
} else {
352-
consumeChar();
353-
break;
354-
}
355-
} else {
356-
// Check if the next token is a pointer/ref
357-
if ((NextToken.ends_with(PointerVal) ||
358-
NextToken.ends_with(ReferenceVal))) {
359-
WordText.push_back(C);
360-
consumeChar();
361-
} else {
362-
if (continueParsing(NextToken)) {
363-
WordText.push_back(C);
364-
consumeChar();
365-
} else {
366-
consumeChar();
367-
break;
368-
}
369-
}
370-
}
371-
}
204+
} else {
205+
consumeChar();
206+
break;
372207
}
373208
}
374209

@@ -462,8 +297,7 @@ class TextTokenRetokenizer {
462297
memcpy(TextPtr, WordText.c_str(), Length + 1);
463298
StringRef Text = StringRef(TextPtr, Length);
464299

465-
formTokenWithChars(Tok, Loc, WordBegin,
466-
Pos.BufferPtr - WordBegin, Text);
300+
formTokenWithChars(Tok, Loc, WordBegin, Pos.BufferPtr - WordBegin, Text);
467301
return true;
468302
}
469303

0 commit comments

Comments
 (0)