diff options
author | Samuel Benzaquen <sbenza@google.com> | 2013-08-22 16:38:33 +0000 |
---|---|---|
committer | Samuel Benzaquen <sbenza@google.com> | 2013-08-22 16:38:33 +0000 |
commit | 8c9f6330e67380d3659b81d02e6492fd99e5c1c2 (patch) | |
tree | 57b313b045d37290df41a5cd3186f27041912377 /clang/lib/ASTMatchers/Dynamic/VariantValue.cpp | |
parent | 4cfe5546015cf30674b931281f622b5ef0dc27d0 (diff) | |
download | bcm5719-llvm-8c9f6330e67380d3659b81d02e6492fd99e5c1c2.tar.gz bcm5719-llvm-8c9f6330e67380d3659b81d02e6492fd99e5c1c2.zip |
Refactor VariantMatcher to use an interface underneath.
Summary:
Refactor VariantMatcher to use an interface underneath.
It supports "Single" and "Polymorphic". Will support more in the future.
Reviewers: klimek
CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D1446
llvm-svn: 189032
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) { |