cquery 解析 c++ boost语法

我最近在使用cquery作为C++语法解析后端时, 发现cquery解析boost的一些语法会报错,但这些语法的写法都是比较基本的官网例子,比如:

{
  ...
  boost::thread t(function);
  ..
}

会报错no matching constructor for initialization of 'boost::thread',或者

class A {
  ...
  boost::asio::io_context io;
  boost::asio::steady_timer timer; 
};

A::A() : timer(io, boost::asio::chrono::seconds(1)) {}

会报错excess elements in scalar initializer

编译环境为Ubuntu16.04, boost版本为1.58, 使用CMake生成的compile_commands.json作为索引.

请问有人遇到类似的情况吗?我的配置或用法是否有问题?

没有建立索引吧

索引建立了,我上面忘了写。。。

.cquery 里面的选项对吗?

bear make 生成配置文件试试。

由于个人编程习惯不好。。。所以现在不具备make的条件。。。bear make编译不了。。。我甚至连makefile都还没有。。。

沒有compile_commands.json .cquery或.ccls,很容易不帶開關編譯(像這樣:clang++ a.cc),對於boost檢索不了很正常

bear make -k,不一定需要編譯通過,能運行編譯命令就好。

现在使用了CMake管理工程, 并通过CMake的CMAKE_EXPORT_COMPILE_COMMANDS生成了compile_commands.json文件. 工程可以正确编译, 并且没有warning, 但是在emacs里依然存在上述问题…

会不会跟 compile_commands.json 文件应该放在哪里有关?

比如工程是这样编译的:

$ mkdir build && cd build
$ cmake ../src
......
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ../src

生成的 compile_commands.json 文件也在 build/,不在项目根目录,所以其实没有起作用?

应该不是找不到compile_commands.json文件的原因:

  1. 我的compile_commands.json文件确实是在build目录下, 但是我再根目录建立了连接, 我看其他有些项目也是这样做的.
  2. 并不是所有语法解析都不正确, 很多其他的语法解析和自动补全都还是正常的. 其实总结一下问题, 目前我发现的主要是两个, 一个是boost类里面有些构造函数解析不太正常, 如主题中的例子; 另一个是有些类找不到合适的定义, 比如最近又遇到了boost::asio::serial_portboost::unordered_map被认为是int型的问题. 其他一些东西, 比如boost::shared_ptrboost::container::deque是可以正常解析的.

PS: 我的boost是安装在系统里的, 路径在/usr/local下面. 不知道语法解析会需要对这个做特殊配置, 但是自动补全是没有问题的.

github上有的話你把鏈接發給我。

最好给个完整的、可构建的例子代码,像这样 GitHub - tomergafner/cmake-boost-boilerplate-template: A boilerplate template to quickly create a c++ project with boost

25_AM 13_AM

这里 是我临时写的一个可以编译运行的工程. 会出现前面我提到的问题. 工程下面的compile_commands.json是一个指向 build 文件夹中内容的一个软连接, 可能需要根据实际情况调整.

再次说明一下: 我的这个工程需要环境安装了 boost 库, 我自己是用的默认的安装方式, 再路径/usr/local下面. 个人感觉 cquery 还是找到了这个位置, 因为很多 boost 库里定义的补全都是可以自动找到的.

这个是在我的机器上的效果, 双显示器不太会处理截图…

Debian libboost-all-dev

boost::asio::io_device <point>io boost::<point>bind等位置都能跳轉。

可能是因爲你的boost path components裏有幾個..的。在Arch Linux還能觀察到#include <string>等都無法檢索,可以觀察到clang++ -xc++ /dev/null -E -v返回的include path 中..太多了。

我很久以前給libclang加了clang_File_tryGetRealPathNameccls用了。

不好意思, 由于我对细节不太了解, 有点没太看懂您的解释. 我可以简单理解为:

  1. 这个问题我在不触碰cquery源码的情况下不能自己解决了吗?
  2. ccls可以正确解析不会有这个问题是吗?

你添加-isystem/usr/include.cquery試試。或其他包含boost的目錄名。

ccls只有用clang>7才有clang_File_tryGetRealPathName。這也只是我的一個猜測。

是否.cquery文件存在后, compile_commands.json就不起做用了? 还是两个同时能起作用, .cquery优先级高些?

试了你给的测试代码,发现我之前 #11 楼贴的图是有问题的:

  • 没开启 cquery/ccls。
  • 补全是 company-clang 提供的

如果不开启 cquery/ccls,我打开 BoostTester.hpp 也会看到 2 处错误(数字可能跟 company-clang 版本有关),错误信息应该也是 comany-clang 给 flycheck 的

04_PM

company-clang 提供的信息可能有点过时。开启 cquery/ccls 之后,flyckeck 就收到正确的信息了,没有错误(注意 mode-line 颜色,红色表示有错误),光标下的函数信息都有提示(底部 minibuffer 和 右侧 tooltip 浮动窗口):

51_PM

我看你的图,也只有 flycheck 下划波浪线提示。检查你打开 hpp 文件的时候是否自动启动了 cquery/ccls:

⋊> pgrep -fl cquery
71685 /usr/local/bin/cquery

@MaskRay

发现一个真正的 cqueyr/ccls 两者都有的问题,总是提示找不到当前正在编辑的文件 BoostTester.hpp

步骤:

  1. 克隆 #12 楼的代码
  2. cd boost_test && mkdir build && cd build
  3. cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
  4. Emacs 打开 BoostTester.hpp 文件
  5. 观察 Minibuffer / *Messages*

我觉得我的情况和您不一样, 其实你仔细看我的图片, 会发现flycheck的错误提示前面都有cquery:***, 这让我觉得我这里的错误确实是cquery报出来的. 至于版本, 由于我是不升级不舒服司机, 所以不敢说最新, 但是cquery, spacemacs和其他的melpa包都应该是比较新的, 而且这个问题出现有比较长的时间了, 几次更新都没有什么改善, 所幸没有遇到新的问题…

发现一个真正的 cqueyr/ccls 两者都有的问题,总是提示找不到当前正在编辑的文件 BoostTester.hpp:

hover(textDocument/hover)在io.run()上不能顯示:

std::size_t boost::asio::io_service::run()

?我這裏是好的。Unable to find file通常是因爲一個檔案解析失敗了,--log-file裏往往會有libclang crash的字樣。

我發現一個真正的ccls的問題,.h裏沒有diagnostics信息,可能在最新的commit Display diagnostics from header files修復了。這裏的改動在於ccls不會直接索引.h,而cquery會(如果.h.cc不在同一目錄,clang command line推導錯誤會導致.h中的索引信息丟失)

确实使用.cquery文件是可以解决问题的, 我还是没太体会

的意思, 因为在我的boost装在/usr/local/include, 而我的环境这个是系统路径, 不论是.cquery还是compile_commands.json文件中都没有与这个路径相关的信息.