c++ - 获取单个文件的 Clang AST

标签 c++ clang llvm-clang

我在代码编辑器扩展中使用 Clang 来实现折叠/折叠,但我遇到了一个问题。

我一次只解析一个文件,而不是整个翻译单元。这部分是为了速度和简单性,也是因为您可以自己打开一个头文件而不知道要解析哪个 cpp。

问题是,一旦 clang 遇到未知符号,它就会放弃,并且文件的整个 block 都从 AST 中丢失。考虑以下片段

void Foo1()
{
    while (PeekMessageA())
    {
        switch (0)
        {
        }
    }
}

这个的 AST 就是

|-FunctionDecl 0x1fde8f67240 <Folding Test.cpp:1:1, line:9:1> line:1:6 Foo1 'void ()'
| `-CompoundStmt 0x1fde8f673f8 <line:2:1, line:9:1>

没有关于 while block 或 switch block 的信息。显然,clang 不可能知道 PeekMessageA 是函数调用还是对象构造等,我对此没有意见。我不需要它是完美的,但我确实希望能够使用 while 和 switch block 。

在这种情况下,有没有办法让 clang 在脸上提供更多信息?我目前正在使用 LibClang,但也愿意使用 LibTooling。

最佳答案

这是一个复杂的问题,没有完美的解决方案,但对于您看似有限的需求,您可以找到解决方案。出现这个问题是因为 C++ 有一些语义歧义,与其他最多有句法歧义的语言(如 C#)相反,因此当文件不编译时,clang 可能无法生成完整的 AST。

发生这种情况至少是因为表达式和声明之间的歧义。 C++ 解析器可能需要做一些符号解析来区分这两种语法。当该解析失败时,例如当一个符号既不能解析为类型也不能解析为变量时,clang 会丢弃整个 AST 部分,因为它根本无法构建它。

几年前我确实遇到过同样的问题,如果我记得在 if 条件下发生错误时整个 if 语句都被丢弃了。因此,在那种情况下,如果你想保留 if 语句,你必须侵入 clang 解析器并创建错误节点来代替条件表达式。同样的问题出现在所有其他包含表达式或声明的语句中。

希望这对您有所帮助。

关于c++ - 获取单个文件的 Clang AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55888279/

相关文章:

c++ - SQLite复制数据库破坏原来的,为什么?

c++ - 为什么在需要数组删除运算符时常规删除运算符起作用?

c++ - 为什么clang不编译在VS2012中可用的源代码?

c++ - Clang:从命令行或 Python 可靠地检测支持的 C++ 标准

C++ 中类似 Python 的迭代器习语

c++ - 带有控制台输出的 Qt GUI 应用程序 - 在 Windows 上正常启动时隐藏控制台

c++ - 如何根据给定的长度确定矩形?

gcc - 可以为 clang 或 gcc 配置 constexpr 递归限制吗?

c++ - 如何使用 AST 进行自定义前端操作和 clang 静态分析

c - LLVM IR 中函数的参数编号与源代码不同