Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:46

0001 //===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file
0010 /// Simple matcher expression parser.
0011 ///
0012 /// The parser understands matcher expressions of the form:
0013 ///   MatcherName(Arg0, Arg1, ..., ArgN)
0014 /// as well as simple types like strings.
0015 /// The parser does not know how to process the matchers. It delegates this task
0016 /// to a Sema object received as an argument.
0017 ///
0018 /// \code
0019 /// Grammar for the expressions supported:
0020 /// <Expression>        := <Literal> | <NamedValue> | <MatcherExpression>
0021 /// <Literal>           := <StringLiteral> | <Boolean> | <Double> | <Unsigned>
0022 /// <StringLiteral>     := "quoted string"
0023 /// <Boolean>           := true | false
0024 /// <Double>            := [0-9]+.[0-9]* | [0-9]+.[0-9]*[eE][-+]?[0-9]+
0025 /// <Unsigned>          := [0-9]+
0026 /// <NamedValue>        := <Identifier>
0027 /// <MatcherExpression> := <Identifier>(<ArgumentList>) |
0028 ///                        <Identifier>(<ArgumentList>).bind(<StringLiteral>)
0029 /// <Identifier>        := [a-zA-Z]+
0030 /// <ArgumentList>      := <Expression> | <Expression>,<ArgumentList>
0031 /// \endcode
0032 //
0033 //===----------------------------------------------------------------------===//
0034 
0035 #ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
0036 #define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H
0037 
0038 #include "clang/ASTMatchers/ASTMatchersInternal.h"
0039 #include "clang/ASTMatchers/Dynamic/Registry.h"
0040 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
0041 #include "llvm/ADT/ArrayRef.h"
0042 #include "llvm/ADT/StringMap.h"
0043 #include "llvm/ADT/StringRef.h"
0044 #include <optional>
0045 #include <utility>
0046 #include <vector>
0047 
0048 namespace clang {
0049 namespace ast_matchers {
0050 namespace dynamic {
0051 
0052 class Diagnostics;
0053 
0054 /// Matcher expression parser.
0055 class Parser {
0056 public:
0057   /// Interface to connect the parser with the registry and more.
0058   ///
0059   /// The parser uses the Sema instance passed into
0060   /// parseMatcherExpression() to handle all matcher tokens. The simplest
0061   /// processor implementation would simply call into the registry to create
0062   /// the matchers.
0063   /// However, a more complex processor might decide to intercept the matcher
0064   /// creation and do some extra work. For example, it could apply some
0065   /// transformation to the matcher by adding some id() nodes, or could detect
0066   /// specific matcher nodes for more efficient lookup.
0067   class Sema {
0068   public:
0069     virtual ~Sema();
0070 
0071     /// Process a matcher expression.
0072     ///
0073     /// All the arguments passed here have already been processed.
0074     ///
0075     /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
0076     ///
0077     /// \param NameRange The location of the name in the matcher source.
0078     ///   Useful for error reporting.
0079     ///
0080     /// \param BindID The ID to use to bind the matcher, or a null \c StringRef
0081     ///   if no ID is specified.
0082     ///
0083     /// \param Args The argument list for the matcher.
0084     ///
0085     /// \return The matcher objects constructed by the processor, or a null
0086     ///   matcher if an error occurred. In that case, \c Error will contain a
0087     ///   description of the error.
0088     virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
0089                                                   SourceRange NameRange,
0090                                                   StringRef BindID,
0091                                                   ArrayRef<ParserValue> Args,
0092                                                   Diagnostics *Error) = 0;
0093 
0094     /// Look up a matcher by name.
0095     ///
0096     /// \param MatcherName The matcher name found by the parser.
0097     ///
0098     /// \return The matcher constructor, or std::optional<MatcherCtor>() if not
0099     /// found.
0100     virtual std::optional<MatcherCtor>
0101     lookupMatcherCtor(StringRef MatcherName) = 0;
0102 
0103     virtual bool isBuilderMatcher(MatcherCtor) const = 0;
0104 
0105     virtual ASTNodeKind nodeMatcherType(MatcherCtor) const = 0;
0106 
0107     virtual internal::MatcherDescriptorPtr
0108     buildMatcherCtor(MatcherCtor, SourceRange NameRange,
0109                      ArrayRef<ParserValue> Args, Diagnostics *Error) const = 0;
0110 
0111     /// Compute the list of completion types for \p Context.
0112     ///
0113     /// Each element of \p Context represents a matcher invocation, going from
0114     /// outermost to innermost. Elements are pairs consisting of a reference to
0115     /// the matcher constructor and the index of the next element in the
0116     /// argument list of that matcher (or for the last element, the index of
0117     /// the completion point in the argument list). An empty list requests
0118     /// completion for the root matcher.
0119     virtual std::vector<ArgKind> getAcceptedCompletionTypes(
0120         llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
0121 
0122     /// Compute the list of completions that match any of
0123     /// \p AcceptedTypes.
0124     ///
0125     /// \param AcceptedTypes All types accepted for this completion.
0126     ///
0127     /// \return All completions for the specified types.
0128     /// Completions should be valid when used in \c lookupMatcherCtor().
0129     /// The matcher constructed from the return of \c lookupMatcherCtor()
0130     /// should be convertible to some type in \p AcceptedTypes.
0131     virtual std::vector<MatcherCompletion>
0132     getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes);
0133   };
0134 
0135   /// Sema implementation that uses the matcher registry to process the
0136   ///   tokens.
0137   class RegistrySema : public Parser::Sema {
0138   public:
0139     ~RegistrySema() override;
0140 
0141     std::optional<MatcherCtor>
0142     lookupMatcherCtor(StringRef MatcherName) override;
0143 
0144     VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
0145                                           SourceRange NameRange,
0146                                           StringRef BindID,
0147                                           ArrayRef<ParserValue> Args,
0148                                           Diagnostics *Error) override;
0149 
0150     std::vector<ArgKind> getAcceptedCompletionTypes(
0151         llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) override;
0152 
0153     bool isBuilderMatcher(MatcherCtor Ctor) const override;
0154 
0155     ASTNodeKind nodeMatcherType(MatcherCtor) const override;
0156 
0157     internal::MatcherDescriptorPtr
0158     buildMatcherCtor(MatcherCtor, SourceRange NameRange,
0159                      ArrayRef<ParserValue> Args,
0160                      Diagnostics *Error) const override;
0161 
0162     std::vector<MatcherCompletion>
0163     getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override;
0164   };
0165 
0166   using NamedValueMap = llvm::StringMap<VariantValue>;
0167 
0168   /// Parse a matcher expression.
0169   ///
0170   /// \param MatcherCode The matcher expression to parse.
0171   ///
0172   /// \param S The Sema instance that will help the parser
0173   ///   construct the matchers. If null, it uses the default registry.
0174   ///
0175   /// \param NamedValues A map of precomputed named values.  This provides
0176   ///   the dictionary for the <NamedValue> rule of the grammar.
0177   ///   If null, it is ignored.
0178   ///
0179   /// \return The matcher object constructed by the processor, or an empty
0180   ///   Optional if an error occurred. In that case, \c Error will contain a
0181   ///   description of the error.
0182   ///   The caller takes ownership of the DynTypedMatcher object returned.
0183   static std::optional<DynTypedMatcher>
0184   parseMatcherExpression(StringRef &MatcherCode, Sema *S,
0185                          const NamedValueMap *NamedValues, Diagnostics *Error);
0186   static std::optional<DynTypedMatcher>
0187   parseMatcherExpression(StringRef &MatcherCode, Sema *S, Diagnostics *Error) {
0188     return parseMatcherExpression(MatcherCode, S, nullptr, Error);
0189   }
0190   static std::optional<DynTypedMatcher>
0191   parseMatcherExpression(StringRef &MatcherCode, Diagnostics *Error) {
0192     return parseMatcherExpression(MatcherCode, nullptr, Error);
0193   }
0194 
0195   /// Parse an expression.
0196   ///
0197   /// Parses any expression supported by this parser. In general, the
0198   /// \c parseMatcherExpression function is a better approach to get a matcher
0199   /// object.
0200   ///
0201   /// \param S The Sema instance that will help the parser
0202   ///   construct the matchers. If null, it uses the default registry.
0203   ///
0204   /// \param NamedValues A map of precomputed named values.  This provides
0205   ///   the dictionary for the <NamedValue> rule of the grammar.
0206   ///   If null, it is ignored.
0207   static bool parseExpression(StringRef &Code, Sema *S,
0208                               const NamedValueMap *NamedValues,
0209                               VariantValue *Value, Diagnostics *Error);
0210   static bool parseExpression(StringRef &Code, Sema *S, VariantValue *Value,
0211                               Diagnostics *Error) {
0212     return parseExpression(Code, S, nullptr, Value, Error);
0213   }
0214   static bool parseExpression(StringRef &Code, VariantValue *Value,
0215                               Diagnostics *Error) {
0216     return parseExpression(Code, nullptr, Value, Error);
0217   }
0218 
0219   /// Complete an expression at the given offset.
0220   ///
0221   /// \param S The Sema instance that will help the parser
0222   ///   construct the matchers. If null, it uses the default registry.
0223   ///
0224   /// \param NamedValues A map of precomputed named values.  This provides
0225   ///   the dictionary for the <NamedValue> rule of the grammar.
0226   ///   If null, it is ignored.
0227   ///
0228   /// \return The list of completions, which may be empty if there are no
0229   /// available completions or if an error occurred.
0230   static std::vector<MatcherCompletion>
0231   completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S,
0232                      const NamedValueMap *NamedValues);
0233   static std::vector<MatcherCompletion>
0234   completeExpression(StringRef &Code, unsigned CompletionOffset, Sema *S) {
0235     return completeExpression(Code, CompletionOffset, S, nullptr);
0236   }
0237   static std::vector<MatcherCompletion>
0238   completeExpression(StringRef &Code, unsigned CompletionOffset) {
0239     return completeExpression(Code, CompletionOffset, nullptr);
0240   }
0241 
0242 private:
0243   class CodeTokenizer;
0244   struct ScopedContextEntry;
0245   struct TokenInfo;
0246 
0247   Parser(CodeTokenizer *Tokenizer, Sema *S,
0248          const NamedValueMap *NamedValues,
0249          Diagnostics *Error);
0250 
0251   bool parseBindID(std::string &BindID);
0252   bool parseExpressionImpl(VariantValue *Value);
0253   bool parseMatcherBuilder(MatcherCtor Ctor, const TokenInfo &NameToken,
0254                            const TokenInfo &OpenToken, VariantValue *Value);
0255   bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
0256                                   const TokenInfo &OpenToken,
0257                                   std::optional<MatcherCtor> Ctor,
0258                                   VariantValue *Value);
0259   bool parseIdentifierPrefixImpl(VariantValue *Value);
0260 
0261   void addCompletion(const TokenInfo &CompToken,
0262                      const MatcherCompletion &Completion);
0263   void addExpressionCompletions();
0264 
0265   std::vector<MatcherCompletion>
0266   getNamedValueCompletions(ArrayRef<ArgKind> AcceptedTypes);
0267 
0268   CodeTokenizer *const Tokenizer;
0269   Sema *const S;
0270   const NamedValueMap *const NamedValues;
0271   Diagnostics *const Error;
0272 
0273   using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>;
0274 
0275   ContextStackTy ContextStack;
0276   std::vector<MatcherCompletion> Completions;
0277 };
0278 
0279 } // namespace dynamic
0280 } // namespace ast_matchers
0281 } // namespace clang
0282 
0283 #endif // LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H