-
Notifications
You must be signed in to change notification settings - Fork 259
M-x company-diag
, make sureUsed backend:
includes company-lsp
.
There are at least three sets of implicit include paths. They take effect without your -I
option in .ccls
or compile_commands.json
// a.cc
// system C header, usually in /usr/include
#include <stdio.h>
// system C++ header. The location varies among distributions, e.g. /usr/include/c++/{6,7.2.1}
#include <new>
// In Clang resource directory lib/clang/7.0.0, lib/clang/7.0.0/include/stddef.h
#include <stddef.h>
Put a.cc
in some directory with echo clang++ > .ccls
. Open the file, you should be able to jump to stdio.h
new
stddef.h
when you trigger textDocument/definition
on the include lines.
Note that this might not work on Windows. To solve this, add the system include directories to compile_commands.json via your build system of choice using the INCLUDE environment variable (available after executing VsDevCmd.bat).
For CMake this can be achieved in a single line: target_include_directories(<target> SYSTEM PRIVATE $ENV{INCLUDE})
Check Clang_EXECUTABLE
in your CMakeCache.txt
. The output of command $Clang_EXECUTABLE -print-resource-dir
will be passed to -DDEFAULT_RESOURCE_DIRECTORY
. Make sure you can locate include/stddef.h
in the resource directory.
Read Initialization options how to set "cacheFormat": "json"
.
If "cacheDirectory": "/tmp/ccls"
, and the source file is /tmp/c/a.cc
,
run jq . < /tmp/ccls/@tmp@c/a.cc.json
to see if -resource-dir
is correct, e.g. "-resource-dir=/home/ray/ccls/Debug/lib/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/lib/clang/6.0.0"
ccls infers system search paths (e.g. /usr/include
). The underneath mechanism is similar to that of clang -v -E -x c++ /dev/null
.
-isystem
system include paths is usually unnecessary. But for cross compiling or on some bizarre system you may have to specify them. A simple approach other than trial and error (changing .ccls
and restarting your editor) is to use c-index-test
.
Debug/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/c-index-test -index-file local /tmp/c/a.cc -isystem/usr/include/c++/7.3.0 -isystemyour_include_path2
Play with your -isystem
options until you get a group of options that you can add to .ccls
If you want the ccls binary at a specific location use a symlink - do not move the binary itself.
If you want to specify additional search paths:
print '%clang\n%cpp -std=gnu++17\n-isystem/tmp/include' > .ccls
- emacs-ccls:
(setq ccls-extra-init-params '(:clang (:extraArgs ["-isystem", "/tmp/include"])))
In C++17 mode, it is possible to cause clang to crash when bits/unordered_map.h
is indexed.
See https://bugs.llvm.org/show_bug.cgi?id=37695 for details.
The workaround is to add -D__cpp_deduction_guides=0 -Wno-macro-redefined
to the initialization option clang.extraArgs
In Emacs, it is:
(setq ccls-extra-init-params
'(:clang (:extraArgs ("-D__cpp_deduction_guides=0" "-Wno-macro-redefined"))))
emacs-ccls locates the project root with ccls-project-root-matchers
:
-
.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.
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.
proj
.ccls-root # Use this file if you want subproject files to be associated with the root project
compile_commands.json
subproj0 # without .ccls-root, files will be associated with this root directory
.git
subproj1
.git
When indexing ccls itself, some files require more than 1000 file descriptors. Remember to increase RLIMIT_NOFILE
.
ulimit -n 32768
/etc/security/limits.conf
:
* hard nofile 32768
* soft nofile 32768
Here is an example.
include/a.h
:
int bad;
a.cc
:
int main(){return bad;}
.ccls
:
%clang
%cpp -std=gnu++14
-Iinclude
ccls will save a file in cacheDirectory
:
jq . < /tmp/ccls/@tmp@c/a.cc.json
15
{
"last_modification_time": 1520737513,
"language": 1,
"import_file": "/tmp/c/a.cc",
"args": [
"clang++",
"-working-directory=/tmp/c",
"-std=gnu++14",
"-Iinclude",
"/tmp/c/a.cc",
"-resource-dir=/home/maskray/Dev/Util/ccls/build/debug/lib/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04/lib/clang/6.0.0",
"-Wno-unknown-warning-option",
"-fparse-all-comments"
],
"includes": [
{
"line": 0,
"resolved_path": "/tmp/c/include/a.h"
}
],
"dependencies": [
"/tmp/c/include/a.h"
],
...
textDocument/definition
can be used in many places. Some are current implementation details and may subject to change.
-
void foo();
A declaration jumps to the definition -
void foo() {}
The definition lists all declarations -
A a;
For variables of custom types, besides declarations of the variable, both the type and the variable jump to the declaration/definition of its typeA
-
class C {
jumps to declarations (and constructors/destructors) -
a.field
jumps to the member in the struct declaration -
#include <map>
jumps to the header -
std::string a = "a";
takes you to the constructor. Many implicit constructors can also be jumped in this way. -
a == b
operator==
for user defined operators -
namespace ns {
find original or extension namespaces -
// ns::foo
in comments, it recognizes the identifier around the cursor, approximately finds the best matching symbol and jumps to it; onns
, it jumps to the namespace
-
#include <iostream>
lists all#include
lines in the project pointing to the included file -
[](){}
lists all(?) lambda expressions thanks to implicitstd::function
move constructor -
extern int a;
IfReferenceContext.includeDeclaration
is true, the definition and declarations are also listed. - If no references is found but the point is on the first line, list
#include
lines referencing current file.
-
struct A:B{void f()override;};
listsB
orB::f()
-
struct B{virtual void f();};
derived classes or virtual function overrides
-
A a;
lists all instances of user-definedA
. -
int i;
lists all instances ofint
.
(ccls-call-hierarchy nil) ; caller hierarchy
(ccls-call-hierarchy t) ; callee hierarchy
(ccls-inheritance-hierarchy nil) ; base hierarchy
(ccls-inheritance-hierarchy t) ; derived hierarchy
Recursively list members of a record type. 😂 nobody has implemented vscode-ccls UI for the feature. Help wanted!