Qt Creator and Clang

Published Wednesday October 19th, 2011
41 Comments on Qt Creator and Clang
Posted in C++, QtCreator

As mentioned in the recent editor news blog post, we have been working on integrating Clang as a replacement for our current C++ code-model in Qt Creator. While we are still in an early stage, we feel that it is now in a state where others can look at it, play with it, and even contribute to it.

Now I hear some people thinking: “But I already have a compiler!” I get this reaction a lot when I tell this to people. So first of all: a code-model is not a compiler, so you still need your own favourite one.

What is a code-model, what does it do?

The code-model is the part of an IDE that “understands” the language you are using to write your application. It is the framework which allows us to provide:

  • code-completion
  • highlighting (both syntactically and semantically)
  • navigation (the locator, follow symbol, etc)
  • introspection (the class browser, the outline, etc)
  • diagnostics and tool-tips
  • find usages and renaming
  • refactoring actions

As such it needs to have a parser for the language, and the semantic analyses. The only difference with a compiler is that a code-model does not generate an executable.

Why switch to Clang?

Switching from our current code-model to Clang gives us some important improvements. Most notable of these is that Clang is an actual compiler which means that the information we get out of it is correct. So the feedback you get through warning and error markers is the same as the compiler will give you, not an incomplete set or a close approximation. When we are talking about those diagnostics: Clang focusses on detailed information for diagnostics, which is really useful in those rare cases where a developer makes a typo ๐Ÿ™‚

Also, Clang already supports C++98/03, C89 and C99, Objective-C (and Objective-C++), and C++11 support is in active development.

But all those good things do not come for free. When using Clang as code-model it does not need to generate object files, but it still needs to parse and analyse the source files. For small projects which only use STL, this works okay. But for bigger projects like Qt Creator, which uses large parts of Qt, processing a single file and all the included files can take a while. For this we use one or more pre-compiled headers, and with the current integration you will have to manually add them to your project or point Qt Creator to it. More details below.

What is switched already?

The current integration uses Clang for:

  • syntactic highlighting (“keyword highlighting”) and semantic highlighting (types/methods/fields/labels/etc)
  • code-completion
  • diagnostics
  • code navigation

Please notice that some of the above items still only work in a limited range of situations.

Where to get it

First you need to compile Clang/LLVM, either version 3.0 or trunk. Build instructions can be found on the LLVM website. If you want to use git instead of svn, use llvm.git and clang.git. Please make sure that you do a release (optimised) build!

The Qt Creator integration is in the wip/clang branch in the git repository on gitorious. Building Qt Creator works as usual: run qmake, then make, and depending on your platform a make install. If you are on Linux/Mac and do not have the directory with llvm-config in your path, or if you are on Windows, you can use the LLVM_INSTALL_DIR qmake variable to tell qmake where to find the Clang/LLVM libraries and headers.

When starting Qt Creator, make sure the clang libraries are in the library search path by including the <llvm-install-prefix>/lib directory in your LD_LIBRARY_PATH (Linux), or in the PATH (Windows).

How to use it

You can use this version of Qt Creator as you would do with any other version. However, there is one thing to keep in mind: if you use big libraries like Qt or Boost in your project, you can speed up the code-model (and therefore the highlighting and completion) quite a bit by defining one or more pre-compiled header(s). For a typical Qt project, this header can consist of:

#ifndef PCH_H
#define PCH_H

#include <QtCore>
#include <QtGui>

#endif // PCH_H

Only header files that do not change (so those which are part of the system), otherwise the pre-compiled header needs to be re-generated, which in turn negates the caching advantage.

There are two ways to do tell Qt Creator to use this header as a cache:

  • If you use qmake, then you can set the PRECOMPILED_HEADER variable in your .pro file:
    PRECOMPILED_HEADER = pch.h
    Depending on the qmake spec file for your compiler, this pre-compiled header might also be used for compilation.
  • When you go to the “Projects” mode, you will see an extra tab with “Code Completion Settings”, where you can select a “custom” header. When selecting this option, the code-model will use that header as a cache, but the compiler will not use it.

How to contribute

As mentioned at the beginning of this post, this release is mainly targeted towards people who would like to contribute, because no, we are not finished. There is still quite some work to do, so if you feel like helping out, let us know! The main communication channel is the qtcreator mailing-list, and #qt-creator on freenode.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in C++, QtCreator

41 comments

Most Qt projects have, as part of their precompiled header settings, the project’s own headers. Take, for example, corelib.pro (global.pri):

PRECOMPILED_HEADER = global/qt_pch.h

And that includes qcoreapplication.h, qlist.h, qvariant.h, qobject.h, qregexp.h, qstringlist.h and qtextcodec.h.

Suppose I am hacking on one of those files. Will Qt Creator automatically detect the change and re-generate the cached precompiled header?

Jason says:

There was never this requirement prior to the clang support. Does this imply that clang is slower than the old manual code-model, and therefore requires these things to speed it up?

Also, if it is just the code-model and not the code-generator from clang, why do I need to install llvm as well? Aren’t these components supposed to be uncoupled?

Peter says:

What is the exact reason for this devedelopment? To me the old cold model seemed pretty reasonable and worked pretty well.
-why introduce such a dependency, especially if the perfomance is worse.

zelegolas says:

It was one of my suggestion and I’m very happy that you used CLang and LLVM with Qt Creator.
GCC is good but CLang/LLVM are doing a better job. For those who are not convinced go to the website of LLVM and take the time to read how it works.
Good job ๐Ÿ™‚

Simon says:

Does this mean Nokia does not want to maintain their code model, anymore?
And the “community” has to do/finish the work?

Roland says:

Early versions of Creator were unable to digest headers with lots of templates. Especially boost libraries, like boost::spirit caused a problem. Today this works very well, probably because the current code model had been limited. I wonder if it is possible to use CLang and still be able to use boost libraries. Boost libraries are sick but sometimes very handy.

Great news.

By the way, I can’t build Qt 4.8 (git) with clang (svn).

make[1]: Entering directory `src/corelib’
moc animation/qabstractanimation.h
compiling global/qt_pch.h
compiling animation/qabstractanimation.cpp
error: unable to read PCH file: ‘Is a directory’
make[1]: *** [.obj/release-shared/qabstractanimation.o] Error 1
make[1]: Leaving directory `src/corelib’
make: *** [sub-corelib-make_default-ordered] Error 2
==> ERROR: A failure occurred in build().
Aborting…

This command fails:

echo compiling animation/qabstractanimation.cpp && clang++ -c -include .pch/release-shared/QtCore -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector –param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -fpermissive -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -O2 -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DENABLE_WEBGL=1 -DENABLE_ANIMATION_API=1 -DQT_BUILD_CORE_LIB -DQT_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT3_SUPPORT -DQT_MOC_COMPAT -DQT_USE_QSTRINGBUILDER -DELF_INTERPRETER=”/lib/ld-linux-x86-64.so.2″ -DQLIBRARYINFO_EPOCROOT -DQT_USE_ICU -DHB_EXPORT=Q_CORE_EXPORT -DQT_NO_DEBUG -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_HAVE_SSE3 -DQT_HAVE_SSSE3 -DQT_HAVE_SSE4_1 -DQT_HAVE_SSE4_2 -DQT_HAVE_AVX -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -I../../mkspecs/linux-g++-64 -I. -I../../include -I../../include/QtCore -I.rcc/release-shared -Iglobal -I../../tools/shared -I../3rdparty/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -I.moc/release-shared -o .obj/release-shared/qabstractanimation.o animation/qabstractanimation.cpp

Leandro T. C. Melo says:

Trying to clarify some concernsโ€ฆ

The reason for this development is pretty much to evaluate the future of Qt Creator in terms of the developer experience and what benefits the clang front-end can bring to our C++ environment. But in the beginning we would like to adapt the main features which already exist in the official Creator in order to have a starting point.

Is this going to be eventually released as the “new Qt Creator”? We don’t know yet. This is a work in progress. We hope that the outcome of this development is an even cooler IDE with even better C++ support and features. Specially now with open governance coming, the community can play an important role by both providing feedback and contributing to the project.

Yes, our current C++ model is quite good and fast. And one of the reasons for it being fast is that we don’t do a few things that a real compiler would do like proper name-lookup or type-checking. Some of those can still be treated somehow, but the point is that we cannot be as conforming and accurate as we would like. Then we miss opportunities to provide better analysis, diagnostics, semantic checks, etc.

Besides, it does take an effort to maintain and improve a C++ parser. Although we have the general cases well covered, you can still find quite usual code that fails to produce the expected result (some issues are smaller, but there are also more complex ones). In addition, there’s the new C++ Standardโ€ฆ So it’s not that we “don’t want to maintain our code model”, but it’s that we believe we can build upon an open-source, high-quality, and actively developed front-end for the core stuff and then focus more on end-user features.

Yes, there are indeed trade-offs and performance is one of them. Currently, most notably during initial indexing. But again, this is a work in progress and there should be plenty of room for improvements and even design changes. Still, due to the reasoning above, it’s quite unlikely that we can make the clang-based model faster than the current one.

Simon says:

Leandro:

thank you for the clarifications. I understand this move now.

Erik Verbruggen says:

@Thiago: No, not yet. It is one of those to-do things why we call it wip (work-in-progress).

@Jason: regarding speed: yes. It does not impact completion/highlighting too much, but indexing suffers quite noticeably. Regarding Clang/LLVM coupling: Clang uses lots of infrastructure classes from LLVM. The codegen libs are not linked in.

@Roland: You can use Clang with Boost. For the details about what is (was?) not working smoothly yet: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-October/017842.html

hdarama says:

Thanks. I wish QtCreator support D Language code completion one day, and QtD also. http://www.d-programming-language.org/
Just a wish. Thanks for all.

tbl says:

What about support C++11?

Cristian says:

@tbl have a look at http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport at the last column ๐Ÿ˜‰

QtCreator will have the same support as clang 3.0 or trunk, if I read this post correctly.

Johan Simon Seland says:

I am super excited about and dream that one day we will have an C++ IDE which is a good as Eclipse is for Java.
I mostly deal with numerical codes, very often with their share of templates.
How will the Clang model handle templates? What about templates with split definition and implementations?

Konstantin Tokarev says:

Sorry if I’ve missed some details but it seems like this post does not point to the actual “this version” of Qt Creator.

Is Clang support available in master? How should it be compiled (I mean specifying of path to Clang headers)?

TomCooksey says:

How well will CLang cope with code which doesn’t compile? One of the things I like about QtCreator’s code model is that it’s fairly resilient to half-written functions and such – I can still use code navigation and auto-complete features. When using other C/C++ IDEs with auto-complete, I’ve found the features stop working very quickly as soon as you actually start modifying code. I worry that CLang will abort parsing earlier when encountering a coding error (like I’m half-way through writing a function) and thus not provide QtCreator with information which the old model would have.

Erik Verbruggen says:

@tbl: search for the line “… and C++11 support is in active development.” in the post ๐Ÿ™‚ We try to auto-detect if you use C++11 through compiler command-line options.

@Johan: Clang handles templates the same as, well, a compiler. So if it is according to the C++ specification, it works (and if not, it is probably a bug).

@Konstantin: it is in a separate branch called “wip/clang”.

Erik Verbruggen says:

@TomCooksey: the “old” code model does largely the same as what Clang does: parse the file, recover from errors, then provide completion. So the trick/question is how well a parser recovers. We improved the “old” code-model over time by simply using it, and then fixing the pain-points. We can (and want to) do the same for Clang.

Oliver Knoll says:

I am very excited about this news ๐Ÿ™‚ Note that Apple did (or is doing) the same move with their XCode IDE!

Auto-completion etc. is only the start. I am curious about “real refactoring stuff” coming ๐Ÿ™‚

To get you some ideas what you can do with that, here’s what Apple does: ARC – or Automatic Reference Counting! It’s not some “indeterministic garbage collector” which suddenly kicks in (and would not work in a mixed C/C++/Obj-C world anyway reliably) taking away valuable CPU time! It is implemented at *compile* time in a deterministic way – with the help of the code model provided by LLVM!

A very nice article is available on Ars: http://arstechnica.com/apple/reviews/2011/07/mac-os-x-10-7.ars/10

“In fact, ARC follows the rules in a more pedantic manner than any human ever would, bracketing every operation that could possibly be influenced by object ownership with the appropriate retain and release messages. This can produce a huge number of memory management operations. Luckily, Apple has an excellent optimizing compiler called Clang (since rechristened by Apple’s marketing geniuses as the Apple LLVM Compiler 3.0). Clang sweeps through this sea of mechanically generated code, detecting and eliminating redundancies until what remains looks a lot like what a human would have written.”

So huh, yes, it is apparently not exactly the LLVM “static model” which is used to figure out where to “retain” or “release” memory, but still the Clang compiler helps in figuring out which code (retain/release) is redundant and “optimises” the code to be compiled:

“ARC doesn’t even use LLVM’s sophisticated static analyzer to figure out where to put the retains and releases. The static analyzer takes a long time to runโ€”too long to be a mandatory part of the build process; it can also produce false positives. That’s fine for a tool meant to detect possible bugs, but reliable memory management requires certainty.”

Anyway, I am waiting for the day where I can select a block of code and e.g. say “extract method”, or select a method and say “move to super-class” and stuff!

Cheers, Oliver

Patrick Noffke says:

One of the great things about Qt Creator now is that it automatically parses libraries that are not “standard.” For example, I’m using the dc1394 library, for which I added an include directive to my CMakeLists.txt, and #include the dc1394.h header in my source code. Qt Creator then “sees” (perhaps after the first compile) all the routines available in that library, so code completion, follow symbol, syntax highlighting etc., Just Work.

Please, if you switch to Clang, do not require us to explicitly make pre-compiled headers for “extra” libraries. Either automatically make one when a new library is detected, or don’t change to Clang. I think to lose this feature for an improvement in accuracy would be a step back, especially since the accuracy seems good enough for most purposes now.

Thank you for making a great IDE.

Patrick

Konstantin Tokarev says:

Oliver: AFAIK, ARC is available only for ObjC and therefore is irrelevant for most of Qt code.

Yuriy says:

PRECOMPILED_HEADER = pch.h

//begin test.cpp
#include
void my_func()
{
std::
}
// end test.cpp

will be it is taken from analysis cstdio or from analysis pch.h?

Yuriy says:

Characters aren’t displayed. I will repeat with inverted commas

PRECOMPILED_HEADER = pch.h

//begin test.cpp
#include “cstdio”
void my_func()
{
std::”The autocompletion list”
}
// end test.cpp

“The autocompletion list” will be it is taken from analysis cstdio or from analysis pch.h?

User says:

Clang is good, but don’t change too many things. You should make it transparent to users as much as possible.

Erik Verbruggen says:

@Patrick Noffke: You do not have to pre-compile anything at all. You could see pre-compiling as a hint that those files can be cached and do not need to be re-parsed time and time again (which is: every time you do completion, and when you open an editor and once 500ms after you stop typing to do semantic highlighting and show errors).

@User: no worries ๐Ÿ˜‰

Erik Verbruggen says:

@Yuriy: From both.

Yuriy says:

@Erik: And then we will see thousand names of space std, instead of thirty names necessary to us from a file cstdio? And local elements will try to be built in heading files from all cpp-files of the project? It is bad.

second.h
int my_ CTRL+SPACE => and I will see my_var from first.cpp where it is defined as namespace { double my_var; }

Oliver Knoll says:

@Konstantin: I know that ARC is only available for Objective-C. That was not the point of my comment. My point was to illustrate what you can do with the “code model” (or what not) and what we might get in the future for C/C++ (and Objective-C as well ;)).

Patrick Noffke says:

@Erik: It sounds like you’re saying that for the IDE to perform well, I do need to pre-compile. Can’t the IDE do that without having to be told? I don’t quite follow your comment of “I could see pre-compiling as a hint…”. A hint to me that I need to pre-compile?

Sebastian Redl says:

Clang supports automatic precompiling to a degree, but it still requires the IDE to call it the right way for that. The feature is called “precompiled preamble”, and essentially it means that Clang tries to detect the header of the file (the part that only includes other stuff) and builds a precompiled header from that part.

Yuriy says:

You haven’t specified from what version QtCreator this idea will be used.

Andre' says:

@Yuriy: As usual: when it is ready and has been proven to be useful.

Erik Verbruggen says:

@Patrick Noffke: no, to the IDE, but…:
@Sebastian Redl: yes, but (1) I didn’t do any performance analysis yet, and (b)…:

The problem is that a compiler or a code model cannot guess which headers are unchangable (stdio.h) and which are not (my_header.h). Furthermore, the C/C++/ObjC/ObjC++ compiler has to work on separate files, each having their own #defines or -D flags, meaning that there is no fool-proof way to detect the one-true-way-to-process-a-header/library. If you’re editing a file, pre-compiled preambles are great. If you want to index a project (which is finding out which types (classes/structs/enums/methods/functions) are defined), then a preamble is useless, because you touch/parse a file just once. (And don’t get me started on include-order of header files, or recursively including the same header file with different defines…)

That said, if anybody can come up with a good heuristic to get the indexing to run faster, I’m more than happy to give that a shot. And that is one of the reasons to publish this: we would like to have feedback. But one request: if you have suggestions or discussions like this, can we have it on the mailing-list please? That’s a nicer medium than replying to replies to blog posts ๐Ÿ™‚

lemmel says:

Thanks Guys ! I just tested it and it is effective. This will save time (no need to compile too frequently, or waste a lot of time to correct small syntax error : the ide provide more feedback now).

Loaden says:

Launch failed after build if use MSVC 2010.
LLVM/CLang 3.0rc2 or master branch.

Here is the error message:
Cannot load plugin because dependency failed to load: CppTools(2.4.81)
Reason: D:qpSOFTDEVx86qtlibqtcreatorpluginsNokiaCppTools.dll: Cannot load library

Loaden says:

Unfortunately, launch failed under Linux (Chakra 64bit) also.
Same reason.

ckamm says:

@Loaden: I think the likely cause is the CppTools plugin not finding the clang libraries. You need to set PATH (Windows) or LD_LIBRARY_PATH (Linux) to your-llvm-prefix/lib.

Loaden says:

@ckamm
Thanks, Issue solved.
In Windows, CppTools depend to libclang.dll, and under Linux, It’s depend to liblibclang.so.
There has some way to build clang as static library?
Thanks again!

Dragomir says:

@Erik: This project is fantastic. The future is in consolidating the development, and not fragment it.
I was wondering, will you teach clang about QT extensions preprocessed by moc (aka. “signal”,”slot”,”emit”)? Currently clang doesn’t know them. The other thing is that GIT is becoming de-facto standard vcs under Linux, is there any more sane git plugin in your plans? I mean something like the one in Anjuta 2.x. In Anjuta 3.x they broke it completely. Thank you.

Loaden says:

It can not work with MSVC 10 on QtCreator Project.
But works well if use simple STL Console Project.

Commenting closed.

Get started today with Qt Download now