jaredgrubb created this revision.
jaredgrubb added reviewers: HazardyKnusperkeks, djasper, egorzhdan.
jaredgrubb added a project: clang-format.
Herald added a project: All.
jaredgrubb requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

I noticed that clang-format was inserting some strange indentation whenever I 
used custom "attribute-like macros"
(things like `FOO_EXTERN` to wrap attribute-visible-default, or macros with 
parentheses like `NS_SWIFT_NAME(...)`).

There are two parts to this fix:

- tokenize the paren after an `AttributeMacro` as a `TT_AttributeParen`
- treat a `AttributeMacro`-without-paren the same as one with a paren (eg, the 
`FOO_EXTERN` case)

I added a new test-case to differentiate a macro that is or is-not a 
`AttributeMacro`; also handled whether the
`ColumnLimit` is set to infinite (0) or a finite value, as part of this patch 
is in `ContinuationIndenter`.

There may be other places that need to handle `TT_AttributeMacro` better, but 
this is at least a step in the right
direction.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145262

Files:
  clang/lib/Format/ContinuationIndenter.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/test/Format/objc-definitions.m

Index: clang/test/Format/objc-definitions.m
===================================================================
--- /dev/null
+++ clang/test/Format/objc-definitions.m
@@ -0,0 +1,58 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s \
+// RUN:   | clang-format -style="{BasedOnStyle: LLVM, AttributeMacros: [MACRO]}" \
+// RUN:   | FileCheck -strict-whitespace %s --check-prefixes=CHECK-COMMON,CHECK-ATTRMACRO
+// RUN: grep -Ev "// *[A-Z-]+:" %s \
+// RUN:   | clang-format -style="{BasedOnStyle: LLVM, AttributeMacros: [MACRO], ColumnLimit: 0}" \
+// RUN:   | FileCheck -strict-whitespace %s --check-prefixes=CHECK-COMMON,CHECK-ATTRMACRO
+// RUN: grep -Ev "// *[A-Z-]+:" %s \
+// RUN:   | clang-format -style="{BasedOnStyle: LLVM}" \
+// RUN:   | FileCheck -strict-whitespace %s --check-prefixes=CHECK-COMMON,CHECK-PLAIN
+// RUN: grep -Ev "// *[A-Z-]+:" %s \
+// RUN:   | clang-format -style="{BasedOnStyle: LLVM, ColumnLimit: 0}" \
+// RUN:   | FileCheck -strict-whitespace %s --check-prefixes=CHECK-COMMON,CHECK-PLAIN-COL0
+
+// CHECK-COMMON: {{^@interface Foo$}}
+// CHECK-COMMON-NEXT: {{^@end$}}
+@interface Foo
+@end
+
+// CHECK-COMMON: {{^MACRO$}}
+// CHECK-COMMON-NEXT: {{^@interface Foo$}}
+// CHECK-COMMON-NEXT: {{^@end$}}
+MACRO
+@interface Foo
+@end
+
+// CHECK-COMMON: {{^MACRO\(A\)$}}
+// CHECK-COMMON-NEXT: {{^@interface Foo$}}
+// CHECK-COMMON-NEXT: {{^@end$}}
+MACRO(A)
+@interface Foo
+@end
+
+// CHECK-ATTRMACRO: {{^MACRO MACRO\(A\)$}}
+// CHECK-ATTRMACRO-NEXT: {{^@interface Foo$}}
+// CHECK-ATTRMACRO-NEXT: {{^@end$}}
+// CHECK-PLAIN: {{^MACRO MACRO\(A\) @interface Foo$}}
+// CHECK-PLAIN-NEXT: {{^@end$}}
+// COM: The leading indentation in the next case is existing behavior but probably not desired.
+// CHECK-PLAIN-COL0: {{^MACRO MACRO\(A\)$}}
+// CHECK-PLAIN-COL0-NEXT: {{^    @interface Foo$}}
+// CHECK-PLAIN-COL0-NEXT: {{^@end$}}
+MACRO MACRO(A)
+@interface Foo
+@end
+
+// CHECK-ATTRMACRO: {{^MACRO\(A\) MACRO$}}
+// CHECK-ATTRMACRO-NEXT: {{^@interface Foo$}}
+// CHECK-ATTRMACRO-NEXT: {{^@end$}}
+// CHECK-PLAIN: {{^MACRO\(A\) MACRO @interface Foo$}}
+// CHECK-PLAIN-NEXT: {{^@end$}}
+// COM: The leading indentation in the next case is existing behavior but probably not desired.
+// CHECK-PLAIN-COL0: {{^MACRO\(A\)$}}
+// CHECK-PLAIN-COL0: {{^MACRO$}}
+// CHECK-PLAIN-COL0-NEXT: {{^    @interface Foo$}}
+// CHECK-PLAIN-COL0-NEXT: {{^@end$}}
+MACRO(A) MACRO
+@interface Foo
+@end
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -369,7 +369,7 @@
     // Infer the role of the l_paren based on the previous token if we haven't
     // detected one yet.
     if (PrevNonComment && OpeningParen.is(TT_Unknown)) {
-      if (PrevNonComment->is(tok::kw___attribute)) {
+      if (PrevNonComment->isOneOf(tok::kw___attribute, TT_AttributeMacro)) {
         OpeningParen.setType(TT_AttributeParen);
       } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
                                          tok::kw_typeof,
@@ -4889,8 +4889,10 @@
   }
 
   // Ensure wrapping after __attribute__((XX)) and @interface etc.
-  if (Left.is(TT_AttributeParen) && Right.is(TT_ObjCDecl))
+  if (Left.isOneOf(TT_AttributeMacro, TT_AttributeParen) &&
+      Right.is(TT_ObjCDecl)) {
     return true;
+  }
 
   if (Left.is(TT_LambdaLBrace)) {
     if (IsFunctionArgument(Left) &&
Index: clang/lib/Format/ContinuationIndenter.cpp
===================================================================
--- clang/lib/Format/ContinuationIndenter.cpp
+++ clang/lib/Format/ContinuationIndenter.cpp
@@ -1228,8 +1228,9 @@
        (PreviousNonComment->ClosesTemplateDeclaration ||
         PreviousNonComment->ClosesRequiresClause ||
         PreviousNonComment->isOneOf(
-            TT_AttributeParen, TT_AttributeSquare, TT_FunctionAnnotationRParen,
-            TT_JavaAnnotation, TT_LeadingJavaAnnotation))) ||
+            TT_AttributeParen, TT_AttributeMacro, TT_AttributeSquare,
+            TT_FunctionAnnotationRParen, TT_JavaAnnotation,
+            TT_LeadingJavaAnnotation))) ||
       (!Style.IndentWrappedFunctionNames &&
        NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName))) {
     return std::max(CurrentState.LastSpace, CurrentState.Indent);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to