我正在尝试找出如何最好地将C ++ 0x的override
标识符添加到已经覆盖在大量C ++代码中的所有现有方法中,而不是手动执行。
(我们有很多,几十万行代码,并且手动完成这将是一个完全不起作用的。)
我们的编码标准说我们应该在派生类中对所有隐式虚方法添加virtual
关键字,即使严格不必要(以帮助理解)。
因此,如果我自己编写脚本,我会编写一个脚本来读取所有标题,找到所有以virtual开头的函数,并在下面的分号前插入override
。然后在支持override
的编译器上编译它,并修复基类中的所有错误。
但我真的不愿意使用这种本土化的方式,因为:
那么,是否有一个工具可以解析C ++代码,检测覆盖的现有方法,并将override
附加到它们的声明中?
(我知道静态分析工具,例如PC-lint,它们会警告那些看起来应该覆盖的函数。我所追求的是实际上会使我们的代码变得混乱的东西,以便将来的错误覆盖将在编译时检测,而不是稍后在静态分析中检测到)
(如果有人想要指出C ++ 03不支持'覆盖'......在实践中,我将添加一个宏,而不是实际的“覆盖”标识符,以使用我们的不支持此功能的旧编译器上的代码。所以在添加标识符之后,我会运行一个单独的脚本来替换它我们将要使用的任何宏...)
提前致谢...
答案 0 :(得分:14)
LLVM项目正在开发一个名为“cpp11-migrate”的工具,该工具目前具有以下功能:
NULL
或0
)转换为C ++ 11 nullptr
auto
类型说明符override
说明符添加到适用的成员函数此工具记录为here,应作为clang 3.3的一部分发布。 但是,您可以下载源代码并立即自行构建。
修改强>
更多信息:
编辑2:2013-09-07
“cpp11-migrate”已重命名为“clang-modernize”。对于Windows用户,它现在包含在新的LLVM Snapshot Builds。
中答案 1 :(得分:7)
我们的DMS Software Reengineering Toolkit及其支持C ++ 11的C++ Front End可以执行此操作。
DMS是用于任意编程语言的通用程序转换系统; C ++前端允许它处理C ++。 DMS解析,构建准确的AST和符号表(这对C ++来说很难),提供对查询AST节点和树的属性的支持,允许在树上进行过程转换和源到源转换。完成所有更改后,可以重新生成修改后的树,并保留注释。
您的问题需要找到派生的虚拟方法并进行更改。执行此操作的DMS源到源转换规则类似于:
source domain Cpp. -- tells DMS the following rules are for C++
rule insert_virtual_keyword (n:identifier, a: arguments, s: statements):
method_declaration -> method_declaration " =
" void \n(\a) { \s } " -> " virtual void \n(\a) { \s }"
if is_implicitly_virtual(n).
此类规则与语法树匹配,因此它们不会与注释,字符串或其他内容不匹配。有趣的引号不是C ++字符串引号;它们是元引号,允许规则语言知道它们内部的内容必须被视为目标语言(“Cpp”)语法。反斜杠是目标语言文本的转义,允许匹配任意结构,例如,\ a表示需要“a”,它被定义为语法类别“arguments”。
你需要更多的规则来处理函数返回非空结果的情况,等等,但你不需要很多。
有趣的部分是实现控制转换应用程序的谓词(返回TRUE或FALSE):is_implicitly_virtual。该谓词采用(抽象语法树)方法名称n。 这个谓词将参考完整的C ++符号表来确定n究竟是什么。我们已经知道它是一种方法,只是它的语法设置,但我们想知道在什么类的上下文中。 符号表提供方法和类之间的链接,类的符号表信息告诉我们类继承的内容,以及这些类,它们包含哪些方法以及如何声明它们,最终导致发现(或不)父类方法是虚拟的。执行此操作的代码必须实现为针对C ++符号表API的过程代码。然而,所有艰苦的工作都已完成;符号表是正确的,包含对所需的所有其他数据的引用。 (如果您没有此信息,则无法通过算法决定,并且任何代码更改都可能是错误的。)
DMS过去曾使用程序转换对C ++代码进行大量更改。(查看网站上的论文页面,了解C ++重新架构主题)。
(我不是C ++专家,只是DMS架构师,所以如果我有错误的细节,请原谅。)
答案 2 :(得分:2)
我在头文件中搜索了“virtual”来查找大部分内容,我偶尔会发现另一个缺少override关键字的原型。
我发现了两个错误。
答案 3 :(得分:0)
Eclipse CDT具有可用的C ++解析器和语义实用程序。最新版本IIRC还具有覆盖方法的标记。
编写一个基于此的插件并在适当的时候重写代码以包含override
标记不需要太多代码。
答案 4 :(得分:0)
一个选择是
启用建议覆盖编译器警告,然后编写脚本 可以将override关键字插入发出的警告所指向的位置