我想用宏将项目中的每个字符串文字包装起来。我想确保项目中的每个字符串文字都被一个宏包裹,并且有一些外部工具可以帮助我找到一个没有被宏包裹的文字。
有什么方法可以使用Clang插件来确保每个字符串文字都包裹在宏中?
我要处理的情况:
#define MY_ASSERT(Y) {if(!(Y)) throw Exception(#Y); }
应将#Y警告为未包装的字符串文字。
"a" "b" "c"
这将要求整个对象都在宏中,如下所示:
MY_STR("a" "b" "c")
我该如何使用Clang插件做到这一点,或者一般还有其他方法可以做到这一点?
答案 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) ";
...