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 @@ -97,7 +97,8 @@ bool VisitTypedefNameDecl(TypedefNameDecl *TD) { if(const auto *TSI = TD->getTypeSourceInfo()) - addTypeLoc(TD->getLocation(), TSI->getTypeLoc()); + if (const Type *TP = TSI->getTypeLoc().getTypePtr()) + addType(TD->getLocation(), TP); return true; } @@ -121,8 +122,8 @@ // TypeLoc. if (TL.getTypeLocClass() == TypeLoc::TypeLocClass::Elaborated) return true; - - addTypeLoc(TL.getBeginLoc(), TL); + if (const Type *TP = TL.getTypePtr()) + addType(TL.getBeginLoc(), TP); return true; } @@ -136,14 +137,33 @@ HighlightingTokenCollector>::TraverseNestedNameSpecifierLoc(NNSLoc); } + 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; + SourceLocation Loc = D->getTypeSpecStartLoc(); + if (AT->isDecltypeAuto()) + // If this is a decltype(auto) it's still the "auto" keyword that should + // get the highlightings. But there is no way to get the SLoc of the + // "auto" keyword other than + Loc = Loc.getLocWithOffset(9); + Deduced.getTypePtr()->dump(); + addType(Loc, Deduced.getTypePtr()); + } + return true; + } + 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); + void addType(SourceLocation Loc, const Type *TP) { + 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); } } 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]](); + decltype($Class[[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);