[Format/ObjC] Support NS_ASSUME_NONNULL_BEGIN and FOUNDATION_EXPORT in ObjC language...
authorBen Hamilton <benhamilton@google.com>
Fri, 26 May 2023 18:44:21 +0000 (12:44 -0600)
committerBen Hamilton <benhamilton@google.com>
Tue, 30 May 2023 17:12:03 +0000 (11:12 -0600)
This adds to the ObjC language guesser a few more common macros used
in ObjC headers. These can help distinguish ObjC headers which
otherwise lack ObjC types from C++ headers.

Contributed by danblakemore.

Tested: New tests included. Ran unit tests with:
  ```
  % cmake -S llvm -B build -G Ninja && \
    ninja -C build FormatTests && \
    ./build/tools/clang/unittests/Format/FormatTests --gtest_filter="*FormatTestObjC*"

  (snip)
  [----------] 24 tests from FormatTestObjC (265 ms total)

  [----------] Global test environment tear-down
  [==========] 26 tests from 2 test suites ran. (270 ms total)
  [  PASSED  ] 26 tests.
  ```

Reviewed By: MyDeveloperDay

Differential Revision: https://reviews.llvm.org/D151578

clang/lib/Format/Format.cpp
clang/test/Format/dump-config-objc-macros.h [new file with mode: 0644]
clang/unittests/Format/FormatTestObjC.cpp

index 154e6a2..d7128ed 100644 (file)
@@ -2687,6 +2687,8 @@ private:
         "CGSizeMake",
         "CGVector",
         "CGVectorMake",
+        "FOUNDATION_EXPORT", // This is an alias for FOUNDATION_EXTERN.
+        "FOUNDATION_EXTERN",
         "NSAffineTransform",
         "NSArray",
         "NSAttributedString",
@@ -2743,6 +2745,7 @@ private:
         "NSURLQueryItem",
         "NSUUID",
         "NSValue",
+        "NS_ASSUME_NONNULL_BEGIN",
         "UIImage",
         "UIView",
     };
diff --git a/clang/test/Format/dump-config-objc-macros.h b/clang/test/Format/dump-config-objc-macros.h
new file mode 100644 (file)
index 0000000..c90aa60
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang-format -dump-config %s | FileCheck %s
+
+// CHECK: Language: ObjC
+NS_ASSUME_NONNULL_BEGIN
+
+FOUNDATION_EXTERN int kConstant;
+
+NS_ASSUME_NONNULL_END
index 55969ff..0cae6e2 100644 (file)
@@ -94,6 +94,26 @@ TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {
   ASSERT_TRUE((bool)Style);
   EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
 
+  Style = getStyle("{}", "a.h", "none", R"objc(
+NS_ASSUME_NONNULL_BEGIN
+extern int i;
+NS_ASSUME_NONNULL_END
+)objc");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+  Style = getStyle("{}", "a.h", "none", R"objc(
+FOUNDATION_EXTERN void DoStuff(void);
+)objc");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
+  Style = getStyle("{}", "a.h", "none", R"objc(
+FOUNDATION_EXPORT void DoStuff(void);
+)objc");
+  ASSERT_TRUE((bool)Style);
+  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
+
   Style = getStyle("{}", "a.h", "none", "enum Foo {};");
   ASSERT_TRUE((bool)Style);
   EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);