@@ -75,6 +75,25 @@ class TextTokenRetokenizer {
75
75
return *Pos.BufferPtr ;
76
76
}
77
77
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
+
78
97
void consumeChar () {
79
98
assert (!isEnd ());
80
99
assert (Pos.BufferPtr != Pos.BufferEnd );
@@ -89,6 +108,29 @@ class TextTokenRetokenizer {
89
108
}
90
109
}
91
110
111
+ // / Extract a template type
112
+ bool lexTemplateType (SmallString<32 > &WordText) {
113
+ unsigned IncrementCounter = 0 ;
114
+ while (!isEnd ()) {
115
+ const char C = peek ();
116
+ WordText.push_back (C);
117
+ consumeChar ();
118
+ switch (C) {
119
+ default :
120
+ break ;
121
+ case ' <' : {
122
+ IncrementCounter++;
123
+ } break ;
124
+ case ' >' : {
125
+ IncrementCounter--;
126
+ if (!IncrementCounter)
127
+ return true ;
128
+ } break ;
129
+ }
130
+ }
131
+ return false ;
132
+ }
133
+
92
134
// / Add a token.
93
135
// / Returns true on success, false if there are no interesting tokens to
94
136
// / fetch from lexer.
@@ -149,6 +191,76 @@ class TextTokenRetokenizer {
149
191
addToken ();
150
192
}
151
193
194
+ // / Extract a type argument
195
+ bool lexDataType (Token &Tok) {
196
+ if (isEnd ())
197
+ return false ;
198
+ Position SavedPos = Pos;
199
+ consumeWhitespace ();
200
+ SmallString<32 > NextToken;
201
+ SmallString<32 > WordText;
202
+ const char *WordBegin = Pos.BufferPtr ;
203
+ SourceLocation Loc = getSourceLocation ();
204
+ StringRef ConstVal = StringRef (" const" );
205
+ bool ConstPointer = false ;
206
+
207
+ while (!isEnd ()) {
208
+ const char C = peek ();
209
+ if (!isWhitespace (C)) {
210
+ if (C == ' <' ) {
211
+ if (!lexTemplateType (WordText))
212
+ return false ;
213
+ } else {
214
+ WordText.push_back (C);
215
+ consumeChar ();
216
+ }
217
+ } else {
218
+ if (WordText.equals (ConstVal)) {
219
+ WordText.push_back (C);
220
+ consumeChar ();
221
+ } else if (WordText.ends_with (StringRef (" *" )) ||
222
+ WordText.ends_with (StringRef (" &" ))) {
223
+ NextToken.clear ();
224
+ peekNextToken (NextToken);
225
+ if (NextToken.equals (ConstVal)) {
226
+ ConstPointer = true ;
227
+ WordText.push_back (C);
228
+ consumeChar ();
229
+ } else {
230
+ consumeChar ();
231
+ break ;
232
+ }
233
+ } else {
234
+ NextToken.clear ();
235
+ peekNextToken (NextToken);
236
+ if ((NextToken.ends_with (StringRef (" *" )) ||
237
+ NextToken.ends_with (StringRef (" &" ))) &&
238
+ !ConstPointer) {
239
+ WordText.push_back (C);
240
+ consumeChar ();
241
+ } else {
242
+ consumeChar ();
243
+ break ;
244
+ }
245
+ }
246
+ }
247
+ }
248
+
249
+ const unsigned Length = WordText.size ();
250
+ if (Length == 0 ) {
251
+ Pos = SavedPos;
252
+ return false ;
253
+ }
254
+
255
+ char *TextPtr = Allocator.Allocate <char >(Length + 1 );
256
+
257
+ memcpy (TextPtr, WordText.c_str (), Length + 1 );
258
+ StringRef Text = StringRef (TextPtr, Length);
259
+
260
+ formTokenWithChars (Tok, Loc, WordBegin, Length, Text);
261
+ return true ;
262
+ }
263
+
152
264
// / Extract a word -- sequence of non-whitespace characters.
153
265
bool lexWord (Token &Tok) {
154
266
if (isEnd ())
@@ -295,6 +407,7 @@ Parser::parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs) {
295
407
Comment::Argument[NumArgs];
296
408
unsigned ParsedArgs = 0 ;
297
409
Token Arg;
410
+
298
411
while (ParsedArgs < NumArgs && Retokenizer.lexWord (Arg)) {
299
412
Args[ParsedArgs] = Comment::Argument{
300
413
SourceRange (Arg.getLocation (), Arg.getEndLocation ()), Arg.getText ()};
@@ -304,6 +417,23 @@ Parser::parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs) {
304
417
return llvm::ArrayRef (Args, ParsedArgs);
305
418
}
306
419
420
+ ArrayRef<Comment::Argument>
421
+ Parser::parseThrowCommandArgs (TextTokenRetokenizer &Retokenizer,
422
+ unsigned NumArgs) {
423
+ auto *Args = new (Allocator.Allocate <Comment::Argument>(NumArgs))
424
+ Comment::Argument[NumArgs];
425
+ unsigned ParsedArgs = 0 ;
426
+ Token Arg;
427
+
428
+ while (ParsedArgs < NumArgs && Retokenizer.lexDataType (Arg)) {
429
+ Args[ParsedArgs] = Comment::Argument{
430
+ SourceRange (Arg.getLocation (), Arg.getEndLocation ()), Arg.getText ()};
431
+ ParsedArgs++;
432
+ }
433
+
434
+ return llvm::ArrayRef (Args, ParsedArgs);
435
+ }
436
+
307
437
BlockCommandComment *Parser::parseBlockCommand () {
308
438
assert (Tok.is (tok::backslash_command) || Tok.is (tok::at_command));
309
439
@@ -356,6 +486,9 @@ BlockCommandComment *Parser::parseBlockCommand() {
356
486
parseParamCommandArgs (PC, Retokenizer);
357
487
else if (TPC)
358
488
parseTParamCommandArgs (TPC, Retokenizer);
489
+ else if (Info->IsThrowsCommand )
490
+ S.actOnBlockCommandArgs (
491
+ BC, parseThrowCommandArgs (Retokenizer, Info->NumArgs ));
359
492
else
360
493
S.actOnBlockCommandArgs (BC, parseCommandArgs (Retokenizer, Info->NumArgs ));
361
494
0 commit comments