任何基于libclang的C / C ++重构工具? (即使是最简单的“玩具示例”)

时间:2011-11-01 15:54:56

标签: c++ refactoring llvm clang

正如我已经指出的那样 - here - 似乎clang的libclang应该适用于实现C / C ++代码分析和修改(check out video presentation and slides)这一艰巨任务。

你知道基于libclang的任何 C / C ++重构工具吗?

“Any”包括简单的alpha状态项目,支持一种重构技术。它可以没有预处理器支持。作为功​​能上我正在谈论的一个例子:更改方法名称,它是否支持多个文件或一次只支持一个文件。您可能想知道甚至是小工作示例的目标是什么我的想法是创建一个代码示例列表和一个位置的小工具将提供更好的资源来学习如何使用libclang实现重构< / em>的。我相信,从简单的项目可能会以适当的开源方式发展更大的项目:)。

8 个答案:

答案 0 :(得分:23)

Clang包含一个名为“CIndex”的库,我相信它是为在IDE中完成代码而开发的。它也可以用于解析C ++和遍历AST,但没有任何重构方式。见Eli Bendersky的文章here

我最近开始了这样一个项目:cmonster。它是一个基于Python的API,用于解析C ++(使用libclang),分析AST,带有“重写”接口(即插入/删除/修改源范围)。对于修改函数名称和将其转换为源代码修改这样的事情还没有很好的方法,但这样做并不是非常困难。

我还没有创建一个具有此功能的版本(虽然它在github repo中),因为我正在等待llvm / clang 3.0发布。

另外,我应该指出几件事:

  • 代码非常粗糙,称为alpha可能很慷慨。
  • 我不是这方面的专家(不像那里的艾拉巴克斯特博士)。

适当调整期望。

更新: cmonster 0.2已发布,其中包含所述功能。请查看on Github

答案 1 :(得分:15)

Google一直致力于为Clang开发工具库。 In since the 3.2 release。它包括一个ASTMatchers库,因此您可以建立一个查询,而不必走AST。

主题上有一个great video talk,它通过一个简单的重命名示例。 (这与上面发布的MapReduce talk相同,但是更新,更多的是关于简单的实际实现,而不是谷歌正在进行的内部设计和企业规模的事情。)

tooling branch中提供了重命名方法的示例源。它可能在行李箱的某个地方,但我找不到它。另外将getDeclAs函数重命名为getNodesAs,另一个是apparently deprecated。)。还有一个advanced example that removes duplicated c_str calls(在主干中,有人在上面发布)。

以下是LibASTMatchersLibTooling的文档。

编辑:ASTMatcher的一些更好的文档。 Herehere

编辑:Google are now working on something called Clangd旨在成为某种重构的Clang服务器。

答案 2 :(得分:8)

Google为其C ++代码库制作了基于Clang的重构工具,并计划发布它。我不知道项目的当前状态,但您可以在2011 LLVM开发者会议上看到此演示:https://www.youtube.com/watch?v=mVbDzTM21BQ

此外,XCode(4+)内置的自动完成和重构功能基于libclang。

答案 3 :(得分:6)

这可能有点'元',但是有一个用clang编写的例子作为在clang上运行的工具(尽管如此,还有更多不仅仅是那个。

RemoveCStrCalls.cpp

//  This file implements a tool that prints replacements that remove redundant
//  calls of c_str() on strings.
//
//  Usage:
//  remove-cstr-calls <cmake-output-dir> <file1> <file2> ...
//
//  Where <cmake-output-dir> is a CMake build directory in which a file named
//  compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in
//  CMake to get this output).
//
//  <file1> ... specify the paths of files in the CMake source tree. This path
//  is looked up in the compile command database. If the path of a file is
//  absolute, it needs to point into CMake's source tree. If the path is
//  relative, the current working directory needs to be in the CMake source
//  tree and the file must be in a subdirectory of the current working
//  directory. "./" prefixes in the relative files will be automatically
//  removed, but the rest of a relative path must be a suffix of a path in
//  the compile command line database.
//
//  For example, to use remove-cstr-calls on all files in a subtree of the
//  source tree, use:
//
//    /path/in/subtree $ find . -name '*.cpp'|
//        xargs remove-cstr-calls /path/to/source

答案 4 :(得分:5)

不是开源的,但已被用来执行非玩具massive automated refactoring of C++ programs: 我们的DMS Software Reengineering Toolkit。 DMS是一个“库”(我们称之为“工具包”)的设施,可以组成实现分析和/或自动翻译。

与C ++相关,DMS目前提供:

  • 完整的C ++ 11解析器,构建AST并能够准确地重新生成源代码 包括评论,以及完整的预处理器
  • C ++(ANSI,GNU,MS Visual C ++)的名称和类型解析的完整C ++解析器
  • C ++的控制流分析
  • 源到源转换
  • 部分完成“重命名”机器(见下面的讨论)

我从经验中可以说,C ++是一种变换语言的婊子。

我们继续努力,并正在完成一个可靠的重命名工具。即使这很难;一个关键问题是名称阴影问题。你有一个局部变量X,并在该范围内引用了Y;您尝试将Y重命名为X并发现本地变量“捕获”访问权限。令人惊讶的是,您需要在C ++中担心多少名称空间和捕获类型。这需要作为许多其他重构的基础。

EDIT 2014年2月:完​​整的C ++ 14解析器,控制流分析,本地数据流分析

答案 5 :(得分:5)

https://github.com/lukhnos/refactorial基于clang和声明

  

提供转换

     

访问者:为指定成员合成getter和setter   变量

     

MethodMove:将内联成员函数体移动到实现中   文件

     

ExtractParameter:将函数变量提升为参数   功能

     

TypeRename:重命名类型,包括标记类型(枚举,结构,联合,   class),模板类,Objective-C类型(类和协议),   typedef甚至bulit-in类型(例如unsigned to uint32_t)

     

RecordFieldRename:重命名记录(struct,union)字段,包括C ++   成员变量

     

FunctionRename:重命名函数,包括C ++成员函数

通过YAML配置文件中的规范工作。我还没试过(还)。

答案 6 :(得分:3)

另一种可能性是为GCC开发自己的插件,或开发GCC MELT扩展来完成任务。但是扩展GCC(或Clang)需要理解这些编译器的内部表示(Gimple&amp; Tree for GCC),这需要一些工作。 MELT是一种扩展GCC的高级域特定语言。

答案 7 :(得分:2)