Git Product home page Git Product logo

clangd's Introduction

clangd

clangd is a language server, and provides C++ IDE features to editors. This is not its documentation.

Communication channels

If you have any questions or feedback, you can reach community and developers through one of these channels:

clangd's People

Contributors

ceron257 avatar dependabot[bot] avatar ho-cooh avatar hokein avatar kadircet avatar kirillbobyrev avatar sam-mccall avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clangd's Issues

Duplicate TextEdit in textDocument/rename response

Hello,

while refactoring ycmd's LSP client code, we wrote a test for clangd that sendstextDocument/rename request on a simple file. Instead of 4 unique TextEdits, clangd returned 5 with 3rd one duplicated

The exchanged messages, from the ycmd's side:

2019-01-20 13:06:44,206 - DEBUG - TX: Sending message: b'Content-Length: 528\r\n\r\n{"id": "1", "jsonrpc": "2.0", "method": "initialize", "params": {"capabilities": {"textDocument": {"completion": {"completionItemKind": {"valueSet": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]}}}}, "initializationOptions": {}, "processId": 7882, "rootPath": "/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata", "rootUri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata"}}'
2019-01-20 13:06:44,207 - DEBUG - RX: Received message: b'{"id":"1","jsonrpc":"2.0","result":{"capabilities":{"codeActionProvider":true,"completionProvider":{"resolveProvider":false,"triggerCharacters":[".",">",":"]},"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"}","moreTriggerCharacter":[]},"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"executeCommandProvider":{"commands":["clangd.applyFix"]},"hoverProvider":true,"renameProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"textDocumentSync":2,"workspaceSymbolProvider":true}}}'
2019-01-20 13:06:44,207 - DEBUG - TX: Sending notification: b'Content-Length: 57\r\n\r\n{"jsonrpc": "2.0", "method": "initialized", "params": {}}'
2019-01-20 13:06:44,207 - DEBUG - TX: Sending notification: b'Content-Length: 92\r\n\r\n{"jsonrpc": "2.0", "method": "workspace/didChangeConfiguration", "params": {"settings": {}}}'
2019-01-20 13:06:44,207 - DEBUG - TX: Sending notification: b'Content-Length: 546\r\n\r\n{"jsonrpc": "2.0", "method": "textDocument/didOpen", "params": {"textDocument": {"languageId": "cpp", "text": "struct Foo {\\n  int x;\\n  int y;\\n  char c;\\n};\\n\\nint main()\\n{\\n  Foo foo;\\n  // The location after the dot is line 11, col 7\\n  foo.\\n}\\n\\n\\nstatic Foo test_function_that_has_no_errors()\\n{\\n  Foo foo = { 1,2,\'c\'};\\n  if (foo.c ) {\\n    foo.x = 1;\\n    foo.y = 2;\\n  }\\n\\n  return foo;\\n}\\n", "uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp", "version": 1}}}'
2019-01-20 13:06:44,213 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"message":"expected unqualified-id","range":{"end":{"character":1,"line":11},"start":{"character":0,"line":11}},"severity":1}],"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp"}}'
2019-01-20 13:07:15,050 - DEBUG - TX: Sending message: b'Content-Length: 276\r\n\r\n{"id": "2", "jsonrpc": "2.0", "method": "textDocument/rename", "params": {"newName": "Bar", "position": {"character": 3, "line": 16}, "textDocument": {"uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp"}}}'
2019-01-20 13:07:15,051 - DEBUG - RX: Received message: b'{"id":"2","jsonrpc":"2.0","result":{"changes":{"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp":[{"newText":"Bar","range":{"end":{"character":10,"line":0},"start":{"character":7,"line":0}}},{"newText":"Bar","range":{"end":{"character":5,"line":8},"start":{"character":2,"line":8}}},{"newText":"Bar","range":{"end":{"character":10,"line":14},"start":{"character":7,"line":14}}},{"newText":"Bar","range":{"end":{"character":10,"line":14},"start":{"character":7,"line":14}}},{"newText":"Bar","range":{"end":{"character":5,"line":16},"start":{"character":2,"line":16}}}]}}}'
2019-01-20 13:07:15,060 - DEBUG - TX: Sending notification: b'Content-Length: 549\r\n\r\n{"jsonrpc": "2.0", "method": "textDocument/didChange", "params": {"contentChanges": [{"text": "struct Bar {\\n  int x;\\n  int y;\\n  char c;\\n};\\n\\nint main()\\n{\\n  Bar foo;\\n  // The location after the dot is line 11, col 7\\n  foo.\\n}\\n\\n\\nstatic Bar test_function_that_has_no_errors()\\n{\\n  Bar foo = { 1,2,\'c\'};\\n  if (foo.c ) {\\n    foo.x = 1;\\n    foo.y = 2;\\n  }\\n\\n  return foo;\\n}\\n"}], "textDocument": {"uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp", "version": 2}}}'
2019-01-20 13:07:15,565 - DEBUG - RX: Received message: b'{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"diagnostics":[{"message":"expected unqualified-id","range":{"end":{"character":1,"line":11},"start":{"character":0,"line":11}},"severity":1}],"uri":"file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp"}}'

Clangd stderr:

I[13:06:44.206] <-- initialize("1")
I[13:06:44.206] --> reply("1")
I[13:06:44.207] <-- initialized
E[13:06:44.207] Error -32601: method not found
I[13:06:44.207] <-- workspace/didChangeConfiguration
I[13:06:44.207] <-- textDocument/didOpen
I[13:06:44.209] Updating file /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp with command [/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata] clang-tool -xc++ -std=c++11 -iquotequote/ -Isystem/ /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp -resource-dir=/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/clang_includes
E[13:06:44.211] Could not build a preamble for file /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp
I[13:07:15.050] <-- textDocument/rename("2")
I[13:07:15.051] --> reply("2")
I[13:07:15.061] <-- textDocument/didChange
I[13:07:15.561] Updating file /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp with command [/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata] clang-tool -xc++ -std=c++11 -iquotequote/ -Isystem/ /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp -resource-dir=/home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/clang_includes
E[13:07:15.563] Could not build a preamble for file /home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp

The nicely formatted textDocument/rename request:

'{
	"id": "2", 
	"jsonrpc": "2.0", 
	"method": "textDocument/rename", 
	"params": {
		"newName": "Bar", 
		"position": {
			"character": 3, 
			"line": 16
		}, 
		"textDocument": {
			"uri": "file:///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp"
		}
	}
}'

The nicely formatted textDocument/rename response:

'{
	"id": "2",
	"jsonrpc": "2.0",
	"result": {
		"changes": {
			"file: ///home/bstaletic/.vim/pack/bundle/start/YouCompleteMe/third_party/ycmd/ycmd/tests/clangd/testdata/basic.cpp": [
				{
					"newText": "Bar",
					"range": {"end": {"character": 10,"line": 0},"start": {"character": 7,"line": 0}}
				},
				{
					"newText": "Bar",
					"range": {"end": {"character": 5,"line": 8},"start": {"character": 2,"line": 8}}
				},
				{
					"newText": "Bar",
					"range": {"end": {"character": 10,"line": 14},"start": {"character": 7,"line": 14}}
				},
				{
					"newText": "Bar",
					"range": {"end": {"character": 10,"line": 14},"start": {"character": 7,"line": 14}}
				},
				{
					"newText": "Bar",
					"range": {"end": {"character": 5,"line": 16},"start": {"character": 2,"line": 16}}
				}
			]
		}
	}
}'

Clangd doesn't work in files without an extension

Given a file named no_extension with the contents of int x = 5;, upon didOpen there's an error saying Could not build CompilerInvocation for file /home/bstaletic/Temp/sparsehash-c11/no_extension. hover response is {"error":{"code":-32001,"message":"invalid AST"},"id":"2","jsonrpc":"2.0"} and completion response is {"id":"3","jsonrpc":"2.0","result":{"isIncomplete":false,"items":[]}}.

The complete clangd log:

V[21:59:09.337] <<< {"id":"1","jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"completion":{"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]}}}},"initializationOptions":{},"processId":4848,"rootPath":"/home/bstaletic/Temp/sparsehash-c11","rootUri":"file:///home/bstaletic/Temp/sparsehash-c11"}}

I[21:59:09.337] <-- initialize("1")
I[21:59:09.337] --> reply:initialize("1") 0 ms
V[21:59:09.337] >>> {"id":"1","jsonrpc":"2.0","result":{"capabilities":{"codeActionProvider":true,"completionProvider":{"resolveProvider":false,"triggerCharacters":[".",">",":"]},"declarationProvider":true,"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"}","moreTriggerCharacter":[]},"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"executeCommandProvider":{"commands":["clangd.applyFix","clangd.applyTweak"]},"hoverProvider":true,"referencesProvider":true,"renameProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"textDocumentSync":2,"workspaceSymbolProvider":true}}}

V[21:59:09.338] <<< {"jsonrpc":"2.0","method":"initialized","params":{}}

I[21:59:09.338] <-- initialized
I[21:59:09.338] unhandled notification initialized
V[21:59:09.338] <<< {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}

I[21:59:09.338] <-- workspace/didChangeConfiguration
V[21:59:09.339] <<< {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"cpp","text":"auto x = 5;\n","uri":"file:///home/bstaletic/Temp/sparsehash-c11/foo","version":1}}}

I[21:59:09.339] <-- textDocument/didOpen
I[21:59:09.340] Updating file /home/bstaletic/Temp/sparsehash-c11/foo with command [/home/bstaletic/Temp/sparsehash-c11/build/tests] /usr/sbin/clang++ -I/home/bstaletic/Temp/sparsehash-c11/. -I/home/bstaletic/Temp/sparsehash-c11/tests/. -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -O3 -DNDEBUG -O3 -c /home/bstaletic/Temp/sparsehash-c11/foo -resource-dir=/usr/lib/clang/9.0.0
V[21:59:09.343] Ignored diagnostic. /home/bstaletic/Temp/sparsehash-c11/foo: 'linker' input unused
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/.'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/tests/.'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-Wall'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-Wextra'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-Wpedantic'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-Wno-missing-field-initializers'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-O3'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-D NDEBUG'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-O3'
V[21:59:09.343] Ignored diagnostic. argument unused during compilation: '-c'
V[21:59:09.343] Ignored diagnostic. unable to handle compilation, expected exactly one compiler job in ''
E[21:59:09.343] Could not build CompilerInvocation for file /home/bstaletic/Temp/sparsehash-c11/foo
V[21:59:13.216] <<< {"id":"2","jsonrpc":"2.0","method":"textDocument/hover","params":{"position":{"character":5,"line":0},"textDocument":{"uri":"file:///home/bstaletic/Temp/sparsehash-c11/foo"}}}

I[21:59:13.217] <-- textDocument/hover("2")
V[21:59:13.220] Ignored diagnostic. /home/bstaletic/Temp/sparsehash-c11/foo: 'linker' input unused
V[21:59:13.220] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/.'
V[21:59:13.220] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/tests/.'
V[21:59:13.220] Ignored diagnostic. argument unused during compilation: '-Wall'
V[21:59:13.220] Ignored diagnostic. argument unused during compilation: '-Wextra'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-Wpedantic'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-Wno-missing-field-initializers'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-O3'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-D NDEBUG'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-O3'
V[21:59:13.221] Ignored diagnostic. argument unused during compilation: '-c'
V[21:59:13.221] Ignored diagnostic. unable to handle compilation, expected exactly one compiler job in ''
I[21:59:13.221] --> reply:textDocument/hover("2") 4 ms, error: invalid AST
V[21:59:13.221] >>> {"error":{"code":-32001,"message":"invalid AST"},"id":"2","jsonrpc":"2.0"}

V[22:10:25.890] <<< {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"auto x = 5;\n\n"}],"textDocument":{"uri":"file:///home/bstaletic/Temp/sparsehash-c11/foo","version":2}}}

I[22:10:25.890] <-- textDocument/didChange
V[22:10:25.892] <<< {"id":"3","jsonrpc":"2.0","method":"textDocument/completion","params":{"position":{"character":0,"line":1},"textDocument":{"uri":"file:///home/bstaletic/Temp/sparsehash-c11/foo"}}}

I[22:10:25.892] <-- textDocument/completion("3")
V[22:10:25.896] Ignored diagnostic. /home/bstaletic/Temp/sparsehash-c11/foo: 'linker' input unused
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/.'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/tests/.'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-Wall'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-Wextra'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-Wpedantic'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-Wno-missing-field-initializers'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-O3'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-D NDEBUG'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-O3'
V[22:10:25.896] Ignored diagnostic. argument unused during compilation: '-c'
V[22:10:25.896] Ignored diagnostic. unable to handle compilation, expected exactly one compiler job in ''
E[22:10:25.896] Couldn't create CompilerInvocation
I[22:10:25.896] Code complete: 0 results from Sema, 0 from Index, 0 matched, 0 returned.
I[22:10:25.896] --> reply:textDocument/completion("3") 4 ms
V[22:10:25.896] >>> {"id":"3","jsonrpc":"2.0","result":{"isIncomplete":false,"items":[]}}

I[22:10:26.392] Updating file /home/bstaletic/Temp/sparsehash-c11/foo with command [/home/bstaletic/Temp/sparsehash-c11/build/tests] /usr/sbin/clang++ -I/home/bstaletic/Temp/sparsehash-c11/. -I/home/bstaletic/Temp/sparsehash-c11/tests/. -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -O3 -DNDEBUG -O3 -c /home/bstaletic/Temp/sparsehash-c11/foo -resource-dir=/usr/lib/clang/9.0.0
V[22:10:26.396] Ignored diagnostic. /home/bstaletic/Temp/sparsehash-c11/foo: 'linker' input unused
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/.'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-I /home/bstaletic/Temp/sparsehash-c11/tests/.'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-Wall'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-Wextra'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-Wpedantic'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-Wno-missing-field-initializers'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-O3'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-D NDEBUG'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-O3'
V[22:10:26.396] Ignored diagnostic. argument unused during compilation: '-c'
V[22:10:26.396] Ignored diagnostic. unable to handle compilation, expected exactly one compiler job in ''
E[22:10:26.396] Could not build CompilerInvocation for file /home/bstaletic/Temp/sparsehash-c11/foo

Note: Providing a different compile_commands.json or even removing one completely doesn't change the behaviour at all.

Boosting of recent names in switch statements is unhelpful

I was trying to write a switch statement for an enum

enum {
A,
B,
C,
D,
} X;
switch(X) {
  case A:break;
  case B:break;
  case ^
}

was expecting at least alphabetical order, but unfortunately B popsup as first element and makes it hard to find next value. Maybe we should even demote values that we've already seen in switch statements/if else blocks?

clangd crashes in Sema CorrectTypo.

revision: HEAD

reproduce steps:

  1. run clangd with -suggest-missing-includes
  2. edit SwapIfBranches.cpp
  3. type Input.AST.getASTContext().getDi on Line 67 (in SwapIfBranches::execute).
  4. clangd crashes

Stacktrace:

 llvm-upstream/build/../tools/clang/include/clang/Sema/ExternalSemaSource.h:221:0
 #9 0x00000000008f3960 clang::MultiplexExternalSemaSource::CorrectTypo(clang::DeclarationNameInfo const&, int, clang::Scope*, clang::CXXScopeSpec*, clang::CorrectionCandidateCallback&, clang::DeclContext*, bool, clang::ObjCObjectPointerType const*)   llvm-upstream/build/../tools/clang/lib/Sema/MultiplexExternalSemaSource.cpp:322:40
#10 0x0000000000c3dfdb clang::Sema::CorrectTypoDelayed(clang::DeclarationNameInfo const&, clang::Sema::LookupNameKind, clang::Scope*, clang::CXXScopeSpec*, std::unique_ptr<clang::CorrectionCandidateCallback, std::default_delete<clang::CorrectionCandidateCallback> >, std::function<void (clang::TypoCorrection const&)>, std::function<clang::ActionResult<clang::Expr*, true> (clang::Sema&, clang::TypoExpr*, clang::TypoCorrection)>, clang::Sema::CorrectTypoKind, clang::DeclContext*, bool, clang::ObjCObjectPointerType const*)   llvm-upstream/build/../tools/clang/lib/Sema/SemaLookup.cpp:4879:36
#11 0x0000000000bd2fb0 LookupMemberExprInRecord(clang::Sema&, clang::LookupResult&, clang::Expr*, clang::RecordType const*, clang::SourceLocation, bool, clang::CXXScopeSpec&, bool, clang::SourceLocation, clang::TypoExpr*&)   llvm-upstream/build/../tools/clang/lib/Sema/SemaExprMember.cpp:699:16
#12 0x0000000000bd345d LookupMemberExpr(clang::Sema&, clang::LookupResult&, clang::ActionResult<clang::Expr*, true>&, bool&, clang::SourceLocation, clang::CXXScopeSpec&, clang::Decl*, bool, clang::SourceLocation)   llvm-upstream/build/../tools/clang/lib/Sema/SemaExprMember.cpp:1281:9
#13 0x0000000000bd2970 clang::Sema::BuildMemberReferenceExpr(clang::Expr*, clang::QualType, clang::SourceLocation, bool, clang::CXXScopeSpec&, clang::SourceLocation, clang::NamedDecl*, clang::DeclarationNameInfo const&, clang::TemplateArgumentListInfo const*, clang::Scope const*, clang::Sema::ActOnMemberAccessExtraArgs*) 
#14 0x0000000000bd8c34 clang::Sema::ActOnMemberAccessExpr(clang::Scope*, clang::Expr*, clang::SourceLocation, clang::tok::TokenKind, clang::CXXScopeSpec&, clang::SourceLocation, clang::UnqualifiedId&, clang::Decl*)   llvm-upstream/build/../tools/clang/lib/Sema/SemaExprMember.cpp:1710:20
#15 0x000000000145e415 clang::Parser::ParsePostfixExpressionSuffix(clang::ActionResult<clang::Expr*, true>)   llvm-upstream/build/../tools/clang/lib/Parse/ParseExpr.cpp:1834:23
#16 0x0000000001463f64 clang::Parser::ParseCastExpression(bool, bool, bool&, clang::Parser::TypeCastState, bool)   llvm-upstream/build/../tools/clang/lib/Parse/ParseExpr.cpp:1466:9
#17 0x000000000145c75d clang::Parser::ParseCastExpression(bool, bool, clang::Parser::TypeCastState, bool)   llvm-upstream/build/../tools/clang/lib/Parse/ParseExpr.cpp:535:20
#18 0x000000000145c75d clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState)   llvm-upstream/build/../tools/clang/lib/Parse/ParseExpr.cpp:172:0
#19 0x000000000145c6c9 clang::Parser::ParseExpression(clang::Parser::TypeCastState)   llvm-upstream/build/../tools/clang/lib/Parse/ParseExpr.cpp:124:10
#20 0x00000000014a0750 clang::Parser::ParseExprStatement()   llvm-upstream/build/../tools/clang/lib/Parse/ParseStmt.cpp:417:19
#21 0x000000000149f2df clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::AllowedConstructsKind, clang::SourceLocation*, clang::Parser::ParsedAttributesWithRange&)   llvm-upstream/build/../tools/clang/lib/Parse/ParseStmt.cpp:0:12
#22 0x000000000149ee29 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::AllowedConstructsKind, clang::SourceLocation*)   llvm-upstream/build/../tools/clang/lib/Parse/ParseStmt.cpp:109:20
#23 0x00000000014a599c clang::Parser::ParseCompoundStatementBody(bool)   llvm-upstream/build/../tools/clang/lib/Parse/ParseStmt.cpp:1037:11
#24 0x00000000014a63f2 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&)   llvm-upstream/build/../tools/clang/lib/Parse/ParseStmt.cpp:2049:21
#25 0x00000000014250d9 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*)   llvm-upstream/build/../tools/clang/lib/Parse/Parser.cpp:0:10
#26 0x0000000001439dc1 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::SourceLocation*, clang::Parser::ForRangeInit*)   llvm-upstream/build/../tools/clang/lib/Parse/ParseDecl.cpp:2001:16
#27 0x0000000001424328 clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier)   llvm-upstream/build/../tools/clang/lib/Parse/Parser.cpp:1014:10
#28 0x0000000001423cfc clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier)   llvm-upstream/build/../tools/clang/lib/Parse/Parser.cpp:1030:12

textDocument/implementation - derived entities

Semantics in LSP aren't totally clear here, but this looks like a good place to show:

  • overrides of virtual functions
  • derived classes of a base
  • maybe template specializations?

In general, where potentially multiple entities have an "is-a" relationship with the thing under the cursor.
We may want this to fall back to "go to definition" behavior as well.

SystemHeadersMapping doesn't work in dynamic index

In https://reviews.llvm.org/D57508, we enable include insertion in dynamic index.

Reproduce step:

  1. running clangd without any static index
  2. run code completion at
#include <vector>
std::^

Actual result:
image

Expected result: The include header should be STL header, e.g. <memory>.

Off-topic: this feature seems a bit noisy, in the sample above, completion symbols are from <vector> or headers being included transitively, the code is still compilable without the include insertion.

Completion, diagnostics thrown off by e.g. unpaired braces.

e.g. in the following code

public:
  int x() const;
private:
  int x_;
};

if we decide to define x(),

  int x() const { return x
  //          A B          C

then as soon as we open the function body, we get lots of diagnostics, and because the code no longer parses, we can't see x_. and therefore can't complete it.

One idea is to heuristically fix brackets:

  • we should be able to identify the problem (extra {) pretty easily by bracket-matching in most cases
  • we have some history of the file contents, so could potentially notice:
  • likely cause of unmatching is extra { inserted at position B
  • nesting stack at C used to match A, but now is off by an extra {
  • at this point inserting } just before C is likely to give a better parse

Recover better with mismatched braces

Clang recovers very poorly sometimes with mismatched braces. e.g.

void foo() {
  ^

void bar() {
}

One option is to improve clang's own recovery (e.g. using indentation) though this is likely to be hard.
We could also track the region of the file that has been modified since the last compilable version, and inject braces at the end of it.

Operations in regions disabled by #if should not fail silently

Currently, if the user performs an operation, say, go to definition, on a symbol reference inside a code region skipped by a #if, the operation fails silently. A better user experience would be to supply an error message through LSP, explaining the situation. However, to the best of my knowledge, LSP does not provide a way to return a custom error message.

Include completion fails at the end of file

Input (no newline at the end!):

/// file comment
#include "llvm/Sup

Expected:
A completion for 'Support' folder.

Actual:
Global completion results.

The problem goes away if I linebreak at the end of the first line.

Support non-self-contained files

Currently clangd doesn't work with non-self-contained files, even if people have a way to build their projects with those files, for example by merging some/all of non-self-contained files into a single TU and building that file.

strcmp only exists in global namespace

During code completion clangd does not suggest strcmp when queried under std:: scope.

#include <cstring>
void foo() {
  std::strcm^
}

Above code does not yield strcmp as a completion item, whereas the one below works:

#include <cstring>
void foo() {
  strcm^
}

clangd-indexer should use or document -extra-arg="-Wno-everything"

Projects that use g++ may not necessarily compile cleanly with clang due to several warnings treated as errors. The following option to clangd-indexer significantly helps in creating a useful index for these projects:

-extra-arg="-Wno-everything"

Given the purpose of the index, perhaps this should be the default option?
If not, maybe it could at least be promoted more in documentation/usage as it results in a much more useful index for the purposes of symbol lookups etc.

"deep hover" information

Selecting code in clangd would be a great way to show deep info about the code, e.g.

  • dump selected bits of the AST
  • memory layout for struct/class types
  • expanded code for macro expansions

Unclear exactly what the interaction should be. Sections of the hover result? Code actions that insert comments?

bogus signature help triggered when defining a function

This is related to a vexing parse issue. In this snippet, copy is almost certainly a function that returns std::string:
std::string copy(^

But triggering signature help at the caret shows completions for std::string's constructor, as if copy were a variable.

Specifying format style using command line option

Hello guys. I've posted the same message to clangd-dev, just in case posting here.

Clangd by default tries to use .clang-format file to format code. Since "Format as you type" is experimental feature, it may be unusual for people like me who are used to format code before commit or using some keybindings. And personally I have some discomfort when my editor tries to do too much things when I'm typing.
Please consider adding a new command line option. Here's a patch which adds a new option to control formatting style. Using it I can pass "-clang-format-style={DisableFormat: true, SortIncludes: false}" and clangd will not apply any formatting to my code. Since there's "-clang-tidy-checks" for clang-tidy, it looks reasonable to have the same option for clang-format.
Thank you very much!

diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 53f7264e565..e73394f16c5 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -219,6 +219,12 @@ static llvm::cl::opt<bool> SuggestMissingIncludes(
                    "includes using index."),
     llvm::cl::init(true));
 
+static llvm::cl::opt<std::string> FormatStyle(
+    "clang-format-style",
+    llvm::cl::desc("Coding style to format code. "
+                   "Please refer to clang-format style option for details."),
+    llvm::cl::init(""));
+
 namespace {
 
 /// \brief Supports a test URI scheme with relaxed constraints for lit tests.
@@ -458,6 +464,9 @@ int main(int argc, char *argv[]) {
   }
   Opts.ClangTidyOptProvider = ClangTidyOptProvider.get();
   Opts.SuggestMissingIncludes = SuggestMissingIncludes;
+  if (!FormatStyle.empty()) {
+    clang::format::DefaultFormatStyle = FormatStyle.c_str();
+  }
   ClangdLSPServer LSPServer(
       *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath,
       /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts);

"Go to references" on a constructor definition produces all references to the class

When I "go to references" in this file on the constructor definition, I expect to see up to two results: the constructor call in main(), and maybe also the class definition.

Instead, I get all references to the class name in the source file.

class MyClass {
 public:
  MyClass() {}  // Go to references on "MyClass"
};

void consumer(const MyClass &);

int main() {
  consumer(MyClass());
  return 0;
}

Background index does not store reference counts

I have a background index of LLVM and the count of references for std::unique_ptr is always 0.
Not sure about the exact details, but it's clear our design does not allow to store reference counts properly.
In particular, we aim to store each symbol in the slab, corresponding to the file for the symbol declaration, so we don't have a way to increment the reference counts when processing translation units that don't write the corresponding slab.

Provide a text completion for the current filename

Imagine I started a new file (e.g. Lexer.cpp) and copy-pasted a file comment from another file:

//===- Parser.cpp -------------------------------------------------===//

It would be nice to get a completion with a name of the current file to help in fixing up the comment for the current file, i.e. have a Lexer.cpp completion here:

//===- ^ -------------------------------------------------===//

Add option to disable code formatter

The vscode clangd addin seems to auto-install clang formatting. It would be nice if this could be turned off, as some people might use a different formatting provider.

More diagnostic fixes

Clang mostly only emits those that are nice to read, which usually means short.

But some diagnostics have really obvious/useful fixes, e.g.:

  • unhandled enum cases
  • member initializers in the wrong order

Unclear if the logic should go in sema, clangd, or even clang-tidy.

Gentler fuzzy match for important symbols

[sgment] doesn't match the local variable segment, primarily because it would introduce too much spam in global (index) results.

But certain results (locals, members) are pretty few in number and often relevant, maybe we should relax the rules or correct typos for them.

completion: require manual triggering for zero-context completion

A naive editor may request completions on each keystroke. Currently clangd provides completions in too many cases (e.g. variables are completed after typing space).
This means editors need to be smart about when to trigger, it would be nice to reduce this burden.
LSP provides trigger characters but triggering only on these is not sufficient.

We should probably only trigger after whitespace if the CompletionTriggerKind == Invoked.

UTF-8 mode

clangd works natively in utf-8, many editors also work in utf-8.

LSP expresses character ranges in UTF-16 codepoints: microsoft/language-server-protocol#376 which causes server and client to do pointless complexity and busywork converting back and forth.

This needs to be opt-in. Could be a -utf-8 flag or some capabilities-based negotiation.

Type information in hover response useless in some cases

Right now clangd just echoes the declaration line, which is mostly fine, except in two cases:

  • auto it = some_struct_type.member_array.begin();
    • Echoing this line is not very useful, because the user wouldn't find out what is the actual type of the iterator and so it becomes hard to find out what is the type returned by operator*.
    • Discovering the value_type of member_arry isn't that difficult, unless it's defined in some large generated file that makes every editor choke (except vim in compatible mode).
  • Another case where hover response is not very useful is with super long braced init-lists.

More specifically, on this line, the hover response is completely useless, because code_points is declared like this.

On the other hand, ycmd's libclang based completer can retrieve type with auto resolved. https://github.com/Valloric/ycmd/blob/master/cpp/ycm/ClangCompleter/TranslationUnit.cpp#L308

textDocument/declaration

LSP now supports textDocument/declaration and textDocument/definition separately.

Proposed behavior:

  • for declaration, we return the best decl we have
  • for definition, we return the definition if we have one, else best decl
  • if we want a generic "go to" that returns both, then add an extension

Caveats: this breaks back-compat (decl no longer returned to old clients). No way to detect these via capabilities.

Include insertion gone for most symbols in static/auto index

This is a regression:

The theory is that because symbols are first declared in the file, and the header-guard controlling macro isn't identified until the end of the file.

When indexing a preamble post-hoc this shouldn't matter (PP/HeaderSearchInfo has all the information by the time we process the decls), but the static/auto index doesn't use a preamble and processes decls as they are found.

Don't show both const/non-const member overloads.

Common pattern:

class X {
  const int &yyy() const;
  int &yyy();
};
void foo(X &x) { x.y^ }

Here there are two overloads that are identical except for the return type (never used in overload resolution) and the this-qualifiers, which are known. The const overload is dominated and cannot be called (without a cast etc). It should not be suggested in code completion, the same way we don't show private members.

Obviously if arg lists differ then we need to show both, as overload resolution may be able to select either. But identical arg types for the overloads is a common case.

The right fix is probably in Sema. It in fact knows something about the this-qualifiers already:

  • it rejects members with incompatible this-qualifiers
  • it boosts members with exactly-matching this-qualifiers
    The bit that's missing is grouping members by name/signature so we can determine when one is dominated.

textDocument/definition returns only one definition

For virtual functions with multiple definitions, clangd appears to return only the declaration for a textDocument/definition request.

The language specification seems to allow returning an array of locations. I believe clangd should respond with all definition locations.

Find references on overriden method does not return usages of base method

And the other way around.

Input:

struct  Base {
  virtual void foo() = 0;
};

struct Derived : Base {
  void foo() override;
};

void test(Base *b, Derived *d) {
  b->foo(); // #1 
  d->foo(); // #2
}

Expected: searching for references of Base::foo() and Derived::foo() returns both references.
Actual: Base::foo() returns only #1, Derived::foo() returns only #2.

Go-to-definition for broken function calls

If we fail to produce a full, typechecked expression, go-to-definition won't resolve symbols - even in cases where there's only one function overload candidate (and it wasn't satisfied).

This is really common when trying to get a call right.

e.g.

void foo(char*X) {
  foo(1); // go to defintion on "foo" doesn't work
}

(And probably other constructs too, function calls are just the most obvious)

Clang-tidy integration

Inital idea:

Goal
Make clang-tidy checks available as hints while coding.

Implementation idea
Link in clang-tidy library and run checks as part of diagnostics (r347298)

UI
Surface main-file results as regular diagnostics

Performance
Make it fast by restricting AST traversal to the main file (r346847)
Limit scope to AST-matcher based checks, not static analyzers etc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.