summaryrefslogtreecommitdiffstats
path: root/include/clang/ASTMatchers/Dynamic
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/ASTMatchers/Dynamic')
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h185
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h257
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h133
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h326
4 files changed, 0 insertions, 901 deletions
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
deleted file mode 100644
index 2c76dda..0000000
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ /dev/null
@@ -1,185 +0,0 @@
-//===--- Diagnostics.h - Helper class for error diagnostics -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Diagnostics class to manage error messages.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_DIAGNOSTICS_H
-
-#include "clang/ASTMatchers/Dynamic/VariantValue.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-struct SourceLocation {
- SourceLocation() : Line(), Column() {}
- unsigned Line;
- unsigned Column;
-};
-
-struct SourceRange {
- SourceLocation Start;
- SourceLocation End;
-};
-
-/// \brief A VariantValue instance annotated with its parser context.
-struct ParserValue {
- ParserValue() : Text(), Range(), Value() {}
- StringRef Text;
- SourceRange Range;
- VariantValue Value;
-};
-
-/// \brief Helper class to manage error messages.
-class Diagnostics {
-public:
- /// \brief Parser context types.
- enum ContextType {
- CT_MatcherArg = 0,
- CT_MatcherConstruct = 1
- };
-
- /// \brief All errors from the system.
- enum ErrorType {
- ET_None = 0,
-
- ET_RegistryMatcherNotFound = 1,
- ET_RegistryWrongArgCount = 2,
- ET_RegistryWrongArgType = 3,
- ET_RegistryNotBindable = 4,
- ET_RegistryAmbiguousOverload = 5,
- ET_RegistryValueNotFound = 6,
-
- ET_ParserStringError = 100,
- ET_ParserNoOpenParen = 101,
- ET_ParserNoCloseParen = 102,
- ET_ParserNoComma = 103,
- ET_ParserNoCode = 104,
- ET_ParserNotAMatcher = 105,
- ET_ParserInvalidToken = 106,
- ET_ParserMalformedBindExpr = 107,
- ET_ParserTrailingCode = 108,
- ET_ParserUnsignedError = 109,
- ET_ParserOverloadedType = 110
- };
-
- /// \brief Helper stream class.
- class ArgStream {
- public:
- ArgStream(std::vector<std::string> *Out) : Out(Out) {}
- template <class T> ArgStream &operator<<(const T &Arg) {
- return operator<<(Twine(Arg));
- }
- ArgStream &operator<<(const Twine &Arg);
-
- private:
- std::vector<std::string> *Out;
- };
-
- /// \brief Class defining a parser context.
- ///
- /// Used by the parser to specify (possibly recursive) contexts where the
- /// parsing/construction can fail. Any error triggered within a context will
- /// keep information about the context chain.
- /// This class should be used as a RAII instance in the stack.
- struct Context {
- public:
- /// \brief About to call the constructor for a matcher.
- enum ConstructMatcherEnum { ConstructMatcher };
- Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName,
- SourceRange MatcherRange);
- /// \brief About to recurse into parsing one argument for a matcher.
- enum MatcherArgEnum { MatcherArg };
- Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
- SourceRange MatcherRange, unsigned ArgNumber);
- ~Context();
-
- private:
- Diagnostics *const Error;
- };
-
- /// \brief Context for overloaded matcher construction.
- ///
- /// This context will take care of merging all errors that happen within it
- /// as "candidate" overloads for the same matcher.
- struct OverloadContext {
- public:
- OverloadContext(Diagnostics* Error);
- ~OverloadContext();
-
- /// \brief Revert all errors that happened within this context.
- void revertErrors();
-
- private:
- Diagnostics *const Error;
- unsigned BeginIndex;
- };
-
- /// \brief Add an error to the diagnostics.
- ///
- /// All the context information will be kept on the error message.
- /// \return a helper class to allow the caller to pass the arguments for the
- /// error message, using the << operator.
- ArgStream addError(SourceRange Range, ErrorType Error);
-
- /// \brief Information stored for one frame of the context.
- struct ContextFrame {
- ContextType Type;
- SourceRange Range;
- std::vector<std::string> Args;
- };
-
- /// \brief Information stored for each error found.
- struct ErrorContent {
- std::vector<ContextFrame> ContextStack;
- struct Message {
- SourceRange Range;
- ErrorType Type;
- std::vector<std::string> Args;
- };
- std::vector<Message> Messages;
- };
- ArrayRef<ErrorContent> errors() const { return Errors; }
-
- /// \brief Returns a simple string representation of each error.
- ///
- /// Each error only shows the error message without any context.
- void printToStream(llvm::raw_ostream &OS) const;
- std::string toString() const;
-
- /// \brief Returns the full string representation of each error.
- ///
- /// Each error message contains the full context.
- void printToStreamFull(llvm::raw_ostream &OS) const;
- std::string toStringFull() const;
-
-private:
- /// \brief Helper function used by the constructors of ContextFrame.
- ArgStream pushContextFrame(ContextType Type, SourceRange Range);
-
- std::vector<ContextFrame> ContextStack;
- std::vector<ErrorContent> Errors;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
deleted file mode 100644
index 76926f0..0000000
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ /dev/null
@@ -1,257 +0,0 @@
-//===--- 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> | <NamedValue> | <MatcherExpression>
-/// <Literal> := <StringLiteral> | <Unsigned>
-/// <StringLiteral> := "quoted string"
-/// <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/Dynamic/Diagnostics.h"
-#include "clang/ASTMatchers/Dynamic/Registry.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 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;
-
- /// \brief 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;
-
- /// \brief 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);
-
- /// \brief 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);
- };
-
- /// \brief 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;
- };
-
- typedef llvm::StringMap<VariantValue> NamedValueMap;
-
- /// \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. 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);
- }
-
- /// \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.
- ///
- /// \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);
- }
-
- /// \brief 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 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;
-
- typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
- ContextStackTy ContextStack;
- std::vector<MatcherCompletion> Completions;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
deleted file mode 100644
index 3808adb..0000000
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===--- Registry.h - Matcher registry -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Registry of all known matchers.
-///
-/// The registry provides a generic interface to construct any matcher by name.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_REGISTRY_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 {
-
-namespace internal {
-class MatcherDescriptor;
-}
-
-typedef const internal::MatcherDescriptor *MatcherCtor;
-
-struct MatcherCompletion {
- MatcherCompletion() {}
- MatcherCompletion(StringRef TypedText, StringRef MatcherDecl,
- unsigned Specificity)
- : TypedText(TypedText), MatcherDecl(MatcherDecl),
- Specificity(Specificity) {}
-
- /// \brief The text to type to select this matcher.
- std::string TypedText;
-
- /// \brief The "declaration" of the matcher, with type information.
- std::string MatcherDecl;
-
- /// \brief Value corresponding to the "specificity" of the converted matcher.
- ///
- /// Zero specificity indicates that this conversion would produce a trivial
- /// matcher that will either always or never match.
- /// Such matchers are excluded from code completion results.
- unsigned Specificity;
-
- bool operator==(const MatcherCompletion &Other) const {
- return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
- }
-};
-
-class Registry {
-public:
- /// \brief Look up a matcher in the registry by name,
- ///
- /// \return An opaque value which may be used to refer to the matcher
- /// constructor, or Optional<MatcherCtor>() if not found.
- static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
-
- /// \brief 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.
- static std::vector<ArgKind> getAcceptedCompletionTypes(
- llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context);
-
- /// \brief 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.
- static std::vector<MatcherCompletion>
- getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes);
-
- /// \brief Construct a matcher from the registry.
- ///
- /// \param Ctor The matcher constructor to instantiate.
- ///
- /// \param NameRange The location of the name in the matcher source.
- /// Useful for error reporting.
- ///
- /// \param Args The argument list for the matcher. The number and types of the
- /// values must be valid for the matcher requested. Otherwise, the function
- /// will return an error.
- ///
- /// \return The matcher object constructed if no error was found.
- /// A null matcher if the number of arguments or argument types do not match
- /// the signature. In that case \c Error will contain the description of
- /// the error.
- static VariantMatcher constructMatcher(MatcherCtor Ctor,
- SourceRange NameRange,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
-
- /// \brief Construct a matcher from the registry and bind it.
- ///
- /// Similar the \c constructMatcher() above, but it then tries to bind the
- /// matcher to the specified \c BindID.
- /// If the matcher is not bindable, it sets an error in \c Error and returns
- /// a null matcher.
- static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
- SourceRange NameRange,
- StringRef BindID,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
-
-private:
- Registry() = delete;
-};
-
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_REGISTRY_H
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
deleted file mode 100644
index c391b24..0000000
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ /dev/null
@@ -1,326 +0,0 @@
-//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Polymorphic value type.
-///
-/// Supports all the types required for dynamic Matcher construction.
-/// Used by the registry to construct matchers in a generic way.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
-#define LLVM_CLANG_ASTMATCHERS_DYNAMIC_VARIANTVALUE_H
-
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/Twine.h"
-#include <memory>
-#include <vector>
-
-namespace clang {
-namespace ast_matchers {
-namespace dynamic {
-
-/// \brief Kind identifier.
-///
-/// It supports all types that VariantValue can contain.
-class ArgKind {
- public:
- enum Kind {
- AK_Matcher,
- AK_Unsigned,
- AK_String
- };
- /// \brief Constructor for non-matcher types.
- ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
-
- /// \brief Constructor for matcher types.
- ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
- : K(AK_Matcher), MatcherKind(MatcherKind) {}
-
- Kind getArgKind() const { return K; }
- ast_type_traits::ASTNodeKind getMatcherKind() const {
- assert(K == AK_Matcher);
- return MatcherKind;
- }
-
- /// \brief Determines if this type can be converted to \p To.
- ///
- /// \param To the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ArgKind To, unsigned *Specificity) const;
-
- bool operator<(const ArgKind &Other) const {
- if (K == AK_Matcher && Other.K == AK_Matcher)
- return MatcherKind < Other.MatcherKind;
- return K < Other.K;
- }
-
- /// \brief String representation of the type.
- std::string asString() const;
-
-private:
- Kind K;
- ast_type_traits::ASTNodeKind MatcherKind;
-};
-
-using ast_matchers::internal::DynTypedMatcher;
-
-/// \brief A variant matcher object.
-///
-/// The purpose of this object is to abstract simple and polymorphic matchers
-/// into a single object type.
-/// Polymorphic matchers might be implemented as a list of all the possible
-/// overloads of the matcher. \c VariantMatcher knows how to select the
-/// appropriate overload when needed.
-/// To get a real matcher object out of a \c VariantMatcher you can do:
-/// - getSingleMatcher() which returns a matcher, only if it is not ambiguous
-/// to decide which matcher to return. Eg. it contains only a single
-/// matcher, or a polymorphic one with only one overload.
-/// - hasTypedMatcher<T>()/getTypedMatcher<T>(): These calls will determine if
-/// the underlying matcher(s) can unambiguously return a Matcher<T>.
-class VariantMatcher {
- /// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
- class MatcherOps {
- public:
- MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
-
- bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const;
-
- /// \brief Convert \p Matcher the destination type and return it as a new
- /// DynTypedMatcher.
- virtual DynTypedMatcher
- convertMatcher(const DynTypedMatcher &Matcher) const = 0;
-
- /// \brief Constructs a variadic typed matcher from \p InnerMatchers.
- /// Will try to convert each inner matcher to the destination type and
- /// return llvm::None if it fails to do so.
- llvm::Optional<DynTypedMatcher>
- constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
- ArrayRef<VariantMatcher> InnerMatchers) const;
-
- protected:
- ~MatcherOps() = default;
-
- private:
- ast_type_traits::ASTNodeKind NodeKind;
- };
-
- /// \brief Payload interface to be specialized by each matcher type.
- ///
- /// It follows a similar interface as VariantMatcher itself.
- class Payload : public RefCountedBaseVPTR {
- public:
- ~Payload() override;
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
- virtual std::string getTypeAsString() const = 0;
- virtual llvm::Optional<DynTypedMatcher>
- getTypedMatcher(const MatcherOps &Ops) const = 0;
- virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
- unsigned *Specificity) const = 0;
- };
-
-public:
- /// \brief A null matcher.
- VariantMatcher();
-
- /// \brief Clones the provided matcher.
- static VariantMatcher SingleMatcher(const DynTypedMatcher &Matcher);
-
- /// \brief Clones the provided matchers.
- ///
- /// They should be the result of a polymorphic matcher.
- static VariantMatcher
- PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
-
- /// \brief Creates a 'variadic' operator matcher.
- ///
- /// It will bind to the appropriate type on getTypedMatcher<T>().
- static VariantMatcher
- VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op,
- std::vector<VariantMatcher> Args);
-
- /// \brief Makes the matcher the "null" matcher.
- void reset();
-
- /// \brief Whether the matcher is null.
- bool isNull() const { return !Value; }
-
- /// \brief Return a single matcher, if there is no ambiguity.
- ///
- /// \returns the matcher, if there is only one matcher. An empty Optional, if
- /// the underlying matcher is a polymorphic matcher with more than one
- /// representation.
- llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
-
- /// \brief Determines if the contained matcher can be converted to
- /// \c Matcher<T>.
- ///
- /// For the Single case, it returns true if it can be converted to
- /// \c Matcher<T>.
- /// For the Polymorphic case, it returns true if one, and only one, of the
- /// overloads can be converted to \c Matcher<T>. If there are more than one
- /// that can, the result would be ambiguous and false is returned.
- template <class T>
- bool hasTypedMatcher() const {
- if (!Value) return false;
- return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
- }
-
- /// \brief Determines if the contained matcher can be converted to \p Kind.
- ///
- /// \param Kind the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
- unsigned *Specificity) const {
- if (Value)
- return Value->isConvertibleTo(Kind, Specificity);
- return false;
- }
-
- /// \brief Return this matcher as a \c Matcher<T>.
- ///
- /// Handles the different types (Single, Polymorphic) accordingly.
- /// Asserts that \c hasTypedMatcher<T>() is true.
- template <class T>
- ast_matchers::internal::Matcher<T> getTypedMatcher() const {
- assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
- return Value->getTypedMatcher(TypedMatcherOps<T>())
- ->template convertTo<T>();
- }
-
- /// \brief String representation of the type of the value.
- ///
- /// If the underlying matcher is a polymorphic one, the string will show all
- /// the types.
- std::string getTypeAsString() const;
-
-private:
- explicit VariantMatcher(Payload *Value) : Value(Value) {}
-
- template <typename T> struct TypedMatcherOps;
-
- class SinglePayload;
- class PolymorphicPayload;
- class VariadicOpPayload;
-
- IntrusiveRefCntPtr<const Payload> Value;
-};
-
-template <typename T>
-struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
- TypedMatcherOps()
- : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
- typedef ast_matchers::internal::Matcher<T> MatcherT;
-
- DynTypedMatcher
- convertMatcher(const DynTypedMatcher &Matcher) const override {
- return DynTypedMatcher(Matcher.convertTo<T>());
- }
-};
-
-/// \brief Variant value class.
-///
-/// Basically, a tagged union with value type semantics.
-/// It is used by the registry as the return value and argument type for the
-/// matcher factory methods.
-/// It can be constructed from any of the supported types. It supports
-/// copy/assignment.
-///
-/// Supported types:
-/// - \c unsigned
-/// - \c llvm::StringRef
-/// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
-class VariantValue {
-public:
- VariantValue() : Type(VT_Nothing) {}
-
- VariantValue(const VariantValue &Other);
- ~VariantValue();
- VariantValue &operator=(const VariantValue &Other);
-
- /// \brief Specific constructors for each supported type.
- VariantValue(unsigned Unsigned);
- VariantValue(StringRef String);
- VariantValue(const VariantMatcher &Matchers);
-
- /// \brief Returns true iff this is not an empty value.
- explicit operator bool() const { return hasValue(); }
- bool hasValue() const { return Type != VT_Nothing; }
-
- /// \brief Unsigned value functions.
- bool isUnsigned() const;
- unsigned getUnsigned() const;
- void setUnsigned(unsigned Unsigned);
-
- /// \brief String value functions.
- bool isString() const;
- const std::string &getString() const;
- void setString(StringRef String);
-
- /// \brief Matcher value functions.
- bool isMatcher() const;
- const VariantMatcher &getMatcher() const;
- void setMatcher(const VariantMatcher &Matcher);
-
- /// \brief Determines if the contained value can be converted to \p Kind.
- ///
- /// \param Kind the requested destination type.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion.
- bool isConvertibleTo(ArgKind Kind, unsigned* Specificity) const;
-
- /// \brief Determines if the contained value can be converted to any kind
- /// in \p Kinds.
- ///
- /// \param Kinds the requested destination types.
- ///
- /// \param Specificity value corresponding to the "specificity" of the
- /// convertion. It is the maximum specificity of all the possible
- /// conversions.
- bool isConvertibleTo(ArrayRef<ArgKind> Kinds, unsigned *Specificity) const;
-
- /// \brief String representation of the type of the value.
- std::string getTypeAsString() const;
-
-private:
- void reset();
-
- /// \brief All supported value types.
- enum ValueType {
- VT_Nothing,
- VT_Unsigned,
- VT_String,
- VT_Matcher
- };
-
- /// \brief All supported value types.
- union AllValues {
- unsigned Unsigned;
- std::string *String;
- VariantMatcher *Matcher;
- };
-
- ValueType Type;
- AllValues Value;
-};
-
-} // end namespace dynamic
-} // end namespace ast_matchers
-} // end namespace clang
-
-#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
OpenPOWER on IntegriCloud