使用 libtooling 检索和存储有关 C++ 实体的元数据

问题描述 投票:0回答:1

免责声明:我是 libtooling 的新手。

我想从源代码中检索有关所有 C++ 实体(例如类和类模板)的元数据并将其存储以供以后处理。

我按照 LibTooling 和 LibASTMatchers 教程中所述检索 AST 节点:

struct Handler : MatchFinder::MatchCallback
{
    void run(const MatchFinder::MatchResult& result) override
    {
        if (const auto entity = result.Nodes.getNodeAs<clang::CXXRecordDecl>("rec"))
        { /* ? */ }
    }
};

// Create parser, parse command-line args

auto classMatcher = clang::ast_matchers::cxxRecordDecl().bind("rec");
ClangTool tool { parser->getCompilations(), parser->getSourcePathList() };
Handler handler;
MatchFinder finder;
finder.addMatcher(classMatcher, &handler);
tool.run(newFrontendActionFactory(&finder).get());

,这个没有问题。

但我无法决定如何存储它们。我看到两个选项:为每个实体(类型、参数、命名空间、类等)创建包装器并使用指向

<Entity>Decl
.

的原始指针

第一种方法似乎不错,但我必须为 LibTooling 已经提供的内容编写很多包装器。

至于第二种方式:我尝试过,但出现错误 - 似乎 AST 上下文在

ClangTool::run
完成后被破坏,并且我无法使用指向
<Entity>Decl
节点的原始指针。

使用LibTooling的人通常是怎么做的?创建包装器?或者是否有某种方法可以保留 AST 上下文并继续使用指向节点的原始指针?也许还有第三种方法?

c++ clang libtooling
1个回答
0
投票

我认为您问的是如何运行 Clang 解析器来获取 AST,然后(仍在同一进程中)在

ClangTool
框架之外分析该 AST,这对分析代码何时运行提出了某些要求它会自动销毁
ASTContext
。 (例如,使用
ClangTool
,很难解析两个不相关的翻译单元,然后将它们相互比较。)

如果是这样,我知道的主要替代方法是使用

ASTUnit
系统而不是
ClangTool
ASTUnit
ASTContext
和 AST 本身(以
TranslationUnitDecl
作为根)组合成单个对象。它有几个
static
方法来创建一个,例如
LoadFromCommandLine
。一旦创建,
ASTUnit
及其组件就可以无限期地使用和检查;由您(图书馆客户端)决定何时选择销毁它。您还可以同时在内存中保存许多它们(当然,取决于总可用内存)。因此,在分析中直接使用 Clang AST 指针的“第二种方法”将会很好地工作。

我的

这个答案
中有一个使用ASTUnit::LoadFromCommandLine的例子。

如果您的目标是序列化 AST 以在稍后的过程中进行分析,

ASTUnit
再次提供了一些读取和写入 AST 的方法。但请注意,虽然新解析的翻译单元可以访问原始源代码,但序列化的 AST 不会存储该源代码,因此以后可能无法使用。

© www.soinside.com 2019 - 2024. All rights reserved.