Add support for polymorphic matchers. Use runtime type checking to determine the right polymorphic overload to use.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184558 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 912858f..79c5c8e 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -20,6 +20,48 @@
namespace ast_matchers {
namespace dynamic {
+MatcherList::MatcherList() : List() {}
+
+MatcherList::MatcherList(const DynTypedMatcher &Matcher)
+ : List(1, Matcher.clone()) {}
+
+MatcherList::MatcherList(const MatcherList& Other) {
+ *this = Other;
+}
+
+MatcherList::~MatcherList() {
+ reset();
+}
+
+MatcherList &MatcherList::operator=(const MatcherList &Other) {
+ if (this == &Other) return *this;
+ reset();
+ for (size_t i = 0, e = Other.List.size(); i != e; ++i) {
+ List.push_back(Other.List[i]->clone());
+ }
+ return *this;
+}
+
+void MatcherList::add(const DynTypedMatcher &Matcher) {
+ List.push_back(Matcher.clone());
+}
+
+void MatcherList::reset() {
+ for (size_t i = 0, e = List.size(); i != e; ++i) {
+ delete List[i];
+ }
+ List.resize(0);
+}
+
+std::string MatcherList::getTypeAsString() const {
+ std::string Inner;
+ for (size_t I = 0, E = List.size(); I != E; ++I) {
+ if (I != 0) Inner += "|";
+ Inner += List[I]->getSupportedKind().asStringRef();
+ }
+ return (Twine("Matcher<") + Inner + ">").str();
+}
+
VariantValue::VariantValue(const VariantValue &Other) : Type(VT_Nothing) {
*this = Other;
}
@@ -33,7 +75,11 @@
}
VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
- setMatcher(Matcher);
+ setMatchers(MatcherList(Matcher));
+}
+
+VariantValue::VariantValue(const MatcherList &Matchers) : Type(VT_Nothing) {
+ setMatchers(Matchers);
}
VariantValue::~VariantValue() { reset(); }
@@ -48,8 +94,8 @@
case VT_String:
setString(Other.getString());
break;
- case VT_Matcher:
- setMatcher(Other.getMatcher());
+ case VT_Matchers:
+ setMatchers(Other.getMatchers());
break;
case VT_Nothing:
Type = VT_Nothing;
@@ -63,8 +109,8 @@
case VT_String:
delete Value.String;
break;
- case VT_Matcher:
- delete Value.Matcher;
+ case VT_Matchers:
+ delete Value.Matchers;
break;
// Cases that do nothing.
case VT_Unsigned:
@@ -104,33 +150,25 @@
Value.String = new std::string(NewValue);
}
-bool VariantValue::isMatcher() const {
- return Type == VT_Matcher;
+bool VariantValue::isMatchers() const {
+ return Type == VT_Matchers;
}
-const DynTypedMatcher &VariantValue::getMatcher() const {
- assert(isMatcher());
- return *Value.Matcher;
+const MatcherList &VariantValue::getMatchers() const {
+ assert(isMatchers());
+ return *Value.Matchers;
}
-void VariantValue::setMatcher(const DynTypedMatcher &NewValue) {
+void VariantValue::setMatchers(const MatcherList &NewValue) {
reset();
- Type = VT_Matcher;
- Value.Matcher = NewValue.clone();
-}
-
-void VariantValue::takeMatcher(DynTypedMatcher *NewValue) {
- reset();
- Type = VT_Matcher;
- Value.Matcher = NewValue;
+ Type = VT_Matchers;
+ Value.Matchers = new MatcherList(NewValue);
}
std::string VariantValue::getTypeAsString() const {
switch (Type) {
case VT_String: return "String";
- case VT_Matcher:
- return (Twine("Matcher<") + getMatcher().getSupportedKind().asStringRef() +
- ">").str();
+ case VT_Matchers: return getMatchers().getTypeAsString();
case VT_Unsigned: return "Unsigned";
case VT_Nothing: return "Nothing";
}