Warning: This page is a work in progress (it started as a simple response on bugzilla). It is not well structured yet but might still contain useful information.
In case of semantic errors reported such as "Symbol 'foo' could not be resolved" ...
Diagnosing the index
Doing a manual rebuild of the index will output a useful report in the view Error Log (the view comes by default with the Eclipse for C/C++ package but might not be in your CDT installation depending how you got it), you can also find the same report in your workspace log file under "your_workspace/.metadata/.log" file. To rebuild the index, right-click on the project > Index > Rebuild.
!MESSAGE Indexed 'mariadb-server' (1,784 sources, 3,493 headers) in 505 sec: 688,918 declarations; 4,042,030 references; 11 unresolved inclusions; 411 syntax errors; 66,635 unresolved names (1.4%)
Your goal should be to make the "unresolved names" number as low as possible. I would recommend to try to get it below 0.01% but your level of tolerance for inaccuracies might vary (although remember that your level of confidence in the index will be affected and you might start making bad programming decisions based on inaccurate results).
First, you should check if there are any unresolved includes as these tend to produce a lot of unresolved symbols. To reduce the noise for the number of unresolved inclusions (and names), you can set the Indexer preference to disable "Index unused headers" and disable "Index source builds not included in the build". Doing so will limit your the possibility your you to do code completion on headers never used before (for example) but it will help you get a better picture. Then rebuild the index (as described above) to get an updated report (you might want do this after every configuration change you make to track your progress).
You can see the list of unresolved includes by right-clicking on a project > Index > Search for Unresolved Includes.
You can also use the view "Include Browser" to help you understand what the indexer sees as header dependencies. If an include path is missing, see the section further.
There is no easy way to display *all* unresolved symbols within in a project in the UI but you can enable tracing of them using a .options file (or enabling the equivalent in the Tracing tab if you are setup for CDT development and check the Console view of your Eclipse SDK). You should enable "org.eclipse.cdt.core/debug" and "org.eclipse.cdt.core/debug/indexer/problems"
Here is an example .options file. Start ./eclipse -debug (in a terminal) with the .options in the working directory or specify its path with ./eclipse -debug /path/to/.options. (use eclipsec.exe on Windows)
The you can just rebuild the index to get a possibly huge output with lines such as:
Indexer: unresolved name at /Users/malaperle/git/lldb-mi/src/MIUtilVariant.cpp(126); Attempt to use symbol failed: MIunused ...
Then, you can inspect the headers to see if the unresolved symbols of interest are not in inactive preprocessor regions. If they are in inactive regions but should be active, it's possible that you are missing some defined macros, commonly either from the build output parsing or the detection of built-in macros (those are the typical sources that feed the indexer but there can be others).
To see if the indexer is truly missing macros or includes, you can create a parser log, by right-clicking on a source file (not header) > Index > Create Parser log file. You can see there if the macros and include paths you expect are there.
Tweaking language entries
How to troubleshoot missing macros or include paths will depend on the type of project you created. If you created a managed build project (TODO: explain which one that is), you should start by checking project properties > C/C++ General > Preprocessor Include Paths, macros. Under the entries tab, check that the entries are what you expect. On Linux, I would expect you have the "CDT GCC Build-in Compiler Settings" enabled. For this one, a common problem is that the -std flag is not passed. You can just add/hard-code it in the configuration of this provider under the "Provider" tab next to Entries. Any other flags that affect built-in macros might be important here but -std is usually the biggest culprit.
If you rely on the build output to parse macros/include paths, you should redo the same exercise and open the properties dialog on the problematic source file (not the project) but instead look at the entries under the provider called "CDT GCC Build Output Parser". If they are not what you expect, double check the configuration of this provider, for example, the regex might not parse a gcc command with a custom name.
If all macros and include paths look OK in the parser log, there are further possibilities. If the unresolved symbol is in the middle of a syntax error, it might be because of missing macros being parsed as regular identifiers but it could also be a bug or something not implemented in the parser. See #Important limitations If the unresolved symbol's declaration depends on another unresolved symbol, the dependency should be solved first and so on.
Troubleshooting individual errors
- Language support is not nearly complete. In fact, at the time of this writing, C99, C++14, C++17, etc and later are not fully supported. Expect parsing errors due to this resulting in many different symptoms (syntax errors, symbols not found, etc). Support for new feature is not expected to improve drastically as the community is now small and efforts are put on language servers such as Clangd.
- By default, the indexer only indexes *one variant* of a given header, if it detects "pragma-once semantics" (#pragma once of #ifndef FOO_H). If a header is meant to be included differently multiple times and it should declare new symbols, you might need to tell the indexer to explicitly to index all variants of this header. You can do so in the indexer preferences. Be aware that indexing all variants (especially of all headers) will incur a huge performance cost so this should be done sparingly.
- The index cannot maintain different typedefs with the same name. See bug 337583. You can sometimes work around this by strategically excluding files you don't care about in combination with disabling the indexer preference "Index source builds not included in the build".
- Countless other bugs: See Bugzilla
Using Oomph might be the quickest way to get started.
Classes of interest
- org.eclipse.cdt.internal.core.dom.parser.ProblemBinding: When you have a "Symbol 'foo' could not be resolved" error, put a breakpoint in the constructors of this class and you can work your way back in the stack where/why the parsing produced this.
- org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor.executeInclude: This method is where the CDT preprocessor handles #include. This can be a useful starting point if you want to debug why a header is not resolved or the wrong one is included or skipped, etc.