Author: Kadir Cetinkaya Date: 2023-05-23T16:40:51+02:00 New Revision: cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7
URL: https://github.com/llvm/llvm-project/commit/cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7 DIFF: https://github.com/llvm/llvm-project/commit/cce7b816a1ee70f2d1f3c21d2a99475c17b54bd7.diff LOG: [include-cleaner] Treat references to nested types implicit Differential Revision: https://reviews.llvm.org/D149948 Added: Modified: clang-tools-extra/include-cleaner/lib/WalkAST.cpp clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 4ea7bceeb96ed..c593192c50191 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -218,31 +218,45 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { } // TypeLoc visitors. + void reportType(SourceLocation RefLoc, NamedDecl *ND) { + // Reporting explicit references to types nested inside classes can cause + // issues, e.g. a type accessed through a derived class shouldn't require + // inclusion of the base. + // Hence we report all such references as implicit. The code must spell the + // outer type-location somewhere, which will trigger an explicit reference + // and per IWYS, it's that spelling's responsibility to bring in necessary + // declarations. + RefType RT = llvm::isa<RecordDecl>(ND->getDeclContext()) + ? RefType::Implicit + : RefType::Explicit; + return report(RefLoc, ND, RT); + } + bool VisitUsingTypeLoc(UsingTypeLoc TL) { - report(TL.getNameLoc(), TL.getFoundDecl()); + reportType(TL.getNameLoc(), TL.getFoundDecl()); return true; } bool VisitTagTypeLoc(TagTypeLoc TTL) { - report(TTL.getNameLoc(), TTL.getDecl()); + reportType(TTL.getNameLoc(), TTL.getDecl()); return true; } bool VisitTypedefTypeLoc(TypedefTypeLoc TTL) { - report(TTL.getNameLoc(), TTL.getTypedefNameDecl()); + reportType(TTL.getNameLoc(), TTL.getTypedefNameDecl()); return true; } bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { - report(TL.getTemplateNameLoc(), - getMostRelevantTemplatePattern(TL.getTypePtr())); + reportType(TL.getTemplateNameLoc(), + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } bool VisitDeducedTemplateSpecializationTypeLoc( DeducedTemplateSpecializationTypeLoc TL) { - report(TL.getTemplateNameLoc(), - getMostRelevantTemplatePattern(TL.getTypePtr())); + reportType(TL.getTemplateNameLoc(), + getMostRelevantTemplatePattern(TL.getTypePtr())); return true; } diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp index ffe8bbffc3712..0d504c3303f9e 100644 --- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp @@ -341,6 +341,34 @@ TEST(WalkAST, TemplateNames) { testWalk("template<typename T> struct $explicit^S { S(T); };", "^S s(42);"); } +TEST(WalkAST, NestedTypes) { + testWalk(R"cpp( + struct Base { typedef int $implicit^a; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct Base { using $implicit^a = int; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct ns { struct a {}; }; + struct Base : public ns { using ns::$implicit^a; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk(R"cpp( + struct Base { struct $implicit^a {}; }; + struct Derived : public Base {};)cpp", + "void fun() { Derived::^a x; }"); + testWalk("struct Base { struct $implicit^a {}; };", + "struct Derived : public Base { ^a x; };"); + testWalk(R"cpp( + struct Base { struct $implicit^a {}; }; + struct Derived : public Base {}; + struct SoDerived : public Derived {}; + )cpp", + "void fun() { SoDerived::Derived::^a x; }"); +} + TEST(WalkAST, MemberExprs) { testWalk("struct $implicit^S { static int f; };", "void foo() { S::^f; }"); testWalk("struct B { static int f; }; struct $implicit^S : B {};", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits