| Summary: | parser sometimes ignores custom parser options | ||
|---|---|---|---|
| Product: | [Applications] kdevelop | Reporter: | Daniel Santos <daniel.santos> |
| Component: | Language Support: CPP (Clang-based) | Assignee: | kdevelop-bugs-null |
| Status: | REPORTED --- | ||
| Severity: | normal | CC: | daniel.santos |
| Priority: | NOR | ||
| Version First Reported In: | 5.6.2 | ||
| Target Milestone: | --- | ||
| Platform: | Gentoo Packages | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
| Attachments: | very ugly patch | ||
This appears to be the source of the problem, at plugins/clang/clangparsejob.cpp:175:
if (auto file = findProjectFileItem(tuUrl, &hasBuildSystemInfo)) {
This is failing when it should not, as this file belongs to the project:
(gdb) p url.c_str()
$2 = 0x5555561feb45 "/home/daniel/proj/embedded/openwrt/linux-5.4.143/drivers/staging/mt7621-pinctrl/pinctrl-rt2880.c"
(gdb) p hasBuildSystemInfo
$3 = false
In the below backtrace, I added a little debug spew:
--- a/plugins/clang/clangparsejob.cpp
+++ b/plugins/clang/clangparsejob.cpp
@@ -177,6 +177,8 @@ ClangParseJob::ClangParseJob(const IndexedString& url, ILanguageSupport* languag
m_environment.addFrameworkDirectories(IDefinesAndIncludesManager::manager()->frameworkDirectories(file));
m_environment.addDefines(IDefinesAndIncludesManager::manager()->defines(file));
m_environment.setParserSettings(ClangSettingsManager::self()->parserSettings(file));
+ auto const &ps = m_environment.parserSettings();
+ std::cout << "111111111111111111111111 " << ps << std::endl;
if (hasBuildSystemInfo) {
// Assume the builder invokes the compiler in the build directory.
m_environment.setWorkingDirectory(file->project()->buildSystemManager()->buildDirectory(file));
@@ -186,6 +188,8 @@ ClangParseJob::ClangParseJob(const IndexedString& url, ILanguageSupport* languag
m_environment.addFrameworkDirectories(IDefinesAndIncludesManager::manager()->frameworkDirectories(tuUrl.str()));
m_environment.addDefines(IDefinesAndIncludesManager::manager()->defines(tuUrl.str()));
m_environment.setParserSettings(ClangSettingsManager::self()->parserSettings(tuUrl.str()));
+ auto ps = m_environment.parserSettings();
+ std::cout << "222222222222222222222222 " << ps << std::endl;
}
const bool isSource = ClangHelpers::isSource(tuUrl.str());
#0 ClangParseJob::ClangParseJob(KDevelop::IndexedString const&, KDevelop::ILanguageSupport*)
(this=this@entry=0x555557849f80, url=..., languageSupport=languageSupport@entry=0x5555569f5138) at ../plugins/clang/clangparsejob.cpp:191
#1 0x00007fff600e11fa in ClangSupport::createParseJob(KDevelop::IndexedString const&) (this=0x5555569f5110, url=...) at ../plugins/clang/clangsupport.cpp:245
#2 0x00007ffff4f75e14 in KDevelop::BackgroundParserPrivate::createParseJob(KDevelop::IndexedString const&, DocumentParsePlan const&) (this=this@entry=
0x555555e72980, url=..., parsePlan=...) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:369
#3 0x00007ffff4f7740e in KDevelop::BackgroundParserPrivate::parseDocumentsInternal() (this=this@entry=0x555555e72980) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:309
#4 0x00007ffff4f7270c in KDevelop::BackgroundParser::parseDocuments() (this=0x555555c2a9d0) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:679
#5 0x00007ffff4f568cd in KDevelop::BackgroundParser::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
(_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=0x7fff20017628) at kdevplatform/language/KDevPlatformLanguage_autogen/7BZAXZBZPZ/moc_backgroundparser.cpp:249
#6 0x00007ffff66038c6 in QObject::event(QEvent*) (this=0x555555c2a9d0, e=0x7fff200175e0)
at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:1314
#7 0x00007ffff722adaf in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x555555c2a9d0, e=0x7fff200175e0)
at /usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:3632
#8 0x00007ffff65d8008 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x555555c2a9d0, event=0x7fff200175e0)
at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qcoreapplication.cpp:1064
#9 0x00007ffff65db675 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555555575950)
at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qcoreapplication.cpp:1821
#10 0x00007ffff662a6d3 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=s@entry=0x5555555fd700)
at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:277
#11 0x00007ffff2c20065 in g_main_dispatch (context=0x7fffdc005000) at ../glib-2.68.4/glib/gmain.c:3337
#12 g_main_context_dispatch (context=0x7fffdc005000) at ../glib-2.68.4/glib/gmain.c:4055
#13 0x00007ffff2c20408 in g_main_context_iterate (context=context@entry=0x7fffdc005000, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>)
at ../glib-2.68.4/glib/gmain.c:4131
#14 0x00007ffff2c204bf in g_main_context_iteration (context=0x7fffdc005000, may_block=1) at ../glib-2.68.4/glib/gmain.c:4196
#15 0x00007ffff662a164 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55555561baa0, flags=...)
at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:423
#16 0x00007ffff65d69fb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fffffffcfd0, flags=..., flags@entry=...)
at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:69
#17 0x00007ffff65df02d in QCoreApplication::exec() () at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:121
#18 0x00007ffff6ae2f7c in QGuiApplication::exec() () at /usr/src/debug/dev-qt/qtgui-5.15.2-r13/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/gui/kernel/qguiapplication.cpp:1867
#19 0x00007ffff722ad25 in QApplication::exec() () at /usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:2824
#20 0x000055555556198e in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at ../app/main.cpp:850
So I believe this is happening because the file is in a subdirectory that is filtered: [Filters][64] inclusive=0 pattern=/drivers/staging targets=2 Some may call this a user error, but I can't afford to have the entire kernel parsed, but if I need to open a file in my filter, I can't have it mis-parsed. So for the sake of parse jobs, can we modify findProjectFileItem() so that if project->filesForPath(url) fails to find a match, we can still look for a project who's root contains the path of the file? This would solve my problem without forcing me to parse the entire kernel -- since that usually results in KDevelop crashing anyway. Created attachment 144169 [details]
very ugly patch
WARNING: very ugly patch ahead! I am in NO WAY suggesting this for merging!
I think some of this might be useful, namely not adding -nostdinc and -nostdinc++ if it's already supplied in the arguments, but mostly not adding the system include paths in such a case. Also, not overriding -working-directory if already in custom parser options.
But if there's a cleaner, prettier way of using the root project's parser settings (or nearest sub-directory) when the file is filtered, then that would be helpful upstream.
+ for (auto project : projects) {
+ const auto root = project->path().path();
+ if (!url.str().startsWith(root))
+ continue;
+ // Do something nice here
|
SUMMARY 16 threads and the Linux kernel sources and I sometimes end up with #include <linux/modules.h> referencing /usr/include/linux/modules.h. All parse jobs run by the background parser seem correct. But when I open a file (in the project) and it's scheduled for immediate parsing, BANG, I see the debug spew using the default arguments. This essential breaks KDevelop as a usable IDE for the Linux kernel sources, because I have to 'git grep' and use elixir.bootlin.com to look up types and functions, since KDevelop can't find them. STEPS TO REPRODUCE 1. KDEV_CLANG_DISPLAY_ARGS=1 KDEV_CLANG_DISPLAY_DIAGS=1 kdevelop 2. Open sources to Linux kernel 3. set custom C parser options based upon building the kernel and sucking out the arguments. In my particular case, I'm cross-compiling and these are my arguments: --target=mipsel-openwrt-linux -mno-check-zero-division -mabi=32 -mno-abicalls -msoft-float -march=mips32r2 -mtune=34kc -std=gnu89 -nostdinc -isystem /home/daniel/proj/embedded/openwrt/v21.02.y/staging_dir/toolchain-mipsel_24kc_gcc-10.2.0_musl/lib/gcc/mipsel-openwrt-linux-musl/10.2.0/include -Iarch/mips/include -Iarch/mips/include/generated -Iinclude -Iarch/mips/include/uapi -Iarch/mips/include/generated/uapi -Iinclude/uapi -Iinclude/generated/uapi -include include/linux/kconfig.h -include include/linux/compiler_types.h -Iarch/mips/include/asm/mach-ralink -Iarch/mips/include/asm/mach-ralink/mt7620 -Iarch/mips/include/asm/mach-generic -D__KERNEL__ -D__MIPSEL__ -DVMLINUX_LOAD_ADDRESS=0xffffffff80000000 -DLINKER_LOAD_ADDRESS=0x80000000 -DDATAOFFSET=0 -DGAS_HAS_SET_HARDFLOAT -DTOOLCHAIN_SUPPORTS_VIRT -DTOOLCHAIN_SUPPORTS_XPA -DTOOLCHAIN_SUPPORTS_CRC -DTOOLCHAIN_SUPPORTS_DSP -DTOOLCHAIN_SUPPORTS_GINV -ferror-limit=99 -fspell-checking -Wdocumentation -Wall -Wundef -Wno-trigraphs -Wno-format-security -Wno-frame-address -Wno-address-of-packed-member -Wframe-larger-than=1024 -Wimplicit-fallthrough -Wno-unused-const-variable -Wdeclaration-after-statement -Wvla -Wno-pointer-sign -Wno-array-bounds -Wno-uninitialized -Wno-incompatible-library-redeclaration -Wno-unknown-warning-option -Wno-implicit-fallthrough -working-directory /home/daniel/proj/embedded/openwrt/linux-5.4.143 Actually, for this to even work, I had to hack kdvelop and stop it from inserting a -working-directory argument, but I can probably just change all of my include paths to absolute and not have that problem. 4. let it start parsing and notice it's correct 5. Open a file and notice that it's incorrect (it parsed with the default options). 6. If I allow all parsing to complete before opening any files, then they are correct until some point later after editing enough. I haven't seen it incorrectly parse a file after making changes (yet) only after initially opening it (before background parsing has completed). I don't know if this is a race or not. I'm on a 8/16 Ryzen and using 16 parsing threads and 500ms delay. I've tried digging into the KDevelop sources, and I got as as finding where the job is run and where the job is scheduled. Job run from: (gdb) bt #0 ParseSessionData::ParseSessionData (this=this@entry=0x7fff39085260, unsavedFiles=..., index=index@entry=0x5555569dbb70, environment=..., options=..., options@entry=...) at ../plugins/clang/duchain/parsesession.cpp:272 #1 0x00007fff47b68213 in ClangParseJob::createSessionData (this=this@entry=0x555557c10270) at /usr/src/debug/dev-util/kdevelop-5.6.2/kdevelop-5.6.2/plugins/clang/clangparsejob.cpp:394 #2 0x00007fff47b69bcc in ClangParseJob::run (this=<optimized out>) at /usr/src/debug/dev-util/kdevelop-5.6.2/kdevelop-5.6.2/plugins/clang/clangparsejob.cpp:300 #3 0x00007ffff2bb8f99 in ThreadWeaver::IdDecorator::run (this=<optimized out>, self=..., thread=0x555556ac2350) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/iddecorator.cpp:50 #4 0x00007ffff2bb9597 in ThreadWeaver::Executor::run (this=<optimized out>, job=..., thread=<optimized out>) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/executor.cpp:33 #5 0x00007ffff2bb8580 in ThreadWeaver::Job::execute (this=<optimized out>, self=..., th=0x555556ac2350) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/job.cpp:64 #6 0x00007ffff2bb7d82 in ThreadWeaver::Thread::run (this=0x555556ac2350) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/thread.cpp:98 #7 0x00007ffff6420c56 in QThreadPrivate::start (arg=0x555556ac2350) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/thread/qthread_unix.cpp:329 #8 0x00007ffff34e9e21 in start_thread (arg=0x7fff3ffff640) at pthread_create.c:481 #9 0x00007ffff6066b3f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 job schedule from: (gdb) where #0 ThreadWeaver::Weaver::enqueue (this=0x555555b9a450, jobs=...) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/weaver.cpp:204 #1 0x00007ffff2bb3c45 in ThreadWeaver::Queue::enqueue (jobs=..., this=0x555555dc3eb8) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/queue.cpp:169 #2 ThreadWeaver::Queue::enqueue (this=this@entry=0x555555dc3eb8, job=...) at /usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/queue.cpp:174 #3 0x00007ffff4f77870 in KDevelop::BackgroundParserPrivate::parseDocumentsInternal (this=this@entry=0x555555dc3e40) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:331 #4 0x00007ffff4f7270c in KDevelop::BackgroundParser::parseDocuments (this=0x555555d97d10) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:678 #5 0x00007ffff4f72a0f in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KDevelop::BackgroundParser::*)()>::call(void (KDevelop::BackgroundParser::*)(), KDevelop::BackgroundParser*, void**) (arg=<optimized out>, o=<optimized out>, f=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:152 #6 QtPrivate::FunctionPointer<void (KDevelop::BackgroundParser::*)()>::call<QtPrivate::List<>, void>(void (KDevelop::BackgroundParser::*)(), KDevelop::BackgroundParser*, void**) (arg=<optimized out>, o=<optimized out>, f=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:185 #7 QtPrivate::QSlotObject<void (KDevelop::BackgroundParser::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=<optimized out>, this_=<optimized out>, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:418 #8 0x00007ffff66099b6 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffccc0, r=0x555555d97d10, this=0x555555c9af30) at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobjectdefs_impl.h:398 #9 doActivate<false> (sender=0x555555dc3e60, signal_index=3, argv=0x7fffffffccc0) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:3886 #10 0x00007ffff6603717 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7ffff68afca0 <QTimer::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffccc0) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:3946 #11 0x00007ffff660db0a in QTimer::timeout (this=<optimized out>, _t1=...) at .moc/moc_qtimer.cpp:205 #12 0x00007ffff66017bf in QObject::event (this=0x555555dc3e60, e=0x7fffffffce10) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:1336 #13 0x00007ffff7228daf in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x555555dc3e60, e=0x7fffffffce10) at /usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:3632 #14 0x00007ffff65d6008 in QCoreApplication::notifyInternal2 (receiver=0x555555dc3e60, event=0x7fffffffce10) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qcoreapplication.cpp:1064 #15 0x00007ffff662748b in QTimerInfoList::activateTimers (this=0x5555555ebcb0) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qtimerinfo_unix.cpp:643 #16 0x00007ffff6627d91 in timerSourceDispatch (source=<optimized out>) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:183 #17 idleTimerSourceDispatch (source=source@entry=0x5555555fd670) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:230 #18 0x00007ffff2c20065 in g_main_dispatch (context=0x7fffdc005000) at ../glib-2.68.4/glib/gmain.c:3337 #19 g_main_context_dispatch (context=0x7fffdc005000) at ../glib-2.68.4/glib/gmain.c:4055 #20 0x00007ffff2c20408 in g_main_context_iterate (context=context@entry=0x7fffdc005000, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib-2.68.4/glib/gmain.c:4131 #21 0x00007ffff2c204bf in g_main_context_iteration (context=0x7fffdc005000, may_block=1) at ../glib-2.68.4/glib/gmain.c:4196 #22 0x00007ffff6628164 in QEventDispatcherGlib::processEvents (this=0x55555561b7f0, flags=...) at /usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:423 #23 0x00007ffff65d49fb in QEventLoop::exec (this=this@entry=0x7fffffffd050, flags=..., flags@entry=...) at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:69 #24 0x00007ffff65dd02d in QCoreApplication::exec () at ../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:121 #25 0x00007ffff6ae2f7c in QGuiApplication::exec () at /usr/src/debug/dev-qt/qtgui-5.15.2-r13/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/gui/kernel/qguiapplication.cpp:1867 #26 0x00007ffff7228d25 in QApplication::exec () at /usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:2824 #27 0x000055555556198e in main (argc=<optimized out>, argv=<optimized out>) at ../app/main.cpp:850 (gdb) frame #3 0x00007ffff4f77870 in KDevelop::BackgroundParserPrivate::parseDocumentsInternal (this=this@entry=0x555555dc3e40) at ../kdevplatform/language/backgroundparser/backgroundparser.cpp:331 331 m_parseJobs.insert(url, decorator); I was examining the ClangParseJob ctor, as that seems to be where the m_environment data is read from one place and passed to another, but I'm out of time and I have to get back to fixing kernel code w/o a good IDE / parser :( I'm probably just going to build a hacked version of kdvelop that has my settings hard-coded so that I can resume with my job (which right now is to fix a silly OpenWRT/kernel bug). Then I'll only run that version for kernel hacking. OBSERVED RESULT Some files parsed with incorrect settings, making it 92% useless as a code navigator. EXPECTED RESULT Never look at /usr/include when I have -nostdinc -isystem/my/path, etc. (Linux kernel implements it's own subset of standard C library, so there's never an external libc.) SOFTWARE/OS VERSIONS Windows: sucks macOS: Linux/KDE Plasma: 5.6.2 (available in About System) KDE Plasma Version: KDE Frameworks Version: Qt Version: ADDITIONAL INFORMATION Caveats: I should probably open an additional bug report for: 1. Do not add -working-directory to clang parser arguments when the argument is already present. Alternatively, allow user to select if cwd will be the project root or the directory of the file being parsed. I should probably open a new feature requests for: 1. Option to suppress clang parser from adding "-nostdinc -isystem/usr/include" (very important for kernel hacking) 2. Option to suppress or override clang parser from adding "-isystem/path/to/clang/headers" (less important) 3. Facilitate relative paths so that a kdevelop project file can be put in source control and work in different directories. If any developers are interested, I am willing to tar up my entire working tree for experimentation. Thanks!