diff options
Diffstat (limited to 'clang/lib/ASTMatchers/Dynamic/VariantValue.cpp')
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/VariantValue.cpp | 134 |
1 files changed, 85 insertions, 49 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp index a8fd7c6bbb9..87aca7da853 100644 --- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -21,69 +21,105 @@ namespace clang { namespace ast_matchers { namespace dynamic { -VariantMatcher::VariantMatcher() : List() {} +VariantMatcher::MatcherOps::~MatcherOps() {} +VariantMatcher::Payload::~Payload() {} -VariantMatcher::VariantMatcher(const VariantMatcher& Other) { - *this = Other; -} +class VariantMatcher::SinglePayload : public VariantMatcher::Payload { +public: + SinglePayload(const DynTypedMatcher &Matcher) : Matcher(Matcher.clone()) {} -VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) { - VariantMatcher Out; - Out.List.push_back(Matcher.clone()); - return Out; -} + virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const { + Out = Matcher.get(); + return true; + } -VariantMatcher -VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) { - VariantMatcher Out; - for (size_t i = 0, e = Matchers.size(); i != e; ++i) { - Out.List.push_back(Matchers[i]->clone()); + virtual std::string getTypeAsString() const { + return (Twine("Matcher<") + Matcher->getSupportedKind().asStringRef() + ">") + .str(); } - return Out; -} -VariantMatcher::~VariantMatcher() { - reset(); -} + virtual bool hasTypedMatcher(const MatcherOps &Ops) const { + return Ops.canConstructFrom(*Matcher); + } -VariantMatcher &VariantMatcher::operator=(const VariantMatcher &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()); + virtual const DynTypedMatcher *getTypedMatcher(const MatcherOps &Ops) const { + assert(hasTypedMatcher(Ops)); + return Matcher.get(); } - return *this; -} -bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const { - if (List.size() != 1) return false; - Out = List[0]; - return true; -} +private: + OwningPtr<const DynTypedMatcher> Matcher; +}; -void VariantMatcher::reset() { - llvm::DeleteContainerPointers(List); -} +class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload { +public: + PolymorphicPayload(ArrayRef<const DynTypedMatcher *> MatchersIn) { + for (size_t i = 0, e = MatchersIn.size(); i != e; ++i) { + Matchers.push_back(MatchersIn[i]->clone()); + } + } -std::string VariantMatcher::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(); + virtual ~PolymorphicPayload() { + llvm::DeleteContainerPointers(Matchers); } - return (Twine("Matcher<") + Inner + ">").str(); -} -const DynTypedMatcher *VariantMatcher::getTypedMatcher( - bool (*CanConstructCallback)(const DynTypedMatcher &)) const { - const DynTypedMatcher *Out = NULL; - for (size_t i = 0, e = List.size(); i != e; ++i) { - if (CanConstructCallback(*List[i])) { - if (Out) return NULL; - Out = List[i]; + virtual bool getSingleMatcher(const DynTypedMatcher *&Out) const { + if (Matchers.size() != 1) + return false; + Out = Matchers[0]; + return true; + } + + 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 bool hasTypedMatcher(const MatcherOps &Ops) const { + return getTypedMatcher(Ops) != NULL; } - return Out; + + virtual const DynTypedMatcher *getTypedMatcher(const 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 NULL; + Found = Matchers[i]; + } + } + return Found; + } + +private: + std::vector<const DynTypedMatcher *> Matchers; +}; + +VariantMatcher::VariantMatcher() {} + +VariantMatcher VariantMatcher::SingleMatcher(const DynTypedMatcher &Matcher) { + return VariantMatcher(new SinglePayload(Matcher)); +} + +VariantMatcher +VariantMatcher::PolymorphicMatcher(ArrayRef<const DynTypedMatcher *> Matchers) { + return VariantMatcher(new PolymorphicPayload(Matchers)); +} + +bool VariantMatcher::getSingleMatcher(const DynTypedMatcher *&Out) const { + if (Value) return Value->getSingleMatcher(Out); + return false; +} + +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) { |