forked from OSchip/llvm-project
Complete support for the cxxCtorInitializer() AST matcher so that it can be used as a top-level matcher.
llvm-svn: 282417
This commit is contained in:
parent
b3d2546c43
commit
5fa302cb65
|
@ -158,6 +158,8 @@ public:
|
|||
MatchCallback *Action);
|
||||
void addMatcher(const TypeLocMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
|
||||
MatchCallback *Action);
|
||||
/// @}
|
||||
|
||||
/// \brief Adds a matcher to execute when running over the AST.
|
||||
|
@ -208,6 +210,7 @@ public:
|
|||
std::vector<std::pair<NestedNameSpecifierLocMatcher, MatchCallback *>>
|
||||
NestedNameSpecifierLoc;
|
||||
std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
|
||||
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
|
||||
/// \brief All the callbacks in one container to simplify iteration.
|
||||
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
|
||||
};
|
||||
|
|
|
@ -125,6 +125,7 @@ typedef internal::Matcher<QualType> TypeMatcher;
|
|||
typedef internal::Matcher<TypeLoc> TypeLocMatcher;
|
||||
typedef internal::Matcher<NestedNameSpecifier> NestedNameSpecifierMatcher;
|
||||
typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher;
|
||||
typedef internal::Matcher<CXXCtorInitializer> CXXCtorInitializerMatcher;
|
||||
/// @}
|
||||
|
||||
/// \brief Matches any node.
|
||||
|
|
|
@ -126,6 +126,8 @@ public:
|
|||
traverse(*Q);
|
||||
else if (const TypeLoc *T = DynNode.get<TypeLoc>())
|
||||
traverse(*T);
|
||||
else if (const auto *C = DynNode.get<CXXCtorInitializer>())
|
||||
traverse(*C);
|
||||
// FIXME: Add other base types after adding tests.
|
||||
|
||||
// It's OK to always overwrite the bound nodes, as if there was
|
||||
|
@ -194,6 +196,12 @@ public:
|
|||
return false;
|
||||
return traverse(NNS);
|
||||
}
|
||||
bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit) {
|
||||
if (!CtorInit)
|
||||
return true;
|
||||
ScopedIncrement ScopedDepth(&CurrentDepth);
|
||||
return traverse(*CtorInit);
|
||||
}
|
||||
|
||||
bool shouldVisitTemplateInstantiations() const { return true; }
|
||||
bool shouldVisitImplicitCode() const { return true; }
|
||||
|
@ -235,6 +243,10 @@ private:
|
|||
bool baseTraverse(NestedNameSpecifierLoc NNS) {
|
||||
return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
|
||||
}
|
||||
bool baseTraverse(const CXXCtorInitializer &CtorInit) {
|
||||
return VisitorBase::TraverseConstructorInitializer(
|
||||
const_cast<CXXCtorInitializer *>(&CtorInit));
|
||||
}
|
||||
|
||||
// Sets 'Matched' to true if 'Matcher' matches 'Node' and:
|
||||
// 0 < CurrentDepth <= MaxDepth.
|
||||
|
@ -371,6 +383,7 @@ public:
|
|||
bool TraverseTypeLoc(TypeLoc TypeNode);
|
||||
bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
|
||||
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
|
||||
bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
|
||||
|
||||
// Matches children or descendants of 'Node' with 'BaseMatcher'.
|
||||
bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
|
||||
|
@ -472,6 +485,8 @@ public:
|
|||
match(*N);
|
||||
} else if (auto *N = Node.get<TypeLoc>()) {
|
||||
match(*N);
|
||||
} else if (auto *N = Node.get<CXXCtorInitializer>()) {
|
||||
match(*N);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,6 +608,9 @@ private:
|
|||
void matchDispatch(const NestedNameSpecifierLoc *Node) {
|
||||
matchWithoutFilter(*Node, Matchers->NestedNameSpecifierLoc);
|
||||
}
|
||||
void matchDispatch(const CXXCtorInitializer *Node) {
|
||||
matchWithoutFilter(*Node, Matchers->CtorInit);
|
||||
}
|
||||
void matchDispatch(const void *) { /* Do nothing. */ }
|
||||
/// @}
|
||||
|
||||
|
@ -864,6 +882,17 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
|
|||
RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
|
||||
}
|
||||
|
||||
bool MatchASTVisitor::TraverseConstructorInitializer(
|
||||
CXXCtorInitializer *CtorInit) {
|
||||
if (!CtorInit)
|
||||
return true;
|
||||
|
||||
match(*CtorInit);
|
||||
|
||||
return RecursiveASTVisitor<MatchASTVisitor>::TraverseConstructorInitializer(
|
||||
CtorInit);
|
||||
}
|
||||
|
||||
class MatchASTConsumer : public ASTConsumer {
|
||||
public:
|
||||
MatchASTConsumer(MatchFinder *Finder,
|
||||
|
@ -934,6 +963,12 @@ void MatchFinder::addMatcher(const TypeLocMatcher &NodeMatch,
|
|||
Matchers.AllCallbacks.insert(Action);
|
||||
}
|
||||
|
||||
void MatchFinder::addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
Matchers.CtorInit.emplace_back(NodeMatch, Action);
|
||||
Matchers.AllCallbacks.insert(Action);
|
||||
}
|
||||
|
||||
bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
|
||||
MatchCallback *Action) {
|
||||
if (NodeMatch.canConvertTo<Decl>()) {
|
||||
|
@ -954,6 +989,9 @@ bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch,
|
|||
} else if (NodeMatch.canConvertTo<TypeLoc>()) {
|
||||
addMatcher(NodeMatch.convertTo<TypeLoc>(), Action);
|
||||
return true;
|
||||
} else if (NodeMatch.canConvertTo<CXXCtorInitializer>()) {
|
||||
addMatcher(NodeMatch.convertTo<CXXCtorInitializer>(), Action);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -528,6 +528,11 @@ TEST(Matcher, ConstructorCall) {
|
|||
EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
|
||||
}
|
||||
|
||||
TEST(Match, ConstructorInitializers) {
|
||||
EXPECT_TRUE(matches("class C { int i; public: C(int ii) : i(ii) {} };",
|
||||
cxxCtorInitializer(forField(hasName("i")))));
|
||||
}
|
||||
|
||||
TEST(Matcher, ThisExpr) {
|
||||
EXPECT_TRUE(
|
||||
matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
|
||||
|
|
Loading…
Reference in New Issue