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