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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits