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.h151
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h75
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h261
4 files changed, 672 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
new file mode 100644
index 0000000..aec0c0e
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -0,0 +1,185 @@
+//===--- 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_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
+
+#include <string>
+#include <vector>
+
+#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"
+
+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_RegistryNotFound = 1,
+ ET_RegistryWrongArgCount = 2,
+ ET_RegistryWrongArgType = 3,
+ ET_RegistryNotBindable = 4,
+ ET_RegistryAmbiguousOverload = 5,
+
+ 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,
+ const SourceRange &MatcherRange);
+ /// \brief About to recurse into parsing one argument for a matcher.
+ enum MatcherArgEnum { MatcherArg };
+ Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName,
+ const 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(const 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
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
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
new file mode 100644
index 0000000..c113c14
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -0,0 +1,75 @@
+//===--- 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_AST_MATCHERS_DYNAMIC_REGISTRY_H
+#define LLVM_CLANG_AST_MATCHERS_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/StringRef.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+class Registry {
+public:
+ /// \brief Construct a matcher from the registry by name.
+ ///
+ /// Consult the registry of known matchers and construct the appropriate
+ /// matcher by name.
+ ///
+ /// \param MatcherName The name of the matcher 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 matcher is not found, or 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(StringRef MatcherName,
+ const 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(StringRef MatcherName,
+ const SourceRange &NameRange,
+ StringRef BindID,
+ ArrayRef<ParserValue> Args,
+ Diagnostics *Error);
+
+private:
+ Registry() LLVM_DELETED_FUNCTION;
+};
+
+} // 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
new file mode 100644
index 0000000..b9bc017
--- /dev/null
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -0,0 +1,261 @@
+//===--- 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_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
+#define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
+
+#include <vector>
+
+#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 "llvm/Support/type_traits.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+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:
+ virtual ~MatcherOps();
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0;
+ virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
+ virtual void constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers) = 0;
+ };
+
+ /// \brief Payload interface to be specialized by each matcher type.
+ ///
+ /// It follows a similar interface as VariantMatcher itself.
+ class Payload : public RefCountedBaseVPTR {
+ public:
+ virtual ~Payload();
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
+ virtual std::string getTypeAsString() const = 0;
+ virtual void makeTypedMatcher(MatcherOps &Ops) 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(ArrayRef<DynTypedMatcher> Matchers);
+
+ /// \brief Creates a 'variadic' operator matcher.
+ ///
+ /// It will bind to the appropriate type on getTypedMatcher<T>().
+ static VariantMatcher VariadicOperatorMatcher(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<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 {
+ TypedMatcherOps<T> Ops;
+ if (Value) Value->makeTypedMatcher(Ops);
+ return Ops.hasMatcher();
+ }
+
+ /// \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 {
+ TypedMatcherOps<T> Ops;
+ Value->makeTypedMatcher(Ops);
+ assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
+ return Ops.matcher();
+ }
+
+ /// \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) {}
+
+ class SinglePayload;
+ class PolymorphicPayload;
+ class VariadicOpPayload;
+
+ template <typename T>
+ class TypedMatcherOps : public MatcherOps {
+ public:
+ typedef ast_matchers::internal::Matcher<T> MatcherT;
+
+ virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
+ return Matcher.canConvertTo<T>();
+ }
+
+ virtual void constructFrom(const DynTypedMatcher& Matcher) {
+ Out.reset(new MatcherT(Matcher.convertTo<T>()));
+ }
+
+ virtual void constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers) {
+ const size_t NumArgs = InnerMatchers.size();
+ MatcherT **InnerArgs = new MatcherT *[NumArgs]();
+ bool HasError = false;
+ for (size_t i = 0; i != NumArgs; ++i) {
+ // Abort if any of the inner matchers can't be converted to
+ // Matcher<T>.
+ if (!InnerMatchers[i].hasTypedMatcher<T>()) {
+ HasError = true;
+ break;
+ }
+ InnerArgs[i] = new MatcherT(InnerMatchers[i].getTypedMatcher<T>());
+ }
+ if (!HasError) {
+ Out.reset(new MatcherT(
+ new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
+ Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
+ }
+ for (size_t i = 0; i != NumArgs; ++i) {
+ delete InnerArgs[i];
+ }
+ delete[] InnerArgs;
+ }
+
+ bool hasMatcher() const { return Out.get() != NULL; }
+ const MatcherT &matcher() const { return *Out; }
+
+ private:
+ OwningPtr<MatcherT> Out;
+ };
+
+ IntrusiveRefCntPtr<const Payload> Value;
+};
+
+/// \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 std::string
+/// - \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(const std::string &String);
+ VariantValue(const VariantMatcher &Matchers);
+
+ /// \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(const std::string &String);
+
+ /// \brief Matcher value functions.
+ bool isMatcher() const;
+ const VariantMatcher &getMatcher() const;
+ void setMatcher(const VariantMatcher &Matcher);
+
+ /// \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