Qt Creator's Clang Code Model

Starting with the upcoming Qt Creator 4.7, the Clang Code Model is enabled by default. That's a great time to look at the differences between our old code model and the new Clang Code Model. But first things first.

History of C/C++ Support in Qt Creator

Since the beginning of Qt Creator the C/C++ support was implemented around a custom C++ frontend (lexer, preprocessor, parser, lookup). The whole support was referred to as the "C/C++ Code Model", the code model being the collection of language-specific services, for example code completion and semantic highlighting.

Back then the next C++ standard was a long time in the coming (C++0x - C++1x - C++11), the tooling support from Clang was not where it is today and  a custom C++ front-end gave us some extra flexibility when it comes to performance, error recovery and support of Qt-specifics. The code model around the custom front-end served us well (and still does) - the appropriate trade-offs between precision and performance were made back then. However, maintaining a custom C++ front-end is not a trivial task, notably so during the interesting times for the company we were part of back then, and with only a few developers on it. With the availability of Clang and its tooling, especially from the point on where it became self-hosting, we did some experiments to base the code model on it - the "Clang Code Model" was born. The experiments looked promising in general, but the stability and performance were a problem from the beginning on, especially when considering all platforms.

Fast forward: today C++ evolves much faster, Clang and its tooling are prospering and we have picked up working on the Clang Code Model.

Status of the Clang Code Model

We believe to have addressed the most severe performance and stability issues by now. With the Clang Code Model you get up to date language support based on libclang 6.0, greatly improved precision and diagnostics.

The first big area we have tackled are the services related to the currently open file, not taking any project or global index information into account yet, which is work in progress. Currently, the following services are implemented with the Clang Code Model:

  • Code completion
  • Syntactic and semantic highlighting
  • Diagnostics with fixits and integrated Clang-Tidy and Clazy checks
  • Follow Symbol (partly)
  • Outline of symbols
  • Tooltips
  • Renaming of local symbols

For the not yet ported services, the services based on the custom frontend are used. This includes for example indexing, find usages and refactoring.

Due to Clang's precision the Clang Code Model is inherently slower than the old code model and has lower error recovery capabilities. However, the extra precision and diagnostics will result in less build errors and thus reduce your edit-build-cycle count.

Differences to the old code model

Now what are the visible changes that you can observe as a user?

Updated language support

The Clang Code Model is based on libclang 6.0 and as such it can parse C++17 and more.

Precision

You will immediately notice the improved precision in highlighting and diagnostics.

For example, our custom front-end never validated function calls and thus you would notice these when building. With the Clang Code Model only valid function calls are properly highlighted, whereas invalid ones will be rendered as "Text", that is, black by default.

Another example is code completion. Items are no longer offered for declarations that are below your completion position, except class members of course. Also, completion of const objects will take the "constness" into account.

Diagnostics

Chances are that you will notice Clang's diagnostics early on, as they are displayed as inline annotations in the editor. Detailed information is provided by tooltips. Check out for the light bulb at the end of the line, as these indicate the availability of "Fixits". These are small/local refactoring actions fixing diagnostics.

Of course the diagnostics for the current document are also available in the Issues pane. This behavior can be disabled by using the "Filter by categories" icon in the Issues pane toolbar.

You can set up diagnostic configurations in C++ > Code Model > "Manage..." in the options dialog. The predefined configurations are really a starting point and it is recommended to adapt them to your needs. For example, you could set up a configuration for a specific project.

Note that Clang-Tidy and Clazy checks are integrated, too. Enabling these checks for the Clang Code Model will naturally slow down re-parsing, but depending on your machine and the specific selection of checks this can be a great help. Starting from this version, it is also possible to run Clang-Tidy and Clazy checks for the whole project or a subset of it (Menu: Analyze > "Clang-Tidy and Clazy..."). For example, you could set up a diagnostic configuration for this mode that also enables the expensive checks and run it once in a while.

Code Completion

In general, the completion is more context-sensitive now. For example, completing after "switch (", "case ", "int foo = " or after "return " will put more relevant items to the top of the completion list.

The completion of templated classes and functions is improved. Completion of unique_ptr<>/shared_ptr<> objects and friends works now on all platforms.

Does your code base make use of doxygen comments? Then you will probably be happy to see doxygen comments as part of the completion item, too.

Miscellaneous

Italic arguments in a function call indicate that the function call might modify the argument ("Output Argument" in the text editor settings).

Tooltips resolve "auto" properly and show also doxygen comments.

A visible document is automatically re-parsed if one of its headers is modified, either in an editor or on disk.

Future of C/C++ Support

Given the evolving tooling around C++ it is pretty unlikely that we will go back to a custom front-end.

Given the raise of the Language Server Protocol and the development of clangd, how to proceed from here on? The implementation of an LSP client makes sense for any IDE to also get support for other languages. And we are actively working on that. Having that, it will also help us to evaluate clangd further.


Blog Topics:

Comments