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

Reply via email to