确保每个字符串文字都包装在宏中

时间:2019-02-25 13:53:07

标签: c++ clang clang-plugin

我想用宏将项目中的每个字符串文字包装起来。我想确保项目中的每个字符串文字都被一个宏包裹,并且有一些外部工具可以帮助我找到一个没有被宏包裹的文字。

有什么方法可以使用Clang插件来确保每个字符串文字都包裹在宏中?

我要处理的情况:

  1. #define MY_ASSERT(Y) {if(!(Y)) throw Exception(#Y); }
    

    应将#Y警告为未包装的字符串文字。

  2. "a" "b" "c"
    

    这将要求整个对象都在宏中,如下所示:

    MY_STR("a" "b" "c")
    

我该如何使用Clang插件做到这一点,或者一般还有其他方法可以做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以使用DMS软件再造工具包及其C ++前端来做到这一点。

DMS可以根据它读取C ++的明确语法定义的源代码(在GCC和MS方言中处理C ++ 17),构建AST,应用提供的重写规则来修改树,然后将AST漂亮地打印回源文字,保留注释,文字对齐方式,数字基数等。

为此,您只需要一个DMS规则(有关详细信息,请参见DMS Rewrite Rules

rule wrap_string_in_macro(s:string_literal):primary_expression->primary_expression
 = "\s" -> " my_macro_name(\s) ";

非终结符 string_literal 涵盖了各种各样的C ++字符串(8位,ISO,宽,原始,字符串序列等),因此您不必担心它们,这条规则会接他们。但是您的宏可能需要担心这些。因此可以说可以编写更大的规则集,以便专门进行宏调用:

rule wrap_ISO_string_in_macro(s:ISO_STRING_LITERAL):primary_expression->primary_expression
 = "\s" -> " my_macro_name_for_ISO_string(\s) ";

rule wrap_ISO_string_in_macro(s:WIDE_STRING_LITERAL):primary_expression->primary_expression
 = "\s" -> " my_macro_name_for_wide_string(\s) ";

...

这些规则将提取单个字符串,但这留下了处理字符串序列的问题:

rule wrap_ISO_string_list_in_macro(seq: string_literal_list,s:ISO_STRING_LITERAL):primary_expression->primary_expression
 = " \string_literal_list \s" -> " my_macro_name_for_ISO_string_list(\s) ";

...