https://github.com/dmaclach updated 
https://github.com/llvm/llvm-project/pull/216201

>From 23010f10d8c513f542a78b59e7d41a5f6e2e9152 Mon Sep 17 00:00:00 2001
From: Dave MacLachlan <[email protected]>
Date: Thu, 13 Aug 2026 15:23:11 -0700
Subject: [PATCH 1/2] [include-cleaner] Support Objective-C literals and boxed
 expressions in WalkAST

This change adds AST visitors for ObjCBoxedExpr, ObjCArrayLiteral, 
ObjCDictionaryLiteral, and ObjCStringLiteral. This ensures that the underlying 
class interfaces (such as NSNumber, NSArray, NSDictionary, and NSString) and 
any associated categories used for these literals are correctly reported as 
referenced. Unit tests are included to verify the new behavior.
---
 .../include-cleaner/lib/WalkAST.cpp           | 28 +++++++
 .../include-cleaner/unittests/WalkASTTest.cpp | 73 +++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 17e7bd6ed683f..976e998e1d45f 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -622,6 +622,34 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
     }
     return true;
   }
+
+  void ReportObjCMethodDecl(SourceLocation Loc, ObjCMethodDecl *Method) {
+    if (!Method)
+      return;
+    report(Loc, Method->getClassInterface(), RefType::Implicit);
+    report(Loc, dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()));
+  }
+
+  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
+    ReportObjCMethodDecl(E->getBeginLoc(), E->getBoxingMethod());
+    return true;
+  }
+
+  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
+    ReportObjCMethodDecl(E->getBeginLoc(), E->getArrayWithObjectsMethod());
+    return true;
+  }
+
+  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
+    ReportObjCMethodDecl(E->getBeginLoc(), E->getDictWithObjectsMethod());
+    return true;
+  }
+
+  bool VisitObjCStringLiteral(ObjCStringLiteral *E) {
+    if (const auto *ObjCPtr = E->getType()->getAs<ObjCObjectPointerType>())
+      report(E->getBeginLoc(), ObjCPtr->getInterfaceDecl(), RefType::Implicit);
+    return true;
+  }
 };
 
 } // namespace
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index ace55ea7aa23f..71bc455ca00ed 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -1250,6 +1250,7 @@ TEST(WalkAST, ObjCTollFreeBridgeCStyleCast) {
            {"-x", "objective-c"});
 }
 
+
 TEST(WalkAST, ObjCBridgedCastExprToProtocol) {
   // Note this test case is handled by TraverseObjCProtocolLoc instead of
   // VisitCastExpr.
@@ -1545,5 +1546,77 @@ TEST(WalkAST, ObjCEncodeExpr) {
            {"-x", "objective-c"});
 }
 
+TEST(WalkAST, ObjCBoxedExprInt) {
+  testWalk(R"objc(
+    @interface $implicit^NSNumber
+    + (id)numberWithInt:(int)val;
+    @end
+  )objc",
+           R"objc(
+    void test() {
+      id x = ^@42;
+    }
+  )objc",
+           {"-x", "objective-c"});
+}
+
+
+TEST(WalkAST, ObjCBoxedExprCategory) {
+  testWalk(R"objc(
+    @interface $implicit^NSNumber
+    @end
+    @interface $explicit^NSNumber (CustomCategory)
+    + (id)numberWithInt:(int)val;
+    @end
+  )objc",
+           R"objc(
+    void test() {
+      id x = ^@42;
+    }
+  )objc",
+           {"-x", "objective-c"});
+}
+
+TEST(WalkAST, ObjCArrayLiteral) {
+  testWalk(R"objc(
+    @interface $implicit^NSArray
+    + (id)arrayWithObjects:(const id *)objects count:(unsigned long)cnt;
+    @end
+  )objc",
+           R"objc(
+    void test(id a, id b) {
+      id arr = ^@[a, b];
+    }
+  )objc",
+           {"-x", "objective-c"});
+}
+
+TEST(WalkAST, ObjCDictionaryLiteral) {
+  testWalk(R"objc(
+    @interface $implicit^NSDictionary
+    + (id)dictionaryWithObjects:(const id *)objects forKeys:(const id *)keys 
count:(unsigned long)cnt;
+    @end
+  )objc",
+           R"objc(
+    void test(id k, id v) {
+      id dict = ^@{k: v};
+    }
+  )objc",
+           {"-x", "objective-c"});
+}
+
+TEST(WalkAST, ObjCStringLiteral) {
+  testWalk(R"objc(
+    @interface $implicit^NSString
+    @end
+  )objc",
+           R"objc(
+    void test() {
+      id s = ^@"hello";
+    }
+  )objc",
+           {"-x", "objective-c"});
+}
+
 } // namespace
 } // namespace clang::include_cleaner

>From 90228f581f914f637e43076f6c51b5464349ba29 Mon Sep 17 00:00:00 2001
From: Dave MacLachlan <[email protected]>
Date: Mon, 24 Aug 2026 10:23:14 -0700
Subject: [PATCH 2/2] Cleaned up based on comments   - Changed references to
 explicit   - Removed unneeded references for categories   - Added test for
 Boxed C Structures

---
 .../include-cleaner/lib/WalkAST.cpp           | 16 +++++------
 .../include-cleaner/unittests/WalkASTTest.cpp | 27 ++++++++++---------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 976e998e1d45f..5449411371e60 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -623,31 +623,31 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
     return true;
   }
 
-  void ReportObjCMethodDecl(SourceLocation Loc, ObjCMethodDecl *Method) {
+  void reportObjCLiteralMethod(SourceLocation Loc, ObjCMethodDecl *Method) {
     if (!Method)
       return;
-    report(Loc, Method->getClassInterface(), RefType::Implicit);
-    report(Loc, dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()));
+    report(Loc, Method->getClassInterface());
   }
 
   bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
-    ReportObjCMethodDecl(E->getBeginLoc(), E->getBoxingMethod());
+    // Handles NSNumber literals and NSValue literals.
+    reportObjCLiteralMethod(E->getBeginLoc(), E->getBoxingMethod());
     return true;
   }
 
   bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
-    ReportObjCMethodDecl(E->getBeginLoc(), E->getArrayWithObjectsMethod());
+    reportObjCLiteralMethod(E->getBeginLoc(), E->getArrayWithObjectsMethod());
     return true;
   }
 
   bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
-    ReportObjCMethodDecl(E->getBeginLoc(), E->getDictWithObjectsMethod());
+    reportObjCLiteralMethod(E->getBeginLoc(), E->getDictWithObjectsMethod());
     return true;
   }
 
   bool VisitObjCStringLiteral(ObjCStringLiteral *E) {
-    if (const auto *ObjCPtr = E->getType()->getAs<ObjCObjectPointerType>())
-      report(E->getBeginLoc(), ObjCPtr->getInterfaceDecl(), RefType::Implicit);
+    report(E->getBeginLoc(),
+           E->getType()->getAs<ObjCObjectPointerType>()->getInterfaceDecl());
     return true;
   }
 };
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index 71bc455ca00ed..bcc1df3f618e4 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -1548,7 +1548,7 @@ TEST(WalkAST, ObjCEncodeExpr) {
 
 TEST(WalkAST, ObjCBoxedExprInt) {
   testWalk(R"objc(
-    @interface $implicit^NSNumber
+    @interface $explicit^NSNumber
     + (id)numberWithInt:(int)val;
     @end
   )objc",
@@ -1560,18 +1560,19 @@ TEST(WalkAST, ObjCBoxedExprInt) {
            {"-x", "objective-c"});
 }
 
-
-TEST(WalkAST, ObjCBoxedExprCategory) {
+TEST(WalkAST, ObjCBoxedExprStruct) {
   testWalk(R"objc(
-    @interface $implicit^NSNumber
-    @end
-    @interface $explicit^NSNumber (CustomCategory)
-    + (id)numberWithInt:(int)val;
+    struct __attribute__((objc_boxable)) Point {
+      int x, y;
+    };
+    @interface $explicit^NSValue
+    + (id)valueWithBytes:(const void *)bytes objCType:(const char *)type;
     @end
   )objc",
            R"objc(
     void test() {
-      id x = ^@42;
+    struct Point p = {1, 2};
+      id x = ^@(p);
     }
   )objc",
            {"-x", "objective-c"});
@@ -1579,7 +1580,7 @@ TEST(WalkAST, ObjCBoxedExprCategory) {
 
 TEST(WalkAST, ObjCArrayLiteral) {
   testWalk(R"objc(
-    @interface $implicit^NSArray
+    @interface $explicit^NSArray
     + (id)arrayWithObjects:(const id *)objects count:(unsigned long)cnt;
     @end
   )objc",
@@ -1593,8 +1594,10 @@ TEST(WalkAST, ObjCArrayLiteral) {
 
 TEST(WalkAST, ObjCDictionaryLiteral) {
   testWalk(R"objc(
-    @interface $implicit^NSDictionary
-    + (id)dictionaryWithObjects:(const id *)objects forKeys:(const id *)keys 
count:(unsigned long)cnt;
+    @interface $explicit^NSDictionary
+    + (id)dictionaryWithObjects:(const id *)objects
+                        forKeys:(const id *)keys
+                          count:(unsigned long)cnt;
     @end
   )objc",
            R"objc(
@@ -1607,7 +1610,7 @@ TEST(WalkAST, ObjCDictionaryLiteral) {
 
 TEST(WalkAST, ObjCStringLiteral) {
   testWalk(R"objc(
-    @interface $implicit^NSString
+    @interface $explicit^NSString
     @end
   )objc",
            R"objc(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to