我在代码编辑器扩展中使用Clang来实现折叠/折叠,但是遇到了问题。
我一次只解析一个文件,而不是整个翻译单元。这部分是出于速度和简便性的考虑,还因为您可以单独打开头文件,却不知道要解析哪个cpp。
问题在于,当clang遇到一个未知符号时,它就会放弃并且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块或switch块的信息。显然,对于clang来说,不可能知道PeekMessageA是函数调用还是对象构造等,对此我很好。我不需要它是完美的,但我确实希望能够使用while并切换块。
在这种情况下,是否有办法让clang从脸上提供更多信息?我目前正在使用LibClang,但也可以使用LibTooling。
答案 0 :(得分:0)
这不是一个没有完美解决方案的简单问题,但是对于您看来有限的需求,您可以找到一个解决方案。之所以会出现问题,是因为C ++具有某些语义歧义性,与其他语言中最多具有词义歧义性的语言(如C#)相反,因此当文件无法编译时clang可能无法产生完整的AST。
发生这种情况至少是因为表达式和声明之间的歧义。 C ++解析器可能必须做一些符号解析才能区分这两种语法。当该解析失败时,例如,当符号无法同时解析为类型或变量时,clang会丢弃AST的整个部分,因为它根本无法构建它。
几年前,我确实遇到过同样的问题,如果我很好地记得在if条件下发生错误时,整个if语句都将被丢弃。因此,在这种情况下,如果要保留if语句,则必须侵入clang解析器并创建错误节点来代替条件表达式。在包含表达式或声明的所有其他语句中也会发生相同的问题。
希望这会有所帮助。