Remove clang::ast_type_traits namespace in favor of clang

DynTypedNode and ASTNodeKind are implemented as part of the clang AST
library, which uses the main clang namespace. There doesn't seem to be a
need for this extra level of namespacing.

I left behind aliases in the ast_type_traits namespace for out of tree
clients of these APIs. To provide aliases for the enumerators, I used
this pattern:
  namespace ast_type_traits {
  constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs;
  }
I think the typedefs will be useful for migration, but we might be able
to drop these enumerator aliases.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D74499
This commit is contained in:
Reid Kleckner 2020-02-12 11:34:13 -08:00
parent 2fb6268854
commit cd62511496
29 changed files with 474 additions and 596 deletions

View File

@ -7381,11 +7381,11 @@ Usable as: Any Matcher
</pre></td></tr>
<tr><td>Matcher&lt;T&gt;</td><td class="name" onclick="toggle('traverse1')"><a name="traverse1Anchor">traverse</a></td><td>ast_type_traits::TraversalKind TK, const BindableMatcher&lt;T&gt; InnerMatcher</td></tr>
<tr><td>Matcher&lt;T&gt;</td><td class="name" onclick="toggle('traverse1')"><a name="traverse1Anchor">traverse</a></td><td>TraversalKind TK, const BindableMatcher&lt;T&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="traverse1"><pre></pre></td></tr>
<tr><td>Matcher&lt;T&gt;</td><td class="name" onclick="toggle('traverse0')"><a name="traverse0Anchor">traverse</a></td><td>ast_type_traits::TraversalKind TK, const Matcher&lt;T&gt; InnerMatcher</td></tr>
<tr><td>Matcher&lt;T&gt;</td><td class="name" onclick="toggle('traverse0')"><a name="traverse0Anchor">traverse</a></td><td>TraversalKind TK, const Matcher&lt;T&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="traverse0"><pre>Causes all nested matchers to be matched with the specified traversal kind.
Given
@ -7394,7 +7394,7 @@ Given
int i = 3.0;
}
The matcher
traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
traverse(TK_IgnoreImplicitCastsAndParentheses,
varDecl(hasInitializer(floatLiteral().bind("init")))
)
matches the variable declaration with "init" bound to the "3.0".

View File

@ -94,6 +94,7 @@ class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
class ParentMapContext;
class DynTypedNode;
class DynTypedNodeList;
class Expr;
class FixedPointSemantics;
@ -130,9 +131,6 @@ class VarTemplateDecl;
class VTableContextBase;
struct BlockVarCopyInit;
namespace ast_type_traits {
class DynTypedNode;
}
namespace Builtin {

View File

@ -66,8 +66,7 @@ class ASTNodeTraverser
/// not already been loaded.
bool Deserialize = false;
ast_type_traits::TraversalKind Traversal =
ast_type_traits::TraversalKind::TK_AsIs;
TraversalKind Traversal = TraversalKind::TK_AsIs;
NodeDelegateType &getNodeDelegate() {
return getDerived().doGetNodeDelegate();
@ -78,7 +77,7 @@ public:
void setDeserialize(bool D) { Deserialize = D; }
bool getDeserialize() const { return Deserialize; }
void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
void Visit(const Decl *D) {
getNodeDelegate().AddChild([=] {
@ -109,12 +108,12 @@ public:
if (auto *E = dyn_cast_or_null<Expr>(S)) {
switch (Traversal) {
case ast_type_traits::TK_AsIs:
case TK_AsIs:
break;
case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
case TK_IgnoreImplicitCastsAndParentheses:
S = E->IgnoreParenImpCasts();
break;
case ast_type_traits::TK_IgnoreUnlessSpelledInSource:
case TK_IgnoreUnlessSpelledInSource:
S = E->IgnoreUnlessSpelledInSource();
break;
}
@ -132,8 +131,7 @@ public:
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S))
return;
if (isa<LambdaExpr>(S) &&
Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource)
if (isa<LambdaExpr>(S) && Traversal == TK_IgnoreUnlessSpelledInSource)
return;
for (const Stmt *SubStmt : S->children())
@ -229,7 +227,7 @@ public:
});
}
void Visit(const ast_type_traits::DynTypedNode &N) {
void Visit(const DynTypedNode &N) {
// FIXME: Improve this with a switch or a visitor pattern.
if (const auto *D = N.get<Decl>())
Visit(D);
@ -659,7 +657,7 @@ public:
}
void VisitLambdaExpr(const LambdaExpr *Node) {
if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) {
if (Traversal == TK_IgnoreUnlessSpelledInSource) {
for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
const auto *C = Node->capture_begin() + I;
if (!C->isExplicit())

View File

@ -33,8 +33,6 @@ namespace clang {
struct PrintingPolicy;
namespace ast_type_traits {
/// Defines how we descend a level in the AST when we pass
/// through expressions.
enum TraversalKind {
@ -522,18 +520,29 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
}
};
} // end namespace ast_type_traits
// Previously these types were defined in the clang::ast_type_traits namespace.
// Provide typedefs so that legacy code can be fixed asynchronously.
namespace ast_type_traits {
using DynTypedNode = ::clang::DynTypedNode;
using ASTNodeKind = ::clang::ASTNodeKind;
using TraversalKind = ::clang::TraversalKind;
constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs;
constexpr TraversalKind TK_IgnoreImplicitCastsAndParentheses =
::clang::TK_IgnoreImplicitCastsAndParentheses;
constexpr TraversalKind TK_IgnoreUnlessSpelledInSource =
::clang::TK_IgnoreUnlessSpelledInSource;
} // namespace ast_type_traits
} // end namespace clang
namespace llvm {
template <>
struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind>
: clang::ast_type_traits::ASTNodeKind::DenseMapInfo {};
struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
template <>
struct DenseMapInfo<clang::ast_type_traits::DynTypedNode>
: clang::ast_type_traits::DynTypedNode::DenseMapInfo {};
struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
} // end namespace llvm

View File

@ -52,33 +52,31 @@ public:
/// NestedNameSpecifier or NestedNameSpecifierLoc.
template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node);
DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node);
DynTypedNodeList getParents(const DynTypedNode &Node);
/// Clear parent maps.
void clear();
ast_type_traits::TraversalKind getTraversalKind() const { return Traversal; }
void setTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; }
TraversalKind getTraversalKind() const { return Traversal; }
void setTraversalKind(TraversalKind TK) { Traversal = TK; }
const Expr *traverseIgnored(const Expr *E) const;
Expr *traverseIgnored(Expr *E) const;
ast_type_traits::DynTypedNode
traverseIgnored(const ast_type_traits::DynTypedNode &N) const;
DynTypedNode traverseIgnored(const DynTypedNode &N) const;
private:
ASTContext &ASTCtx;
class ParentMap;
ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
TraversalKind Traversal = TK_AsIs;
std::unique_ptr<ParentMap> Parents;
};
class TraversalKindScope {
ParentMapContext &Ctx;
ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs;
TraversalKind TK = TK_AsIs;
public:
TraversalKindScope(ASTContext &ASTCtx,
llvm::Optional<ast_type_traits::TraversalKind> ScopeTK)
TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK)
: Ctx(ASTCtx.getParentMapContext()) {
TK = Ctx.getTraversalKind();
if (ScopeTK)
@ -91,10 +89,9 @@ public:
/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
using DynTypedNode = ast_type_traits::DynTypedNode;
using DynTypedNode = DynTypedNode;
llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode,
ArrayRef<DynTypedNode>> Storage;
llvm::AlignedCharArrayUnion<DynTypedNode, ArrayRef<DynTypedNode>> Storage;
bool IsSingleNode;
public:
@ -106,14 +103,14 @@ public:
new (Storage.buffer) ArrayRef<DynTypedNode>(A);
}
const ast_type_traits::DynTypedNode *begin() const {
const DynTypedNode *begin() const {
if (!IsSingleNode)
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
->begin();
return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
}
const ast_type_traits::DynTypedNode *end() const {
const DynTypedNode *end() const {
if (!IsSingleNode)
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
->end();
@ -131,7 +128,7 @@ public:
template <typename NodeT>
inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) {
return getParents(ast_type_traits::DynTypedNode::create(Node));
return getParents(DynTypedNode::create(Node));
}
template <typename NodeT>
@ -140,8 +137,7 @@ inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) {
}
template <>
inline DynTypedNodeList
ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) {
return getParentMapContext().getParents(Node);
}

View File

@ -182,10 +182,9 @@ public:
///
/// @{
template <typename T> void match(const T &Node, ASTContext &Context) {
match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
match(clang::DynTypedNode::create(Node), Context);
}
void match(const clang::ast_type_traits::DynTypedNode &Node,
ASTContext &Context);
void match(const clang::DynTypedNode &Node, ASTContext &Context);
/// @}
/// Finds all matches in the given AST.
@ -242,9 +241,8 @@ SmallVector<BoundNodes, 1>
match(MatcherT Matcher, const NodeT &Node, ASTContext &Context);
template <typename MatcherT>
SmallVector<BoundNodes, 1>
match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
ASTContext &Context);
SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node,
ASTContext &Context);
/// @}
/// Returns the results of matching \p Matcher on the translation unit of
@ -283,9 +281,8 @@ public:
}
template <typename MatcherT>
SmallVector<BoundNodes, 1>
match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
ASTContext &Context) {
SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node,
ASTContext &Context) {
internal::CollectMatchesCallback Callback;
MatchFinder Finder;
Finder.addMatcher(Matcher, &Callback);
@ -296,7 +293,7 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node,
template <typename MatcherT, typename NodeT>
SmallVector<BoundNodes, 1>
match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) {
return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context);
return match(Matcher, DynTypedNode::create(Node), Context);
}
template <typename MatcherT>
@ -310,8 +307,8 @@ match(MatcherT Matcher, ASTContext &Context) {
}
inline SmallVector<BoundNodes, 1>
matchDynamic(internal::DynTypedMatcher Matcher,
const ast_type_traits::DynTypedNode &Node, ASTContext &Context) {
matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node,
ASTContext &Context) {
internal::CollectMatchesCallback Callback;
MatchFinder Finder;
Finder.addDynamicMatcher(Matcher, &Callback);
@ -323,8 +320,7 @@ template <typename NodeT>
SmallVector<BoundNodes, 1> matchDynamic(internal::DynTypedMatcher Matcher,
const NodeT &Node,
ASTContext &Context) {
return matchDynamic(Matcher, ast_type_traits::DynTypedNode::create(Node),
Context);
return matchDynamic(Matcher, DynTypedNode::create(Node), Context);
}
inline SmallVector<BoundNodes, 1>

View File

@ -115,7 +115,7 @@ public:
/// Type of mapping from binding identifiers to bound nodes. This type
/// is an associative container with a key type of \c std::string and a value
/// type of \c clang::ast_type_traits::DynTypedNode
/// type of \c clang::DynTypedNode
using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap;
/// Retrieve mapping from binding identifiers to bound nodes.
@ -722,13 +722,13 @@ AST_POLYMORPHIC_MATCHER_P(
/// \endcode
/// The matcher
/// \code
/// traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
/// traverse(TK_IgnoreImplicitCastsAndParentheses,
/// varDecl(hasInitializer(floatLiteral().bind("init")))
/// )
/// \endcode
/// matches the variable declaration with "init" bound to the "3.0".
template <typename T>
internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK,
internal::Matcher<T> traverse(TraversalKind TK,
const internal::Matcher<T> &InnerMatcher) {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
@ -738,8 +738,7 @@ internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK,
template <typename T>
internal::BindableMatcher<T>
traverse(ast_type_traits::TraversalKind TK,
const internal::BindableMatcher<T> &InnerMatcher) {
traverse(TraversalKind TK, const internal::BindableMatcher<T> &InnerMatcher) {
return internal::BindableMatcher<T>(
internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
@ -749,7 +748,7 @@ traverse(ast_type_traits::TraversalKind TK,
template <typename... T>
internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>
traverse(ast_type_traits::TraversalKind TK,
traverse(TraversalKind TK,
const internal::VariadicOperatorMatcher<T...> &InnerMatcher) {
return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>(
TK, InnerMatcher);
@ -759,9 +758,8 @@ template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
typename T, typename ToTypes>
internal::TraversalWrapper<
internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>
traverse(ast_type_traits::TraversalKind TK,
const internal::ArgumentAdaptingMatcherFuncAdaptor<
ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor<
ArgumentAdapterT, T, ToTypes> &InnerMatcher) {
return internal::TraversalWrapper<
internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T,
ToTypes>>(TK, InnerMatcher);
@ -771,10 +769,8 @@ template <template <typename T, typename P1> class MatcherT, typename P1,
typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>
traverse(
ast_type_traits::TraversalKind TK,
const internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>
&InnerMatcher) {
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam1<
MatcherT, P1, ReturnTypesF> &InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>(
TK, InnerMatcher);
@ -784,10 +780,8 @@ template <template <typename T, typename P1, typename P2> class MatcherT,
typename P1, typename P2, typename ReturnTypesF>
internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>
traverse(
ast_type_traits::TraversalKind TK,
const internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>
&InnerMatcher) {
traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam2<
MatcherT, P1, P2, ReturnTypesF> &InnerMatcher) {
return internal::TraversalWrapper<
internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>(
TK, InnerMatcher);
@ -4584,7 +4578,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
// they're ever reused.
internal::NotEqualsBoundNodePredicate Predicate;
Predicate.ID = ID;
Predicate.Node = ast_type_traits::DynTypedNode::create(Node);
Predicate.Node = DynTypedNode::create(Node);
return Builder->removeBindings(Predicate);
}
@ -6735,8 +6729,7 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
InnerMatcher) {
const auto &Parents = Finder->getASTContext().getParents(Node);
llvm::SmallVector<ast_type_traits::DynTypedNode, 8> Stack(Parents.begin(),
Parents.end());
llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end());
while(!Stack.empty()) {
const auto &CurNode = Stack.back();
Stack.pop_back();

View File

@ -148,7 +148,7 @@ public:
/// Adds \c Node to the map with key \c ID.
///
/// The node's base type should be in NodeBaseType or it will be unaccessible.
void addNode(StringRef ID, const ast_type_traits::DynTypedNode& DynNode) {
void addNode(StringRef ID, const DynTypedNode &DynNode) {
NodeMap[std::string(ID)] = DynNode;
}
@ -165,10 +165,10 @@ public:
return It->second.get<T>();
}
ast_type_traits::DynTypedNode getNode(StringRef ID) const {
DynTypedNode getNode(StringRef ID) const {
IDToNodeMap::const_iterator It = NodeMap.find(ID);
if (It == NodeMap.end()) {
return ast_type_traits::DynTypedNode();
return DynTypedNode();
}
return It->second;
}
@ -183,8 +183,7 @@ public:
/// Note that we're using std::map here, as for memoization:
/// - we need a comparison operator
/// - we need an assignment operator
using IDToNodeMap =
std::map<std::string, ast_type_traits::DynTypedNode, std::less<>>;
using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>;
const IDToNodeMap &getMap() const {
return NodeMap;
@ -223,7 +222,7 @@ public:
};
/// Add a binding from an id to a node.
void setBinding(StringRef Id, const ast_type_traits::DynTypedNode &DynNode) {
void setBinding(StringRef Id, const DynTypedNode &DynNode) {
if (Bindings.empty())
Bindings.emplace_back();
for (BoundNodesMap &Binding : Bindings)
@ -280,11 +279,10 @@ public:
///
/// May bind \p DynNode to an ID via \p Builder, or recurse into
/// the AST via \p Finder.
virtual bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const = 0;
virtual llvm::Optional<ast_type_traits::TraversalKind> TraversalKind() const {
virtual llvm::Optional<TraversalKind> TraversalKind() const {
return llvm::None;
}
};
@ -307,8 +305,7 @@ public:
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const = 0;
bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return matches(DynNode.getUnchecked<T>(), Finder, Builder);
}
@ -347,7 +344,7 @@ public:
/// Takes ownership of the provided implementation pointer.
template <typename T>
DynTypedMatcher(MatcherInterface<T> *Implementation)
: SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()),
: SupportedKind(ASTNodeKind::getFromNodeKind<T>()),
RestrictKind(SupportedKind), Implementation(Implementation) {}
/// Construct from a variadic function.
@ -375,40 +372,38 @@ public:
};
static DynTypedMatcher
constructVariadic(VariadicOperator Op,
ast_type_traits::ASTNodeKind SupportedKind,
constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers);
static DynTypedMatcher
constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
ast_type_traits::ASTNodeKind RestrictKind);
ASTNodeKind RestrictKind);
/// Get a "true" matcher for \p NodeKind.
///
/// It only checks that the node is of the right kind.
static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind);
static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind);
void setAllowBind(bool AB) { AllowBind = AB; }
/// Check whether this matcher could ever match a node of kind \p Kind.
/// \return \c false if this matcher will never match such a node. Otherwise,
/// return \c true.
bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind Kind) const;
bool canMatchNodesOfKind(ASTNodeKind Kind) const;
/// Return a matcher that points to the same implementation, but
/// restricts the node types for \p Kind.
DynTypedMatcher dynCastTo(const ast_type_traits::ASTNodeKind Kind) const;
DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
/// Returns true if the matcher matches the given \c DynNode.
bool matches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const;
bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const;
/// Same as matches(), but skips the kind check.
///
/// It is faster, but the caller must ensure the node is valid for the
/// kind of this matcher.
bool matchesNoKindCheck(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const;
/// Bind the specified \p ID to the matcher.
@ -423,7 +418,7 @@ public:
/// include both in the ID to make it unique.
///
/// \c MatcherIDType supports operator< and provides strict weak ordering.
using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>;
using MatcherIDType = std::pair<ASTNodeKind, uint64_t>;
MatcherIDType getID() const {
/// FIXME: Document the requirements this imposes on matcher
/// implementations (no new() implementation_ during a Matches()).
@ -435,9 +430,7 @@ public:
///
/// \c matches() will always return false unless the node passed is of this
/// or a derived type.
ast_type_traits::ASTNodeKind getSupportedKind() const {
return SupportedKind;
}
ASTNodeKind getSupportedKind() const { return SupportedKind; }
/// Returns \c true if the passed \c DynTypedMatcher can be converted
/// to a \c Matcher<T>.
@ -445,9 +438,9 @@ public:
/// This method verifies that the underlying matcher in \c Other can process
/// nodes of types T.
template <typename T> bool canConvertTo() const {
return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
return canConvertTo(ASTNodeKind::getFromNodeKind<T>());
}
bool canConvertTo(ast_type_traits::ASTNodeKind To) const;
bool canConvertTo(ASTNodeKind To) const;
/// Construct a \c Matcher<T> interface around the dynamic matcher.
///
@ -466,20 +459,19 @@ public:
template <typename T> Matcher<T> unconditionalConvertTo() const;
private:
DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind,
ast_type_traits::ASTNodeKind RestrictKind,
IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
: SupportedKind(SupportedKind), RestrictKind(RestrictKind),
Implementation(std::move(Implementation)) {}
DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind,
IntrusiveRefCntPtr<DynMatcherInterface> Implementation)
: SupportedKind(SupportedKind), RestrictKind(RestrictKind),
Implementation(std::move(Implementation)) {}
bool AllowBind = false;
ast_type_traits::ASTNodeKind SupportedKind;
ASTNodeKind SupportedKind;
/// A potentially stricter node kind.
///
/// It allows to perform implicit and dynamic cast of matchers without
/// needing to change \c Implementation.
ast_type_traits::ASTNodeKind RestrictKind;
ASTNodeKind RestrictKind;
IntrusiveRefCntPtr<DynMatcherInterface> Implementation;
};
@ -520,7 +512,7 @@ public:
!std::is_same<From, T>::value> * = nullptr)
: Implementation(restrictMatcher(Other.Implementation)) {
assert(Implementation.getSupportedKind().isSame(
ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
ASTNodeKind::getFromNodeKind<T>()));
}
/// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
@ -545,8 +537,7 @@ public:
bool matches(const T &Node,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return Implementation.matches(ast_type_traits::DynTypedNode::create(Node),
Finder, Builder);
return Implementation.matches(DynTypedNode::create(Node), Finder, Builder);
}
/// Returns an ID that uniquely identifies the matcher.
@ -576,8 +567,8 @@ public:
BoundNodesTreeBuilder *Builder) const override {
if (Node.isNull())
return false;
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder,
Builder);
}
};
@ -589,13 +580,13 @@ private:
friend class DynTypedMatcher;
static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) {
return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>());
}
explicit Matcher(const DynTypedMatcher &Implementation)
: Implementation(restrictMatcher(Implementation)) {
assert(this->Implementation.getSupportedKind()
.isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()));
assert(this->Implementation.getSupportedKind().isSame(
ASTNodeKind::getFromNodeKind<T>()));
}
DynTypedMatcher Implementation;
@ -615,9 +606,8 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) {
template <>
inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const {
assert(canConvertTo<QualType>());
const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind();
if (SourceKind.isSame(
ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) {
const ASTNodeKind SourceKind = getSupportedKind();
if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) {
// We support implicit conversion from Matcher<Type> to Matcher<QualType>
return unconditionalConvertTo<Type>();
}
@ -919,9 +909,8 @@ private:
/// is \c NULL.
bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
return Node != nullptr &&
this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(*Node), Finder, Builder);
return Node != nullptr && this->InnerMatcher.matches(
DynTypedNode::create(*Node), Finder, Builder);
}
};
@ -1003,8 +992,8 @@ public:
template <typename T>
bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
ast_type_traits::TraversalKind Traverse, BindKind Bind) {
BoundNodesTreeBuilder *Builder, TraversalKind Traverse,
BindKind Bind) {
static_assert(std::is_base_of<Decl, T>::value ||
std::is_base_of<Stmt, T>::value ||
std::is_base_of<NestedNameSpecifier, T>::value ||
@ -1012,8 +1001,8 @@ public:
std::is_base_of<TypeLoc, T>::value ||
std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
getASTContext(), Matcher, Builder, Traverse, Bind);
return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
Builder, Traverse, Bind);
}
template <typename T>
@ -1028,8 +1017,8 @@ public:
std::is_base_of<TypeLoc, T>::value ||
std::is_base_of<QualType, T>::value,
"unsupported type for recursive matching");
return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
getASTContext(), Matcher, Builder, Bind);
return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, Bind);
}
// FIXME: Implement support for BindKind.
@ -1043,27 +1032,24 @@ public:
std::is_base_of<Stmt, T>::value ||
std::is_base_of<TypeLoc, T>::value,
"type not allowed for recursive matching");
return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
getASTContext(), Matcher, Builder, MatchMode);
return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, MatchMode);
}
virtual ASTContext &getASTContext() const = 0;
protected:
virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx, const DynTypedMatcher &Matcher,
virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
ast_type_traits::TraversalKind Traverse,
BindKind Bind) = 0;
TraversalKind Traverse, BindKind Bind) = 0;
virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) = 0;
virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) = 0;
@ -1182,41 +1168,38 @@ struct ArgumentAdaptingMatcherFunc {
template <typename T>
class TraversalMatcher : public WrapperMatcherInterface<T> {
ast_type_traits::TraversalKind Traversal;
TraversalKind Traversal;
public:
explicit TraversalMatcher(ast_type_traits::TraversalKind TK,
const Matcher<T> &ChildMatcher)
explicit TraversalMatcher(TraversalKind TK, const Matcher<T> &ChildMatcher)
: TraversalMatcher::WrapperMatcherInterface(ChildMatcher), Traversal(TK) {
}
bool matches(const T &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(Node), Finder, Builder);
return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder,
Builder);
}
llvm::Optional<ast_type_traits::TraversalKind>
TraversalKind() const override {
llvm::Optional<TraversalKind> TraversalKind() const override {
return Traversal;
}
};
template <typename MatcherType> class TraversalWrapper {
public:
TraversalWrapper(ast_type_traits::TraversalKind TK,
const MatcherType &InnerMatcher)
TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
: TK(TK), InnerMatcher(InnerMatcher) {}
template <typename T> operator Matcher<T>() const {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
private:
ast_type_traits::TraversalKind TK;
TraversalKind TK;
MatcherType InnerMatcher;
};
@ -1299,8 +1282,7 @@ public:
template <typename T>
operator Matcher<T>() const {
return DynTypedMatcher::trueMatcher(
ast_type_traits::ASTNodeKind::getFromNodeKind<T>())
return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
};
@ -1348,7 +1330,7 @@ public:
bool matches(const T &Node, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
ast_type_traits::TraversalKind::TK_AsIs,
TraversalKind::TK_AsIs,
ASTMatchFinder::BK_First);
}
};
@ -1371,7 +1353,7 @@ class ForEachMatcher : public WrapperMatcherInterface<T> {
BoundNodesTreeBuilder* Builder) const override {
return Finder->matchesChildOf(
Node, this->InnerMatcher, Builder,
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
ASTMatchFinder::BK_All);
}
};
@ -1392,7 +1374,7 @@ public:
template <typename T> operator Matcher<T>() const {
return DynTypedMatcher::constructVariadic(
Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
Op, ASTNodeKind::getFromNodeKind<T>(),
getMatchers<T>(std::index_sequence_for<Ps...>()))
.template unconditionalConvertTo<T>();
}
@ -1448,10 +1430,9 @@ BindableMatcher<T> makeAllOfComposite(
std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()),
PI(InnerMatchers.end()));
return BindableMatcher<T>(
DynTypedMatcher::constructVariadic(
DynTypedMatcher::VO_AllOf,
ast_type_traits::ASTNodeKind::getFromNodeKind<T>(),
std::move(DynMatchers))
DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf,
ASTNodeKind::getFromNodeKind<T>(),
std::move(DynMatchers))
.template unconditionalConvertTo<T>());
}
@ -1652,9 +1633,8 @@ public:
}
private:
static ast_type_traits::DynTypedNode
extract(const NestedNameSpecifierLoc &Loc) {
return ast_type_traits::DynTypedNode::create(*Loc.getNestedNameSpecifier());
static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
return DynTypedNode::create(*Loc.getNestedNameSpecifier());
}
};
@ -1671,8 +1651,8 @@ public:
BoundNodesTreeBuilder *Builder) const override {
if (!Node)
return false;
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(Node.getType()), Finder, Builder);
return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()),
Finder, Builder);
}
};
@ -1692,8 +1672,8 @@ public:
QualType NextNode = (Node.*TraverseFunction)();
if (NextNode.isNull())
return false;
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
Builder);
}
private:
@ -1716,8 +1696,8 @@ public:
TypeLoc NextNode = (Node.*TraverseFunction)();
if (!NextNode)
return false;
return this->InnerMatcher.matches(
ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder);
return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder,
Builder);
}
private:
@ -1817,7 +1797,7 @@ struct NotEqualsBoundNodePredicate {
}
std::string ID;
ast_type_traits::DynTypedNode Node;
DynTypedNode Node;
};
template <typename Ty>

View File

@ -43,11 +43,10 @@ class ArgKind {
ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); }
/// Constructor for matcher types.
ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
: K(AK_Matcher), MatcherKind(MatcherKind) {}
ArgKind(ASTNodeKind MatcherKind) : K(AK_Matcher), MatcherKind(MatcherKind) {}
Kind getArgKind() const { return K; }
ast_type_traits::ASTNodeKind getMatcherKind() const {
ASTNodeKind getMatcherKind() const {
assert(K == AK_Matcher);
return MatcherKind;
}
@ -71,7 +70,7 @@ class ArgKind {
private:
Kind K;
ast_type_traits::ASTNodeKind MatcherKind;
ASTNodeKind MatcherKind;
};
using ast_matchers::internal::DynTypedMatcher;
@ -93,7 +92,7 @@ class VariantMatcher {
/// Methods that depend on T from hasTypedMatcher/getTypedMatcher.
class MatcherOps {
public:
MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
MatcherOps(ASTNodeKind NodeKind) : NodeKind(NodeKind) {}
bool canConstructFrom(const DynTypedMatcher &Matcher,
bool &IsExactMatch) const;
@ -114,7 +113,7 @@ class VariantMatcher {
~MatcherOps() = default;
private:
ast_type_traits::ASTNodeKind NodeKind;
ASTNodeKind NodeKind;
};
/// Payload interface to be specialized by each matcher type.
@ -127,7 +126,7 @@ class VariantMatcher {
virtual std::string getTypeAsString() const = 0;
virtual llvm::Optional<DynTypedMatcher>
getTypedMatcher(const MatcherOps &Ops) const = 0;
virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
virtual bool isConvertibleTo(ASTNodeKind Kind,
unsigned *Specificity) const = 0;
};
@ -184,8 +183,7 @@ public:
///
/// \param Specificity value corresponding to the "specificity" of the
/// conversion.
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const {
if (Value)
return Value->isConvertibleTo(Kind, Specificity);
return false;
@ -223,8 +221,7 @@ private:
template <typename T>
struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
TypedMatcherOps()
: MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {}
TypedMatcherOps() : MatcherOps(ASTNodeKind::getFromNodeKind<T>()) {}
typedef ast_matchers::internal::Matcher<T> MatcherT;
DynTypedMatcher

View File

@ -37,11 +37,11 @@ enum ChangeKind {
struct Node {
NodeId Parent, LeftMostDescendant, RightMostDescendant;
int Depth, Height, Shift = 0;
ast_type_traits::DynTypedNode ASTNode;
DynTypedNode ASTNode;
SmallVector<NodeId, 4> Children;
ChangeKind Change = None;
ast_type_traits::ASTNodeKind getType() const;
ASTNodeKind getType() const;
StringRef getTypeLabel() const;
bool isLeaf() const { return Children.empty(); }
llvm::Optional<StringRef> getIdentifier() const;

View File

@ -15,7 +15,7 @@
namespace clang {
namespace diff {
using DynTypedNode = ast_type_traits::DynTypedNode;
using DynTypedNode = DynTypedNode;
class SyntaxTree;
class SyntaxTreeImpl;

View File

@ -48,12 +48,11 @@ enum class SourceSelectionKind {
/// actually be selected, e.g. a statement in macro whose child is in a macro
/// argument.
struct SelectedASTNode {
ast_type_traits::DynTypedNode Node;
DynTypedNode Node;
SourceSelectionKind SelectionKind;
std::vector<SelectedASTNode> Children;
SelectedASTNode(const ast_type_traits::DynTypedNode &Node,
SourceSelectionKind SelectionKind)
SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind)
: Node(Node), SelectionKind(SelectionKind) {}
SelectedASTNode(SelectedASTNode &&) = default;
SelectedASTNode &operator=(SelectedASTNode &&) = default;

View File

@ -18,8 +18,7 @@
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
namespace clang {
namespace ast_type_traits {
using namespace clang;
const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
{ NKI_None, "<None>" },
@ -178,6 +177,3 @@ SourceRange DynTypedNode::getSourceRange() const {
return SourceRange(C->getBeginLoc(), C->getEndLoc());
return SourceRange();
}
} // end namespace ast_type_traits
} // end namespace clang

View File

@ -34,54 +34,53 @@ Expr *ParentMapContext::traverseIgnored(Expr *E) const {
return nullptr;
switch (Traversal) {
case ast_type_traits::TK_AsIs:
case TK_AsIs:
return E;
case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
case TK_IgnoreImplicitCastsAndParentheses:
return E->IgnoreParenImpCasts();
case ast_type_traits::TK_IgnoreUnlessSpelledInSource:
case TK_IgnoreUnlessSpelledInSource:
return E->IgnoreUnlessSpelledInSource();
}
llvm_unreachable("Invalid Traversal type!");
}
ast_type_traits::DynTypedNode
ParentMapContext::traverseIgnored(const ast_type_traits::DynTypedNode &N) const {
DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const {
if (const auto *E = N.get<Expr>()) {
return ast_type_traits::DynTypedNode::create(*traverseIgnored(E));
return DynTypedNode::create(*traverseIgnored(E));
}
return N;
}
class ParentMapContext::ParentMap {
/// Contains parents of a node.
using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
using ParentVector = llvm::SmallVector<DynTypedNode, 2>;
/// Maps from a node to its parents. This is used for nodes that have
/// pointer identity only, which are more common and we can save space by
/// only storing a unique pointer to them.
using ParentMapPointers = llvm::DenseMap<
const void *,
llvm::PointerUnion<const Decl *, const Stmt *,
ast_type_traits::DynTypedNode *, ParentVector *>>;
using ParentMapPointers =
llvm::DenseMap<const void *,
llvm::PointerUnion<const Decl *, const Stmt *,
DynTypedNode *, ParentVector *>>;
/// Parent map for nodes without pointer identity. We store a full
/// DynTypedNode for all keys.
using ParentMapOtherNodes = llvm::DenseMap<
ast_type_traits::DynTypedNode,
llvm::PointerUnion<const Decl *, const Stmt *,
ast_type_traits::DynTypedNode *, ParentVector *>>;
using ParentMapOtherNodes =
llvm::DenseMap<DynTypedNode,
llvm::PointerUnion<const Decl *, const Stmt *,
DynTypedNode *, ParentVector *>>;
ParentMapPointers PointerParents;
ParentMapOtherNodes OtherParents;
class ASTVisitor;
static ast_type_traits::DynTypedNode
static DynTypedNode
getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) {
if (const auto *D = U.dyn_cast<const Decl *>())
return ast_type_traits::DynTypedNode::create(*D);
return DynTypedNode::create(*D);
if (const auto *S = U.dyn_cast<const Stmt *>())
return ast_type_traits::DynTypedNode::create(*S);
return *U.get<ast_type_traits::DynTypedNode *>();
return DynTypedNode::create(*S);
return *U.get<DynTypedNode *>();
}
template <typename NodeTy, typename MapTy>
@ -89,7 +88,7 @@ class ParentMapContext::ParentMap {
const MapTy &Map) {
auto I = Map.find(Node);
if (I == Map.end()) {
return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
return llvm::ArrayRef<DynTypedNode>();
}
if (const auto *V = I->second.template dyn_cast<ParentVector *>()) {
return llvm::makeArrayRef(*V);
@ -101,28 +100,26 @@ public:
ParentMap(ASTContext &Ctx);
~ParentMap() {
for (const auto &Entry : PointerParents) {
if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
delete Entry.second.get<ast_type_traits::DynTypedNode *>();
if (Entry.second.is<DynTypedNode *>()) {
delete Entry.second.get<DynTypedNode *>();
} else if (Entry.second.is<ParentVector *>()) {
delete Entry.second.get<ParentVector *>();
}
}
for (const auto &Entry : OtherParents) {
if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
delete Entry.second.get<ast_type_traits::DynTypedNode *>();
if (Entry.second.is<DynTypedNode *>()) {
delete Entry.second.get<DynTypedNode *>();
} else if (Entry.second.is<ParentVector *>()) {
delete Entry.second.get<ParentVector *>();
}
}
}
DynTypedNodeList getParents(ast_type_traits::TraversalKind TK,
const ast_type_traits::DynTypedNode &Node) {
DynTypedNodeList getParents(TraversalKind TK, const DynTypedNode &Node) {
if (Node.getNodeKind().hasPointerIdentity()) {
auto ParentList =
getDynNodeFromMap(Node.getMemoizationData(), PointerParents);
if (ParentList.size() == 1 &&
TK == ast_type_traits::TK_IgnoreUnlessSpelledInSource) {
if (ParentList.size() == 1 && TK == TK_IgnoreUnlessSpelledInSource) {
const auto *E = ParentList[0].get<Expr>();
const auto *Child = Node.get<Expr>();
if (E && Child)
@ -186,28 +183,25 @@ public:
}
const auto *P = dyn_cast<Expr>(S);
if (!P)
return ast_type_traits::DynTypedNode::create(*S);
return DynTypedNode::create(*S);
Child = E;
E = P;
}
return ast_type_traits::DynTypedNode::create(*E);
return DynTypedNode::create(*E);
}
};
/// Template specializations to abstract away from pointers and TypeLocs.
/// @{
template <typename T>
static ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) {
return ast_type_traits::DynTypedNode::create(*Node);
template <typename T> static DynTypedNode createDynTypedNode(const T &Node) {
return DynTypedNode::create(*Node);
}
template <> DynTypedNode createDynTypedNode(const TypeLoc &Node) {
return DynTypedNode::create(Node);
}
template <>
ast_type_traits::DynTypedNode createDynTypedNode(const TypeLoc &Node) {
return ast_type_traits::DynTypedNode::create(Node);
}
template <>
ast_type_traits::DynTypedNode
createDynTypedNode(const NestedNameSpecifierLoc &Node) {
return ast_type_traits::DynTypedNode::create(Node);
DynTypedNode createDynTypedNode(const NestedNameSpecifierLoc &Node) {
return DynTypedNode::create(Node);
}
/// @}
@ -257,13 +251,12 @@ private:
else if (const auto *S = ParentStack.back().get<Stmt>())
NodeOrVector = S;
else
NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
NodeOrVector = new DynTypedNode(ParentStack.back());
} else {
if (!NodeOrVector.template is<ParentVector *>()) {
auto *Vector = new ParentVector(
1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
delete NodeOrVector
.template dyn_cast<ast_type_traits::DynTypedNode *>();
delete NodeOrVector.template dyn_cast<DynTypedNode *>();
NodeOrVector = Vector;
}
@ -299,28 +292,27 @@ private:
bool TraverseTypeLoc(TypeLoc TypeLocNode) {
return TraverseNode(
TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode),
TypeLocNode, DynTypedNode::create(TypeLocNode),
[&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
&Map.OtherParents);
}
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
return TraverseNode(
NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode),
NNSLocNode, DynTypedNode::create(NNSLocNode),
[&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
&Map.OtherParents);
}
ParentMap &Map;
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
llvm::SmallVector<DynTypedNode, 16> ParentStack;
};
ParentMapContext::ParentMap::ParentMap(ASTContext &Ctx) {
ASTVisitor(*this).TraverseAST(Ctx);
}
DynTypedNodeList
ParentMapContext::getParents(const ast_type_traits::DynTypedNode &Node) {
DynTypedNodeList ParentMapContext::getParents(const DynTypedNode &Node) {
if (!Parents)
// We build the parent map for the traversal scope (usually whole TU), as
// hasAncestor can escape any subtree.

View File

@ -57,9 +57,9 @@ static const unsigned MaxMemoizationEntries = 10000;
// provides enough benefit for the additional amount of code.
struct MatchKey {
DynTypedMatcher::MatcherIDType MatcherID;
ast_type_traits::DynTypedNode Node;
DynTypedNode Node;
BoundNodesTreeBuilder BoundNodes;
ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
TraversalKind Traversal = TK_AsIs;
bool operator<(const MatchKey &Other) const {
return std::tie(Traversal, MatcherID, Node, BoundNodes) <
@ -87,8 +87,7 @@ public:
// matching the descendants.
MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder, int MaxDepth,
ast_type_traits::TraversalKind Traversal,
ASTMatchFinder::BindKind Bind)
TraversalKind Traversal, ASTMatchFinder::BindKind Bind)
: Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0),
MaxDepth(MaxDepth), Traversal(Traversal), Bind(Bind), Matches(false) {}
@ -103,7 +102,7 @@ public:
// Traverse*(c) for each child c of 'node'.
// - Traverse*(c) in turn calls Traverse(c), completing the
// recursion.
bool findMatch(const ast_type_traits::DynTypedNode &DynNode) {
bool findMatch(const DynTypedNode &DynNode) {
reset();
if (const Decl *D = DynNode.get<Decl>())
traverse(*D);
@ -145,15 +144,14 @@ public:
auto *LambdaNode = dyn_cast_or_null<LambdaExpr>(StmtNode);
if (LambdaNode &&
Finder->getASTContext().getParentMapContext().getTraversalKind() ==
ast_type_traits::TK_IgnoreUnlessSpelledInSource)
TK_IgnoreUnlessSpelledInSource)
StmtToTraverse = LambdaNode;
else
StmtToTraverse =
Finder->getASTContext().getParentMapContext().traverseIgnored(
ExprNode);
}
if (Traversal ==
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses) {
if (Traversal == TraversalKind::TK_IgnoreImplicitCastsAndParentheses) {
if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode))
StmtToTraverse = ExprNode->IgnoreParenImpCasts();
}
@ -220,7 +218,7 @@ public:
}
bool TraverseLambdaExpr(LambdaExpr *Node) {
if (Finder->getASTContext().getParentMapContext().getTraversalKind() !=
ast_type_traits::TK_IgnoreUnlessSpelledInSource)
TK_IgnoreUnlessSpelledInSource)
return VisitorBase::TraverseLambdaExpr(Node);
if (!Node)
return true;
@ -311,7 +309,7 @@ private:
}
if (Bind != ASTMatchFinder::BK_All) {
BoundNodesTreeBuilder RecursiveBuilder(*Builder);
if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
if (Matcher->matches(DynTypedNode::create(Node), Finder,
&RecursiveBuilder)) {
Matches = true;
ResultBindings.addMatch(RecursiveBuilder);
@ -319,7 +317,7 @@ private:
}
} else {
BoundNodesTreeBuilder RecursiveBuilder(*Builder);
if (Matcher->matches(ast_type_traits::DynTypedNode::create(Node), Finder,
if (Matcher->matches(DynTypedNode::create(Node), Finder,
&RecursiveBuilder)) {
// After the first match the matcher succeeds.
Matches = true;
@ -346,7 +344,7 @@ private:
BoundNodesTreeBuilder ResultBindings;
int CurrentDepth;
const int MaxDepth;
const ast_type_traits::TraversalKind Traversal;
const TraversalKind Traversal;
const ASTMatchFinder::BindKind Bind;
bool Matches;
};
@ -443,12 +441,10 @@ public:
bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
// Matches children or descendants of 'Node' with 'BaseMatcher'.
bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder, int MaxDepth,
ast_type_traits::TraversalKind Traversal,
BindKind Bind) {
TraversalKind Traversal, BindKind Bind) {
// For AST-nodes that don't have an identity, we can't memoize.
if (!Node.getMemoizationData() || !Builder->isComparable())
return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
@ -480,11 +476,10 @@ public:
}
// Matches children or descendants of 'Node' with 'BaseMatcher'.
bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
bool matchesRecursively(const DynTypedNode &Node,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder, int MaxDepth,
ast_type_traits::TraversalKind Traversal,
BindKind Bind) {
TraversalKind Traversal, BindKind Bind) {
MatchChildASTVisitor Visitor(
&Matcher, this, Builder, MaxDepth, Traversal, Bind);
return Visitor.findMatch(Node);
@ -501,10 +496,9 @@ public:
bool Directly) override;
// Implements ASTMatchFinder::matchesChildOf.
bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
ast_type_traits::TraversalKind Traversal,
bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder, TraversalKind Traversal,
BindKind Bind) override {
if (ResultCache.size() > MaxMemoizationEntries)
ResultCache.clear();
@ -512,19 +506,18 @@ public:
Bind);
}
// Implements ASTMatchFinder::matchesDescendantOf.
bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx, const DynTypedMatcher &Matcher,
bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) override {
if (ResultCache.size() > MaxMemoizationEntries)
ResultCache.clear();
return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX,
ast_type_traits::TraversalKind::TK_AsIs,
Bind);
TraversalKind::TK_AsIs, Bind);
}
// Implements ASTMatchFinder::matchesAncestorOf.
bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx, const DynTypedMatcher &Matcher,
bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) override {
// Reset the cache outside of the recursive call to make sure we
@ -537,7 +530,7 @@ public:
// Matches all registered matchers on the given node and calls the
// result callback for every node that matches.
void match(const ast_type_traits::DynTypedNode &Node) {
void match(const DynTypedNode &Node) {
// FIXME: Improve this with a switch or a visitor pattern.
if (auto *N = Node.get<Decl>()) {
match(*N);
@ -615,7 +608,7 @@ private:
}
}
void matchWithFilter(const ast_type_traits::DynTypedNode &DynNode) {
void matchWithFilter(const DynTypedNode &DynNode) {
auto Kind = DynNode.getNodeKind();
auto it = MatcherFiltersMap.find(Kind);
const auto &Filter =
@ -639,8 +632,7 @@ private:
}
}
const std::vector<unsigned short> &
getFilterForKind(ast_type_traits::ASTNodeKind Kind) {
const std::vector<unsigned short> &getFilterForKind(ASTNodeKind Kind) {
auto &Filter = MatcherFiltersMap[Kind];
auto &Matchers = this->Matchers->DeclOrStmt;
assert((Matchers.size() < USHRT_MAX) && "Too many matchers.");
@ -655,10 +647,10 @@ private:
/// @{
/// Overloads to pair the different node types to their matchers.
void matchDispatch(const Decl *Node) {
return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
return matchWithFilter(DynTypedNode::create(*Node));
}
void matchDispatch(const Stmt *Node) {
return matchWithFilter(ast_type_traits::DynTypedNode::create(*Node));
return matchWithFilter(DynTypedNode::create(*Node));
}
void matchDispatch(const Type *Node) {
@ -695,10 +687,11 @@ private:
// Once there are multiple parents, the breadth first search order does not
// allow simple memoization on the ancestors. Thus, we only memoize as long
// as there is a single parent.
bool memoizedMatchesAncestorOfRecursively(
const ast_type_traits::DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
bool memoizedMatchesAncestorOfRecursively(const DynTypedNode &Node,
ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
// For AST-nodes that don't have an identity, we can't memoize.
if (!Builder->isComparable())
return matchesAncestorOfRecursively(Node, Ctx, Matcher, Builder,
@ -730,8 +723,7 @@ private:
return CachedResult.ResultOfMatch;
}
bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node,
ASTContext &Ctx,
bool matchesAncestorOfRecursively(const DynTypedNode &Node, ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
@ -758,7 +750,7 @@ private:
}
if (Parents.size() == 1) {
// Only one parent - do recursive memoization.
const ast_type_traits::DynTypedNode Parent = Parents[0];
const DynTypedNode Parent = Parents[0];
BoundNodesTreeBuilder BuilderCopy = *Builder;
if (Matcher.matches(Parent, this, &BuilderCopy)) {
*Builder = std::move(BuilderCopy);
@ -773,8 +765,7 @@ private:
} else {
// Multiple parents - BFS over the rest of the nodes.
llvm::DenseSet<const void *> Visited;
std::deque<ast_type_traits::DynTypedNode> Queue(Parents.begin(),
Parents.end());
std::deque<DynTypedNode> Queue(Parents.begin(), Parents.end());
while (!Queue.empty()) {
BoundNodesTreeBuilder BuilderCopy = *Builder;
if (Matcher.matches(Queue.front(), this, &BuilderCopy)) {
@ -864,8 +855,7 @@ private:
/// kind (and derived kinds) so it is a waste to try every matcher on every
/// node.
/// We precalculate a list of matchers that pass the toplevel restrict check.
llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>>
MatcherFiltersMap;
llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap;
const MatchFinder::MatchFinderOptions &Options;
ASTContext *ActiveASTContext;
@ -1140,8 +1130,7 @@ std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() {
return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone);
}
void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node,
ASTContext &Context) {
void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) {
internal::MatchASTVisitor Visitor(&Matchers, Options);
Visitor.set_active_ast_context(&Context);
Visitor.match(Node);

View File

@ -51,26 +51,23 @@ AST_MATCHER_P(ObjCMessageExpr, hasAnySelectorMatcher, std::vector<std::string>,
namespace internal {
bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
bool NotUnaryOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool AllOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool EachOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool AnyOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
bool OptionallyVariadicOperator(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
@ -86,7 +83,7 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
namespace {
using VariadicOperatorFunction = bool (*)(
const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
template <VariadicOperatorFunction Func>
@ -95,8 +92,7 @@ public:
VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
: InnerMatchers(std::move(InnerMatchers)) {}
bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
return Func(DynNode, Finder, Builder, InnerMatchers);
}
@ -111,16 +107,14 @@ public:
IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher)
: ID(ID), InnerMatcher(std::move(InnerMatcher)) {}
bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const override {
bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
if (Result) Builder->setBinding(ID, DynNode);
return Result;
}
llvm::Optional<ast_type_traits::TraversalKind>
TraversalKind() const override {
llvm::Optional<clang::TraversalKind> TraversalKind() const override {
return InnerMatcher->TraversalKind();
}
@ -140,7 +134,7 @@ public:
Retain(); // Reference count will never become zero.
}
bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
bool dynMatches(const DynTypedNode &, ASTMatchFinder *,
BoundNodesTreeBuilder *) const override {
return true;
}
@ -150,10 +144,10 @@ public:
static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
DynTypedMatcher DynTypedMatcher::constructVariadic(
DynTypedMatcher::VariadicOperator Op,
ast_type_traits::ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers) {
DynTypedMatcher
DynTypedMatcher::constructVariadic(DynTypedMatcher::VariadicOperator Op,
ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers) {
assert(!InnerMatchers.empty() && "Array must not be empty.");
assert(llvm::all_of(InnerMatchers,
[SupportedKind](const DynTypedMatcher &M) {
@ -174,8 +168,8 @@ DynTypedMatcher DynTypedMatcher::constructVariadic(
// invalid types earlier and we can elide the kind checks inside the
// matcher.
for (auto &IM : InnerMatchers) {
RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType(
RestrictKind, IM.RestrictKind);
RestrictKind =
ASTNodeKind::getMostDerivedType(RestrictKind, IM.RestrictKind);
}
return DynTypedMatcher(
SupportedKind, RestrictKind,
@ -206,34 +200,30 @@ DynTypedMatcher DynTypedMatcher::constructVariadic(
llvm_unreachable("Invalid Op value.");
}
DynTypedMatcher DynTypedMatcher::constructRestrictedWrapper(
const DynTypedMatcher &InnerMatcher,
ast_type_traits::ASTNodeKind RestrictKind) {
DynTypedMatcher
DynTypedMatcher::constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher,
ASTNodeKind RestrictKind) {
DynTypedMatcher Copy = InnerMatcher;
Copy.RestrictKind = RestrictKind;
return Copy;
}
DynTypedMatcher DynTypedMatcher::trueMatcher(
ast_type_traits::ASTNodeKind NodeKind) {
DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {
return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
}
bool DynTypedMatcher::canMatchNodesOfKind(
ast_type_traits::ASTNodeKind Kind) const {
bool DynTypedMatcher::canMatchNodesOfKind(ASTNodeKind Kind) const {
return RestrictKind.isBaseOf(Kind);
}
DynTypedMatcher DynTypedMatcher::dynCastTo(
const ast_type_traits::ASTNodeKind Kind) const {
DynTypedMatcher DynTypedMatcher::dynCastTo(const ASTNodeKind Kind) const {
auto Copy = *this;
Copy.SupportedKind = Kind;
Copy.RestrictKind =
ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
Copy.RestrictKind = ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
return Copy;
}
bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
bool DynTypedMatcher::matches(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
TraversalKindScope RAII(Finder->getASTContext(),
@ -253,9 +243,9 @@ bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
return false;
}
bool DynTypedMatcher::matchesNoKindCheck(
const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
bool DynTypedMatcher::matchesNoKindCheck(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const {
TraversalKindScope raii(Finder->getASTContext(),
Implementation->TraversalKind());
@ -281,10 +271,10 @@ llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
return std::move(Result);
}
bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
bool DynTypedMatcher::canConvertTo(ASTNodeKind To) const {
const auto From = getSupportedKind();
auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
auto QualKind = ASTNodeKind::getFromNodeKind<QualType>();
auto TypeKind = ASTNodeKind::getFromNodeKind<Type>();
/// Mimic the implicit conversions of Matcher<>.
/// - From Matcher<Type> to Matcher<QualType>
if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
@ -296,8 +286,8 @@ void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
}
bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
bool NotUnaryOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
if (InnerMatchers.size() != 1)
return false;
@ -316,8 +306,7 @@ bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
}
bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool AllOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
// allOf leads to one matcher for each alternative in the first
@ -330,8 +319,7 @@ bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
return true;
}
bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool EachOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
BoundNodesTreeBuilder Result;
@ -347,8 +335,7 @@ bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
return Matched;
}
bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
ASTMatchFinder *Finder,
bool AnyOfVariadicOperator(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {
for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
@ -361,7 +348,7 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
return false;
}
bool OptionallyVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
bool OptionallyVariadicOperator(const DynTypedNode &DynNode,
ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers) {

View File

@ -80,7 +80,7 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
}
static ArgKind getKind() {
return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
return ArgKind(ASTNodeKind::getFromNodeKind<T>());
}
};
@ -211,7 +211,7 @@ public:
/// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
// FIXME: We should provide the ability to constrain the output of this
// function based on the types of other matcher arguments.
virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
virtual void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &ArgKinds) const = 0;
/// Returns whether this matcher is convertible to the given type. If it is
@ -221,20 +221,19 @@ public:
/// same matcher overload. Zero specificity indicates that this conversion
/// would produce a trivial matcher that will either always or never match.
/// Such matchers are excluded from code completion results.
virtual bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
virtual bool
isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity = nullptr,
ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
/// Returns whether the matcher will, given a matcher of any type T, yield a
/// matcher of type T.
virtual bool isPolymorphic() const { return false; }
};
inline bool isRetKindConvertibleTo(
ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) {
for (const ast_type_traits::ASTNodeKind &NodeKind : RetKinds) {
inline bool isRetKindConvertibleTo(ArrayRef<ASTNodeKind> RetKinds,
ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) {
for (const ASTNodeKind &NodeKind : RetKinds) {
if (ArgKind(NodeKind).isConvertibleTo(Kind, Specificity)) {
if (LeastDerivedKind)
*LeastDerivedKind = NodeKind;
@ -264,10 +263,10 @@ public:
/// \param RetKinds The list of matcher types to which the matcher is
/// convertible.
/// \param ArgKinds The types of the arguments this matcher takes.
FixedArgCountMatcherDescriptor(
MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
ArrayRef<ArgKind> ArgKinds)
FixedArgCountMatcherDescriptor(MarshallerType Marshaller, void (*Func)(),
StringRef MatcherName,
ArrayRef<ASTNodeKind> RetKinds,
ArrayRef<ArgKind> ArgKinds)
: Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
RetKinds(RetKinds.begin(), RetKinds.end()),
ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
@ -281,14 +280,13 @@ public:
bool isVariadic() const override { return false; }
unsigned getNumArgs() const override { return ArgKinds.size(); }
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ArgKinds[ArgNo]);
}
bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) const override {
return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
LeastDerivedKind);
}
@ -297,7 +295,7 @@ private:
const MarshallerType Marshaller;
void (* const Func)();
const std::string MatcherName;
const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
const std::vector<ASTNodeKind> RetKinds;
const std::vector<ArgKind> ArgKinds;
};
@ -336,36 +334,35 @@ static VariantMatcher outvalueToVariantMatcher(const T &PolyMatcher,
}
template <typename T>
inline void buildReturnTypeVectorFromTypeList(
std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
RetTypes.push_back(
ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
inline void
buildReturnTypeVectorFromTypeList(std::vector<ASTNodeKind> &RetTypes) {
RetTypes.push_back(ASTNodeKind::getFromNodeKind<typename T::head>());
buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
}
template <>
inline void
buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
std::vector<ASTNodeKind> &RetTypes) {}
template <typename T>
struct BuildReturnTypeVector {
static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
static void build(std::vector<ASTNodeKind> &RetTypes) {
buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
}
};
template <typename T>
struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
static void build(std::vector<ASTNodeKind> &RetTypes) {
RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());
}
};
template <typename T>
struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
static void build(std::vector<ASTNodeKind> &RetTypes) {
RetTypes.push_back(ASTNodeKind::getFromNodeKind<T>());
}
};
@ -439,14 +436,13 @@ public:
bool isVariadic() const override { return true; }
unsigned getNumArgs() const override { return 0; }
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ArgsKind);
}
bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) const override {
return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
LeastDerivedKind);
}
@ -454,7 +450,7 @@ public:
private:
const RunFunc Func;
const std::string MatcherName;
std::vector<ast_type_traits::ASTNodeKind> RetKinds;
std::vector<ASTNodeKind> RetKinds;
const ArgKind ArgsKind;
};
@ -466,12 +462,10 @@ public:
ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
StringRef MatcherName)
: VariadicFuncMatcherDescriptor(Func, MatcherName),
DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
}
DerivedKind(ASTNodeKind::getFromNodeKind<DerivedT>()) {}
bool
isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) const override {
// If Kind is not a base of DerivedKind, either DerivedKind is a base of
// Kind (in which case the match will always succeed) or Kind and
// DerivedKind are unrelated (in which case it will always fail), so set
@ -489,7 +483,7 @@ public:
}
private:
const ast_type_traits::ASTNodeKind DerivedKind;
const ASTNodeKind DerivedKind;
};
/// Helper macros to check the arguments on all marshaller functions.
@ -635,7 +629,7 @@ public:
return Overload0NumArgs;
}
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
for (const auto &O : Overloads) {
if (O->isConvertibleTo(ThisKind))
@ -643,9 +637,8 @@ public:
}
}
bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) const override {
for (const auto &O : Overloads) {
if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
return true;
@ -697,13 +690,13 @@ public:
bool isVariadic() const override { return true; }
unsigned getNumArgs() const override { return 0; }
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
void getArgKinds(ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ThisKind);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity,
ASTNodeKind *LeastDerivedKind) const override {
if (Specificity)
*Specificity = 1;
if (LeastDerivedKind)
@ -727,7 +720,7 @@ private:
template <typename ReturnType>
std::unique_ptr<MatcherDescriptor>
makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
std::vector<ast_type_traits::ASTNodeKind> RetTypes;
std::vector<ASTNodeKind> RetTypes;
BuildReturnTypeVector<ReturnType>::build(RetTypes);
return std::make_unique<FixedArgCountMatcherDescriptor>(
matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
@ -738,7 +731,7 @@ makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) {
template <typename ReturnType, typename ArgType1>
std::unique_ptr<MatcherDescriptor>
makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) {
std::vector<ast_type_traits::ASTNodeKind> RetTypes;
std::vector<ASTNodeKind> RetTypes;
BuildReturnTypeVector<ReturnType>::build(RetTypes);
ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
return std::make_unique<FixedArgCountMatcherDescriptor>(
@ -751,7 +744,7 @@ template <typename ReturnType, typename ArgType1, typename ArgType2>
std::unique_ptr<MatcherDescriptor>
makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
StringRef MatcherName) {
std::vector<ast_type_traits::ASTNodeKind> RetTypes;
std::vector<ASTNodeKind> RetTypes;
BuildReturnTypeVector<ReturnType>::build(RetTypes);
ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
ArgTypeTraits<ArgType2>::getKind() };

View File

@ -101,8 +101,7 @@ public:
return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override {
return ArgKind(Matcher.getSupportedKind())
.isConvertibleTo(Kind, Specificity);
}
@ -159,8 +158,7 @@ public:
return llvm::None;
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override {
unsigned MaxSpecificity = 0;
for (const DynTypedMatcher &Matcher : Matchers) {
unsigned ThisSpecificity;
@ -202,8 +200,7 @@ public:
return Ops.constructVariadicOperator(Op, Args);
}
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind,
unsigned *Specificity) const override {
bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const override {
for (const VariantMatcher &Matcher : Args) {
if (!Matcher.isConvertibleTo(Kind, Specificity))
return false;

View File

@ -684,9 +684,7 @@ private:
}
};
ast_type_traits::ASTNodeKind Node::getType() const {
return ASTNode.getNodeKind();
}
ASTNodeKind Node::getType() const { return ASTNode.getNodeKind(); }
StringRef Node::getTypeLabel() const { return getType().asStringRef(); }

View File

@ -13,7 +13,6 @@
using namespace clang;
using namespace tooling;
using ast_type_traits::DynTypedNode;
namespace {

View File

@ -427,8 +427,7 @@ public:
StartLoc,
EndLoc,
TemplateSpecType->getTemplateName().getAsTemplateDecl(),
getClosestAncestorDecl(
ast_type_traits::DynTypedNode::create(TargetLoc)),
getClosestAncestorDecl(DynTypedNode::create(TargetLoc)),
GetNestedNameForType(TargetLoc),
/*IgnorePrefixQualifers=*/false};
RenameInfos.push_back(Info);
@ -467,8 +466,7 @@ private:
// FIXME: figure out how to handle it when there are multiple parents.
if (Parents.size() != 1)
return nullptr;
if (ast_type_traits::ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(
Parents[0].getNodeKind()))
if (ASTNodeKind::getFromNodeKind<Decl>().isBaseOf(Parents[0].getNodeKind()))
return Parents[0].template get<Decl>();
return getClosestAncestorDecl(Parents[0]);
}

View File

@ -23,8 +23,6 @@ using namespace clang;
using namespace transformer;
using ast_matchers::MatchFinder;
using ast_type_traits::ASTNodeKind;
using ast_type_traits::DynTypedNode;
using llvm::Error;
using llvm::StringError;

View File

@ -25,7 +25,6 @@ using namespace transformer;
using ast_matchers::MatchFinder;
using ast_matchers::internal::DynTypedMatcher;
using ast_type_traits::ASTNodeKind;
using MatchResult = MatchFinder::MatchResult;

View File

@ -26,7 +26,6 @@ using namespace clang;
using namespace transformer;
using ast_matchers::MatchFinder;
using ast_type_traits::DynTypedNode;
using llvm::errc;
using llvm::Error;
using llvm::Expected;

View File

@ -89,7 +89,6 @@ TEST(GetParents, RespectsTraversalScope) {
auto &Foo = *TU.lookup(&Ctx.Idents.get("foo")).front();
auto &Bar = *cast<DeclContext>(Foo).lookup(&Ctx.Idents.get("bar")).front();
using ast_type_traits::DynTypedNode;
// Initially, scope is the whole TU.
EXPECT_THAT(Ctx.getParents(Bar), ElementsAre(DynTypedNode::create(Foo)));
EXPECT_THAT(Ctx.getParents(Foo), ElementsAre(DynTypedNode::create(TU)));

View File

@ -96,7 +96,7 @@ template <typename... NodeType> std::string dumpASTString(NodeType &&... N) {
}
template <typename... NodeType>
std::string dumpASTString(ast_type_traits::TraversalKind TK, NodeType &&... N) {
std::string dumpASTString(TraversalKind TK, NodeType &&... N) {
std::string Buffer;
llvm::raw_string_ostream OS(Buffer);
@ -120,15 +120,13 @@ const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
template <typename T> struct Verifier {
static void withDynNode(T Node, const std::string &DumpString) {
EXPECT_EQ(dumpASTString(ast_type_traits::DynTypedNode::create(Node)),
DumpString);
EXPECT_EQ(dumpASTString(DynTypedNode::create(Node)), DumpString);
}
};
template <typename T> struct Verifier<T *> {
static void withDynNode(T *Node, const std::string &DumpString) {
EXPECT_EQ(dumpASTString(ast_type_traits::DynTypedNode::create(*Node)),
DumpString);
EXPECT_EQ(dumpASTString(DynTypedNode::create(*Node)), DumpString);
}
};
@ -280,7 +278,7 @@ struct MyStruct {
AST->getASTContext());
EXPECT_EQ(BN.size(), 1u);
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource,
BN[0].getNodeAs<Decl>("ctor")),
R"cpp(
CXXConstructorDecl 'MyStruct'
@ -289,9 +287,8 @@ CXXConstructorDecl 'MyStruct'
`-CXXTemporaryObjectExpr
)cpp");
EXPECT_EQ(
dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("ctor")),
R"cpp(
EXPECT_EQ(dumpASTString(TK_AsIs, BN[0].getNodeAs<Decl>("ctor")),
R"cpp(
CXXConstructorDecl 'MyStruct'
|-ParmVarDecl 'i'
`-CompoundStmt
@ -321,7 +318,7 @@ void foo()
AST->getASTContext());
EXPECT_EQ(BN.size(), 1u);
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource,
BN[0].getNodeAs<Decl>("fn")),
R"cpp(
FunctionDecl 'foo'
@ -330,9 +327,8 @@ FunctionDecl 'foo'
`-DeclRefExpr 'someFun'
)cpp");
EXPECT_EQ(
dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("fn")),
R"cpp(
EXPECT_EQ(dumpASTString(TK_AsIs, BN[0].getNodeAs<Decl>("fn")),
R"cpp(
FunctionDecl 'foo'
`-CompoundStmt
`-ExprWithCleanups
@ -437,7 +433,7 @@ FunctionDecl 'func1'
`-IntegerLiteral
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_AsIs, FN), Expected);
EXPECT_EQ(dumpASTString(TK_AsIs, FN), Expected);
Expected = R"cpp(
FunctionDecl 'func1'
@ -445,9 +441,7 @@ FunctionDecl 'func1'
`-ReturnStmt
`-IntegerLiteral
)cpp";
EXPECT_EQ(
dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, FN),
Expected);
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, FN), Expected);
}
llvm::StringRef Expected = R"cpp(
@ -457,9 +451,9 @@ FunctionDecl 'func2'
`-CXXTemporaryObjectExpr
`-IntegerLiteral
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func2")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func2")),
Expected);
Expected = R"cpp(
FunctionDecl 'func3'
@ -468,9 +462,9 @@ FunctionDecl 'func3'
`-CXXFunctionalCastExpr
`-IntegerLiteral
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func3")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func3")),
Expected);
Expected = R"cpp(
FunctionDecl 'func4'
@ -478,9 +472,9 @@ FunctionDecl 'func4'
`-ReturnStmt
`-CXXTemporaryObjectExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func4")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func4")),
Expected);
Expected = R"cpp(
FunctionDecl 'func5'
@ -488,9 +482,9 @@ FunctionDecl 'func5'
`-ReturnStmt
`-CXXTemporaryObjectExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func5")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func5")),
Expected);
Expected = R"cpp(
FunctionDecl 'func6'
@ -498,9 +492,9 @@ FunctionDecl 'func6'
`-ReturnStmt
`-CXXTemporaryObjectExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func6")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func6")),
Expected);
Expected = R"cpp(
FunctionDecl 'func7'
@ -508,9 +502,9 @@ FunctionDecl 'func7'
`-ReturnStmt
`-CXXTemporaryObjectExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func7")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func7")),
Expected);
Expected = R"cpp(
FunctionDecl 'func8'
@ -519,9 +513,9 @@ FunctionDecl 'func8'
`-CXXFunctionalCastExpr
`-InitListExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func8")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func8")),
Expected);
Expected = R"cpp(
FunctionDecl 'func9'
@ -530,9 +524,9 @@ FunctionDecl 'func9'
`-CXXFunctionalCastExpr
`-InitListExpr
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func9")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func9")),
Expected);
Expected = R"cpp(
FunctionDecl 'func10'
@ -543,9 +537,9 @@ FunctionDecl 'func10'
`-ReturnStmt
`-DeclRefExpr 'a'
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func10")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func10")),
Expected);
Expected = R"cpp(
FunctionDecl 'func11'
@ -556,9 +550,9 @@ FunctionDecl 'func11'
`-ReturnStmt
`-DeclRefExpr 'b'
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func11")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func11")),
Expected);
Expected = R"cpp(
FunctionDecl 'func12'
@ -569,9 +563,9 @@ FunctionDecl 'func12'
`-ReturnStmt
`-DeclRefExpr 'c'
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
getFunctionNode("func12")),
Expected);
EXPECT_EQ(
dumpASTString(TK_IgnoreUnlessSpelledInSource, getFunctionNode("func12")),
Expected);
}
TEST(Traverse, LambdaUnlessSpelledInSource) {
@ -629,8 +623,7 @@ LambdaExpr
| `-IntegerLiteral
`-CompoundStmt
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, L),
Expected);
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, L), Expected);
Expected = R"cpp(
LambdaExpr
@ -653,7 +646,7 @@ LambdaExpr
|-DeclRefExpr 'f'
`-CompoundStmt
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_AsIs, L), Expected);
EXPECT_EQ(dumpASTString(TK_AsIs, L), Expected);
}
{
@ -666,8 +659,7 @@ LambdaExpr
|-ParmVarDecl 't'
`-CompoundStmt
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, L),
Expected);
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, L), Expected);
}
{
@ -678,8 +670,7 @@ LambdaExpr
|-CXXThisExpr
`-CompoundStmt
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, L),
Expected);
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, L), Expected);
}
{
@ -692,8 +683,7 @@ LambdaExpr
| `-CXXThisExpr
`-CompoundStmt
)cpp";
EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, L),
Expected);
EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, L), Expected);
}
}

View File

@ -162,8 +162,8 @@ void MatchVerifier<NodeType>::run(const MatchFinder::MatchResult &Result) {
}
template <>
inline void MatchVerifier<ast_type_traits::DynTypedNode>::run(
const MatchFinder::MatchResult &Result) {
inline void
MatchVerifier<DynTypedNode>::run(const MatchFinder::MatchResult &Result) {
BoundNodes::IDToNodeMap M = Result.Nodes.getMap();
BoundNodes::IDToNodeMap::const_iterator I = M.find("");
if (I == M.end()) {
@ -260,7 +260,7 @@ private:
};
/// \brief Verify whether a node's dump contains a given substring.
class DumpVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
class DumpVerifier : public MatchVerifier<DynTypedNode> {
public:
void expectSubstring(const std::string &Str) {
ExpectSubstring = Str;
@ -268,7 +268,7 @@ public:
protected:
void verify(const MatchFinder::MatchResult &Result,
const ast_type_traits::DynTypedNode &Node) override {
const DynTypedNode &Node) override {
std::string DumpStr;
llvm::raw_string_ostream Dump(DumpStr);
Node.dump(Dump, *Result.SourceManager);
@ -287,7 +287,7 @@ private:
};
/// \brief Verify whether a node's pretty print matches a given string.
class PrintVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
class PrintVerifier : public MatchVerifier<DynTypedNode> {
public:
void expectString(const std::string &Str) {
ExpectString = Str;
@ -295,7 +295,7 @@ public:
protected:
void verify(const MatchFinder::MatchResult &Result,
const ast_type_traits::DynTypedNode &Node) override {
const DynTypedNode &Node) override {
std::string PrintStr;
llvm::raw_string_ostream Print(PrintStr);
Node.print(Print, Result.Context->getPrintingPolicy());

View File

@ -36,12 +36,11 @@ TEST(HasNameDeathTest, DiesOnEmptyPattern) {
TEST(ConstructVariadic, MismatchedTypes_Regression) {
EXPECT_TRUE(
matches("const int a = 0;",
internal::DynTypedMatcher::constructVariadic(
internal::DynTypedMatcher::VO_AnyOf,
ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(),
{isConstQualified(), arrayType()})
.convertTo<QualType>()));
matches("const int a = 0;", internal::DynTypedMatcher::constructVariadic(
internal::DynTypedMatcher::VO_AnyOf,
ASTNodeKind::getFromNodeKind<QualType>(),
{isConstQualified(), arrayType()})
.convertTo<QualType>()));
}
// For testing AST_MATCHER_P().
@ -69,7 +68,7 @@ AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
internal::Matcher<Decl>, AMatcher) {
return Finder->matchesChildOf(
Node, AMatcher, Builder,
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
ASTMatchFinder::BK_First);
}

View File

@ -1626,71 +1626,57 @@ void foo()
auto Matcher = varDecl(hasInitializer(floatLiteral()));
EXPECT_TRUE(
notMatches(VarDeclCode, traverse(ast_type_traits::TK_AsIs, Matcher)));
EXPECT_TRUE(
matches(VarDeclCode,
traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
Matcher)));
EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, Matcher)));
EXPECT_TRUE(matches(VarDeclCode,
traverse(TK_IgnoreImplicitCastsAndParentheses, Matcher)));
auto ParentMatcher = floatLiteral(hasParent(varDecl(hasName("i"))));
EXPECT_TRUE(notMatches(VarDeclCode,
traverse(ast_type_traits::TK_AsIs, ParentMatcher)));
EXPECT_TRUE(notMatches(VarDeclCode, traverse(TK_AsIs, ParentMatcher)));
EXPECT_TRUE(matches(VarDeclCode,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
ParentMatcher)));
EXPECT_TRUE(
matches(VarDeclCode, decl(traverse(ast_type_traits::TK_AsIs,
anyOf(cxxRecordDecl(), varDecl())))));
EXPECT_TRUE(matches(VarDeclCode,
floatLiteral(traverse(ast_type_traits::TK_AsIs,
hasParent(implicitCastExpr())))));
traverse(TK_IgnoreUnlessSpelledInSource, ParentMatcher)));
EXPECT_TRUE(matches(
VarDeclCode,
floatLiteral(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasParent(varDecl())))));
VarDeclCode, decl(traverse(TK_AsIs, anyOf(cxxRecordDecl(), varDecl())))));
EXPECT_TRUE(
matches(VarDeclCode,
varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
unless(parmVarDecl())))));
EXPECT_TRUE(notMatches(
VarDeclCode,
varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
has(implicitCastExpr())))));
EXPECT_TRUE(matches(VarDeclCode, varDecl(traverse(ast_type_traits::TK_AsIs,
has(implicitCastExpr())))));
EXPECT_TRUE(matches(
VarDeclCode,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
// The has() below strips away the ImplicitCastExpr before the
// traverse(AsIs) gets to process it.
varDecl(has(traverse(ast_type_traits::TK_AsIs, floatLiteral()))))));
EXPECT_TRUE(matches(
VarDeclCode,
functionDecl(traverse(ast_type_traits::TK_AsIs, hasName("foo")))));
EXPECT_TRUE(matches(
VarDeclCode,
functionDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasName("foo")))));
floatLiteral(traverse(TK_AsIs, hasParent(implicitCastExpr())))));
EXPECT_TRUE(
matches(VarDeclCode, functionDecl(traverse(ast_type_traits::TK_AsIs,
hasAnyName("foo", "bar")))));
matches(VarDeclCode, floatLiteral(traverse(TK_IgnoreUnlessSpelledInSource,
hasParent(varDecl())))));
EXPECT_TRUE(
matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
unless(parmVarDecl())))));
EXPECT_TRUE(
notMatches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
has(implicitCastExpr())))));
EXPECT_TRUE(matches(VarDeclCode,
varDecl(traverse(TK_AsIs, has(implicitCastExpr())))));
EXPECT_TRUE(matches(
VarDeclCode, traverse(TK_IgnoreUnlessSpelledInSource,
// The has() below strips away the ImplicitCastExpr
// before the traverse(AsIs) gets to process it.
varDecl(has(traverse(TK_AsIs, floatLiteral()))))));
EXPECT_TRUE(
matches(VarDeclCode, functionDecl(traverse(TK_AsIs, hasName("foo")))));
EXPECT_TRUE(matches(
VarDeclCode,
functionDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasAnyName("foo", "bar")))));
functionDecl(traverse(TK_IgnoreUnlessSpelledInSource, hasName("foo")))));
EXPECT_TRUE(matches(
VarDeclCode, functionDecl(traverse(TK_AsIs, hasAnyName("foo", "bar")))));
EXPECT_TRUE(
matches(VarDeclCode, functionDecl(traverse(TK_IgnoreUnlessSpelledInSource,
hasAnyName("foo", "bar")))));
const char *Code = R"cpp(
void foo(int a)
@ -1703,32 +1689,28 @@ void bar()
}
)cpp";
EXPECT_TRUE(
matches(Code,
callExpr(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasArgument(0, floatLiteral())))));
matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
hasArgument(0, floatLiteral())))));
EXPECT_TRUE(
matches(Code,
callExpr(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasAnyArgument(floatLiteral())))));
matches(Code, callExpr(traverse(TK_IgnoreUnlessSpelledInSource,
hasAnyArgument(floatLiteral())))));
EXPECT_TRUE(
matches(VarDeclCode, varDecl(traverse(TK_IgnoreUnlessSpelledInSource,
hasType(builtinType())))));
EXPECT_TRUE(
matches(VarDeclCode,
varDecl(traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
hasType(builtinType())))));
functionDecl(hasName("foo"),
traverse(TK_AsIs, hasDescendant(floatLiteral())))));
EXPECT_TRUE(matches(
VarDeclCode,
functionDecl(hasName("foo"), traverse(ast_type_traits::TK_AsIs,
hasDescendant(floatLiteral())))));
EXPECT_TRUE(notMatches(Code, traverse(ast_type_traits::TK_AsIs,
floatLiteral(hasParent(callExpr(callee(
functionDecl(hasName("foo")))))))));
EXPECT_TRUE(
matches(Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
floatLiteral(hasParent(callExpr(
callee(functionDecl(hasName("foo")))))))));
EXPECT_TRUE(notMatches(
Code, traverse(TK_AsIs, floatLiteral(hasParent(callExpr(
callee(functionDecl(hasName("foo")))))))));
EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
floatLiteral(hasParent(callExpr(callee(
functionDecl(hasName("foo")))))))));
Code = R"cpp(
void foo()
@ -1736,23 +1718,22 @@ void foo()
int i = (3);
}
)cpp";
EXPECT_TRUE(
matches(Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
varDecl(hasInitializer(integerLiteral(equals(3)))))));
EXPECT_TRUE(matches(
Code, traverse(TK_IgnoreUnlessSpelledInSource,
varDecl(hasInitializer(integerLiteral(equals(3)))))));
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
traverse(TK_IgnoreUnlessSpelledInSource,
integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
Code = R"cpp(
const char *SomeString{"str"};
)cpp";
EXPECT_TRUE(matches(Code, traverse(ast_type_traits::TK_AsIs,
stringLiteral(hasParent(implicitCastExpr(
hasParent(initListExpr())))))));
EXPECT_TRUE(
matches(Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
matches(Code, traverse(TK_AsIs, stringLiteral(hasParent(implicitCastExpr(
hasParent(initListExpr())))))));
EXPECT_TRUE(
matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
stringLiteral(hasParent(initListExpr())))));
}
@ -1774,9 +1755,8 @@ int foo()
}
)cpp";
EXPECT_TRUE(matcherTemplateWithBinding(
Code,
traverse(ast_type_traits::TK_AsIs,
returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
Code, traverse(TK_AsIs,
returnStmt(has(implicitCastExpr(has(floatLiteral())))))));
}
TEST(Traversal, traverseMatcherNesting) {
@ -1793,12 +1773,11 @@ void foo()
}
)cpp";
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
callExpr(has(callExpr(traverse(
ast_type_traits::TK_AsIs,
callExpr(has(implicitCastExpr(has(floatLiteral())))))))))));
EXPECT_TRUE(
matches(Code, traverse(TK_IgnoreImplicitCastsAndParentheses,
callExpr(has(callExpr(traverse(
TK_AsIs, callExpr(has(implicitCastExpr(
has(floatLiteral())))))))))));
}
TEST(Traversal, traverseMatcherThroughImplicit) {
@ -1813,8 +1792,8 @@ void constructImplicit() {
}
)cpp";
auto Matcher = traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
implicitCastExpr());
auto Matcher =
traverse(TK_IgnoreImplicitCastsAndParentheses, implicitCastExpr());
// Verfiy that it does not segfault
EXPECT_FALSE(matches(Code, Matcher));
@ -1839,10 +1818,10 @@ void foo()
// would cause the overall matcher to be incorrectly false.
EXPECT_TRUE(matches(
Code, functionDecl(anyOf(
hasDescendant(Matcher),
traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses,
functionDecl(hasDescendant(Matcher)))))));
Code,
functionDecl(anyOf(hasDescendant(Matcher),
traverse(TK_IgnoreImplicitCastsAndParentheses,
functionDecl(hasDescendant(Matcher)))))));
}
TEST(Traversal, traverseUnlessSpelledInSource) {
@ -1931,32 +1910,32 @@ void func14() {
)cpp";
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func1"))),
hasReturnValue(integerLiteral(equals(42)))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
integerLiteral(equals(42),
hasParent(returnStmt(forFunction(
functionDecl(hasName("func1")))))))));
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func2"))),
hasReturnValue(cxxTemporaryObjectExpr(
hasArgument(0, integerLiteral(equals(42)))))))));
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
traverse(TK_IgnoreUnlessSpelledInSource,
integerLiteral(
equals(42),
hasParent(cxxTemporaryObjectExpr(hasParent(returnStmt(
forFunction(functionDecl(hasName("func2")))))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func3"))),
hasReturnValue(
cxxFunctionalCastExpr(hasSourceExpression(
@ -1964,76 +1943,76 @@ void func14() {
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
traverse(TK_IgnoreUnlessSpelledInSource,
integerLiteral(
equals(42),
hasParent(cxxFunctionalCastExpr(hasParent(returnStmt(
forFunction(functionDecl(hasName("func3")))))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func4"))),
hasReturnValue(cxxTemporaryObjectExpr())))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func5"))),
hasReturnValue(cxxTemporaryObjectExpr())))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func6"))),
hasReturnValue(cxxTemporaryObjectExpr())))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func7"))),
hasReturnValue(cxxTemporaryObjectExpr())))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func8"))),
hasReturnValue(cxxFunctionalCastExpr(
hasSourceExpression(initListExpr())))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func9"))),
hasReturnValue(cxxFunctionalCastExpr(
hasSourceExpression(initListExpr())))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func10"))),
hasReturnValue(
declRefExpr(to(varDecl(hasName("a")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
declRefExpr(to(varDecl(hasName("a"))),
hasParent(returnStmt(forFunction(
functionDecl(hasName("func10")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func11"))),
hasReturnValue(
declRefExpr(to(varDecl(hasName("b")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
declRefExpr(to(varDecl(hasName("b"))),
hasParent(returnStmt(forFunction(
functionDecl(hasName("func11")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
returnStmt(forFunction(functionDecl(hasName("func12"))),
hasReturnValue(
declRefExpr(to(varDecl(hasName("c")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
declRefExpr(to(varDecl(hasName("c"))),
hasParent(returnStmt(forFunction(
functionDecl(hasName("func12")))))))));
@ -2041,7 +2020,7 @@ void func14() {
EXPECT_TRUE(matches(
Code,
traverse(
ast_type_traits::TK_IgnoreUnlessSpelledInSource,
TK_IgnoreUnlessSpelledInSource,
lambdaExpr(forFunction(functionDecl(hasName("func13"))),
has(compoundStmt(hasDescendant(varDecl(hasName("e"))))),
has(declRefExpr(to(varDecl(hasName("a"))))),
@ -2050,27 +2029,27 @@ void func14() {
has(parmVarDecl(hasName("d")))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
declRefExpr(to(varDecl(hasName("a"))),
hasParent(lambdaExpr(forFunction(
functionDecl(hasName("func13")))))))));
EXPECT_TRUE(matches(
Code,
traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
traverse(TK_IgnoreUnlessSpelledInSource,
varDecl(hasName("b"),
hasInitializer(declRefExpr(to(varDecl(hasName("c"))))),
hasParent(lambdaExpr(
forFunction(functionDecl(hasName("func13")))))))));
EXPECT_TRUE(matches(
Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
Code, traverse(TK_IgnoreUnlessSpelledInSource,
lambdaExpr(
forFunction(functionDecl(hasName("func14"))),
has(templateTypeParmDecl(hasName("TemplateType")))))));
EXPECT_TRUE(
matches(Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
functionDecl(hasName("func14"),
hasDescendant(floatLiteral())))));
}