hypetsch
hypetsch

Reputation: 175

clang-format: indentation of macros

I am trying to apply clang-format to an existing code base and came across the following issue:

Simplified (and formatted) sample code:

#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()

void foo()
{
   int a = 0;

   QUERY_BEGIN()
      a = 1;
      QUERY_NORESULT()
      a = 2;
   QUERY_END()
}

I set the following options:

MacroBlockEnd:   'QUERY_END'
MacroBlockBegin: 'QUERY_BEGIN'

What I want to achieve is the following formatting of the macro part:

   QUERY_BEGIN()
      a = 1;
   QUERY_NORESULT()
      a = 2;
   QUERY_END()

My first guess was to set QUERY_NORESULT as MacroBlockEnd and MacroBlockBegin but that didn't help. It results in the following formatting:

   QUERY_BEGIN()
      a = 1;
      QUERY_NORESULT
         a = 2;
      QUERY_END()

Is there currently a way to achieve the indentation as shown above?

Upvotes: 8

Views: 9892

Answers (2)

Quuxplusone
Quuxplusone

Reputation: 26949

clang-format 3.7 added support for this under the names MacroBlockBegin and MacroBlockEnd. These config options are weirder than the newer-style (Attribute|Statement|If|Foreach)Macros options (which take lists); the older-style MacroBlock(Begin|End) options take regular expressions, which means that if you have multiple begin/end macros, you must glue them together like this:

MacroBlockBegin: '(FIRST_MACRO|SECOND_MACRO)'

Anyway, for your exact input, and this .clang-format file:

$ cat .clang-format 
---
Language: Cpp
BasedOnStyle: LLVM
MacroBlockBegin: 'QUERY_BEGIN'
MacroBlockEnd: 'QUERY_END'
...

clang-format 14.0.6 produces this formatted output:

#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()

void foo() {
  int a = 0;

  QUERY_BEGIN()
    a = 1;
    QUERY_NORESULT()
    a = 2;
  QUERY_END()
}

Upvotes: 0

Li Chen
Li Chen

Reputation: 5260

  • Bad news: Sorry, this is not available in the current release version of clang-format(7).
  • Good news: There is a StatementMacros option, which is available since clang-format 8(not release yet, but you can build from source).

See this commit:

Summary: Some macros are used in the body of function, and actually contain the trailing semicolon: they should thus be automatically followed by a new line, and not get merged with the next line. This is for example the case with Qt's Q_UNUSED macro:

  void foo(int a, int b) {
    Q_UNUSED(a)
    return b;
  }

This patch deals with these cases by introducing a new option to specify list of statement macros. This re-uses the system already in place for foreach macros, to ensure there is no impact on performance.

Document:

◆ StatementMacros

std::vector clang::format::FormatStyle::StatementMacros A vector of macros that should be interpreted as complete statements.

Typical macros are expressions, and require a semi-colon to be added; sometimes this is not the case, and this allows to make clang-format aware of such cases.

For example: Q_UNUSED

Definition at line 1061 of file Format.h.

Referenced by clang::format::FormatTokenLexer::FormatTokenLexer(), clang::format::getLLVMStyle(), llvm::yaml::MappingTraits< FormatStyle >::mapping(), and operator==().

Solution:

build clang from source/wait for llvm/clang8 release, then put StatementMacros ['QUERY_BEGIN()', 'QUERY_NORESULT()', 'QUERY_END()'] into your .clang-format.

Workaround for old clang-format

// clang-format off
    void    unformatted_code  ;
// clang-format on

Turn off clang-format in this macro statements.

Upvotes: 4

Related Questions