Llvm 为什么不是';t libclang是否返回有意义的完成结果?

Llvm 为什么不是';t libclang是否返回有意义的完成结果?,llvm,clang,llvm-clang,libclang,Llvm,Clang,Llvm Clang,Libclang,我试图理解如何使用libclang完成代码。我看过《超越编译器的思考》,看过c-index-test,发现了一个简单的示例程序 我编译了这个程序,并在这个示例文件上运行它,这个示例文件与视频中的示例文件相似: struct List { int Data; struct List *Next; }; int sumListNode(struct List *Node) { int result = 0; for (; Node; Node = Node->

我试图理解如何使用libclang完成代码。我看过《超越编译器的思考》,看过c-index-test,发现了一个简单的示例程序

我编译了这个程序,并在这个示例文件上运行它,这个示例文件与视频中的示例文件相似:

struct List {
    int Data;
    struct List *Next;
};

int sumListNode(struct List *Node) {
    int result = 0;
    for (; Node; Node = Node->Next)
        result = result + Node->
}

void test() {
    sumLi
}
如果我将程序指向Node->之后的第一个不完整空格,它会吐出一些C关键字,但不会吐出下一个或视频中所说的数据

如果我把它指向sumLi后面的空格,它会打印出同样的C关键字。我可以让它打印出sumListNode,如果我将它指向sumLi中有“s”的列,但即使这样,它也会将其指定为与其他关键字相同的优先级值,因此它实际上只是打印出我可以放在那里的所有内容,而不是读取光标下的内容并尝试进行智能猜测。我只是在抓救命稻草,希望把光标放在片段的开头而不是结尾会有所帮助


我从doxygen和c-index-test中了解了很多关于libclang可以提供给我的数据类型以及如何使用它的知识,但我还没有学会如何让它提供给我相关的数据,以便我可以使用。

首先,您应该尝试打印翻译单元输出的任何
CXDiagnostic
,因为任何错误都可能导致代码中的叮当声丢失(在您提到的非常简单的情况下,这是不太可能的)

其次,请注意,libclang定义行和列编号的方式可能与您习惯的方式不同(即,如果您从文本编辑器中获取行/列信息,则可能必须在列编号中添加1才能与clang的定义同步)

第三,可以使用clang编译器本身来测试编译选项和行/列信息的有效性。这样就消除了基于libclang的代码所带来的不确定性。例如,您可以使用以下命令行:

clang++-cc1-fsyntax-only-FILENAME处的代码完成:LINE:COL clang_ARGS

还请注意,这意味着仅在标记开始时调用,并生成所有可能标记的列表,客户机负责使用文本编辑器中已输入的潜在部分标记过滤结果

从文件(重点是我的):

在翻译单元中的给定位置执行代码完成

此函数在源代码中的特定文件、行和列上执行代码完成,根据完成的上下文提供建议潜在代码段的结果。代码完成的基本模型是,Clang将解析完整的源文件,执行语法检查,直到请求代码完成的位置。此时,一个特殊的代码完成标记被传递给解析器,解析器识别该标记,并根据C/Objective-C/C++语法中的当前位置和语义分析的状态确定要提供哪些完成。这些完成将通过新的CXCodeCompleteResults结构返回

当用户键入标点符号或空格时,客户端将触发代码完成本身,此时代码完成位置将与光标重合。例如,如果p是指针,则代码完成可能会在p->中的“-”之后触发,然后在“>”之后触发。当代码完成位置在“>”之后时,完成结果将提供,例如,“p”指向的结构的成员客户端负责将光标放在当前键入的令牌的开头,然后根据令牌的内容过滤结果。例如,当表达式p->get的代码完成时,客户端应该在“>”之后提供指向该代码完成挂钩的位置(例如,指向“g”)。然后,客户端可以基于当前令牌文本(“get”)过滤结果,只显示以“get”开头的结果此接口的目的是将代码完成结果的相对高延迟获取与基于每个字符的结果过滤分开,后者必须具有较低的延迟。

以修改后的第二个示例为例:

int main(int argc,char**argv){
int i=sumLi
//      ^
}
应在标记位置(即标记的开头)调用代码完成。然后,Clang可以给出一长串结果,例如:

  • argc
  • sumListNode()
然后由您根据部分输入的
sumLi
标记筛选此列表,并保留唯一相关的完成:
sumListNode

如果您了解elisp,clang的源代码包含一个Emacs的自动完成库,这是两级实现的一个很好的示例:


谢谢!这几乎解决了我的问题。我的文本编辑器说节点->(这里)是第33列。然而,运行clang本身会将错误放在第27列。看起来它将选项卡计为一列。对于第二个示例,它仍然打印出许多关键字,而不仅仅是预期的“sumListNodes”。如果它们之间没有空间,Clang的建议就无法编译。我在整个专栏里都试过了,只是为了确定。我想应该由我来整理实际的可能性?哎呀,我应该补充一点,我编辑了test.c,以便在该点上它应该是一个整数值,并且在范围中声明了一个结构列表。只是为了确保有一个真实的世界背景让clang理解。但它仍然没有达到我的预期。例如,int i=sumLilong不会编译,但它是gav