diff options
| author | Ralf Luther <luther.ralf@gmail.com> | 2019-03-27 20:23:17 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit2@aicp-server-3> | 2019-03-27 20:23:17 +0000 |
| commit | 1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch) | |
| tree | 391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h | |
| parent | d1d48b140bafaa8a50107292f5fce95562575765 (diff) | |
| parent | 4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff) | |
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h')
| -rw-r--r-- | clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h b/clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h new file mode 100644 index 00000000..15e0aa7e --- /dev/null +++ b/clang-r353983/include/clang/ASTMatchers/Dynamic/Parser.h @@ -0,0 +1,264 @@ +//===- Parser.h - Matcher expression parser ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Simple matcher expression parser. +/// +/// The parser understands matcher expressions of the form: +/// MatcherName(Arg0, Arg1, ..., ArgN) +/// as well as simple types like strings. +/// The parser does not know how to process the matchers. It delegates this task +/// to a Sema object received as an argument. +/// +/// \code +/// Grammar for the expressions supported: +/// <Expression> := <Literal> | <NamedValue> | <MatcherExpression> +/// <Literal> := <StringLiteral> | <Boolean> | <Double> | <Unsigned> +/// <StringLiteral> := "quoted string" +/// <Boolean> := true | false +/// <Double> := [0-9]+.[0-9]* | [0-9]+.[0-9]*[eE][-+]?[0-9]+ +/// <Unsigned> := [0-9]+ +/// <NamedValue> := <Identifier> +/// <MatcherExpression> := <Identifier>(<ArgumentList>) | +/// <Identifier>(<ArgumentList>).bind(<StringLiteral>) +/// <Identifier> := [a-zA-Z]+ +/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList> +/// \endcode +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H +#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_PARSER_H + +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/ASTMatchers/Dynamic/Registry.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <utility> +#include <vector> + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +class Diagnostics; + +/// Matcher expression parser. +class Parser { +public: + /// Interface to connect the parser with the registry and more. + /// + /// The parser uses the Sema instance passed into + /// parseMatcherExpression() to handle all matcher tokens. The simplest + /// processor implementation would simply call into the registry to create + /// the matchers. + /// However, a more complex processor might decide to intercept the matcher + /// creation and do some extra work. For example, it could apply some + /// transformation to the matcher by adding some id() nodes, or could detect + /// specific matcher nodes for more efficient lookup. + class Sema { + public: + virtual ~Sema(); + + /// Process a matcher expression. + /// + /// All the arguments passed here have already been processed. + /// + /// \param Ctor A matcher constructor looked up by lookupMatcherCtor. + /// + /// \param NameRange The location of the name in the matcher source. + /// Useful for error reporting. + /// + /// \param BindID The ID to use to bind the matcher, or a null \c StringRef + /// if no ID is specified. + /// + /// \param Args The argument list for the matcher. + /// + /// \return The matcher objects constructed by the processor, or a null + /// matcher if an error occurred. In that case, \c Error will contain a + /// description of the error. + virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, + SourceRange NameRange, + StringRef BindID, + ArrayRef<ParserValue> Args, + Diagnostics *Error) = 0; + + /// Look up a matcher by name. + /// + /// \param MatcherName The matcher name found by the parser. + /// + /// \return The matcher constructor, or Optional<MatcherCtor>() if not + /// found. + virtual llvm::Optional<MatcherCtor> + lookupMatcherCtor(StringRef MatcherName) = 0; + + /// Compute the list of completion types for \p Context. + /// + /// Each element of \p Context represents a matcher invocation, going from + /// outermost to innermost. Elements are pairs consisting of a reference to + /// the matcher constructor and the index of the next element in the + /// argument list of that matcher (or for the last element, the index of + /// the completion point in the argument list). An empty list requests + /// completion for the root matcher. + virtual std::vector<ArgKind> getAcceptedCompletionTypes( + llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context); + + /// Compute the list of completions that match any of + /// \p AcceptedTypes. + /// + /// \param AcceptedTypes All types accepted for this completion. + /// + /// \return All completions for the specified types. + /// Completions should be valid when used in \c lookupMatcherCtor(). + /// The matcher constructed from the return of \c lookupMatcherCtor() + /// should be convertible to some type in \p AcceptedTypes. + virtual std::vector<MatcherCompletion> + getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes); + }; + + /// Sema implementation that uses the matcher registry to process the + /// tokens. + class RegistrySema : public Parser::Sema { + public: + ~RegistrySema() override; + + llvm::Optional<MatcherCtor> + lookupMatcherCtor(StringRef MatcherName) override; + + VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, + SourceRange NameRange, + StringRef BindID, + ArrayRef<ParserValue> Args, + Diagnostics *Error) override; + + std::vector<ArgKind> getAcceptedCompletionTypes( + llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) override; + + std::vector<MatcherCompletion> + getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) override; + }; + + using NamedValueMap = llvm::StringMap<VariantValue>; + + /// Parse a matcher expression. + /// + /// \param MatcherCode The matcher expression to parse. + /// + /// \param S The Sema instance that will help the parser + /// construct the matchers. If null, it uses the default registry. + /// + /// \param NamedValues A map of precomputed named values. This provides + /// the dictionary for the <NamedValue> rule of the grammar. + /// If null, it is ignored. + /// + /// \return The matcher object constructed by the processor, or an empty + /// Optional if an error occurred. In that case, \c Error will contain a + /// description of the error. + /// The caller takes ownership of the DynTypedMatcher object returned. + static llvm::Optional<DynTypedMatcher> + parseMatcherExpression(StringRef MatcherCode, Sema *S, + const NamedValueMap *NamedValues, + Diagnostics *Error); + static llvm::Optional<DynTypedMatcher> + parseMatcherExpression(StringRef MatcherCode, Sema *S, + Diagnostics *Error) { + return parseMatcherExpression(MatcherCode, S, nullptr, Error); + } + static llvm::Optional<DynTypedMatcher> + parseMatcherExpression(StringRef MatcherCode, Diagnostics *Error) { + return parseMatcherExpression(MatcherCode, nullptr, Error); + } + + /// Parse an expression. + /// + /// Parses any expression supported by this parser. In general, the + /// \c parseMatcherExpression function is a better approach to get a matcher + /// object. + /// + /// \param S The Sema instance that will help the parser + /// construct the matchers. If null, it uses the default registry. + /// + /// \param NamedValues A map of precomputed named values. This provides + /// the dictionary for the <NamedValue> rule of the grammar. + /// If null, it is ignored. + static bool parseExpression(StringRef Code, Sema *S, + const NamedValueMap *NamedValues, + VariantValue *Value, Diagnostics *Error); + static bool parseExpression(StringRef Code, Sema *S, + VariantValue *Value, Diagnostics *Error) { + return parseExpression(Code, S, nullptr, Value, Error); + } + static bool parseExpression(StringRef Code, VariantValue *Value, + Diagnostics *Error) { + return parseExpression(Code, nullptr, Value, Error); + } + + /// Complete an expression at the given offset. + /// + /// \param S The Sema instance that will help the parser + /// construct the matchers. If null, it uses the default registry. + /// + /// \param NamedValues A map of precomputed named values. This provides + /// the dictionary for the <NamedValue> rule of the grammar. + /// If null, it is ignored. + /// + /// \return The list of completions, which may be empty if there are no + /// available completions or if an error occurred. + static std::vector<MatcherCompletion> + completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S, + const NamedValueMap *NamedValues); + static std::vector<MatcherCompletion> + completeExpression(StringRef Code, unsigned CompletionOffset, Sema *S) { + return completeExpression(Code, CompletionOffset, S, nullptr); + } + static std::vector<MatcherCompletion> + completeExpression(StringRef Code, unsigned CompletionOffset) { + return completeExpression(Code, CompletionOffset, nullptr); + } + +private: + class CodeTokenizer; + struct ScopedContextEntry; + struct TokenInfo; + + Parser(CodeTokenizer *Tokenizer, Sema *S, + const NamedValueMap *NamedValues, + Diagnostics *Error); + + bool parseBindID(std::string &BindID); + bool parseExpressionImpl(VariantValue *Value); + bool parseMatcherExpressionImpl(const TokenInfo &NameToken, + VariantValue *Value); + bool parseIdentifierPrefixImpl(VariantValue *Value); + + void addCompletion(const TokenInfo &CompToken, + const MatcherCompletion &Completion); + void addExpressionCompletions(); + + std::vector<MatcherCompletion> + getNamedValueCompletions(ArrayRef<ArgKind> AcceptedTypes); + + CodeTokenizer *const Tokenizer; + Sema *const S; + const NamedValueMap *const NamedValues; + Diagnostics *const Error; + + using ContextStackTy = std::vector<std::pair<MatcherCtor, unsigned>>; + + ContextStackTy ContextStack; + std::vector<MatcherCompletion> Completions; +}; + +} // namespace dynamic +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H |
