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 @@ -523,6 +523,8 @@ /// e.g. highlights dependent names and 'auto' as the underlying type. class CollectExtraHighlightings : public RecursiveASTVisitor { + using Base = RecursiveASTVisitor; + public: CollectExtraHighlightings(HighlightingsBuilder &H) : H(H) {} @@ -533,6 +535,22 @@ return true; } + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + if (!Init->isMemberInitializer()) + return Base::TraverseConstructorInitializer(Init); + if (const auto Member = Init->getMember()) { + const auto MemberType = Member->getType(); + if (MemberType->isLValueReferenceType() && + !MemberType->getPointeeType().isConstQualified()) { + if (const auto Param = dyn_cast(Init->getInit())) { + H.addExtraModifier(Param->getLocation(), + HighlightingModifier::UsedAsMutableReference); + } + } + } + return Base::TraverseConstructorInitializer(Init); + } + bool VisitCallExpr(CallExpr *E) { // Highlighting parameters passed by non-const reference does not really // make sense for literals... 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 @@ -745,6 +745,15 @@ int &operator[](int &); int operator[](int) const; }; + struct $Class_decl[[ClassWithRefMembers]] { + $Class_decl[[ClassWithRefMembers]](int $Parameter_decl[[i]]) + : $Field[[i1]]($Parameter[[i]]), + $Field_readonly[[i2]]($Parameter[[i]]), + $Field[[i3]]($Parameter_usedAsMutableReference[[i]]) {} + int $Field_decl[[i1]]; + const int &$Field_decl_readonly[[i2]]; + int &$Field_decl[[i3]]; + }; void $Function_decl[[fun]](int, const int, int*, const int*, int&, const int&,