Coverage Report

Created: 2020-10-24 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Parser.cpp - Matcher expression 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
/// \file
10
/// Recursive parser implementation for the matcher expression grammar.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/ASTMatchers/Dynamic/Parser.h"
15
#include "clang/ASTMatchers/ASTMatchersInternal.h"
16
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
17
#include "clang/ASTMatchers/Dynamic/Registry.h"
18
#include "clang/Basic/CharInfo.h"
19
#include "llvm/ADT/Optional.h"
20
#include "llvm/ADT/StringRef.h"
21
#include "llvm/Support/ErrorHandling.h"
22
#include "llvm/Support/ManagedStatic.h"
23
#include <algorithm>
24
#include <cassert>
25
#include <cerrno>
26
#include <cstddef>
27
#include <cstdlib>
28
#include <string>
29
#include <utility>
30
#include <vector>
31
32
namespace clang {
33
namespace ast_matchers {
34
namespace dynamic {
35
36
/// Simple structure to hold information for one token from the parser.
37
struct Parser::TokenInfo {
38
  /// Different possible tokens.
39
  enum TokenKind {
40
    TK_Eof,
41
    TK_NewLine,
42
    TK_OpenParen,
43
    TK_CloseParen,
44
    TK_Comma,
45
    TK_Period,
46
    TK_Literal,
47
    TK_Ident,
48
    TK_InvalidChar,
49
    TK_Error,
50
    TK_CodeCompletion
51
  };
52
53
  /// Some known identifiers.
54
  static const char* const ID_Bind;
55
56
566
  TokenInfo() = default;
57
58
  StringRef Text;
59
  TokenKind Kind = TK_Eof;
60
  SourceRange Range;
61
  VariantValue Value;
62
};
63
64
const char* const Parser::TokenInfo::ID_Bind = "bind";
65
66
/// Simple tokenizer for the parser.
67
class Parser::CodeTokenizer {
68
public:
69
  explicit CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error)
70
60
      : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) {
71
60
    NextToken = getNextToken();
72
60
  }
73
74
  CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error,
75
                unsigned CodeCompletionOffset)
76
      : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error),
77
5
        CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
78
5
    NextToken = getNextToken();
79
5
  }
80
81
  /// Returns but doesn't consume the next token.
82
248
  const TokenInfo &peekNextToken() const { return NextToken; }
83
84
  /// Consumes and returns the next token.
85
339
  TokenInfo consumeNextToken() {
86
339
    TokenInfo ThisToken = NextToken;
87
339
    NextToken = getNextToken();
88
339
    return ThisToken;
89
339
  }
90
91
310
  TokenInfo SkipNewlines() {
92
325
    while (NextToken.Kind == TokenInfo::TK_NewLine)
93
15
      NextToken = getNextToken();
94
310
    return NextToken;
95
310
  }
96
97
28
  TokenInfo consumeNextTokenIgnoreNewlines() {
98
28
    SkipNewlines();
99
28
    if (NextToken.Kind == TokenInfo::TK_Eof)
100
6
      return NextToken;
101
22
    return consumeNextToken();
102
22
  }
103
104
503
  TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; }
105
106
private:
107
424
  TokenInfo getNextToken() {
108
424
    consumeWhitespace();
109
424
    TokenInfo Result;
110
424
    Result.Range.Start = currentLocation();
111
112
424
    if (CodeCompletionLocation && 
CodeCompletionLocation <= Code.data()22
) {
113
3
      Result.Kind = TokenInfo::TK_CodeCompletion;
114
3
      Result.Text = StringRef(CodeCompletionLocation, 0);
115
3
      CodeCompletionLocation = nullptr;
116
3
      return Result;
117
3
    }
118
119
421
    if (Code.empty()) {
120
46
      Result.Kind = TokenInfo::TK_Eof;
121
46
      Result.Text = "";
122
46
      return Result;
123
46
    }
124
125
375
    switch (Code[0]) {
126
5
    case '#':
127
68
      Code = Code.drop_until([](char c) { return c == '\n'; });
128
5
      return getNextToken();
129
13
    case ',':
130
13
      Result.Kind = TokenInfo::TK_Comma;
131
13
      Result.Text = Code.substr(0, 1);
132
13
      Code = Code.drop_front();
133
13
      break;
134
13
    case '.':
135
13
      Result.Kind = TokenInfo::TK_Period;
136
13
      Result.Text = Code.substr(0, 1);
137
13
      Code = Code.drop_front();
138
13
      break;
139
23
    case '\n':
140
23
      ++Line;
141
23
      StartOfLine = Code.drop_front();
142
23
      Result.Kind = TokenInfo::TK_NewLine;
143
23
      Result.Text = Code.substr(0, 1);
144
23
      Code = Code.drop_front();
145
23
      break;
146
88
    case '(':
147
88
      Result.Kind = TokenInfo::TK_OpenParen;
148
88
      Result.Text = Code.substr(0, 1);
149
88
      Code = Code.drop_front();
150
88
      break;
151
76
    case ')':
152
76
      Result.Kind = TokenInfo::TK_CloseParen;
153
76
      Result.Text = Code.substr(0, 1);
154
76
      Code = Code.drop_front();
155
76
      break;
156
157
37
    case '"':
158
37
    case '\'':
159
      // Parse a string literal.
160
37
      consumeStringLiteral(&Result);
161
37
      break;
162
163
15
    case '0': case '1': case '2': case '3': case '4':
164
15
    case '5': case '6': case '7': case '8': case '9':
165
      // Parse an unsigned and float literal.
166
15
      consumeNumberLiteral(&Result);
167
15
      break;
168
169
105
    default:
170
105
      if (isAlphanumeric(Code[0])) {
171
        // Parse an identifier
172
105
        size_t TokenLength = 1;
173
765
        while (true) {
174
          // A code completion location in/immediately after an identifier will
175
          // cause the portion of the identifier before the code completion
176
          // location to become a code completion token.
177
765
          if (CodeCompletionLocation == Code.data() + TokenLength) {
178
2
            CodeCompletionLocation = nullptr;
179
2
            Result.Kind = TokenInfo::TK_CodeCompletion;
180
2
            Result.Text = Code.substr(0, TokenLength);
181
2
            Code = Code.drop_front(TokenLength);
182
2
            return Result;
183
2
          }
184
763
          if (TokenLength == Code.size() || 
!isAlphanumeric(Code[TokenLength])757
)
185
103
            break;
186
660
          ++TokenLength;
187
660
        }
188
103
        if (TokenLength == 4 && 
Code.startswith("true")27
) {
189
1
          Result.Kind = TokenInfo::TK_Literal;
190
1
          Result.Value = true;
191
102
        } else if (TokenLength == 5 && 
Code.startswith("false")4
) {
192
1
          Result.Kind = TokenInfo::TK_Literal;
193
1
          Result.Value = false;
194
101
        } else {
195
101
          Result.Kind = TokenInfo::TK_Ident;
196
101
          Result.Text = Code.substr(0, TokenLength);
197
101
        }
198
103
        Code = Code.drop_front(TokenLength);
199
0
      } else {
200
0
        Result.Kind = TokenInfo::TK_InvalidChar;
201
0
        Result.Text = Code.substr(0, 1);
202
0
        Code = Code.drop_front(1);
203
0
      }
204
103
      break;
205
368
    }
206
207
368
    Result.Range.End = currentLocation();
208
368
    return Result;
209
368
  }
210
211
  /// Consume an unsigned and float literal.
212
15
  void consumeNumberLiteral(TokenInfo *Result) {
213
15
    bool isFloatingLiteral = false;
214
15
    unsigned Length = 1;
215
15
    if (Code.size() > 1) {
216
      // Consume the 'x' or 'b' radix modifier, if present.
217
13
      switch (toLowercase(Code[1])) {
218
1
      case 'x': case 'b': Length = 2;
219
13
      }
220
13
    }
221
37
    
while (15
Length < Code.size() &&
isHexDigit(Code[Length])30
)
222
22
      ++Length;
223
224
    // Try to recognize a floating point literal.
225
31
    while (Length < Code.size()) {
226
20
      char c = Code[Length];
227
20
      if (c == '-' || 
c == '+'19
||
c == '.'18
||
isHexDigit(c)14
) {
228
16
        isFloatingLiteral = true;
229
16
        Length++;
230
4
      } else {
231
4
        break;
232
4
      }
233
20
    }
234
235
15
    Result->Text = Code.substr(0, Length);
236
15
    Code = Code.drop_front(Length);
237
238
15
    if (isFloatingLiteral) {
239
4
      char *end;
240
4
      errno = 0;
241
4
      std::string Text = Result->Text.str();
242
4
      double doubleValue = strtod(Text.c_str(), &end);
243
4
      if (*end == 0 && errno
== 03
) {
244
3
        Result->Kind = TokenInfo::TK_Literal;
245
3
        Result->Value = doubleValue;
246
3
        return;
247
3
      }
248
11
    } else {
249
11
      unsigned Value;
250
11
      if (!Result->Text.getAsInteger(0, Value)) {
251
9
        Result->Kind = TokenInfo::TK_Literal;
252
9
        Result->Value = Value;
253
9
        return;
254
9
      }
255
3
    }
256
257
3
    SourceRange Range;
258
3
    Range.Start = Result->Range.Start;
259
3
    Range.End = currentLocation();
260
3
    Error->addError(Range, Error->ET_ParserNumberError) << Result->Text;
261
3
    Result->Kind = TokenInfo::TK_Error;
262
3
  }
263
264
  /// Consume a string literal.
265
  ///
266
  /// \c Code must be positioned at the start of the literal (the opening
267
  /// quote). Consumed until it finds the same closing quote character.
268
37
  void consumeStringLiteral(TokenInfo *Result) {
269
37
    bool InEscape = false;
270
37
    const char Marker = Code[0];
271
307
    for (size_t Length = 1, Size = Code.size(); Length != Size; 
++Length270
) {
272
306
      if (InEscape) {
273
0
        InEscape = false;
274
0
        continue;
275
0
      }
276
306
      if (Code[Length] == '\\') {
277
0
        InEscape = true;
278
0
        continue;
279
0
      }
280
306
      if (Code[Length] == Marker) {
281
36
        Result->Kind = TokenInfo::TK_Literal;
282
36
        Result->Text = Code.substr(0, Length + 1);
283
36
        Result->Value = Code.substr(1, Length - 1);
284
36
        Code = Code.drop_front(Length + 1);
285
36
        return;
286
36
      }
287
306
    }
288
289
1
    StringRef ErrorText = Code;
290
1
    Code = Code.drop_front(Code.size());
291
1
    SourceRange Range;
292
1
    Range.Start = Result->Range.Start;
293
1
    Range.End = currentLocation();
294
1
    Error->addError(Range, Error->ET_ParserStringError) << ErrorText;
295
1
    Result->Kind = TokenInfo::TK_Error;
296
1
  }
297
298
  /// Consume all leading whitespace from \c Code.
299
424
  void consumeWhitespace() {
300
466
    Code = Code.drop_while([](char c) {
301
      // Don't trim newlines.
302
466
      return StringRef(" \t\v\f\r").contains(c);
303
466
    });
304
424
  }
305
306
796
  SourceLocation currentLocation() {
307
796
    SourceLocation Location;
308
796
    Location.Line = Line;
309
796
    Location.Column = Code.data() - StartOfLine.data() + 1;
310
796
    return Location;
311
796
  }
312
313
  StringRef &Code;
314
  StringRef StartOfLine;
315
  unsigned Line = 1;
316
  Diagnostics *Error;
317
  TokenInfo NextToken;
318
  const char *CodeCompletionLocation = nullptr;
319
};
320
321
6
Parser::Sema::~Sema() = default;
322
323
std::vector<ArgKind> Parser::Sema::getAcceptedCompletionTypes(
324
0
    llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
325
0
  return {};
326
0
}
327
328
std::vector<MatcherCompletion>
329
0
Parser::Sema::getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) {
330
0
  return {};
331
0
}
332
333
struct Parser::ScopedContextEntry {
334
  Parser *P;
335
336
77
  ScopedContextEntry(Parser *P, MatcherCtor C) : P(P) {
337
77
    P->ContextStack.push_back(std::make_pair(C, 0u));
338
77
  }
339
340
77
  ~ScopedContextEntry() {
341
77
    P->ContextStack.pop_back();
342
77
  }
343
344
56
  void nextArg() {
345
56
    ++P->ContextStack.back().second;
346
56
  }
347
};
348
349
/// Parse expressions that start with an identifier.
350
///
351
/// This function can parse named values and matchers.
352
/// In case of failure it will try to determine the user's intent to give
353
/// an appropriate error message.
354
87
bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
355
87
  const TokenInfo NameToken = Tokenizer->consumeNextToken();
356
357
87
  if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
358
    // Parse as a named value.
359
10
    if (const VariantValue NamedValue =
360
7
            NamedValues ? NamedValues->lookup(NameToken.Text)
361
7
                        : VariantValue()) {
362
363
7
      if (Tokenizer->nextTokenKind() != TokenInfo::TK_Period) {
364
3
        *Value = NamedValue;
365
3
        return true;
366
3
      }
367
368
4
      std::string BindID;
369
4
      if (!parseBindID(BindID))
370
2
        return false;
371
372
2
      assert(NamedValue.isMatcher());
373
2
      llvm::Optional<DynTypedMatcher> Result =
374
2
          NamedValue.getMatcher().getSingleMatcher();
375
2
      if (Result.hasValue()) {
376
2
        llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
377
2
        if (Bound.hasValue()) {
378
2
          *Value = VariantMatcher::SingleMatcher(*Bound);
379
2
          return true;
380
2
        }
381
0
      }
382
0
      return false;
383
0
    }
384
385
3
    if (Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine) {
386
1
      Error->addError(Tokenizer->peekNextToken().Range,
387
1
                      Error->ET_ParserNoOpenParen)
388
1
          << "NewLine";
389
1
      return false;
390
1
    }
391
392
    // If the syntax is correct and the name is not a matcher either, report
393
    // unknown named value.
394
2
    if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma ||
395
2
         Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen ||
396
1
         Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine ||
397
1
         Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) &&
398
1
        !S->lookupMatcherCtor(NameToken.Text)) {
399
1
      Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound)
400
1
          << NameToken.Text;
401
1
      return false;
402
1
    }
403
    // Otherwise, fallback to the matcher parser.
404
2
  }
405
406
78
  Tokenizer->SkipNewlines();
407
408
  // Parse as a matcher expression.
409
78
  return parseMatcherExpressionImpl(NameToken, Value);
410
78
}
411
412
13
bool Parser::parseBindID(std::string &BindID) {
413
  // Parse .bind("foo")
414
13
  assert(Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period);
415
13
  Tokenizer->consumeNextToken(); // consume the period.
416
13
  const TokenInfo BindToken = Tokenizer->consumeNextToken();
417
13
  if (BindToken.Kind == TokenInfo::TK_CodeCompletion) {
418
1
    addCompletion(BindToken, MatcherCompletion("bind(\"", "bind", 1));
419
1
    return false;
420
1
  }
421
422
12
  const TokenInfo OpenToken = Tokenizer->consumeNextToken();
423
12
  const TokenInfo IDToken = Tokenizer->consumeNextTokenIgnoreNewlines();
424
12
  const TokenInfo CloseToken = Tokenizer->consumeNextTokenIgnoreNewlines();
425
426
  // TODO: We could use different error codes for each/some to be more
427
  //       explicit about the syntax error.
428
12
  if (BindToken.Kind != TokenInfo::TK_Ident ||
429
11
      BindToken.Text != TokenInfo::ID_Bind) {
430
2
    Error->addError(BindToken.Range, Error->ET_ParserMalformedBindExpr);
431
2
    return false;
432
2
  }
433
10
  if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
434
2
    Error->addError(OpenToken.Range, Error->ET_ParserMalformedBindExpr);
435
2
    return false;
436
2
  }
437
8
  if (IDToken.Kind != TokenInfo::TK_Literal || 
!IDToken.Value.isString()7
) {
438
1
    Error->addError(IDToken.Range, Error->ET_ParserMalformedBindExpr);
439
1
    return false;
440
1
  }
441
7
  if (CloseToken.Kind != TokenInfo::TK_CloseParen) {
442
1
    Error->addError(CloseToken.Range, Error->ET_ParserMalformedBindExpr);
443
1
    return false;
444
1
  }
445
6
  BindID = IDToken.Value.getString();
446
6
  return true;
447
6
}
448
449
/// Parse and validate a matcher expression.
450
/// \return \c true on success, in which case \c Value has the matcher parsed.
451
///   If the input is malformed, or some argument has an error, it
452
///   returns \c false.
453
bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
454
78
                                        VariantValue *Value) {
455
78
  assert(NameToken.Kind == TokenInfo::TK_Ident);
456
78
  const TokenInfo OpenToken = Tokenizer->consumeNextToken();
457
78
  if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
458
1
    Error->addError(OpenToken.Range, Error->ET_ParserNoOpenParen)
459
1
        << OpenToken.Text;
460
1
    return false;
461
1
  }
462
463
77
  llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text);
464
465
77
  if (!Ctor) {
466
4
    Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound)
467
4
        << NameToken.Text;
468
    // Do not return here. We need to continue to give completion suggestions.
469
4
  }
470
471
77
  std::vector<ParserValue> Args;
472
77
  TokenInfo EndToken;
473
474
77
  Tokenizer->SkipNewlines();
475
476
77
  {
477
73
    ScopedContextEntry SCE(this, Ctor ? *Ctor : 
nullptr4
);
478
479
133
    while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
480
131
      if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
481
        // End of args.
482
59
        EndToken = Tokenizer->consumeNextToken();
483
59
        break;
484
59
      }
485
72
      if (!Args.empty()) {
486
        // We must find a , token to continue.
487
14
        const TokenInfo CommaToken = Tokenizer->consumeNextToken();
488
14
        if (CommaToken.Kind != TokenInfo::TK_Comma) {
489
1
          Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
490
1
              << CommaToken.Text;
491
1
          return false;
492
1
        }
493
71
      }
494
495
71
      Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
496
71
                               NameToken.Text, NameToken.Range,
497
71
                               Args.size() + 1);
498
71
      ParserValue ArgValue;
499
71
      Tokenizer->SkipNewlines();
500
71
      ArgValue.Text = Tokenizer->peekNextToken().Text;
501
71
      ArgValue.Range = Tokenizer->peekNextToken().Range;
502
71
      if (!parseExpressionImpl(&ArgValue.Value)) {
503
15
        return false;
504
15
      }
505
506
56
      Tokenizer->SkipNewlines();
507
56
      Args.push_back(ArgValue);
508
56
      SCE.nextArg();
509
56
    }
510
77
  }
511
512
61
  if (EndToken.Kind == TokenInfo::TK_Eof) {
513
2
    Error->addError(OpenToken.Range, Error->ET_ParserNoCloseParen);
514
2
    return false;
515
2
  }
516
517
59
  std::string BindID;
518
59
  if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period) {
519
9
    if (!parseBindID(BindID))
520
5
      return false;
521
54
  }
522
523
54
  if (!Ctor)
524
1
    return false;
525
526
  // Merge the start and end infos.
527
53
  Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
528
53
                           NameToken.Text, NameToken.Range);
529
53
  SourceRange MatcherRange = NameToken.Range;
530
53
  MatcherRange.End = EndToken.Range.End;
531
53
  VariantMatcher Result = S->actOnMatcherExpression(
532
53
      *Ctor, MatcherRange, BindID, Args, Error);
533
53
  if (Result.isNull()) 
return false9
;
534
535
44
  *Value = Result;
536
44
  return true;
537
44
}
538
539
// If the prefix of this completion matches the completion token, add it to
540
// Completions minus the prefix.
541
void Parser::addCompletion(const TokenInfo &CompToken,
542
371
                           const MatcherCompletion& Completion) {
543
371
  if (StringRef(Completion.TypedText).startswith(CompToken.Text) &&
544
79
      Completion.Specificity > 0) {
545
79
    Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
546
79
                             Completion.MatcherDecl, Completion.Specificity);
547
79
  }
548
371
}
549
550
std::vector<MatcherCompletion> Parser::getNamedValueCompletions(
551
4
    ArrayRef<ArgKind> AcceptedTypes) {
552
4
  if (!NamedValues) 
return std::vector<MatcherCompletion>()1
;
553
3
  std::vector<MatcherCompletion> Result;
554
6
  for (const auto &Entry : *NamedValues) {
555
6
    unsigned Specificity;
556
6
    if (Entry.getValue().isConvertibleTo(AcceptedTypes, &Specificity)) {
557
3
      std::string Decl =
558
3
          (Entry.getValue().getTypeAsString() + " " + Entry.getKey()).str();
559
3
      Result.emplace_back(Entry.getKey(), Decl, Specificity);
560
3
    }
561
6
  }
562
3
  return Result;
563
3
}
564
565
4
void Parser::addExpressionCompletions() {
566
4
  const TokenInfo CompToken = Tokenizer->consumeNextTokenIgnoreNewlines();
567
4
  assert(CompToken.Kind == TokenInfo::TK_CodeCompletion);
568
569
  // We cannot complete code if there is an invalid element on the context
570
  // stack.
571
4
  for (ContextStackTy::iterator I = ContextStack.begin(),
572
4
                                E = ContextStack.end();
573
8
       I != E; 
++I4
) {
574
4
    if (!I->first)
575
0
      return;
576
4
  }
577
578
4
  auto AcceptedTypes = S->getAcceptedCompletionTypes(ContextStack);
579
367
  for (const auto &Completion : S->getMatcherCompletions(AcceptedTypes)) {
580
367
    addCompletion(CompToken, Completion);
581
367
  }
582
583
3
  for (const auto &Completion : getNamedValueCompletions(AcceptedTypes)) {
584
3
    addCompletion(CompToken, Completion);
585
3
  }
586
4
}
587
588
/// Parse an <Expression>
589
136
bool Parser::parseExpressionImpl(VariantValue *Value) {
590
136
  switch (Tokenizer->nextTokenKind()) {
591
39
  case TokenInfo::TK_Literal:
592
39
    *Value = Tokenizer->consumeNextToken().Value;
593
39
    return true;
594
595
87
  case TokenInfo::TK_Ident:
596
87
    return parseIdentifierPrefixImpl(Value);
597
598
4
  case TokenInfo::TK_CodeCompletion:
599
4
    addExpressionCompletions();
600
4
    return false;
601
602
1
  case TokenInfo::TK_Eof:
603
1
    Error->addError(Tokenizer->consumeNextToken().Range,
604
1
                    Error->ET_ParserNoCode);
605
1
    return false;
606
607
4
  case TokenInfo::TK_Error:
608
    // This error was already reported by the tokenizer.
609
4
    return false;
610
1
  case TokenInfo::TK_NewLine:
611
1
  case TokenInfo::TK_OpenParen:
612
1
  case TokenInfo::TK_CloseParen:
613
1
  case TokenInfo::TK_Comma:
614
1
  case TokenInfo::TK_Period:
615
1
  case TokenInfo::TK_InvalidChar:
616
1
    const TokenInfo Token = Tokenizer->consumeNextToken();
617
1
    Error->addError(Token.Range, Error->ET_ParserInvalidToken)
618
1
        << (Token.Kind == TokenInfo::TK_NewLine ? 
"NewLine"0
: Token.Text);
619
1
    return false;
620
0
  }
621
622
0
  llvm_unreachable("Unknown token kind.");
623
0
}
624
625
static llvm::ManagedStatic<Parser::RegistrySema> DefaultRegistrySema;
626
627
Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
628
               const NamedValueMap *NamedValues, Diagnostics *Error)
629
    : Tokenizer(Tokenizer), S(S ? S : &*DefaultRegistrySema),
630
65
      NamedValues(NamedValues), Error(Error) {}
631
632
0
Parser::RegistrySema::~RegistrySema() = default;
633
634
llvm::Optional<MatcherCtor>
635
73
Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
636
73
  return Registry::lookupMatcherCtor(MatcherName);
637
73
}
638
639
VariantMatcher Parser::RegistrySema::actOnMatcherExpression(
640
    MatcherCtor Ctor, SourceRange NameRange, StringRef BindID,
641
49
    ArrayRef<ParserValue> Args, Diagnostics *Error) {
642
49
  if (BindID.empty()) {
643
46
    return Registry::constructMatcher(Ctor, NameRange, Args, Error);
644
3
  } else {
645
3
    return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
646
3
                                           Error);
647
3
  }
648
49
}
649
650
std::vector<ArgKind> Parser::RegistrySema::getAcceptedCompletionTypes(
651
4
    ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
652
4
  return Registry::getAcceptedCompletionTypes(Context);
653
4
}
654
655
std::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions(
656
4
    ArrayRef<ArgKind> AcceptedTypes) {
657
4
  return Registry::getMatcherCompletions(AcceptedTypes);
658
4
}
659
660
bool Parser::parseExpression(StringRef &Code, Sema *S,
661
                             const NamedValueMap *NamedValues,
662
60
                             VariantValue *Value, Diagnostics *Error) {
663
60
  CodeTokenizer Tokenizer(Code, Error);
664
60
  if (!Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(Value))
665
28
    return false;
666
32
  auto NT = Tokenizer.peekNextToken();
667
32
  if (NT.Kind != TokenInfo::TK_Eof && 
NT.Kind != TokenInfo::TK_NewLine5
) {
668
1
    Error->addError(Tokenizer.peekNextToken().Range,
669
1
                    Error->ET_ParserTrailingCode);
670
1
    return false;
671
1
  }
672
31
  return true;
673
31
}
674
675
std::vector<MatcherCompletion>
676
Parser::completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S,
677
5
                           const NamedValueMap *NamedValues) {
678
5
  Diagnostics Error;
679
5
  CodeTokenizer Tokenizer(Code, &Error, CompletionOffset);
680
5
  Parser P(&Tokenizer, S, NamedValues, &Error);
681
5
  VariantValue Dummy;
682
5
  P.parseExpressionImpl(&Dummy);
683
684
  // Sort by specificity, then by name.
685
5
  llvm::sort(P.Completions,
686
464
             [](const MatcherCompletion &A, const MatcherCompletion &B) {
687
464
               if (A.Specificity != B.Specificity)
688
183
                 return A.Specificity > B.Specificity;
689
281
               return A.TypedText < B.TypedText;
690
281
             });
691
692
5
  return P.Completions;
693
5
}
694
695
llvm::Optional<DynTypedMatcher>
696
Parser::parseMatcherExpression(StringRef &Code, Sema *S,
697
                               const NamedValueMap *NamedValues,
698
29
                               Diagnostics *Error) {
699
29
  VariantValue Value;
700
29
  if (!parseExpression(Code, S, NamedValues, &Value, Error))
701
11
    return llvm::Optional<DynTypedMatcher>();
702
18
  if (!Value.isMatcher()) {
703
1
    Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
704
1
    return llvm::Optional<DynTypedMatcher>();
705
1
  }
706
17
  llvm::Optional<DynTypedMatcher> Result =
707
17
      Value.getMatcher().getSingleMatcher();
708
17
  if (!Result.hasValue()) {
709
1
    Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
710
1
        << Value.getTypeAsString();
711
1
  }
712
17
  return Result;
713
17
}
714
715
} // namespace dynamic
716
} // namespace ast_matchers
717
} // namespace clang