diff options
Diffstat (limited to 'include/clang/ASTMatchers/Dynamic/Parser.h')
-rw-r--r-- | include/clang/ASTMatchers/Dynamic/Parser.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h new file mode 100644 index 0000000..bb6ac76 --- /dev/null +++ b/include/clang/ASTMatchers/Dynamic/Parser.h @@ -0,0 +1,151 @@ +//===--- Parser.h - Matcher expression parser -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief 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> | <MatcherExpression> +/// <Literal> := <StringLiteral> | <Unsigned> +/// <StringLiteral> := "quoted string" +/// <Unsigned> := [0-9]+ +/// <MatcherExpression> := <MatcherName>(<ArgumentList>) | +/// <MatcherName>(<ArgumentList>).bind(<StringLiteral>) +/// <MatcherName> := [a-zA-Z]+ +/// <ArgumentList> := <Expression> | <Expression>,<ArgumentList> +/// \endcode +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H +#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H + +#include "clang/ASTMatchers/Dynamic/Diagnostics.h" +#include "clang/ASTMatchers/Dynamic/VariantValue.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +namespace ast_matchers { +namespace dynamic { + +/// \brief Matcher expression parser. +class Parser { +public: + /// \brief 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(); + + /// \brief Process a matcher expression. + /// + /// All the arguments passed here have already been processed. + /// + /// \param MatcherName The matcher name found by the parser. + /// + /// \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(StringRef MatcherName, + const SourceRange &NameRange, + StringRef BindID, + ArrayRef<ParserValue> Args, + Diagnostics *Error) = 0; + }; + + /// \brief Parse a matcher expression, creating matchers from the registry. + /// + /// This overload creates matchers calling directly into the registry. If the + /// caller needs more control over how the matchers are created, then it can + /// use the overload below that takes a Sema. + /// + /// \param MatcherCode The matcher expression to parse. + /// + /// \return The matcher object constructed, 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, Diagnostics *Error); + + /// \brief Parse a matcher expression. + /// + /// \param MatcherCode The matcher expression to parse. + /// + /// \param S The Sema instance that will help the parser + /// construct the matchers. + /// \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, Diagnostics *Error); + + /// \brief Parse an expression, creating matchers from the registry. + /// + /// Parses any expression supported by this parser. In general, the + /// \c parseMatcherExpression function is a better approach to get a matcher + /// object. + static bool parseExpression(StringRef Code, VariantValue *Value, + Diagnostics *Error); + + /// \brief 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. + static bool parseExpression(StringRef Code, Sema *S, + VariantValue *Value, Diagnostics *Error); + +private: + class CodeTokenizer; + struct TokenInfo; + + Parser(CodeTokenizer *Tokenizer, Sema *S, + Diagnostics *Error); + + bool parseExpressionImpl(VariantValue *Value); + bool parseMatcherExpressionImpl(VariantValue *Value); + + CodeTokenizer *const Tokenizer; + Sema *const S; + Diagnostics *const Error; +}; + +} // namespace dynamic +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H |