xref: /freebsd/contrib/llvm-project/clang/lib/ASTMatchers/Dynamic/Parser.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===- Parser.cpp - Matcher expression parser -----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Recursive parser implementation for the matcher expression grammar.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/ASTMatchers/Dynamic/Parser.h"
150b57cec5SDimitry Andric #include "clang/ASTMatchers/ASTMatchersInternal.h"
160b57cec5SDimitry Andric #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
170b57cec5SDimitry Andric #include "clang/ASTMatchers/Dynamic/Registry.h"
180b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
190b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
220b57cec5SDimitry Andric #include "llvm/Support/ManagedStatic.h"
230b57cec5SDimitry Andric #include <algorithm>
240b57cec5SDimitry Andric #include <cassert>
250b57cec5SDimitry Andric #include <cerrno>
260b57cec5SDimitry Andric #include <cstddef>
270b57cec5SDimitry Andric #include <cstdlib>
280b57cec5SDimitry Andric #include <string>
290b57cec5SDimitry Andric #include <utility>
300b57cec5SDimitry Andric #include <vector>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric namespace clang {
330b57cec5SDimitry Andric namespace ast_matchers {
340b57cec5SDimitry Andric namespace dynamic {
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric /// Simple structure to hold information for one token from the parser.
370b57cec5SDimitry Andric struct Parser::TokenInfo {
380b57cec5SDimitry Andric   /// Different possible tokens.
390b57cec5SDimitry Andric   enum TokenKind {
400b57cec5SDimitry Andric     TK_Eof,
41480093f4SDimitry Andric     TK_NewLine,
420b57cec5SDimitry Andric     TK_OpenParen,
430b57cec5SDimitry Andric     TK_CloseParen,
440b57cec5SDimitry Andric     TK_Comma,
450b57cec5SDimitry Andric     TK_Period,
460b57cec5SDimitry Andric     TK_Literal,
470b57cec5SDimitry Andric     TK_Ident,
480b57cec5SDimitry Andric     TK_InvalidChar,
490b57cec5SDimitry Andric     TK_Error,
500b57cec5SDimitry Andric     TK_CodeCompletion
510b57cec5SDimitry Andric   };
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   /// Some known identifiers.
540b57cec5SDimitry Andric   static const char* const ID_Bind;
55*fe6060f1SDimitry Andric   static const char *const ID_With;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   TokenInfo() = default;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric   StringRef Text;
600b57cec5SDimitry Andric   TokenKind Kind = TK_Eof;
610b57cec5SDimitry Andric   SourceRange Range;
620b57cec5SDimitry Andric   VariantValue Value;
630b57cec5SDimitry Andric };
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric const char* const Parser::TokenInfo::ID_Bind = "bind";
66*fe6060f1SDimitry Andric const char *const Parser::TokenInfo::ID_With = "with";
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric /// Simple tokenizer for the parser.
690b57cec5SDimitry Andric class Parser::CodeTokenizer {
700b57cec5SDimitry Andric public:
71480093f4SDimitry Andric   explicit CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error)
720b57cec5SDimitry Andric       : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) {
730b57cec5SDimitry Andric     NextToken = getNextToken();
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
76480093f4SDimitry Andric   CodeTokenizer(StringRef &MatcherCode, Diagnostics *Error,
770b57cec5SDimitry Andric                 unsigned CodeCompletionOffset)
780b57cec5SDimitry Andric       : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error),
790b57cec5SDimitry Andric         CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
800b57cec5SDimitry Andric     NextToken = getNextToken();
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   /// Returns but doesn't consume the next token.
840b57cec5SDimitry Andric   const TokenInfo &peekNextToken() const { return NextToken; }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   /// Consumes and returns the next token.
870b57cec5SDimitry Andric   TokenInfo consumeNextToken() {
880b57cec5SDimitry Andric     TokenInfo ThisToken = NextToken;
890b57cec5SDimitry Andric     NextToken = getNextToken();
900b57cec5SDimitry Andric     return ThisToken;
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
93480093f4SDimitry Andric   TokenInfo SkipNewlines() {
94480093f4SDimitry Andric     while (NextToken.Kind == TokenInfo::TK_NewLine)
95480093f4SDimitry Andric       NextToken = getNextToken();
96480093f4SDimitry Andric     return NextToken;
97480093f4SDimitry Andric   }
98480093f4SDimitry Andric 
99480093f4SDimitry Andric   TokenInfo consumeNextTokenIgnoreNewlines() {
100480093f4SDimitry Andric     SkipNewlines();
101480093f4SDimitry Andric     if (NextToken.Kind == TokenInfo::TK_Eof)
102480093f4SDimitry Andric       return NextToken;
103480093f4SDimitry Andric     return consumeNextToken();
104480093f4SDimitry Andric   }
105480093f4SDimitry Andric 
1060b57cec5SDimitry Andric   TokenInfo::TokenKind nextTokenKind() const { return NextToken.Kind; }
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric private:
1090b57cec5SDimitry Andric   TokenInfo getNextToken() {
1100b57cec5SDimitry Andric     consumeWhitespace();
1110b57cec5SDimitry Andric     TokenInfo Result;
1120b57cec5SDimitry Andric     Result.Range.Start = currentLocation();
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric     if (CodeCompletionLocation && CodeCompletionLocation <= Code.data()) {
1150b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_CodeCompletion;
1160b57cec5SDimitry Andric       Result.Text = StringRef(CodeCompletionLocation, 0);
1170b57cec5SDimitry Andric       CodeCompletionLocation = nullptr;
1180b57cec5SDimitry Andric       return Result;
1190b57cec5SDimitry Andric     }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric     if (Code.empty()) {
1220b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_Eof;
1230b57cec5SDimitry Andric       Result.Text = "";
1240b57cec5SDimitry Andric       return Result;
1250b57cec5SDimitry Andric     }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric     switch (Code[0]) {
1280b57cec5SDimitry Andric     case '#':
129480093f4SDimitry Andric       Code = Code.drop_until([](char c) { return c == '\n'; });
130480093f4SDimitry Andric       return getNextToken();
1310b57cec5SDimitry Andric     case ',':
1320b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_Comma;
1330b57cec5SDimitry Andric       Result.Text = Code.substr(0, 1);
1340b57cec5SDimitry Andric       Code = Code.drop_front();
1350b57cec5SDimitry Andric       break;
1360b57cec5SDimitry Andric     case '.':
1370b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_Period;
1380b57cec5SDimitry Andric       Result.Text = Code.substr(0, 1);
1390b57cec5SDimitry Andric       Code = Code.drop_front();
1400b57cec5SDimitry Andric       break;
141480093f4SDimitry Andric     case '\n':
142480093f4SDimitry Andric       ++Line;
143480093f4SDimitry Andric       StartOfLine = Code.drop_front();
144480093f4SDimitry Andric       Result.Kind = TokenInfo::TK_NewLine;
145480093f4SDimitry Andric       Result.Text = Code.substr(0, 1);
146480093f4SDimitry Andric       Code = Code.drop_front();
147480093f4SDimitry Andric       break;
1480b57cec5SDimitry Andric     case '(':
1490b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_OpenParen;
1500b57cec5SDimitry Andric       Result.Text = Code.substr(0, 1);
1510b57cec5SDimitry Andric       Code = Code.drop_front();
1520b57cec5SDimitry Andric       break;
1530b57cec5SDimitry Andric     case ')':
1540b57cec5SDimitry Andric       Result.Kind = TokenInfo::TK_CloseParen;
1550b57cec5SDimitry Andric       Result.Text = Code.substr(0, 1);
1560b57cec5SDimitry Andric       Code = Code.drop_front();
1570b57cec5SDimitry Andric       break;
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric     case '"':
1600b57cec5SDimitry Andric     case '\'':
1610b57cec5SDimitry Andric       // Parse a string literal.
1620b57cec5SDimitry Andric       consumeStringLiteral(&Result);
1630b57cec5SDimitry Andric       break;
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric     case '0': case '1': case '2': case '3': case '4':
1660b57cec5SDimitry Andric     case '5': case '6': case '7': case '8': case '9':
1670b57cec5SDimitry Andric       // Parse an unsigned and float literal.
1680b57cec5SDimitry Andric       consumeNumberLiteral(&Result);
1690b57cec5SDimitry Andric       break;
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric     default:
1720b57cec5SDimitry Andric       if (isAlphanumeric(Code[0])) {
1730b57cec5SDimitry Andric         // Parse an identifier
1740b57cec5SDimitry Andric         size_t TokenLength = 1;
1750b57cec5SDimitry Andric         while (true) {
1760b57cec5SDimitry Andric           // A code completion location in/immediately after an identifier will
1770b57cec5SDimitry Andric           // cause the portion of the identifier before the code completion
1780b57cec5SDimitry Andric           // location to become a code completion token.
1790b57cec5SDimitry Andric           if (CodeCompletionLocation == Code.data() + TokenLength) {
1800b57cec5SDimitry Andric             CodeCompletionLocation = nullptr;
1810b57cec5SDimitry Andric             Result.Kind = TokenInfo::TK_CodeCompletion;
1820b57cec5SDimitry Andric             Result.Text = Code.substr(0, TokenLength);
1830b57cec5SDimitry Andric             Code = Code.drop_front(TokenLength);
1840b57cec5SDimitry Andric             return Result;
1850b57cec5SDimitry Andric           }
1860b57cec5SDimitry Andric           if (TokenLength == Code.size() || !isAlphanumeric(Code[TokenLength]))
1870b57cec5SDimitry Andric             break;
1880b57cec5SDimitry Andric           ++TokenLength;
1890b57cec5SDimitry Andric         }
1900b57cec5SDimitry Andric         if (TokenLength == 4 && Code.startswith("true")) {
1910b57cec5SDimitry Andric           Result.Kind = TokenInfo::TK_Literal;
1920b57cec5SDimitry Andric           Result.Value = true;
1930b57cec5SDimitry Andric         } else if (TokenLength == 5 && Code.startswith("false")) {
1940b57cec5SDimitry Andric           Result.Kind = TokenInfo::TK_Literal;
1950b57cec5SDimitry Andric           Result.Value = false;
1960b57cec5SDimitry Andric         } else {
1970b57cec5SDimitry Andric           Result.Kind = TokenInfo::TK_Ident;
1980b57cec5SDimitry Andric           Result.Text = Code.substr(0, TokenLength);
1990b57cec5SDimitry Andric         }
2000b57cec5SDimitry Andric         Code = Code.drop_front(TokenLength);
2010b57cec5SDimitry Andric       } else {
2020b57cec5SDimitry Andric         Result.Kind = TokenInfo::TK_InvalidChar;
2030b57cec5SDimitry Andric         Result.Text = Code.substr(0, 1);
2040b57cec5SDimitry Andric         Code = Code.drop_front(1);
2050b57cec5SDimitry Andric       }
2060b57cec5SDimitry Andric       break;
2070b57cec5SDimitry Andric     }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric     Result.Range.End = currentLocation();
2100b57cec5SDimitry Andric     return Result;
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   /// Consume an unsigned and float literal.
2140b57cec5SDimitry Andric   void consumeNumberLiteral(TokenInfo *Result) {
2150b57cec5SDimitry Andric     bool isFloatingLiteral = false;
2160b57cec5SDimitry Andric     unsigned Length = 1;
2170b57cec5SDimitry Andric     if (Code.size() > 1) {
2180b57cec5SDimitry Andric       // Consume the 'x' or 'b' radix modifier, if present.
2190b57cec5SDimitry Andric       switch (toLowercase(Code[1])) {
2200b57cec5SDimitry Andric       case 'x': case 'b': Length = 2;
2210b57cec5SDimitry Andric       }
2220b57cec5SDimitry Andric     }
2230b57cec5SDimitry Andric     while (Length < Code.size() && isHexDigit(Code[Length]))
2240b57cec5SDimitry Andric       ++Length;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric     // Try to recognize a floating point literal.
2270b57cec5SDimitry Andric     while (Length < Code.size()) {
2280b57cec5SDimitry Andric       char c = Code[Length];
2290b57cec5SDimitry Andric       if (c == '-' || c == '+' || c == '.' || isHexDigit(c)) {
2300b57cec5SDimitry Andric         isFloatingLiteral = true;
2310b57cec5SDimitry Andric         Length++;
2320b57cec5SDimitry Andric       } else {
2330b57cec5SDimitry Andric         break;
2340b57cec5SDimitry Andric       }
2350b57cec5SDimitry Andric     }
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric     Result->Text = Code.substr(0, Length);
2380b57cec5SDimitry Andric     Code = Code.drop_front(Length);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric     if (isFloatingLiteral) {
2410b57cec5SDimitry Andric       char *end;
2420b57cec5SDimitry Andric       errno = 0;
2430b57cec5SDimitry Andric       std::string Text = Result->Text.str();
2440b57cec5SDimitry Andric       double doubleValue = strtod(Text.c_str(), &end);
2450b57cec5SDimitry Andric       if (*end == 0 && errno == 0) {
2460b57cec5SDimitry Andric         Result->Kind = TokenInfo::TK_Literal;
2470b57cec5SDimitry Andric         Result->Value = doubleValue;
2480b57cec5SDimitry Andric         return;
2490b57cec5SDimitry Andric       }
2500b57cec5SDimitry Andric     } else {
2510b57cec5SDimitry Andric       unsigned Value;
2520b57cec5SDimitry Andric       if (!Result->Text.getAsInteger(0, Value)) {
2530b57cec5SDimitry Andric         Result->Kind = TokenInfo::TK_Literal;
2540b57cec5SDimitry Andric         Result->Value = Value;
2550b57cec5SDimitry Andric         return;
2560b57cec5SDimitry Andric       }
2570b57cec5SDimitry Andric     }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric     SourceRange Range;
2600b57cec5SDimitry Andric     Range.Start = Result->Range.Start;
2610b57cec5SDimitry Andric     Range.End = currentLocation();
2620b57cec5SDimitry Andric     Error->addError(Range, Error->ET_ParserNumberError) << Result->Text;
2630b57cec5SDimitry Andric     Result->Kind = TokenInfo::TK_Error;
2640b57cec5SDimitry Andric   }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   /// Consume a string literal.
2670b57cec5SDimitry Andric   ///
2680b57cec5SDimitry Andric   /// \c Code must be positioned at the start of the literal (the opening
2690b57cec5SDimitry Andric   /// quote). Consumed until it finds the same closing quote character.
2700b57cec5SDimitry Andric   void consumeStringLiteral(TokenInfo *Result) {
2710b57cec5SDimitry Andric     bool InEscape = false;
2720b57cec5SDimitry Andric     const char Marker = Code[0];
2730b57cec5SDimitry Andric     for (size_t Length = 1, Size = Code.size(); Length != Size; ++Length) {
2740b57cec5SDimitry Andric       if (InEscape) {
2750b57cec5SDimitry Andric         InEscape = false;
2760b57cec5SDimitry Andric         continue;
2770b57cec5SDimitry Andric       }
2780b57cec5SDimitry Andric       if (Code[Length] == '\\') {
2790b57cec5SDimitry Andric         InEscape = true;
2800b57cec5SDimitry Andric         continue;
2810b57cec5SDimitry Andric       }
2820b57cec5SDimitry Andric       if (Code[Length] == Marker) {
2830b57cec5SDimitry Andric         Result->Kind = TokenInfo::TK_Literal;
2840b57cec5SDimitry Andric         Result->Text = Code.substr(0, Length + 1);
2850b57cec5SDimitry Andric         Result->Value = Code.substr(1, Length - 1);
2860b57cec5SDimitry Andric         Code = Code.drop_front(Length + 1);
2870b57cec5SDimitry Andric         return;
2880b57cec5SDimitry Andric       }
2890b57cec5SDimitry Andric     }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric     StringRef ErrorText = Code;
2920b57cec5SDimitry Andric     Code = Code.drop_front(Code.size());
2930b57cec5SDimitry Andric     SourceRange Range;
2940b57cec5SDimitry Andric     Range.Start = Result->Range.Start;
2950b57cec5SDimitry Andric     Range.End = currentLocation();
2960b57cec5SDimitry Andric     Error->addError(Range, Error->ET_ParserStringError) << ErrorText;
2970b57cec5SDimitry Andric     Result->Kind = TokenInfo::TK_Error;
2980b57cec5SDimitry Andric   }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   /// Consume all leading whitespace from \c Code.
3010b57cec5SDimitry Andric   void consumeWhitespace() {
302480093f4SDimitry Andric     Code = Code.drop_while([](char c) {
303480093f4SDimitry Andric       // Don't trim newlines.
304480093f4SDimitry Andric       return StringRef(" \t\v\f\r").contains(c);
305480093f4SDimitry Andric     });
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   SourceLocation currentLocation() {
3090b57cec5SDimitry Andric     SourceLocation Location;
3100b57cec5SDimitry Andric     Location.Line = Line;
3110b57cec5SDimitry Andric     Location.Column = Code.data() - StartOfLine.data() + 1;
3120b57cec5SDimitry Andric     return Location;
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
315480093f4SDimitry Andric   StringRef &Code;
3160b57cec5SDimitry Andric   StringRef StartOfLine;
3170b57cec5SDimitry Andric   unsigned Line = 1;
3180b57cec5SDimitry Andric   Diagnostics *Error;
3190b57cec5SDimitry Andric   TokenInfo NextToken;
3200b57cec5SDimitry Andric   const char *CodeCompletionLocation = nullptr;
3210b57cec5SDimitry Andric };
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric Parser::Sema::~Sema() = default;
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric std::vector<ArgKind> Parser::Sema::getAcceptedCompletionTypes(
3260b57cec5SDimitry Andric     llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
3270b57cec5SDimitry Andric   return {};
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric std::vector<MatcherCompletion>
3310b57cec5SDimitry Andric Parser::Sema::getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) {
3320b57cec5SDimitry Andric   return {};
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric struct Parser::ScopedContextEntry {
3360b57cec5SDimitry Andric   Parser *P;
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   ScopedContextEntry(Parser *P, MatcherCtor C) : P(P) {
3390b57cec5SDimitry Andric     P->ContextStack.push_back(std::make_pair(C, 0u));
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   ~ScopedContextEntry() {
3430b57cec5SDimitry Andric     P->ContextStack.pop_back();
3440b57cec5SDimitry Andric   }
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   void nextArg() {
3470b57cec5SDimitry Andric     ++P->ContextStack.back().second;
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric };
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric /// Parse expressions that start with an identifier.
3520b57cec5SDimitry Andric ///
3530b57cec5SDimitry Andric /// This function can parse named values and matchers.
3540b57cec5SDimitry Andric /// In case of failure it will try to determine the user's intent to give
3550b57cec5SDimitry Andric /// an appropriate error message.
3560b57cec5SDimitry Andric bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
3570b57cec5SDimitry Andric   const TokenInfo NameToken = Tokenizer->consumeNextToken();
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
3600b57cec5SDimitry Andric     // Parse as a named value.
3610b57cec5SDimitry Andric     if (const VariantValue NamedValue =
3620b57cec5SDimitry Andric             NamedValues ? NamedValues->lookup(NameToken.Text)
3630b57cec5SDimitry Andric                         : VariantValue()) {
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric       if (Tokenizer->nextTokenKind() != TokenInfo::TK_Period) {
3660b57cec5SDimitry Andric         *Value = NamedValue;
3670b57cec5SDimitry Andric         return true;
3680b57cec5SDimitry Andric       }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric       std::string BindID;
371*fe6060f1SDimitry Andric       Tokenizer->consumeNextToken();
372*fe6060f1SDimitry Andric       TokenInfo ChainCallToken = Tokenizer->consumeNextToken();
373*fe6060f1SDimitry Andric       if (ChainCallToken.Kind == TokenInfo::TK_CodeCompletion) {
374*fe6060f1SDimitry Andric         addCompletion(ChainCallToken, MatcherCompletion("bind(\"", "bind", 1));
375*fe6060f1SDimitry Andric         return false;
376*fe6060f1SDimitry Andric       }
377*fe6060f1SDimitry Andric 
378*fe6060f1SDimitry Andric       if (ChainCallToken.Kind != TokenInfo::TK_Ident ||
379*fe6060f1SDimitry Andric           (ChainCallToken.Text != TokenInfo::ID_Bind &&
380*fe6060f1SDimitry Andric            ChainCallToken.Text != TokenInfo::ID_With)) {
381*fe6060f1SDimitry Andric         Error->addError(ChainCallToken.Range,
382*fe6060f1SDimitry Andric                         Error->ET_ParserMalformedChainedExpr);
383*fe6060f1SDimitry Andric         return false;
384*fe6060f1SDimitry Andric       }
385*fe6060f1SDimitry Andric       if (ChainCallToken.Text == TokenInfo::ID_With) {
386*fe6060f1SDimitry Andric 
387*fe6060f1SDimitry Andric         Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
388*fe6060f1SDimitry Andric                                  NameToken.Text, NameToken.Range);
389*fe6060f1SDimitry Andric 
390*fe6060f1SDimitry Andric         Error->addError(ChainCallToken.Range,
391*fe6060f1SDimitry Andric                         Error->ET_RegistryMatcherNoWithSupport);
392*fe6060f1SDimitry Andric         return false;
393*fe6060f1SDimitry Andric       }
3940b57cec5SDimitry Andric       if (!parseBindID(BindID))
3950b57cec5SDimitry Andric         return false;
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric       assert(NamedValue.isMatcher());
3980b57cec5SDimitry Andric       llvm::Optional<DynTypedMatcher> Result =
3990b57cec5SDimitry Andric           NamedValue.getMatcher().getSingleMatcher();
4000b57cec5SDimitry Andric       if (Result.hasValue()) {
4010b57cec5SDimitry Andric         llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
4020b57cec5SDimitry Andric         if (Bound.hasValue()) {
4030b57cec5SDimitry Andric           *Value = VariantMatcher::SingleMatcher(*Bound);
4040b57cec5SDimitry Andric           return true;
4050b57cec5SDimitry Andric         }
4060b57cec5SDimitry Andric       }
4070b57cec5SDimitry Andric       return false;
4080b57cec5SDimitry Andric     }
409480093f4SDimitry Andric 
410480093f4SDimitry Andric     if (Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine) {
411480093f4SDimitry Andric       Error->addError(Tokenizer->peekNextToken().Range,
412480093f4SDimitry Andric                       Error->ET_ParserNoOpenParen)
413480093f4SDimitry Andric           << "NewLine";
414480093f4SDimitry Andric       return false;
415480093f4SDimitry Andric     }
416480093f4SDimitry Andric 
4170b57cec5SDimitry Andric     // If the syntax is correct and the name is not a matcher either, report
4180b57cec5SDimitry Andric     // unknown named value.
4190b57cec5SDimitry Andric     if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma ||
4200b57cec5SDimitry Andric          Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen ||
421480093f4SDimitry Andric          Tokenizer->nextTokenKind() == TokenInfo::TK_NewLine ||
4220b57cec5SDimitry Andric          Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) &&
4230b57cec5SDimitry Andric         !S->lookupMatcherCtor(NameToken.Text)) {
4240b57cec5SDimitry Andric       Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound)
4250b57cec5SDimitry Andric           << NameToken.Text;
4260b57cec5SDimitry Andric       return false;
4270b57cec5SDimitry Andric     }
4280b57cec5SDimitry Andric     // Otherwise, fallback to the matcher parser.
4290b57cec5SDimitry Andric   }
4300b57cec5SDimitry Andric 
431480093f4SDimitry Andric   Tokenizer->SkipNewlines();
432480093f4SDimitry Andric 
433*fe6060f1SDimitry Andric   assert(NameToken.Kind == TokenInfo::TK_Ident);
434*fe6060f1SDimitry Andric   TokenInfo OpenToken = Tokenizer->consumeNextToken();
435*fe6060f1SDimitry Andric   if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
436*fe6060f1SDimitry Andric     Error->addError(OpenToken.Range, Error->ET_ParserNoOpenParen)
437*fe6060f1SDimitry Andric         << OpenToken.Text;
4380b57cec5SDimitry Andric     return false;
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric 
441*fe6060f1SDimitry Andric   llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text);
442*fe6060f1SDimitry Andric 
443*fe6060f1SDimitry Andric   // Parse as a matcher expression.
444*fe6060f1SDimitry Andric   return parseMatcherExpressionImpl(NameToken, OpenToken, Ctor, Value);
445*fe6060f1SDimitry Andric }
446*fe6060f1SDimitry Andric 
447*fe6060f1SDimitry Andric bool Parser::parseBindID(std::string &BindID) {
448*fe6060f1SDimitry Andric   // Parse the parenthesized argument to .bind("foo")
4490b57cec5SDimitry Andric   const TokenInfo OpenToken = Tokenizer->consumeNextToken();
450480093f4SDimitry Andric   const TokenInfo IDToken = Tokenizer->consumeNextTokenIgnoreNewlines();
451480093f4SDimitry Andric   const TokenInfo CloseToken = Tokenizer->consumeNextTokenIgnoreNewlines();
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   // TODO: We could use different error codes for each/some to be more
4540b57cec5SDimitry Andric   //       explicit about the syntax error.
4550b57cec5SDimitry Andric   if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
4560b57cec5SDimitry Andric     Error->addError(OpenToken.Range, Error->ET_ParserMalformedBindExpr);
4570b57cec5SDimitry Andric     return false;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric   if (IDToken.Kind != TokenInfo::TK_Literal || !IDToken.Value.isString()) {
4600b57cec5SDimitry Andric     Error->addError(IDToken.Range, Error->ET_ParserMalformedBindExpr);
4610b57cec5SDimitry Andric     return false;
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric   if (CloseToken.Kind != TokenInfo::TK_CloseParen) {
4640b57cec5SDimitry Andric     Error->addError(CloseToken.Range, Error->ET_ParserMalformedBindExpr);
4650b57cec5SDimitry Andric     return false;
4660b57cec5SDimitry Andric   }
4670b57cec5SDimitry Andric   BindID = IDToken.Value.getString();
4680b57cec5SDimitry Andric   return true;
4690b57cec5SDimitry Andric }
4700b57cec5SDimitry Andric 
471*fe6060f1SDimitry Andric bool Parser::parseMatcherBuilder(MatcherCtor Ctor, const TokenInfo &NameToken,
472*fe6060f1SDimitry Andric                                  const TokenInfo &OpenToken,
473*fe6060f1SDimitry Andric                                  VariantValue *Value) {
474*fe6060f1SDimitry Andric   std::vector<ParserValue> Args;
475*fe6060f1SDimitry Andric   TokenInfo EndToken;
476*fe6060f1SDimitry Andric 
477*fe6060f1SDimitry Andric   Tokenizer->SkipNewlines();
478*fe6060f1SDimitry Andric 
479*fe6060f1SDimitry Andric   {
480*fe6060f1SDimitry Andric     ScopedContextEntry SCE(this, Ctor);
481*fe6060f1SDimitry Andric 
482*fe6060f1SDimitry Andric     while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
483*fe6060f1SDimitry Andric       if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
484*fe6060f1SDimitry Andric         // End of args.
485*fe6060f1SDimitry Andric         EndToken = Tokenizer->consumeNextToken();
486*fe6060f1SDimitry Andric         break;
487*fe6060f1SDimitry Andric       }
488*fe6060f1SDimitry Andric       if (!Args.empty()) {
489*fe6060f1SDimitry Andric         // We must find a , token to continue.
490*fe6060f1SDimitry Andric         TokenInfo CommaToken = Tokenizer->consumeNextToken();
491*fe6060f1SDimitry Andric         if (CommaToken.Kind != TokenInfo::TK_Comma) {
492*fe6060f1SDimitry Andric           Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
493*fe6060f1SDimitry Andric               << CommaToken.Text;
494*fe6060f1SDimitry Andric           return false;
495*fe6060f1SDimitry Andric         }
496*fe6060f1SDimitry Andric       }
497*fe6060f1SDimitry Andric 
498*fe6060f1SDimitry Andric       Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
499*fe6060f1SDimitry Andric                                NameToken.Text, NameToken.Range,
500*fe6060f1SDimitry Andric                                Args.size() + 1);
501*fe6060f1SDimitry Andric       ParserValue ArgValue;
502*fe6060f1SDimitry Andric       Tokenizer->SkipNewlines();
503*fe6060f1SDimitry Andric 
504*fe6060f1SDimitry Andric       if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_CodeCompletion) {
505*fe6060f1SDimitry Andric         addExpressionCompletions();
506*fe6060f1SDimitry Andric         return false;
507*fe6060f1SDimitry Andric       }
508*fe6060f1SDimitry Andric 
509*fe6060f1SDimitry Andric       TokenInfo NodeMatcherToken = Tokenizer->consumeNextToken();
510*fe6060f1SDimitry Andric 
511*fe6060f1SDimitry Andric       if (NodeMatcherToken.Kind != TokenInfo::TK_Ident) {
512*fe6060f1SDimitry Andric         Error->addError(NameToken.Range, Error->ET_ParserFailedToBuildMatcher)
513*fe6060f1SDimitry Andric             << NameToken.Text;
514*fe6060f1SDimitry Andric         return false;
515*fe6060f1SDimitry Andric       }
516*fe6060f1SDimitry Andric 
517*fe6060f1SDimitry Andric       ArgValue.Text = NodeMatcherToken.Text;
518*fe6060f1SDimitry Andric       ArgValue.Range = NodeMatcherToken.Range;
519*fe6060f1SDimitry Andric 
520*fe6060f1SDimitry Andric       llvm::Optional<MatcherCtor> MappedMatcher =
521*fe6060f1SDimitry Andric           S->lookupMatcherCtor(ArgValue.Text);
522*fe6060f1SDimitry Andric 
523*fe6060f1SDimitry Andric       if (!MappedMatcher) {
524*fe6060f1SDimitry Andric         Error->addError(NodeMatcherToken.Range,
525*fe6060f1SDimitry Andric                         Error->ET_RegistryMatcherNotFound)
526*fe6060f1SDimitry Andric             << NodeMatcherToken.Text;
527*fe6060f1SDimitry Andric         return false;
528*fe6060f1SDimitry Andric       }
529*fe6060f1SDimitry Andric 
530*fe6060f1SDimitry Andric       ASTNodeKind NK = S->nodeMatcherType(*MappedMatcher);
531*fe6060f1SDimitry Andric 
532*fe6060f1SDimitry Andric       if (NK.isNone()) {
533*fe6060f1SDimitry Andric         Error->addError(NodeMatcherToken.Range,
534*fe6060f1SDimitry Andric                         Error->ET_RegistryNonNodeMatcher)
535*fe6060f1SDimitry Andric             << NodeMatcherToken.Text;
536*fe6060f1SDimitry Andric         return false;
537*fe6060f1SDimitry Andric       }
538*fe6060f1SDimitry Andric 
539*fe6060f1SDimitry Andric       ArgValue.Value = NK;
540*fe6060f1SDimitry Andric 
541*fe6060f1SDimitry Andric       Tokenizer->SkipNewlines();
542*fe6060f1SDimitry Andric       Args.push_back(ArgValue);
543*fe6060f1SDimitry Andric 
544*fe6060f1SDimitry Andric       SCE.nextArg();
545*fe6060f1SDimitry Andric     }
546*fe6060f1SDimitry Andric   }
547*fe6060f1SDimitry Andric 
548*fe6060f1SDimitry Andric   if (EndToken.Kind == TokenInfo::TK_Eof) {
549*fe6060f1SDimitry Andric     Error->addError(OpenToken.Range, Error->ET_ParserNoCloseParen);
550*fe6060f1SDimitry Andric     return false;
551*fe6060f1SDimitry Andric   }
552*fe6060f1SDimitry Andric 
553*fe6060f1SDimitry Andric   internal::MatcherDescriptorPtr BuiltCtor =
554*fe6060f1SDimitry Andric       S->buildMatcherCtor(Ctor, NameToken.Range, Args, Error);
555*fe6060f1SDimitry Andric 
556*fe6060f1SDimitry Andric   if (!BuiltCtor.get()) {
557*fe6060f1SDimitry Andric     Error->addError(NameToken.Range, Error->ET_ParserFailedToBuildMatcher)
558*fe6060f1SDimitry Andric         << NameToken.Text;
559*fe6060f1SDimitry Andric     return false;
560*fe6060f1SDimitry Andric   }
561*fe6060f1SDimitry Andric 
562*fe6060f1SDimitry Andric   std::string BindID;
563*fe6060f1SDimitry Andric   if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period) {
564*fe6060f1SDimitry Andric     Tokenizer->consumeNextToken();
565*fe6060f1SDimitry Andric     TokenInfo ChainCallToken = Tokenizer->consumeNextToken();
566*fe6060f1SDimitry Andric     if (ChainCallToken.Kind == TokenInfo::TK_CodeCompletion) {
567*fe6060f1SDimitry Andric       addCompletion(ChainCallToken, MatcherCompletion("bind(\"", "bind", 1));
568*fe6060f1SDimitry Andric       addCompletion(ChainCallToken, MatcherCompletion("with(", "with", 1));
569*fe6060f1SDimitry Andric       return false;
570*fe6060f1SDimitry Andric     }
571*fe6060f1SDimitry Andric     if (ChainCallToken.Kind != TokenInfo::TK_Ident ||
572*fe6060f1SDimitry Andric         (ChainCallToken.Text != TokenInfo::ID_Bind &&
573*fe6060f1SDimitry Andric          ChainCallToken.Text != TokenInfo::ID_With)) {
574*fe6060f1SDimitry Andric       Error->addError(ChainCallToken.Range,
575*fe6060f1SDimitry Andric                       Error->ET_ParserMalformedChainedExpr);
576*fe6060f1SDimitry Andric       return false;
577*fe6060f1SDimitry Andric     }
578*fe6060f1SDimitry Andric     if (ChainCallToken.Text == TokenInfo::ID_Bind) {
579*fe6060f1SDimitry Andric       if (!parseBindID(BindID))
580*fe6060f1SDimitry Andric         return false;
581*fe6060f1SDimitry Andric       Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
582*fe6060f1SDimitry Andric                                NameToken.Text, NameToken.Range);
583*fe6060f1SDimitry Andric       SourceRange MatcherRange = NameToken.Range;
584*fe6060f1SDimitry Andric       MatcherRange.End = ChainCallToken.Range.End;
585*fe6060f1SDimitry Andric       VariantMatcher Result = S->actOnMatcherExpression(
586*fe6060f1SDimitry Andric           BuiltCtor.get(), MatcherRange, BindID, {}, Error);
587*fe6060f1SDimitry Andric       if (Result.isNull())
588*fe6060f1SDimitry Andric         return false;
589*fe6060f1SDimitry Andric 
590*fe6060f1SDimitry Andric       *Value = Result;
591*fe6060f1SDimitry Andric       return true;
592*fe6060f1SDimitry Andric     } else if (ChainCallToken.Text == TokenInfo::ID_With) {
593*fe6060f1SDimitry Andric       Tokenizer->SkipNewlines();
594*fe6060f1SDimitry Andric 
595*fe6060f1SDimitry Andric       if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
596*fe6060f1SDimitry Andric         StringRef ErrTxt = Tokenizer->nextTokenKind() == TokenInfo::TK_Eof
597*fe6060f1SDimitry Andric                                ? StringRef("EOF")
598*fe6060f1SDimitry Andric                                : Tokenizer->peekNextToken().Text;
599*fe6060f1SDimitry Andric         Error->addError(Tokenizer->peekNextToken().Range,
600*fe6060f1SDimitry Andric                         Error->ET_ParserNoOpenParen)
601*fe6060f1SDimitry Andric             << ErrTxt;
602*fe6060f1SDimitry Andric         return false;
603*fe6060f1SDimitry Andric       }
604*fe6060f1SDimitry Andric 
605*fe6060f1SDimitry Andric       TokenInfo WithOpenToken = Tokenizer->consumeNextToken();
606*fe6060f1SDimitry Andric 
607*fe6060f1SDimitry Andric       return parseMatcherExpressionImpl(NameToken, WithOpenToken,
608*fe6060f1SDimitry Andric                                         BuiltCtor.get(), Value);
609*fe6060f1SDimitry Andric     }
610*fe6060f1SDimitry Andric   }
611*fe6060f1SDimitry Andric 
612*fe6060f1SDimitry Andric   Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
613*fe6060f1SDimitry Andric                            NameToken.Text, NameToken.Range);
614*fe6060f1SDimitry Andric   SourceRange MatcherRange = NameToken.Range;
615*fe6060f1SDimitry Andric   MatcherRange.End = EndToken.Range.End;
616*fe6060f1SDimitry Andric   VariantMatcher Result = S->actOnMatcherExpression(
617*fe6060f1SDimitry Andric       BuiltCtor.get(), MatcherRange, BindID, {}, Error);
618*fe6060f1SDimitry Andric   if (Result.isNull())
619*fe6060f1SDimitry Andric     return false;
620*fe6060f1SDimitry Andric 
621*fe6060f1SDimitry Andric   *Value = Result;
622*fe6060f1SDimitry Andric   return true;
623*fe6060f1SDimitry Andric }
624*fe6060f1SDimitry Andric 
6250b57cec5SDimitry Andric /// Parse and validate a matcher expression.
6260b57cec5SDimitry Andric /// \return \c true on success, in which case \c Value has the matcher parsed.
6270b57cec5SDimitry Andric ///   If the input is malformed, or some argument has an error, it
6280b57cec5SDimitry Andric ///   returns \c false.
6290b57cec5SDimitry Andric bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
630*fe6060f1SDimitry Andric                                         const TokenInfo &OpenToken,
631*fe6060f1SDimitry Andric                                         llvm::Optional<MatcherCtor> Ctor,
6320b57cec5SDimitry Andric                                         VariantValue *Value) {
6330b57cec5SDimitry Andric   if (!Ctor) {
6340b57cec5SDimitry Andric     Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound)
6350b57cec5SDimitry Andric         << NameToken.Text;
6360b57cec5SDimitry Andric     // Do not return here. We need to continue to give completion suggestions.
6370b57cec5SDimitry Andric   }
6380b57cec5SDimitry Andric 
639*fe6060f1SDimitry Andric   if (Ctor && *Ctor && S->isBuilderMatcher(*Ctor))
640*fe6060f1SDimitry Andric     return parseMatcherBuilder(*Ctor, NameToken, OpenToken, Value);
641*fe6060f1SDimitry Andric 
6420b57cec5SDimitry Andric   std::vector<ParserValue> Args;
6430b57cec5SDimitry Andric   TokenInfo EndToken;
6440b57cec5SDimitry Andric 
645480093f4SDimitry Andric   Tokenizer->SkipNewlines();
646480093f4SDimitry Andric 
6470b57cec5SDimitry Andric   {
6480b57cec5SDimitry Andric     ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr);
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric     while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
6510b57cec5SDimitry Andric       if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
6520b57cec5SDimitry Andric         // End of args.
6530b57cec5SDimitry Andric         EndToken = Tokenizer->consumeNextToken();
6540b57cec5SDimitry Andric         break;
6550b57cec5SDimitry Andric       }
6560b57cec5SDimitry Andric       if (!Args.empty()) {
6570b57cec5SDimitry Andric         // We must find a , token to continue.
6580b57cec5SDimitry Andric         const TokenInfo CommaToken = Tokenizer->consumeNextToken();
6590b57cec5SDimitry Andric         if (CommaToken.Kind != TokenInfo::TK_Comma) {
6600b57cec5SDimitry Andric           Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
6610b57cec5SDimitry Andric               << CommaToken.Text;
6620b57cec5SDimitry Andric           return false;
6630b57cec5SDimitry Andric         }
6640b57cec5SDimitry Andric       }
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric       Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
6670b57cec5SDimitry Andric                                NameToken.Text, NameToken.Range,
6680b57cec5SDimitry Andric                                Args.size() + 1);
6690b57cec5SDimitry Andric       ParserValue ArgValue;
670480093f4SDimitry Andric       Tokenizer->SkipNewlines();
6710b57cec5SDimitry Andric       ArgValue.Text = Tokenizer->peekNextToken().Text;
6720b57cec5SDimitry Andric       ArgValue.Range = Tokenizer->peekNextToken().Range;
6730b57cec5SDimitry Andric       if (!parseExpressionImpl(&ArgValue.Value)) {
6740b57cec5SDimitry Andric         return false;
6750b57cec5SDimitry Andric       }
6760b57cec5SDimitry Andric 
677480093f4SDimitry Andric       Tokenizer->SkipNewlines();
6780b57cec5SDimitry Andric       Args.push_back(ArgValue);
6790b57cec5SDimitry Andric       SCE.nextArg();
6800b57cec5SDimitry Andric     }
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   if (EndToken.Kind == TokenInfo::TK_Eof) {
6840b57cec5SDimitry Andric     Error->addError(OpenToken.Range, Error->ET_ParserNoCloseParen);
6850b57cec5SDimitry Andric     return false;
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   std::string BindID;
6890b57cec5SDimitry Andric   if (Tokenizer->peekNextToken().Kind == TokenInfo::TK_Period) {
690*fe6060f1SDimitry Andric     Tokenizer->consumeNextToken();
691*fe6060f1SDimitry Andric     TokenInfo ChainCallToken = Tokenizer->consumeNextToken();
692*fe6060f1SDimitry Andric     if (ChainCallToken.Kind == TokenInfo::TK_CodeCompletion) {
693*fe6060f1SDimitry Andric       addCompletion(ChainCallToken, MatcherCompletion("bind(\"", "bind", 1));
694*fe6060f1SDimitry Andric       return false;
695*fe6060f1SDimitry Andric     }
696*fe6060f1SDimitry Andric 
697*fe6060f1SDimitry Andric     if (ChainCallToken.Kind != TokenInfo::TK_Ident) {
698*fe6060f1SDimitry Andric       Error->addError(ChainCallToken.Range,
699*fe6060f1SDimitry Andric                       Error->ET_ParserMalformedChainedExpr);
700*fe6060f1SDimitry Andric       return false;
701*fe6060f1SDimitry Andric     }
702*fe6060f1SDimitry Andric     if (ChainCallToken.Text == TokenInfo::ID_With) {
703*fe6060f1SDimitry Andric 
704*fe6060f1SDimitry Andric       Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
705*fe6060f1SDimitry Andric                                NameToken.Text, NameToken.Range);
706*fe6060f1SDimitry Andric 
707*fe6060f1SDimitry Andric       Error->addError(ChainCallToken.Range,
708*fe6060f1SDimitry Andric                       Error->ET_RegistryMatcherNoWithSupport);
709*fe6060f1SDimitry Andric       return false;
710*fe6060f1SDimitry Andric     }
711*fe6060f1SDimitry Andric     if (ChainCallToken.Text != TokenInfo::ID_Bind) {
712*fe6060f1SDimitry Andric       Error->addError(ChainCallToken.Range,
713*fe6060f1SDimitry Andric                       Error->ET_ParserMalformedChainedExpr);
714*fe6060f1SDimitry Andric       return false;
715*fe6060f1SDimitry Andric     }
7160b57cec5SDimitry Andric     if (!parseBindID(BindID))
7170b57cec5SDimitry Andric       return false;
7180b57cec5SDimitry Andric   }
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   if (!Ctor)
7210b57cec5SDimitry Andric     return false;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   // Merge the start and end infos.
7240b57cec5SDimitry Andric   Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
7250b57cec5SDimitry Andric                            NameToken.Text, NameToken.Range);
7260b57cec5SDimitry Andric   SourceRange MatcherRange = NameToken.Range;
7270b57cec5SDimitry Andric   MatcherRange.End = EndToken.Range.End;
7280b57cec5SDimitry Andric   VariantMatcher Result = S->actOnMatcherExpression(
7290b57cec5SDimitry Andric       *Ctor, MatcherRange, BindID, Args, Error);
7300b57cec5SDimitry Andric   if (Result.isNull()) return false;
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   *Value = Result;
7330b57cec5SDimitry Andric   return true;
7340b57cec5SDimitry Andric }
7350b57cec5SDimitry Andric 
7360b57cec5SDimitry Andric // If the prefix of this completion matches the completion token, add it to
7370b57cec5SDimitry Andric // Completions minus the prefix.
7380b57cec5SDimitry Andric void Parser::addCompletion(const TokenInfo &CompToken,
7390b57cec5SDimitry Andric                            const MatcherCompletion& Completion) {
7400b57cec5SDimitry Andric   if (StringRef(Completion.TypedText).startswith(CompToken.Text) &&
7410b57cec5SDimitry Andric       Completion.Specificity > 0) {
7420b57cec5SDimitry Andric     Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
7430b57cec5SDimitry Andric                              Completion.MatcherDecl, Completion.Specificity);
7440b57cec5SDimitry Andric   }
7450b57cec5SDimitry Andric }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric std::vector<MatcherCompletion> Parser::getNamedValueCompletions(
7480b57cec5SDimitry Andric     ArrayRef<ArgKind> AcceptedTypes) {
7490b57cec5SDimitry Andric   if (!NamedValues) return std::vector<MatcherCompletion>();
7500b57cec5SDimitry Andric   std::vector<MatcherCompletion> Result;
7510b57cec5SDimitry Andric   for (const auto &Entry : *NamedValues) {
7520b57cec5SDimitry Andric     unsigned Specificity;
7530b57cec5SDimitry Andric     if (Entry.getValue().isConvertibleTo(AcceptedTypes, &Specificity)) {
7540b57cec5SDimitry Andric       std::string Decl =
7550b57cec5SDimitry Andric           (Entry.getValue().getTypeAsString() + " " + Entry.getKey()).str();
7560b57cec5SDimitry Andric       Result.emplace_back(Entry.getKey(), Decl, Specificity);
7570b57cec5SDimitry Andric     }
7580b57cec5SDimitry Andric   }
7590b57cec5SDimitry Andric   return Result;
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric void Parser::addExpressionCompletions() {
763480093f4SDimitry Andric   const TokenInfo CompToken = Tokenizer->consumeNextTokenIgnoreNewlines();
7640b57cec5SDimitry Andric   assert(CompToken.Kind == TokenInfo::TK_CodeCompletion);
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   // We cannot complete code if there is an invalid element on the context
7670b57cec5SDimitry Andric   // stack.
7680b57cec5SDimitry Andric   for (ContextStackTy::iterator I = ContextStack.begin(),
7690b57cec5SDimitry Andric                                 E = ContextStack.end();
7700b57cec5SDimitry Andric        I != E; ++I) {
7710b57cec5SDimitry Andric     if (!I->first)
7720b57cec5SDimitry Andric       return;
7730b57cec5SDimitry Andric   }
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   auto AcceptedTypes = S->getAcceptedCompletionTypes(ContextStack);
7760b57cec5SDimitry Andric   for (const auto &Completion : S->getMatcherCompletions(AcceptedTypes)) {
7770b57cec5SDimitry Andric     addCompletion(CompToken, Completion);
7780b57cec5SDimitry Andric   }
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric   for (const auto &Completion : getNamedValueCompletions(AcceptedTypes)) {
7810b57cec5SDimitry Andric     addCompletion(CompToken, Completion);
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric /// Parse an <Expression>
7860b57cec5SDimitry Andric bool Parser::parseExpressionImpl(VariantValue *Value) {
7870b57cec5SDimitry Andric   switch (Tokenizer->nextTokenKind()) {
7880b57cec5SDimitry Andric   case TokenInfo::TK_Literal:
7890b57cec5SDimitry Andric     *Value = Tokenizer->consumeNextToken().Value;
7900b57cec5SDimitry Andric     return true;
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric   case TokenInfo::TK_Ident:
7930b57cec5SDimitry Andric     return parseIdentifierPrefixImpl(Value);
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric   case TokenInfo::TK_CodeCompletion:
7960b57cec5SDimitry Andric     addExpressionCompletions();
7970b57cec5SDimitry Andric     return false;
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric   case TokenInfo::TK_Eof:
8000b57cec5SDimitry Andric     Error->addError(Tokenizer->consumeNextToken().Range,
8010b57cec5SDimitry Andric                     Error->ET_ParserNoCode);
8020b57cec5SDimitry Andric     return false;
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   case TokenInfo::TK_Error:
8050b57cec5SDimitry Andric     // This error was already reported by the tokenizer.
8060b57cec5SDimitry Andric     return false;
807480093f4SDimitry Andric   case TokenInfo::TK_NewLine:
8080b57cec5SDimitry Andric   case TokenInfo::TK_OpenParen:
8090b57cec5SDimitry Andric   case TokenInfo::TK_CloseParen:
8100b57cec5SDimitry Andric   case TokenInfo::TK_Comma:
8110b57cec5SDimitry Andric   case TokenInfo::TK_Period:
8120b57cec5SDimitry Andric   case TokenInfo::TK_InvalidChar:
8130b57cec5SDimitry Andric     const TokenInfo Token = Tokenizer->consumeNextToken();
814480093f4SDimitry Andric     Error->addError(Token.Range, Error->ET_ParserInvalidToken)
815480093f4SDimitry Andric         << (Token.Kind == TokenInfo::TK_NewLine ? "NewLine" : Token.Text);
8160b57cec5SDimitry Andric     return false;
8170b57cec5SDimitry Andric   }
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   llvm_unreachable("Unknown token kind.");
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric static llvm::ManagedStatic<Parser::RegistrySema> DefaultRegistrySema;
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
8250b57cec5SDimitry Andric                const NamedValueMap *NamedValues, Diagnostics *Error)
8260b57cec5SDimitry Andric     : Tokenizer(Tokenizer), S(S ? S : &*DefaultRegistrySema),
8270b57cec5SDimitry Andric       NamedValues(NamedValues), Error(Error) {}
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric Parser::RegistrySema::~RegistrySema() = default;
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric llvm::Optional<MatcherCtor>
8320b57cec5SDimitry Andric Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
8330b57cec5SDimitry Andric   return Registry::lookupMatcherCtor(MatcherName);
8340b57cec5SDimitry Andric }
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric VariantMatcher Parser::RegistrySema::actOnMatcherExpression(
8370b57cec5SDimitry Andric     MatcherCtor Ctor, SourceRange NameRange, StringRef BindID,
8380b57cec5SDimitry Andric     ArrayRef<ParserValue> Args, Diagnostics *Error) {
8390b57cec5SDimitry Andric   if (BindID.empty()) {
8400b57cec5SDimitry Andric     return Registry::constructMatcher(Ctor, NameRange, Args, Error);
8410b57cec5SDimitry Andric   } else {
8420b57cec5SDimitry Andric     return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
8430b57cec5SDimitry Andric                                            Error);
8440b57cec5SDimitry Andric   }
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric std::vector<ArgKind> Parser::RegistrySema::getAcceptedCompletionTypes(
8480b57cec5SDimitry Andric     ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
8490b57cec5SDimitry Andric   return Registry::getAcceptedCompletionTypes(Context);
8500b57cec5SDimitry Andric }
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric std::vector<MatcherCompletion> Parser::RegistrySema::getMatcherCompletions(
8530b57cec5SDimitry Andric     ArrayRef<ArgKind> AcceptedTypes) {
8540b57cec5SDimitry Andric   return Registry::getMatcherCompletions(AcceptedTypes);
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
857*fe6060f1SDimitry Andric bool Parser::RegistrySema::isBuilderMatcher(MatcherCtor Ctor) const {
858*fe6060f1SDimitry Andric   return Registry::isBuilderMatcher(Ctor);
859*fe6060f1SDimitry Andric }
860*fe6060f1SDimitry Andric 
861*fe6060f1SDimitry Andric ASTNodeKind Parser::RegistrySema::nodeMatcherType(MatcherCtor Ctor) const {
862*fe6060f1SDimitry Andric   return Registry::nodeMatcherType(Ctor);
863*fe6060f1SDimitry Andric }
864*fe6060f1SDimitry Andric 
865*fe6060f1SDimitry Andric internal::MatcherDescriptorPtr
866*fe6060f1SDimitry Andric Parser::RegistrySema::buildMatcherCtor(MatcherCtor Ctor, SourceRange NameRange,
867*fe6060f1SDimitry Andric                                        ArrayRef<ParserValue> Args,
868*fe6060f1SDimitry Andric                                        Diagnostics *Error) const {
869*fe6060f1SDimitry Andric   return Registry::buildMatcherCtor(Ctor, NameRange, Args, Error);
870*fe6060f1SDimitry Andric }
871*fe6060f1SDimitry Andric 
872480093f4SDimitry Andric bool Parser::parseExpression(StringRef &Code, Sema *S,
8730b57cec5SDimitry Andric                              const NamedValueMap *NamedValues,
8740b57cec5SDimitry Andric                              VariantValue *Value, Diagnostics *Error) {
8750b57cec5SDimitry Andric   CodeTokenizer Tokenizer(Code, Error);
8760b57cec5SDimitry Andric   if (!Parser(&Tokenizer, S, NamedValues, Error).parseExpressionImpl(Value))
8770b57cec5SDimitry Andric     return false;
878480093f4SDimitry Andric   auto NT = Tokenizer.peekNextToken();
879480093f4SDimitry Andric   if (NT.Kind != TokenInfo::TK_Eof && NT.Kind != TokenInfo::TK_NewLine) {
8800b57cec5SDimitry Andric     Error->addError(Tokenizer.peekNextToken().Range,
8810b57cec5SDimitry Andric                     Error->ET_ParserTrailingCode);
8820b57cec5SDimitry Andric     return false;
8830b57cec5SDimitry Andric   }
8840b57cec5SDimitry Andric   return true;
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric std::vector<MatcherCompletion>
888480093f4SDimitry Andric Parser::completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S,
8890b57cec5SDimitry Andric                            const NamedValueMap *NamedValues) {
8900b57cec5SDimitry Andric   Diagnostics Error;
8910b57cec5SDimitry Andric   CodeTokenizer Tokenizer(Code, &Error, CompletionOffset);
8920b57cec5SDimitry Andric   Parser P(&Tokenizer, S, NamedValues, &Error);
8930b57cec5SDimitry Andric   VariantValue Dummy;
8940b57cec5SDimitry Andric   P.parseExpressionImpl(&Dummy);
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric   // Sort by specificity, then by name.
8970b57cec5SDimitry Andric   llvm::sort(P.Completions,
8980b57cec5SDimitry Andric              [](const MatcherCompletion &A, const MatcherCompletion &B) {
8990b57cec5SDimitry Andric                if (A.Specificity != B.Specificity)
9000b57cec5SDimitry Andric                  return A.Specificity > B.Specificity;
9010b57cec5SDimitry Andric                return A.TypedText < B.TypedText;
9020b57cec5SDimitry Andric              });
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric   return P.Completions;
9050b57cec5SDimitry Andric }
9060b57cec5SDimitry Andric 
9070b57cec5SDimitry Andric llvm::Optional<DynTypedMatcher>
908480093f4SDimitry Andric Parser::parseMatcherExpression(StringRef &Code, Sema *S,
9090b57cec5SDimitry Andric                                const NamedValueMap *NamedValues,
9100b57cec5SDimitry Andric                                Diagnostics *Error) {
9110b57cec5SDimitry Andric   VariantValue Value;
9120b57cec5SDimitry Andric   if (!parseExpression(Code, S, NamedValues, &Value, Error))
9130b57cec5SDimitry Andric     return llvm::Optional<DynTypedMatcher>();
9140b57cec5SDimitry Andric   if (!Value.isMatcher()) {
9150b57cec5SDimitry Andric     Error->addError(SourceRange(), Error->ET_ParserNotAMatcher);
9160b57cec5SDimitry Andric     return llvm::Optional<DynTypedMatcher>();
9170b57cec5SDimitry Andric   }
9180b57cec5SDimitry Andric   llvm::Optional<DynTypedMatcher> Result =
9190b57cec5SDimitry Andric       Value.getMatcher().getSingleMatcher();
9200b57cec5SDimitry Andric   if (!Result.hasValue()) {
9210b57cec5SDimitry Andric     Error->addError(SourceRange(), Error->ET_ParserOverloadedType)
9220b57cec5SDimitry Andric         << Value.getTypeAsString();
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric   return Result;
9250b57cec5SDimitry Andric }
9260b57cec5SDimitry Andric 
9270b57cec5SDimitry Andric } // namespace dynamic
9280b57cec5SDimitry Andric } // namespace ast_matchers
9290b57cec5SDimitry Andric } // namespace clang
930