For all the value-added provided by cdt.core -- semantic highlighting, outlines, code navigation, etc. -- it needs to be able to correctly parse the C/C++ source files. To do this it needs to know, per compilation unit (source file), the #define'd preprocessor Macros and the Include search paths to use.
Fundamentally cdt.core doesn't (shouldn't) care where this metadata comes from. Be it managed build, ScannerDiscovery/build output parsing, dwarf or whatever.
Maintain the split between functionality provided by the build system and API provided by cdt.core. The API provided by cdt.core should provide methods for getting and setting the includes and macros per source file, and should be responsible for storing these settings. This API would be used by: scanner discovery, managed build, and contributors.
- The existing UI (Paths & Symbols dialog) can be used by users to edit the full set of contributed paths.
- In this world scanner discovery isn't special, it's merely another source of per-file metadata.
Reduce the complexity of scanner discovery. Scanner discovery should do one thing and one thing well: parse build output and provide a collection of includes path and macros. It *shouldn't* also store this metadata, and somehow try to maintain consistency between cdt.core model (as configurations change) as the set of macros it thinks are defined.
Make it easier for contributors to contribute their own paths and symbols -- everyone's a first class citizen.
Simplify the code. Remove the arbitrary dependency relationship between all the actors that currently exists. All contributors can be treated as black boxes contributing their paths and includes back into cdt.core.
A split in the functionality will increase testability. The break in the API between discovery and storage is natural, and can be easily unit tested. The build output parsers can also be easily unit tested.