Bring back the virtual functions.
http://reviews.llvm.org/D5124
Files:
include/clang/ASTMatchers/ASTMatchersInternal.h
include/clang/ASTMatchers/Dynamic/VariantValue.h
lib/ASTMatchers/ASTMatchersInternal.cpp
lib/ASTMatchers/Dynamic/VariantValue.cpp
Index: include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchersInternal.h
+++ include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -372,9 +372,9 @@
/// This method verifies that the underlying matcher in \c Other can process
/// nodes of types T.
template <typename T> bool canConvertTo() const {
- return getSupportedKind().isBaseOf(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+ return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
}
+ bool canConvertTo(ast_type_traits::ASTNodeKind To) const;
/// \brief Construct a \c Matcher<T> interface around the dynamic matcher.
///
@@ -460,16 +460,8 @@
/// \brief Specialization of the conversion functions for QualType.
///
-/// These specializations provide the Matcher<Type>->Matcher<QualType>
+/// This specialization provides the Matcher<Type>->Matcher<QualType>
/// conversion that the static API does.
-template <> inline bool DynTypedMatcher::canConvertTo<QualType>() const {
- const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
- return SourceKind.isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<Type>()) ||
- SourceKind.isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>());
-}
-
template <>
inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
assert(canConvertTo<QualType>());
Index: include/clang/ASTMatchers/Dynamic/VariantValue.h
===================================================================
--- include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -93,13 +93,26 @@
/// \brief Methods that depend on T from hasTypedMatcher/getTypedMatcher.
class MatcherOps {
public:
- virtual ~MatcherOps();
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const = 0;
- virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
- virtual void constructVariadicOperator(
+ MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
+
+ bool canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const;
+ virtual void *constructFrom(const DynTypedMatcher &Matcher) const = 0;
+ void *constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers);
+
+ private:
+ /// \brief Constructs a variadic typed matcher from \p M.
+ /// Returns a Matcher<T>* as a void*.
+ virtual void *constructVariadicOperator(
ast_matchers::internal::VariadicOperatorFunction Func,
- ArrayRef<VariantMatcher> InnerMatchers) = 0;
+ ArrayRef<DynTypedMatcher> M) const = 0;
+ /// \brief Constructs a DynTypedMatcher out of \p M.
+ /// \p M is a Matcher<T>* as a void* and will be deleted by this function.
+ virtual DynTypedMatcher dynamicConstructFromConsume(void *M) const = 0;
+
+ ast_type_traits::ASTNodeKind NodeKind;
};
/// \brief Payload interface to be specialized by each matcher type.
@@ -110,7 +123,7 @@
virtual ~Payload();
virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
virtual std::string getTypeAsString() const = 0;
- virtual void makeTypedMatcher(MatcherOps &Ops) const = 0;
+ virtual void* makeTypedMatcher(MatcherOps &Ops) const = 0;
virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const = 0;
};
@@ -158,9 +171,10 @@
/// that can, the result would be ambiguous and false is returned.
template <class T>
bool hasTypedMatcher() const {
- TypedMatcherOps<T> Ops;
- if (Value) Value->makeTypedMatcher(Ops);
- return Ops.hasMatcher();
+ auto *M = maybeGetTypedMatcher<T>();
+ bool Result = M != nullptr;
+ delete M;
+ return Result;
}
/// \brief Determines if the contained matcher can be converted to \p Kind.
@@ -182,10 +196,11 @@
/// Asserts that \c hasTypedMatcher<T>() is true.
template <class T>
ast_matchers::internal::Matcher<T> getTypedMatcher() const {
- TypedMatcherOps<T> Ops;
- Value->makeTypedMatcher(Ops);
- assert(Ops.hasMatcher() && "hasTypedMatcher<T>() == false");
- return Ops.matcher();
+ auto *M = maybeGetTypedMatcher<T>();
+ assert(M != nullptr && "hasTypedMatcher<T>() == false");
+ auto Result = *M;
+ delete M;
+ return Result;
}
/// \brief String representation of the type of the value.
@@ -197,51 +212,47 @@
private:
explicit VariantMatcher(Payload *Value) : Value(Value) {}
+ template <typename T> struct TypedMatcherOps;
+
+ template <class T>
+ ast_matchers::internal::Matcher<T>* maybeGetTypedMatcher() const {
+ if (!Value) return nullptr;
+ TypedMatcherOps<T> Ops;
+ return static_cast<ast_matchers::internal::Matcher<T> *>(
+ Value->makeTypedMatcher(Ops));
+ }
+
class SinglePayload;
class PolymorphicPayload;
class VariadicOpPayload;
- template <typename T>
- class TypedMatcherOps : public MatcherOps {
- public:
- typedef ast_matchers::internal::Matcher<T> MatcherT;
-
- virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
- bool &IsExactMatch) const {
- IsExactMatch = Matcher.getSupportedKind().isSame(
- ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
- return Matcher.canConvertTo<T>();
- }
+ IntrusiveRefCntPtr<const Payload> Value;
+};
- virtual void constructFrom(const DynTypedMatcher& Matcher) {
- Out.reset(new MatcherT(Matcher.convertTo<T>()));
- }
+template <typename T>
+struct VariantMatcher::TypedMatcherOps : VariantMatcher::MatcherOps {
+ TypedMatcherOps()
+ : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
+ typedef ast_matchers::internal::Matcher<T> MatcherT;
- virtual void constructVariadicOperator(
- ast_matchers::internal::VariadicOperatorFunction Func,
- ArrayRef<VariantMatcher> InnerMatchers) {
- std::vector<DynTypedMatcher> DynMatchers;
- for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
- // Abort if any of the inner matchers can't be converted to
- // Matcher<T>.
- if (!InnerMatchers[i].hasTypedMatcher<T>()) {
- return;
- }
- DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
- }
- Out.reset(new MatcherT(
- new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
- Func, DynMatchers)));
- }
-
- bool hasMatcher() const { return Out.get() != nullptr; }
- const MatcherT &matcher() const { return *Out; }
+ void *constructFrom(const DynTypedMatcher &Matcher) const override {
+ return new MatcherT(Matcher.convertTo<T>());
+ }
- private:
- std::unique_ptr<MatcherT> Out;
- };
+ DynTypedMatcher dynamicConstructFromConsume(void *M) const override {
+ MatcherT *TypedM = static_cast<MatcherT *>(M);
+ DynTypedMatcher Out = *TypedM;
+ delete TypedM;
+ return Out;
+ }
- IntrusiveRefCntPtr<const Payload> Value;
+ void *constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<DynTypedMatcher> InnerMatchers) const override {
+ return new MatcherT(
+ new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
+ Func, InnerMatchers));
+ }
};
/// \brief Variant value class.
Index: lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- lib/ASTMatchers/ASTMatchersInternal.cpp
+++ lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -26,6 +26,16 @@
}
}
+bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
+ const auto SourceKind = getSupportedKind();
+ auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
+ auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
+ if (To.isSame(QualKind)) {
+ return SourceKind.isSame(TypeKind) || SourceKind.isSame(QualKind);
+ }
+ return SourceKind.isBaseOf(To);
+}
+
DynTypedMatcher::MatcherStorage::~MatcherStorage() {}
void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Index: lib/ASTMatchers/Dynamic/VariantValue.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -49,7 +49,30 @@
return true;
}
-VariantMatcher::MatcherOps::~MatcherOps() {}
+bool
+VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher,
+ bool &IsExactMatch) const {
+ IsExactMatch = Matcher.getSupportedKind().isSame(NodeKind);
+ return Matcher.canConvertTo(NodeKind);
+}
+
+void *VariantMatcher::MatcherOps::constructVariadicOperator(
+ ast_matchers::internal::VariadicOperatorFunction Func,
+ ArrayRef<VariantMatcher> InnerMatchers) {
+ std::vector<DynTypedMatcher> DynMatchers;
+ for (const auto &InnerMatcher : InnerMatchers) {
+ // Abort if any of the inner matchers can't be converted to
+ // Matcher<T>.
+ if (!InnerMatcher.Value)
+ return nullptr;
+ void* Inner = InnerMatcher.Value->makeTypedMatcher(*this);
+ if (!Inner)
+ return nullptr;
+ DynMatchers.push_back(dynamicConstructFromConsume(Inner));
+ }
+ return constructVariadicOperator(Func, DynMatchers);
+}
+
VariantMatcher::Payload::~Payload() {}
class VariantMatcher::SinglePayload : public VariantMatcher::Payload {
@@ -65,10 +88,11 @@
.str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ void* makeTypedMatcher(MatcherOps &Ops) const override {
bool Ignore;
if (Ops.canConstructFrom(Matcher, Ignore))
- Ops.constructFrom(Matcher);
+ return Ops.constructFrom(Matcher);
+ return nullptr;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -104,7 +128,7 @@
return (Twine("Matcher<") + Inner + ">").str();
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
+ void* makeTypedMatcher(MatcherOps &Ops) const override {
bool FoundIsExact = false;
const DynTypedMatcher *Found = nullptr;
int NumFound = 0;
@@ -124,7 +148,8 @@
}
// We only succeed if we found exactly one, or if we found an exact match.
if (Found && (FoundIsExact || NumFound == 1))
- Ops.constructFrom(*Found);
+ return Ops.constructFrom(*Found);
+ return nullptr;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
@@ -165,8 +190,8 @@
return Inner;
}
- void makeTypedMatcher(MatcherOps &Ops) const override {
- Ops.constructVariadicOperator(Func, Args);
+ void* makeTypedMatcher(MatcherOps &Ops) const override {
+ return Ops.constructVariadicOperator(Func, Args);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits