forked from OSchip/llvm-project
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:
parent
2fb6268854
commit
cd62511496
|
@ -7381,11 +7381,11 @@ Usable as: Any Matcher
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<T></td><td class="name" onclick="toggle('traverse1')"><a name="traverse1Anchor">traverse</a></td><td>ast_type_traits::TraversalKind TK, const BindableMatcher<T> InnerMatcher</td></tr>
|
||||
<tr><td>Matcher<T></td><td class="name" onclick="toggle('traverse1')"><a name="traverse1Anchor">traverse</a></td><td>TraversalKind TK, const BindableMatcher<T> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="traverse1"><pre></pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<T></td><td class="name" onclick="toggle('traverse0')"><a name="traverse0Anchor">traverse</a></td><td>ast_type_traits::TraversalKind TK, const Matcher<T> InnerMatcher</td></tr>
|
||||
<tr><td>Matcher<T></td><td class="name" onclick="toggle('traverse0')"><a name="traverse0Anchor">traverse</a></td><td>TraversalKind TK, const Matcher<T> 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".
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace clang {
|
||||
namespace diff {
|
||||
|
||||
using DynTypedNode = ast_type_traits::DynTypedNode;
|
||||
using DynTypedNode = DynTypedNode;
|
||||
|
||||
class SyntaxTree;
|
||||
class SyntaxTreeImpl;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ⤅
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
using namespace clang;
|
||||
using namespace tooling;
|
||||
using ast_type_traits::DynTypedNode;
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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())))));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue