clang格式:宏的缩进

clang-format: indentation of macros

本文关键字:缩进 格式 clang      更新时间:2023-10-16

我试图将clang格式应用于现有的代码库,遇到了以下问题:

简化(和格式化(示例代码:

#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()
void foo()
{
int a = 0;
QUERY_BEGIN()
a = 1;
QUERY_NORESULT()
a = 2;
QUERY_END()
}

我设置了以下选项:

MacroBlockEnd:   'QUERY_END'
MacroBlockBegin: 'QUERY_BEGIN'

我想要实现的是宏部分的以下格式:

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

我的第一个猜测是将QUERY_NORESULT设置为MacroBlockEndMacroBlockBegin,但这没有帮助。它产生以下格式:

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

目前有没有一种方法可以实现如上所示的缩进?

  • 坏消息:很抱歉,这在clang格式(7(的当前发布版本中不可用
  • 好消息:有一个StatementMacros选项,它从clang format 8开始就可用(尚未发布,但您可以从源代码构建(

查看此提交:

摘要:有些宏在函数体中使用,实际上包含尾随分号:因此,它们应该自动后跟一行新行,而不是与下一行合并。例如,Qt的Q_UNUSED宏就是这样:

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

此补丁通过引入一个新选项来指定语句宏列表来处理这些情况。这将重新使用foreach宏的现有系统,以确保不会对性能产生影响。

文档:

◆语句宏

std::vector clang::format::FormatStyle::StatementMacros应解释为完整语句的宏向量。

典型的宏是表达式,需要添加分号;有时情况并非如此,这允许clang格式了解此类情况。

例如:Q_UNUSED

文件Format.h 第1061行的定义

由clang::format::FormatTokenLexer::FormatToken Lexer((,clang:;format::getLLVMStyle((,llvm::yaml::MappingTraits<FormatStyle>::mapping((,运算符==((。

解决方案:

从源代码构建clang/等待llvm/crang8发布,然后将StatementMacros ['QUERY_BEGIN()', 'QUERY_NORESULT()', 'QUERY_END()']放入您的.clang-format中。

旧clang格式的解决方案

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

关闭此宏语句中的clang格式。

clang format 3.7在名称MacroBlockBeginMacroBlockEnd下添加了对此的支持。这些配置选项比新样式的(Attribute|Statement|If|Foreach)Macros选项(采用列表(更奇怪;旧样式的MacroBlock(Begin|End)选项采用正则表达式,这意味着如果您有多个开始/结束宏,则必须像这样将它们粘合在一起:

MacroBlockBegin: '(FIRST_MACRO|SECOND_MACRO)'

不管怎样,对于您的确切输入,以及这个.clang格式的文件:

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

clang格式14.0.6产生以下格式化输出:

#define QUERY_BEGIN()
#define QUERY_NORESULT()
#define QUERY_END()
void foo() {
int a = 0;
QUERY_BEGIN()
a = 1;
QUERY_NORESULT()
a = 2;
QUERY_END()
}