【问题标题】:any C/C++ refactoring tool based on libclang? (even simplest "toy example" ) [closed]任何基于 libclang 的 C/C++ 重构工具? (甚至最简单的“玩具示例”)[关闭]
【发布时间】:2011-12-19 15:01:04
【问题描述】:

正如我所指出的 - here - 似乎 clang 的 libclang 应该非常适合执行 C/C++ 代码分析和修改这一艰巨任务 (check out video presentation and slides)。

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

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

【问题讨论】:

  • 即使有很好的基础设施,这也比看起来要困难得多。作为第一步,你对预处理器有什么看法?
  • 好的,我同意这不是一件小事。我“轻松”地写了对我来说太过分了。请让我把它改成另一个形容词。我的观点是 - 使用 libclang 可能会更容易,但我同意 - 仍然不容易。
  • 可以说 Clang 那个简单的重构项目,而且它看起来确实在增长。
  • 您的问题是更关注 Clang 作为 C/C++ 重构工具,还是您对 C/C++ 重构工具更感兴趣,其中 Clang 可能是一个有趣的候选者?
  • 有一个somewhat similar question on the Software Recommendations SE,显然是基于这个的。

标签: c++ refactoring llvm clang


【解决方案1】:

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

与C++相关,DMS在这个时间点提供:

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

我可以根据经验说,C++ 是一种需要转换的语言。

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

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

【讨论】:

  • 我不知道为什么我是第一个投票赞成这个答案的人。如果提问者想限制开源,他们应该这么说。当您说 C++ 是一种很难通过解析器/机器“理解”的语言时,我相信您:这对带有重命名功能的 Eclipse 的 CDT 有何说明?从来没有用过 C++ 的 Eclipse,但我用过 Java,以及它丰富的重构工具——当然,更简单。
  • 公平地说,OP 要求提供与 Clang 相关的答案,而我的答案与 Clang 无关。我添加它是因为它的含义似乎是在 C++ 上没有任何东西可以重构,这是不正确的。
【解决方案2】:

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 服务器。

【讨论】:

    【解决方案3】:

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

    提供的转换

    Accessor:为指定成员合成 getter 和 setter 变量

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

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

    TypeRename:重命名类型,包括标签类型(enum、struct、union、 类)、模板类、Objective-C 类型(类和协议)、 typedefs 甚至是内置类型(例如 unsigned 到 uint32_t)

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

        我尚未创建具有此功能的版本(尽管它位于 github 存储库中),因为我正在等待 llvm/clang 3.0 的发布。

        另外,我要指出几点:

        • 代码非常粗糙,称它为 alpha 可能会很慷慨。
        • 我绝不是这方面的专家(不像那边的 Ira Baxter 博士)。

        适当调整预期。

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

        【讨论】:

          【解决方案6】:

          【讨论】:

            【解决方案7】:

            这可能有点“元”,但有一个用 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
            

            【讨论】:

            • 它可以被视为一种重构。当然,对于对重构感兴趣的人来说,它可能是有用的代码。所以+1 :)
            【解决方案8】:

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

            【讨论】:

            • 还有其他几个用于 C++ 重构的开源基础,包括 Eclipse CDT。
            • @IraBaxter - 提到 Eclipse CDT 很好。我看到的问题是,我还没有看到提供这种功能的命令行工具或库。所以我认为 Eclipse CDT 不能独立工作,但作为“可点击的 gui 工具”,限制了应用程序 - 尤其是在考虑重构自动化时。
            • @GrzegorzWierzowiecki:好吧,如果 Eclipse 可以通过 gui-click 来实现功能,那么这些功能内部显然有机制,并且通过一些(?)努力可以将它们公开为命令行工具。那是你的目标吗?从你提出问题的方式来看,还不清楚。如果是的话,我希望你能欣赏我的回答。
            • @IraBaxter 我的意思是 - 如果有人知道 Eclipse CDT 作为库或命令行工具公开:请告诉我们:)。
            • @IraBaxter 我不知道现在情况如何,但我在 2009-2010 年尝试使用 Eclipse CDT。我记得它感觉不适合用作批处理任务的“重构组件”和/或适合为 vim、emacs 和某人可能喜欢的东西准备插件的编辑器无关组件。这就是为什么我主要询问 libclang - 我发现它的 api 很有趣。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-05-01
            • 2010-11-26
            • 2016-08-18
            • 2013-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多