
Cquery: highly-scalable, low-latency language server for C++ - ingve
https://github.com/jacobdufault/cquery/#cquery
======
krylon
Wow!

I consider myself lucky that I practically do not have to deal with C++, but
if I were a C++ kind of person, right now I would deeply appreciate how much
hard work goes into a tool like this. [1]

In order to be any good, it has to be even more clever than the compiler, at
least in a few ways.

And I have a hunch that in the field of programming languages that are used
these days, C++ is probably not the easiest one to write such an analyzer for.
;-)

TL;DR - Respect! I can only - but vividly - imagine how hard it must be to
create a tool like this.

[1] I have mixed feelings regarding C++, because I have only used it in tiny
doses. I treat the language the same way I would treat a bear, if one suddenly
appeared: Keep my distance, avoid any sudden motions, but also, under no
circumstances, dare I turn my back on it because of the slight chance that it
might come after me eventually. I do not actively dislike C++, I just have not
found the time to learn it, and I get the impression that if I really want to
learn it, it will take much more time than I can currently afford to invest.
Maybe some day it will come to pass (that will be a good day also to finally
read Moby Dick all the way through from end to end.)

~~~
phaedrus
Some advice if you do decide to learn C++: there has been a steady stream of
improvements in standard C++ the past 8 years (C++11-17), and some (Bjarne
Stroustroup, Herb Sutter, others) promote it as a better starting point for
beginners under the name 'Modern C++'.

From: [https://msdn.microsoft.com/en-
us/library/hh279654.aspx](https://msdn.microsoft.com/en-
us/library/hh279654.aspx)

"[...] Over the years, features have been added to the language, together with
highly-tested standard libraries of data structures and algorithms. It's these
additions that have made the modern C++ style possible. Modern C++ emphasizes:

Stack-based scope instead of heap or static global scope.

Auto type inference instead of explicit type names.

Smart pointers instead of raw pointers.

std::string and std::wstring types (see <string>) instead of raw char[]
arrays.

Standard template library (STL) containers like vector, list, and map instead
of raw arrays or custom containers. See <vector>, <list>, and <map>.

STL algorithms instead of manually coded ones. Exceptions, to report and
handle error conditions.

Lock-free inter-thread communication using STL

std::atomic<> (see <atomic>) instead of other inter-thread communication
mechanisms.

Inline lambda functions instead of small functions implemented separately.

Range-based for loops [...]"

~~~
weberc2
C++ as a language has certainly modernized, but its tools are still stuck in
the 90's. Contrary to the increasingly bizarre rationalizations offered up by
its proponents, CMake and friends are not acceptable package managers or build
tools, at least to those of us who have used newer languages. I don't need a
build tool assumes all projects are unique snowflakes in need of their own
hand-crafted build system; I just want to get up and running quickly without
sticking a bunch of maintenance into my build system.

I don't mean to dump on C++; I like the language and I take this post as a
sign that things are beginning to improve, and I hope this pace of improvement
accelerates. However, I have been disappointed by the head-in-the-sand
attitude of some proponents.

~~~
flohofwoe
The funny thing about cmake is though that simple things are indeed simple,
you can describe an executable made of several compile units in a single line
of cmake script. The problem is that it doesn't enforce any standardization
beyond that of how to structure complex projects, especially if external
dependencies are involved.

PS: I don't think you will find a single "fan" of cmake who would say it's the
best thing since sliced bread. Most people know it sucks, but grudgingly admit
that its better to have one bad standard than a dozen competing solutions.

~~~
weberc2
> I don't think you will find a single "fan" of cmake who would say it's the
> best thing since sliced bread.

This happens in all the time. At one point here on HN I lamented that C++
didn't have a build system like Rust's Cargo, and lots of C++ folks came out
of the woodwork to argue that Cargo is a shitty tool because it can't support
certain byzantine projects. Similar arguments were made in a thread about a
new C++ package manager that attempts to modernize C++ package management.
Almost all of the pro-CMake arguments focus on how capable it is to handle
bizarre projects, without realizing that most such projects are bizarre only
because they each had to implement their own build system instead of using one
that encouraged them toward some standard structure. I can't recall anyone
making an argument that resembled "it's better to have one bad standard than a
dozen competing standards", even in response to something like "CMake is the
best of all C++ tools, but still a far cry from other languages' tooling."
Some people _would_ allude to C++ projects being uniquely difficult to build,
and so it would be impossible to emulate another language's tools; however,
this too seemed to be confusing "C++ projects lack a standard structure" with
"C++ projects _can 't have_ a standard structure". I could go on and on.

------
sient
Author here! Wasn't quite ready to post to HN yet since cquery is still in
development, and I plan to eventually publish on the vscode marketplace so
using cquery should be as simple as using the existing C/C++ extension.

Let me know if you have any questions.

~~~
archgoon
Hi! I see you're using compile_commands.json. How are you handling header
files? I've found that header files present problems for compile_commands
since a number of tools using compiler_commands (like bear) only look at the
compiler commands for .c files, and don't notice that the header files should
be added as well.

I know that some tools, like YCM, attempt to intelligently map a header file
to it's associated .cpp/.cc/.c file to guess what the compiler commands are,
but this doesn't always work.

What is the state of generating compiler_commands.json for Chromium? I
remember running into this issue a few years back.

~~~
sient
> Hi! I see you're using compile_commands.json. How are you handling header
> files? I've found that header files present problems for compile_commands
> since a number of tools using compiler_commands (like bear) only look at the
> compiler commands for .c files, and don't notice that the header files
> should be added as well.

When a cc file is indexed cquery will index the associated header files. There
is some logic to deduplicate multiple header file parsing so it only happens
once, but that is fundamentally how it works. cquery then knows which header
files are associated to which cc files.

> I know that some tools, like YCM, attempt to intelligently map a header file
> to it's associated .cpp/.cc/.c file to guess what the compiler commands are,
> but this doesn't always work.

cquery does this as well, because you can, for example, create a new file that
is not in compile_commands.json. cquery has sophisticated logic here, as it
will also try to infer if the file is test or platform specific (use general
postfix matching) as those often have a very different set of arguments.

> What is the state of generating compiler_commands.json for Chromium? I
> remember running into this issue a few years back.

Chrome compiles using ninja, which natively supports compile_commands.json, so
generating the file works well and is easy to do. I have not run into any
issue here.

------
jhasse
Wow! I've just tested this and it's awesome. Much better than the C/C++
extension, since it's more robust (no false-positives for go-to-definition),
faster and has more features (e.g. refactoring, better auto-complete, ...). It
basically turns VS Code into the best C++ IDE possible for me.

~~~
makapuf
It's not really linked to VSCode, is it ? i was under the impression that by
example Sublime integration for LSP was possible.

~~~
iainmerrick
Yep, the idea is that the same protocol can work with any editor:
[https://langserver.org](https://langserver.org)

------
rombix
This project seems to be very similar to clangd. It is also similar to
YouCompleteMe, though YCM does not support LSP yet. How does Cquery compare to
those projects in terms of features?

In particular, should it be considered as an alternative to clangd? Could it
make sense to combine efforts between clangd and Cquery?

~~~
sient
At the moment, clangd and ycm are very similar projects; they are very limited
compared to cquery. clangd and ycm support code completion, diagnostics,
fixits, and goto declaration (but not definition), whereas cquery supports
references, derived types, callers, etc. Basically, if the feature requires
knowledge across multiple translation units, clangd/ycm do not support it.

cquery is designed to support very large projects, so it makes very specific
design decisions w.r.t. the data model, indexing pipeline, and multithreading
model. I hope clangd can match the performance - but so far every project I've
seen simply does not run nearly fast enough on a code-base the size of
Chrome/ChromeOS.

~~~
rombix
Thanks for the explanations!

In the meantime I tried it out with VSCode on my MacBook. Works like a charm!
Awesome job!!!

------
snowAbstraction
Is this like
[https://github.com/Andersbakken/rtags](https://github.com/Andersbakken/rtags)
but for vscode?

Any key differences?

~~~
jchw
For one thing, it sounds like it implements the Language Server protocol,
which will make it usable for other IDEs and text editors with support for
this protocol (a quickly growing list.)

Not aware of Rtags but I'll assume it's similar to the omnipresent C tags but
with an actual C++ parser. If that's the case, in theory cquery is a lot more
powerful; it would include the symbol indexing of Rtags but also code
refactoring tools ("fixits",) fully aware context-sensitive auto-complete,
ability to detect dead code (i.e. #if 0 or #ifndef _WIN32) and support for the
type hierarchy. Some of that stuff is definitely not supported by LSP so I
imagine it's custom stuff for VSCode only.

All in all, it sounds like it would provide most of the IDE experience to VS
Code. The only annoying part would be that you'll have to extract the compile
flags from your build system yourself, but that's not usually too big of a
deal.

~~~
to3m
One interesting thing that rtags does is provide a gcc/clang wrapper script.
You make symlinks to it called cc/c++/gcc/g++/etc. in a folder that's in PATH
ahead of wherever gcc/clang proper live. When invoked, the script submits an
appropriate tags job to the rtags server, complete with compile flags actually
used, then passes the command line on to the appropriate tool so that the
compile actually gets done.

So quite often you won't need to do anything. (If you use CMake, you will have
to rebuild your Ninja/make files after first setting this up.)

I didn't find rtags perfect. There were a few files that it simply never
seemed to create tags for, and the rtags setup is complicated enough that I
couldn't quickly figure out why, so I just put up with it. But when it works,
it works very well...

(This sort of thing seems to be par for the course with this kind of tool.
I've seen a number of people complain about how terrible Visual Studio's code
browsing is, for example, but it's been a long time since I've had a problem
with it...)

~~~
zarkov99
Rtags is great for code browsing, but completion is slow and dumb.

~~~
to3m
I found it fine once I'd set it up to do completion only by request, so I'd
know that I might have to wait. The default, whereby it tries to pop up as you
type, was absolutely maddening...

------
yalph
Use c++ on a daily basis. I think the direction the language is going is
really really troublesome. It was a mistake to follow the boost’s lead. At
this point language is more or less a clusterfuck. While python peeps are
saving the world here on this dark side of the world we wrestle with move
semantics. Simplicity and beauty of C is long gone.

~~~
sobellian
I used to use C++ a lot for a mixture of reasons. I avoid it like the plague
now, because I'm not confident that _anyone_ completely understands the
semantics of a non-trivial C++ program.

Even if I did, the cognitive overhead of this stuff detracts from real
programming.

~~~
kraghen
I have a suspicion that all non-trivial C++ programs contain undefined
behaviour (e.g. not checking for or preventing overflow at every arithmetic
operation involving signed integers), so trying to understand the semantics of
these programs is kind of a moot point.

On the other hand, if anyone tried to formalise the semantics of C++ and prove
some kind of soundness theorem they would probably find that the language
definition is technically inconsistent.

Paraphrasing Feynman, if you think you understand C++ then you don't
understand C++.

------
speps
Is there one similar to this but that doesn't require your code to compile
under Clang? I have plenty of projects at home that don't instantly work under
Clang. So far, I've never seen any C++ language server that doesn't rely on
Clang unfortunately.

~~~
feanaro
What are the usual culprits that prevent it from working under clang?

~~~
jhasse
Clang doesn't support

    
    
        template<class ...Args>
        void foo(int x = 0, Args&&... args)
    

for example (default argument before variadic templates args).

~~~
lfowles
Wow, I was going to guess that was illegal anyways, but cppref validates that
behavior[0].

0:
[http://en.cppreference.com/w/cpp/language/default_arguments](http://en.cppreference.com/w/cpp/language/default_arguments)

------
jdright
Run away from Jonathan Blow, as of today he was full rant mode on language
server and similar stuff including on people that think this is a acceptable
stuff, notably Hacker News audience.

FYI, I 150% disagree with his useless rants.

~~~
iainmerrick
I saw that on Twitter but I couldn't figure out what his actual complaint was.
I think I'd probably disagree but I'm still interested in knowing.

~~~
cgag
That doing all of this stuff via rpcs vs function calls is crazy I believe.

~~~
iainmerrick
He's not totally wrong, but casting it as a 100% clear-cut decision -- with
the RPC version as the obviously bad, "highly damaging" choice -- is just
wilfully stupid and dishonest. It's clearly a tradeoff.

------
blaket
What's the word on using this with emacs?

~~~
sient
Eventually this will be supported with lsp-mode. If you check
[https://gitter.im/cquery-project/Lobby](https://gitter.im/cquery-
project/Lobby) @topisani made good progress here quickly and already has
cquery up and running.

------
jdlyga
This looks nice. Reminds me a lot of the Clang Code Model that I use with
QtCreator.

------
photonios
I can only applaud this effort!

------
pollow
Looks pretty, I wonder how it different from ycmd?

~~~
sient
See
[https://news.ycombinator.com/item?id=15725119](https://news.ycombinator.com/item?id=15725119)

