Created attachment 108661 [details] Bug report illustration KDevelop C++ code completion does not respect user defined system-wide include directories in CMake projects. Please see attached illustration video. *How to reproduce?* 1. Open attached sample project. 2. Build it. 3. Open file "SampleLibraryStuff.cpp" 4. On top of that file try to type "#include <My" 5. Press Ctrl+Space to force invoke auto completion. *What happens?* KDevelop just proposes operating system wide files/folders along with automatic word completion. *Expected behavior?* KDevelop should propose "MyNamespace" directory (user defined system wide include) first along with other matches. *Notes:* - Please note the angle bracket "<" which is supposed to be for system wide includes. The local project related includes works well. - The user defined system wide include directory is specified in CMakeLists.txxt by target_include_directory command argument SYSTEM PUBLIC - for details please see attached sample project. - My system is using Clang 5.x, CMake 3.8 with server support, KDevelop 5.1.80.
Created attachment 108662 [details] Sample project required to reproduce reported behavior.
I tested KDevelop 5.2.0 from Neon packages today and it still do not work properly.
Hm, actually I don't think we have a concept of adding system includes from projects at all, so this is not super simple to fix. I see how it's a minor problem in some specific situations, though.
I did not dig into details (yet) however I was thinking that as long as KDevelop is using Clang as backend for C++ language support (code completion & friends), it does not play a role. I mean, if the Clang call for particular project/file is using proper flags/parameters, then KDevelop should receive proper expansion/evaluation of the completion query. Or am I completely wrong?
It's not that simple, we can retrieve information from the build system but we assemble the compiler command line ourselves. We also add your hand-configured includes etc. and that code, from a quick look, simply doesn't have a way to add system includes.
Ok, I got it. I have observation that in some cases when the include is already written e.g. ```code #include <MyNamespace/MyInclude.hpp> ``` The included file can be "clicked-through" (Ctrl+LMB on the included file) which will open the file. Is this evaluated by different process/principle? This observation gives me still some home.. :-)
I think the thing is that clang simply doesn't suggest local includes (specified with -I) when typing #include < even though the resulting code would still be compiling. Since we specify all your includes with -I (I think) the analyzer doesn't complain, but doesn't suggest the completions either.
Is there a way how I can help? I cloned KDevelop just for fun and learning, trying to find out how is designed. Later after some difficulties also compiled it. Are there any design diagrams (sysml/uml/or just ideas on paper)?
If you want to fix this, I think you need to do three things: 1) add an API function systemIncludes() to IDefinesAndIncludesManager 2) in MakeFileResolver::processOutput, differentiate -I and -isystem (like it differentiates -I and -iframework already) 3) Refactor how appendPaths() works in ClangParsingEnvironment, because it currently assumes "everything in the project dir is a non-system include". All this is just from a quick look and could be wrong ... but it would be very nice if you want to have a look at this!
Uhm sorry to interrupt, but the gif shows an issue that has nothing do with clang. It's our custom include path code completion. seems like that is not querying for (all) the include paths and thus misses one? Should be easy to fix, since it doesn't involve clang ;-)
Oh, sorry, I thought clang was completing this. Thanks for the interruption. I still think IDAIM not making this differentation is something that should be fixed eventually.
@sven: Yes, but that's unrelated to the bug shown here. Its impact would only be marginal anyways, as it only affects the diagnostics and nothing else (i.e. some diagnostics are ignored in system headers).
ok, the bug really is trivial to fix - we currently ignore system paths for local completion (#include "...") and vice versa ignore project paths for global completion (#include <...>). That is plain wrong.
Git commit 015141e38b795b6c8ff9fe616e87cf0a55065406 by Milian Wolff. Committed on 18/11/2017 at 18:07. Pushed by mwolff into branch '5.2'. kdev-clang: Offer all include paths for code completion We used to only offer code completion of project paths for local code completion in `#include "..."` contexts. And for vice versa, we only offered system paths for global code completion in `#include <...>` contexts. This is wrong, as the include style only changes the order in which a compiler iterates through these paths to find an include file. For code completion purposes, this is not important. Now we offer code completion in both path lists always. To show the user the right file/dir being included, we don't sort and unify the search path list anymore as that potentially changes the final result. Rather, we use a hash set to ensure we don't encounter paths multiple times and iterate over the search path lists in their original order. M +18 -9 plugins/clang/codecompletion/includepathcompletioncontext.cpp M +1 -1 plugins/clang/tests/test_codecompletion.cpp https://commits.kde.org/kdevelop/015141e38b795b6c8ff9fe616e87cf0a55065406
I did compile the commit 015141e38b795b6c8ff9fe616e87cf0a55065406 and I can confirm that now it works. Even with the simplification described in the commit message, it works for my everyday work. In the meantime I did started learning how it works while trying to fix it. It helped me understand some part of KDevelop. Thank you all!