This revision was automatically updated to reflect the committed changes.
Closed by commit rGc3a21e5de3dc: [ASTMatchers] Ensure that we can match inside
lambdas (authored by stephenkelly).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93688/new/
https://reviews.llvm.org/D93688
Files:
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/lib/ASTMatchers/ASTMatchFinder.cpp
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -3065,6 +3065,33 @@
traverse(TK_IgnoreUnlessSpelledInSource,
functionDecl(hasName("func14"), hasDescendant(floatLiteral()))),
langCxx20OrLater()));
+
+ Code = R"cpp(
+void foo() {
+ int explicit_captured = 0;
+ int implicit_captured = 0;
+ auto l = [&, explicit_captured](int i) {
+ if (i || explicit_captured || implicit_captured) return;
+ };
+}
+)cpp";
+
+ EXPECT_TRUE(matches(Code, traverse(TK_AsIs, ifStmt())));
+ EXPECT_TRUE(
+ matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, ifStmt())));
+
+ auto lambdaExplicitCapture = declRefExpr(
+ to(varDecl(hasName("explicit_captured"))), unless(hasAncestor(ifStmt())));
+ auto lambdaImplicitCapture = declRefExpr(
+ to(varDecl(hasName("implicit_captured"))), unless(hasAncestor(ifStmt())));
+
+ EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaExplicitCapture)));
+ EXPECT_TRUE(matches(
+ Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaExplicitCapture)));
+
+ EXPECT_TRUE(matches(Code, traverse(TK_AsIs, lambdaImplicitCapture)));
+ EXPECT_FALSE(matches(
+ Code, traverse(TK_IgnoreUnlessSpelledInSource, lambdaImplicitCapture)));
}
TEST(IgnoringImpCasts, MatchesImpCasts) {
Index: clang/lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -293,6 +293,10 @@
Finder->IsMatchingInASTNodeNotSpelledInSource())
return false;
+ if (!Finder->isTraversalIgnoringImplicitNodes() &&
+ Finder->IsMatchingInASTNodeNotAsIs())
+ return false;
+
auto N =
Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
@@ -317,6 +321,10 @@
Finder->IsMatchingInASTNodeNotSpelledInSource())
return false;
+ if (!Finder->isTraversalIgnoringImplicitNodes() &&
+ Finder->IsMatchingInASTNodeNotAsIs())
+ return false;
+
auto N =
Finder->getASTContext().getParentMapContext().traverseIgnored(DynNode);
Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp
===================================================================
--- clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -475,6 +475,55 @@
}
}
return true;
+ } else if (auto *LE = dyn_cast<LambdaExpr>(S)) {
+ for (auto I : llvm::zip(LE->captures(), LE->capture_inits())) {
+ auto C = std::get<0>(I);
+ ASTNodeNotSpelledInSourceScope RAII(
+ this, TraversingASTNodeNotSpelledInSource || !C.isExplicit());
+ TraverseLambdaCapture(LE, &C, std::get<1>(I));
+ }
+
+ {
+ ASTNodeNotSpelledInSourceScope RAII(this, true);
+ TraverseDecl(LE->getLambdaClass());
+ }
+ {
+ ASTNodeNotAsIsSourceScope RAII(this, true);
+
+ // We need to poke around to find the bits that might be explicitly
+ // written.
+ TypeLoc TL = LE->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
+
+ if (auto *TPL = LE->getTemplateParameterList()) {
+ for (NamedDecl *D : *TPL) {
+ TraverseDecl(D);
+ }
+ if (Expr *RequiresClause = TPL->getRequiresClause()) {
+ TraverseStmt(RequiresClause);
+ }
+ }
+
+ if (LE->hasExplicitParameters()) {
+ // Visit parameters.
+ for (ParmVarDecl *Param : Proto.getParams())
+ TraverseDecl(Param);
+ }
+
+ const auto *T = Proto.getTypePtr();
+ for (const auto &E : T->exceptions())
+ TraverseType(E);
+
+ if (Expr *NE = T->getNoexceptExpr())
+ TraverseStmt(NE, Queue);
+
+ if (LE->hasExplicitResultType())
+ TraverseTypeLoc(Proto.getReturnLoc());
+ TraverseStmt(LE->getTrailingRequiresClause());
+
+ TraverseStmt(LE->getBody());
+ }
+ return true;
}
return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue);
}
@@ -617,6 +666,9 @@
bool IsMatchingInASTNodeNotSpelledInSource() const override {
return TraversingASTNodeNotSpelledInSource;
}
+ bool IsMatchingInASTNodeNotAsIs() const override {
+ return TraversingASTNodeNotAsIs;
+ }
bool TraverseTemplateInstantiations(ClassTemplateDecl *D) {
ASTNodeNotSpelledInSourceScope RAII(this, true);
@@ -638,6 +690,7 @@
private:
bool TraversingASTNodeNotSpelledInSource = false;
+ bool TraversingASTNodeNotAsIs = false;
bool TraversingASTChildrenNotSpelledInSource = false;
struct ASTNodeNotSpelledInSourceScope {
@@ -654,6 +707,18 @@
bool MB;
};
+ struct ASTNodeNotAsIsSourceScope {
+ ASTNodeNotAsIsSourceScope(MatchASTVisitor *V, bool B)
+ : MV(V), MB(V->TraversingASTNodeNotAsIs) {
+ V->TraversingASTNodeNotAsIs = B;
+ }
+ ~ASTNodeNotAsIsSourceScope() { MV->TraversingASTNodeNotAsIs = MB; }
+
+ private:
+ MatchASTVisitor *MV;
+ bool MB;
+ };
+
struct ASTChildrenNotSpelledInSource {
ASTChildrenNotSpelledInSource(MatchASTVisitor *V, bool B)
: MV(V), MB(V->TraversingASTChildrenNotSpelledInSource) {
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -723,6 +723,8 @@
virtual bool IsMatchingInASTNodeNotSpelledInSource() const = 0;
+ virtual bool IsMatchingInASTNodeNotAsIs() const = 0;
+
bool isTraversalIgnoringImplicitNodes() const;
protected:
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits