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