summaryrefslogtreecommitdiffstats
path: root/lib/ASTMatchers/Dynamic/VariantValue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ASTMatchers/Dynamic/VariantValue.cpp')
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
new file mode 100644
index 0000000..3e49e1b
--- /dev/null
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -0,0 +1,256 @@
+//===--- VariantValue.cpp - 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.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+VariantMatcher::MatcherOps::~MatcherOps() {}
+VariantMatcher::Payload::~Payload() {}
+
+class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
+public:
+ SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher) {}
+
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ return Matcher;
+ }
+
+ virtual std::string getTypeAsString() const {
+ return (Twine("Matcher<") + Matcher.getSupportedKind().asStringRef() + ">")
+ .str();
+ }
+
+ virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ if (Ops.canConstructFrom(Matcher))
+ Ops.constructFrom(Matcher);
+ }
+
+private:
+ const DynTypedMatcher Matcher;
+};
+
+class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
+public:
+ PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
+ : Matchers(MatchersIn) {}
+
+ virtual ~PolymorphicPayload() {}
+
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ if (Matchers.size() != 1)
+ return llvm::Optional<DynTypedMatcher>();
+ return Matchers[0];
+ }
+
+ virtual std::string getTypeAsString() const {
+ std::string Inner;
+ for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
+ if (i != 0)
+ Inner += "|";
+ Inner += Matchers[i].getSupportedKind().asStringRef();
+ }
+ return (Twine("Matcher<") + Inner + ">").str();
+ }
+
+ virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ const DynTypedMatcher *Found = NULL;
+ for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
+ if (Ops.canConstructFrom(Matchers[i])) {
+ if (Found)
+ return;
+ Found = &Matchers[i];
+ }
+ }
+ if (Found)
+ Ops.constructFrom(*Found);
+ }
+
+ const std::vector<DynTypedMatcher> Matchers;
+};
+
+class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
+public:
+ VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> Args)
+ : Func(Func), Args(Args) {}
+
+ virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
+ return llvm::Optional<DynTypedMatcher>();
+ }
+
+ virtual std::string getTypeAsString() const {
+ std::string Inner;
+ for (size_t i = 0, e = Args.size(); i != e; ++i) {
+ if (i != 0)
+ Inner += "&";
+ Inner += Args[i].getTypeAsString();
+ }
+ return Inner;
+ }
+
+ virtual void makeTypedMatcher(MatcherOps &Ops) const {
+ Ops.constructVariadicOperator(Func, Args);
+ }
+
+private:
+ const ast_matchers::internal::VariadicOperatorFunction Func;
+ const std::vector<VariantMatcher> Args;
+};
+
+VariantMatcher::VariantMatcher() {}
+
+VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) {
+ return VariantMatcher(new SinglePayload(Matcher));
+}
+
+VariantMatcher
+VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
+ return VariantMatcher(new PolymorphicPayload(Matchers));
+}
+
+VariantMatcher VariantMatcher::VariadicOperatorMatcher(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> Args) {
+ return VariantMatcher(new VariadicOpPayload(Func, Args));
+}
+
+llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
+ return Value ? Value->getSingleMatcher() : llvm::Optional<DynTypedMatcher>();
+}
+
+void VariantMatcher::reset() { Value.reset(); }
+
+std::string VariantMatcher::getTypeAsString() const {
+ if (Value) return Value->getTypeAsString();
+ return "<Nothing>";
+}
+
+VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
+ *this = Other;
+}
+
+VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
+ setUnsigned(Unsigned);
+}
+
+VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
+ setString(String);
+}
+
+VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) {
+ setMatcher(Matcher);
+}
+
+VariantValue::~VariantValue() { reset(); }
+
+VariantValue &VariantValue::operator=(const VariantValue &Other) {
+ if (this == &Other) return *this;
+ reset();
+ switch (Other.Type) {
+ case VT_Unsigned:
+ setUnsigned(Other.getUnsigned());
+ break;
+ case VT_String:
+ setString(Other.getString());
+ break;
+ case VT_Matcher:
+ setMatcher(Other.getMatcher());
+ break;
+ case VT_Nothing:
+ Type = VT_Nothing;
+ break;
+ }
+ return *this;
+}
+
+void VariantValue::reset() {
+ switch (Type) {
+ case VT_String:
+ delete Value.String;
+ break;
+ case VT_Matcher:
+ delete Value.Matcher;
+ break;
+ // Cases that do nothing.
+ case VT_Unsigned:
+ case VT_Nothing:
+ break;
+ }
+ Type = VT_Nothing;
+}
+
+bool VariantValue::isUnsigned() const {
+ return Type == VT_Unsigned;
+}
+
+unsigned VariantValue::getUnsigned() const {
+ assert(isUnsigned());
+ return Value.Unsigned;
+}
+
+void VariantValue::setUnsigned(unsigned NewValue) {
+ reset();
+ Type = VT_Unsigned;
+ Value.Unsigned = NewValue;
+}
+
+bool VariantValue::isString() const {
+ return Type == VT_String;
+}
+
+const std::string &VariantValue::getString() const {
+ assert(isString());
+ return *Value.String;
+}
+
+void VariantValue::setString(const std::string &NewValue) {
+ reset();
+ Type = VT_String;
+ Value.String = new std::string(NewValue);
+}
+
+bool VariantValue::isMatcher() const {
+ return Type == VT_Matcher;
+}
+
+const VariantMatcher &VariantValue::getMatcher() const {
+ assert(isMatcher());
+ return *Value.Matcher;
+}
+
+void VariantValue::setMatcher(const VariantMatcher &NewValue) {
+ reset();
+ Type = VT_Matcher;
+ Value.Matcher = new VariantMatcher(NewValue);
+}
+
+std::string VariantValue::getTypeAsString() const {
+ switch (Type) {
+ case VT_String: return "String";
+ case VT_Matcher: return getMatcher().getTypeAsString();
+ case VT_Unsigned: return "Unsigned";
+ case VT_Nothing: return "Nothing";
+ }
+ llvm_unreachable("Invalid Type");
+}
+
+} // end namespace dynamic
+} // end namespace ast_matchers
+} // end namespace clang
OpenPOWER on IntegriCloud