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 @@ -96,8 +96,8 @@ } bool VisitTypedefNameDecl(TypedefNameDecl *TD) { - if(const auto *TSI = TD->getTypeSourceInfo()) - addTypeLoc(TD->getLocation(), TSI->getTypeLoc()); + if (const auto *TSI = TD->getTypeSourceInfo()) + addType(TD->getLocation(), TSI->getTypeLoc().getTypePtr()); return true; } @@ -119,10 +119,8 @@ // structs. It also makes us not highlight certain namespace qualifiers // twice. For elaborated types the actual type is highlighted as an inner // TypeLoc. - if (TL.getTypeLocClass() == TypeLoc::TypeLocClass::Elaborated) - return true; - - addTypeLoc(TL.getBeginLoc(), TL); + if (TL.getTypeLocClass() != TypeLoc::TypeLocClass::Elaborated) + addType(TL.getBeginLoc(), TL.getTypePtr()); return true; } @@ -136,15 +134,28 @@ HighlightingTokenCollector>::TraverseNestedNameSpecifierLoc(NNSLoc); } -private: - void addTypeLoc(SourceLocation Loc, const TypeLoc &TL) { - if (const Type *TP = TL.getTypePtr()) { - if (const TagDecl *TD = TP->getAsTagDecl()) - addToken(Loc, TD); - if (TP->isBuiltinType()) - // Builtins must be special cased as they do not have a TagDecl. - addToken(Loc, HighlightingKind::Primitive); + bool VisitDeclaratorDecl(DeclaratorDecl *D) { + if ((!D->getTypeSourceInfo())) + return true; + + if (auto *AT = D->getType()->getContainedAutoType()) { + const auto Deduced = AT->getDeducedType(); + if (Deduced.isNull()) + return true; + addType(D->getTypeSpecStartLoc(), Deduced.getTypePtr()); } + return true; + } + +private: + void addType(SourceLocation Loc, const Type *TP) { + if (!TP) + return; + if (TP->isBuiltinType()) + // Builtins must be special cased as they do not have a TagDecl. + addToken(Loc, HighlightingKind::Primitive); + if (const TagDecl *TD = TP->getAsTagDecl()) + addToken(Loc, TD); } void addToken(SourceLocation Loc, const NamedDecl *D) { 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 @@ -99,9 +99,9 @@ struct { } $Variable[[S]]; $Primitive[[void]] $Function[[foo]]($Primitive[[int]] $Variable[[A]], $Class[[AS]] $Variable[[As]]) { - auto $Variable[[VeryLongVariableName]] = 12312; + $Primitive[[auto]] $Variable[[VeryLongVariableName]] = 12312; $Class[[AS]] $Variable[[AA]]; - auto $Variable[[L]] = $Variable[[AA]].$Field[[SomeMember]] + $Variable[[A]]; + $Primitive[[auto]] $Variable[[L]] = $Variable[[AA]].$Field[[SomeMember]] + $Variable[[A]]; auto $Variable[[FN]] = [ $Variable[[AA]]]($Primitive[[int]] $Variable[[A]]) -> $Primitive[[void]] {}; $Variable[[FN]](12312); } @@ -276,6 +276,20 @@ $Class[[Foo]] *$Variable[[FP]] = ($Class[[Foo]]*)$Variable[[B]]; $Primitive[[int]] $Variable[[I]] = ($Primitive[[int]])$Variable[[B]]; } + )cpp", + R"cpp( + enum $Enum[[E]] { + $EnumConstant[[E]], + }; + class $Class[[Foo]] {}; + $Enum[[auto]] $Variable[[AE]] = $Enum[[E]]::$EnumConstant[[E]]; + $Class[[auto]] $Variable[[AF]] = $Class[[Foo]](); + $Class[[decltype]](auto) $Variable[[AF2]] = $Class[[Foo]](); + $Class[[auto]] *$Variable[[AFP]] = &$Variable[[AF]]; + $Enum[[auto]] &$Variable[[AER]] = $Variable[[AE]]; + $Primitive[[auto]] $Variable[[Form]] = 10.2 + 2 * 4; + $Primitive[[decltype]]($Variable[[Form]]) $Variable[[F]] = 10; + auto $Variable[[Fun]] = []()->$Primitive[[void]]{}; )cpp"}; for (const auto &TestCase : TestCases) { checkHighlightings(TestCase);