diff options
Diffstat (limited to 'include/clang/ASTMatchers/Dynamic/VariantValue.h')
-rw-r--r-- | include/clang/ASTMatchers/Dynamic/VariantValue.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h new file mode 100644 index 0000000000..9a41b448cf --- /dev/null +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -0,0 +1,125 @@ +//===--- 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 "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersInternal.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 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 std::string +/// - \c DynTypedMatcher, and any \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(const std::string &String); + VariantValue(const DynTypedMatcher &Matcher); + + /// \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 DynTypedMatcher &getMatcher() const; + void setMatcher(const DynTypedMatcher &Matcher); + /// \brief Set the value to be \c Matcher by taking ownership of the object. + void takeMatcher(DynTypedMatcher *Matcher); + + /// \brief Specialized Matcher<T> is/get functions. + template <class T> + bool isTypedMatcher() const { + // TODO: Add some logic to test if T is actually valid for the underlying + // type of the matcher. + return isMatcher(); + } + + template <class T> + ast_matchers::internal::Matcher<T> getTypedMatcher() const { + return ast_matchers::internal::makeMatcher( + new DerivedTypeMatcher<T>(getMatcher())); + } + +private: + void reset(); + + /// \brief Matcher bridge between a Matcher<T> and a generic DynTypedMatcher. + template <class T> + class DerivedTypeMatcher : + public ast_matchers::internal::MatcherInterface<T> { + public: + explicit DerivedTypeMatcher(const DynTypedMatcher &DynMatcher) + : DynMatcher(DynMatcher.clone()) {} + virtual ~DerivedTypeMatcher() {} + + typedef ast_matchers::internal::ASTMatchFinder ASTMatchFinder; + typedef ast_matchers::internal::BoundNodesTreeBuilder BoundNodesTreeBuilder; + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return DynMatcher->matches(ast_type_traits::DynTypedNode::create(Node), + Finder, Builder); + } + + private: + const OwningPtr<DynTypedMatcher> DynMatcher; + }; + + /// \brief All supported value types. + enum ValueType { + VT_Nothing, + VT_String, + VT_Matcher + }; + + /// \brief All supported value types. + union AllValues { + std::string *String; + DynTypedMatcher *Matcher; + }; + + ValueType Type; + AllValues Value; +}; + +} // end namespace dynamic +} // end namespace ast_matchers +} // end namespace clang + +#endif // LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H |