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

Grz*_*cki 47 c++ refactoring llvm clang

正如我已经指出的那样 - 在这里 - 似乎clang的libclang应该非常适合实现C/C++代码分析和修改(查看视频演示和幻灯片)这样的艰巨任务.

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

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

axw*_*axw 23

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

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

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

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

  • 代码非常粗糙,称为alpha可能是慷慨的.
  • 我绝不是这个主题的专家(不像那里的艾拉巴克斯特博士).

适当调整期望.

更新: cmonster 0.2已发布,其中包含所述功能.在Github上查看.


Dav*_*hop 15

谷歌一直在为Clang开发工具库.自3.2发布以来.它包括一个ASTMatchers库,因此您可以建立一个查询,而不必走AST.

关于这个主题的一个很棒的视频谈话,通过一个简单的重命名示例.(这与上面发布的MapReduce讲话的内容相同,但是更新,更多的是关于简单的实际实现,而不是谷歌正在进行的内部设计和企业规模的事情).

重命名方法的示例源可在工具分支中找到.它可能在行李箱的某个地方,但我找不到它.还将getDeclAs函数重命名为getNodesAs,因为另一个显然已弃用.).有一个更高级的示例可以删除重复的c_str调用(位于主干和上面发布的人).

这是LibASTMatchersLibTooling的文档.

编辑:ASTMatcher的一些更好的文档.这里这里.

编辑:谷歌正在研究一种叫做Clangd的东西,它的目的是成为某种用于重构的Clang服务器.


Reu*_*ais 8

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

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


syn*_*tel 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
Run Code Online (Sandbox Code Playgroud)


Ira*_*ter 5

不是开源的,但已经被用来进行C++程序的非玩具大规模自动重构:我们的DMS软件再造工具包.DMS是一个"库"(我们称之为"工具包")的设施,可以组成实现分析和/或自动翻译.

与C++相关,DMS在此时提供:

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

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

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

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

  • 公平地说,OP 要求提供与 Clang 相关的答案,而我的答案与 Clang 无关。我添加它是因为这意味着似乎没有任何东西可以在 C++ 上进行重构,但事实并非如此。 (2认同)

mab*_*ham 5

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

提供变换

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

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

ExtractParameter:将函数变量提升为该函数的参数

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

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

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

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