Add header guard

Fangrui Song 2018-11-10 16:18:27 -08:00
parent 700c423954
commit e5ec341a55

39
FAQ.md

@ -60,13 +60,13 @@ In Emacs, it is:
### Project root detection ### Project root detection
[emacs-ccls](https://github.com/MaskRay/emacs-cquery/) locates the project root with `ccls-project-root-matchers`: [emacs-ccls](https://github.com/MaskRay/emacs-cquery/) locates the project root in the following order:
* `.ccls-root`. If this file exists in any parent directory, that directory is treated as the project root. * `.ccls-root`. If this file exists in any parent directory, that directory is treated as the project root.
* `(projectile-project-root)`. Then this function is called. You likely don't want `/usr/include/c++/8/algorithm` to be treated as in the project `/usr/include/c++/8/`, `(setq projectile-require-project-root t)` inhibits the behavior. * `(lsp--suggest-project-root)` which in turn calls `(projectile-project-root)`. Usually you don't want `/usr/include/c++/8/algorithm` to be treated as in the project `/usr/include/c++/8/`, `(setq projectile-require-project-root t)` inhibits the behavior.
The root directory is sent to ccls (the language server) through the `rootUri` field in the `initialize` request. The root directory is sent to ccls (the language server) through the `rootUri` field in the `initialize` request.
ccls finds `.ccls` or `compile_commands.json` in the directory. ccls reads `.ccls` or `compile_commands.json` in the directory. If neither exists, ccls fallbacks to `%clang $path`.
``` ```
proj proj
@ -80,7 +80,7 @@ proj
### Maximum number of file descriptors ### Maximum number of file descriptors
When indexing ccls itself, some files require more than 1000 file descriptors. Remember to increase `RLIMIT_NOFILE`. Some projects may require more than 1000 file descriptors. Remember to increase `RLIMIT_NOFILE`.
```zsh ```zsh
ulimit -n 32768 ulimit -n 32768
@ -143,6 +143,37 @@ ccls will save a file in `cacheDirectory`:
... ...
``` ```
### Diagnostics in headers
For efficiency, headers are compiled on their own (as if `clang [options] a.h`) to utilize Clang's preamble optimization.
For headers that are not self-contained (e.g. some `/usr/include/bits/*.h` which require a predefined macro) ccls emits diagnostics that you don't see when building the project.
```c
// a.c
#define M
#include "a.h"
// a.h
#ifndef M
#error M not defined
#endif
```
One approach ccls explored before was to compile its import file `a.c`, but it caused severe performance issue for some projects.
For smaller files this does not matter and checking for a header guard may help the situation.
### Multi-version headers
A header can be included in different translation units with different compiler flags. It may behave differently via `#ifdef`.
Ideally there should be some mechanism to switch among different views (compiler flags) when you are editing the file.
For efficiency, a header is only indexed with one set of compiler flags, so either the `#if` block or `#else` is indexed, the other is left blank.
For macros, there is code to track different usage, thus you may find them able to jump to multiple targets.
`index.multiVersion` is an experimental option to index every version to certify that the author is aware of this issue :)
It may not be very useful though. It is of type `number` but not `boolean` as the author is also aware of other dimensions of the multi-version problem.
### Definitions ### Definitions
`textDocument/definition` can be used in many places. Some are current implementation details and may subject to change. `textDocument/definition` can be used in many places. Some are current implementation details and may subject to change.