usaxena95 created this revision.
usaxena95 added reviewers: massberg, sammccall.
Herald added a subscriber: kadircet.
Herald added a project: All.
usaxena95 requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.
This is similar to D155858 <https://reviews.llvm.org/D155858> and is probably
more suited to be a followup to it.
Happy to wait if the mentioned revision is ready to land soon. Otherwise we
could land this first and fix the include-cleaner bug.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D158842
Files:
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
clang/include/clang/AST/RecursiveASTVisitor.h
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -463,15 +463,13 @@
bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
+ bool TraverseConceptReference(const ConceptReference &C);
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
- /// Traverses the qualifier, name and template arguments of a concept
- /// reference.
- bool TraverseConceptReferenceHelper(const ConceptReference &C);
// Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
template <typename T>
@@ -507,7 +505,7 @@
bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
const TypeConstraint *C) {
if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO(TraverseConceptReferenceHelper(*C));
+ TRY_TO(TraverseConceptReference(*C));
return true;
}
if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
@@ -517,7 +515,7 @@
// if we have an immediately-declared-constraint, otherwise
// we'll end up visiting the concept and the arguments in
// the TC twice.
- TRY_TO(TraverseConceptReferenceHelper(*C));
+ TRY_TO(TraverseConceptReference(*C));
}
return true;
}
@@ -541,7 +539,7 @@
}
template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseConceptReferenceHelper(
+bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
const ConceptReference &C) {
TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo()));
@@ -2904,7 +2902,7 @@
})
DEF_TRAVERSE_STMT(ConceptSpecializationExpr,
- { TRY_TO(TraverseConceptReferenceHelper(*S)); })
+ { TRY_TO(TraverseConceptReference(*S)); })
DEF_TRAVERSE_STMT(RequiresExpr, {
TRY_TO(TraverseDecl(S->getBody()));
Index: clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
===================================================================
--- clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp
@@ -198,6 +198,45 @@
Pair(Code.point("4"), UnorderedElementsAre(MainFile))));
}
+TEST_F(WalkUsedTest, Concepts) {
+ llvm::Annotations ConceptHdr(guard(R"cpp(
+ template<typename T>
+ concept Foo = true;
+ )cpp"));
+ llvm::Annotations Code(R"cpp(
+ #include "concept.h"
+
+ template<typename T>
+ concept $Bar1^Bar = $Foo1^Foo<T> && true;
+
+ template<$Bar2^Bar T> requires $Bar3^Bar<T> && $Foo2^Foo<T>
+ void $1^func1() {}
+
+ template<$Foo3^Foo T>
+ void $2^func2() requires $Bar4^Bar<T> {}
+ )cpp");
+ Inputs.Code = Code.code();
+ Inputs.ExtraFiles["concept.h"] = ConceptHdr.code();
+ Inputs.ExtraArgs.push_back("--std=c++20");
+ TestAST AST(Inputs);
+ auto &SM = AST.sourceManager();
+ const auto *ConceptHdrFile = SM.getFileManager().getFile("concept.h").get();
+ auto MainFile = Header(SM.getFileEntryForID(SM.getMainFileID()));
+
+ EXPECT_THAT(
+ offsetToProviders(AST),
+ UnorderedElementsAre(
+ Pair(Code.point("Foo1"), UnorderedElementsAre(ConceptHdrFile)),
+ Pair(Code.point("Foo2"), UnorderedElementsAre(ConceptHdrFile)),
+ Pair(Code.point("Foo3"), UnorderedElementsAre(ConceptHdrFile)),
+ Pair(Code.point("Bar1"), UnorderedElementsAre(MainFile)),
+ Pair(Code.point("Bar2"), UnorderedElementsAre(MainFile)),
+ Pair(Code.point("Bar3"), UnorderedElementsAre(MainFile)),
+ Pair(Code.point("Bar4"), UnorderedElementsAre(MainFile)),
+ Pair(Code.point("1"), UnorderedElementsAre(MainFile)),
+ Pair(Code.point("2"), UnorderedElementsAre(MainFile))));
+}
+
class AnalyzeTest : public testing::Test {
protected:
TestInputs Inputs;
@@ -299,7 +338,7 @@
Results.Unused.push_back(Inc.atLine(4));
EXPECT_EQ(fixIncludes(Results, "d.cc", Code, format::getLLVMStyle()),
-R"cpp(#include "d.h"
+ R"cpp(#include "d.h"
#include "a.h"
#include "aa.h"
#include "ab.h"
@@ -310,7 +349,7 @@
Results.Missing.push_back("\"d.h\"");
Code = R"cpp(#include "a.h")cpp";
EXPECT_EQ(fixIncludes(Results, "d.cc", Code, format::getLLVMStyle()),
-R"cpp(#include "d.h"
+ R"cpp(#include "d.h"
#include "a.h")cpp");
}
Index: clang-tools-extra/include-cleaner/lib/WalkAST.cpp
===================================================================
--- clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -232,6 +232,15 @@
return true;
}
+ bool VisitConceptDecl(ConceptDecl *CD) {
+ report(CD->getLocation(), CD);
+ return true;
+ }
+
+ bool TraverseConceptReference(const ConceptReference &C) {
+ report(C.getConceptNameLoc(), C.getFoundDecl());
+ return RecursiveASTVisitor::TraverseConceptReference(C);
+ }
// Report a reference from explicit specializations to the specialized
// template. Implicit ones are filtered out by RAV and explicit instantiations
// are already traversed through typelocs.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits