diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -601,16 +601,24 @@ auto *AT = D->getType()->getContainedAutoType(); if (!AT) return true; - if (auto K = kindForType(AT->getDeducedType().getTypePtrOrNull(), - H.getResolver())) { - auto &Tok = H.addToken(D->getTypeSpecStartLoc(), *K) - .addModifier(HighlightingModifier::Deduced); - const Type *Deduced = AT->getDeducedType().getTypePtrOrNull(); - if (auto Mod = scopeModifier(Deduced)) - Tok.addModifier(*Mod); - if (isDefaultLibrary(Deduced)) - Tok.addModifier(HighlightingModifier::DefaultLibrary); - } + auto K = + kindForType(AT->getDeducedType().getTypePtrOrNull(), H.getResolver()); + if (!K) + return true; + SourceLocation StartLoc = D->getTypeSpecStartLoc(); + // The AutoType may not have a corresponding token, e.g. in the case of + // init-captures. In this case, StartLoc overlaps with the location + // of the decl itself, and producing a token for the type here would result + // in both it and the token for the decl being dropped due to conflict. + if (StartLoc == D->getLocation()) + return true; + auto &Tok = + H.addToken(StartLoc, *K).addModifier(HighlightingModifier::Deduced); + const Type *Deduced = AT->getDeducedType().getTypePtrOrNull(); + if (auto Mod = scopeModifier(Deduced)) + Tok.addModifier(*Mod); + if (isDefaultLibrary(Deduced)) + Tok.addModifier(HighlightingModifier::DefaultLibrary); return true; } diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -772,6 +772,14 @@ $Function[[foo]]($Parameter[[x]]); } )cpp", + // init-captures + R"cpp( + void $Function_decl[[foo]]() { + int $LocalVariable_decl[[a]], $LocalVariable_decl[[b]]; + [ $LocalVariable_decl[[c]] = $LocalVariable[[a]], + $LocalVariable_decl[[d]]($LocalVariable[[b]]) ]() {}(); + } + )cpp", }; for (const auto &TestCase : TestCases) // Mask off scope modifiers to keep the tests manageable. @@ -840,7 +848,7 @@ )cpp", R"cpp( // Lambdas are considered functions, not classes. - auto $Variable_fileScope[[x]] = [m(42)] { // FIXME: annotate capture + auto $Variable_fileScope[[x]] = [$LocalVariable_functionScope[[m]](42)] { return $LocalVariable_functionScope[[m]]; }; )cpp",