[clangd] Highlight typedefs to template parameters as template parameters

Summary:
Template parameters were handled outside `addType`, this led to lack of highlightings for typedefs
to template types.

This was never desirable, we want to highlight our typedefs as their underlying type.
Note that typedefs to more complicated types, like pointers and references are still not highlighted.

Original patch by Johan Vikström.

Reviewers: hokein, jvikstrom

Reviewed By: hokein

Subscribers: nridge, javed.absar, kristof.beyls, MaskRay, jkorous, arphaman, kadircet, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66516

git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@371379 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/clangd/SemanticHighlighting.cpp b/clangd/SemanticHighlighting.cpp
index 61de0f4..b5f1c40 100644
--- a/clangd/SemanticHighlighting.cpp
+++ b/clangd/SemanticHighlighting.cpp
@@ -15,6 +15,8 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include <algorithm>
 
 namespace clang {
@@ -128,13 +130,12 @@
     return true;
   }
 
-  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc &TL) {
-    // TemplateTypeParmTypeLoc does not have a TagDecl in its type ptr.
-    addToken(TL.getBeginLoc(), TL.getDecl());
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    addType(TL.getBeginLoc(), TL.getTypePtr());
     return true;
   }
 
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc &TL) {
+  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
     if (const TemplateDecl *TD =
             TL.getTypePtr()->getTemplateName().getAsTemplateDecl())
       addToken(TL.getBeginLoc(), TD);
@@ -187,7 +188,10 @@
     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())
+    if (auto *TD = dyn_cast<TemplateTypeParmType>(TP))
+      // TemplateTypeParmType also do not have a TagDecl.
+      addToken(Loc, TD->getDecl());
+    if (auto *TD = TP->getAsTagDecl())
       addToken(Loc, TD);
   }
 
diff --git a/clangd/unittests/SemanticHighlightingTests.cpp b/clangd/unittests/SemanticHighlightingTests.cpp
index 6630396..92e6256 100644
--- a/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clangd/unittests/SemanticHighlightingTests.cpp
@@ -474,7 +474,7 @@
         $Macro[[assert]]($Variable[[x]] != $Function[[f]]());
       }
     )cpp",
-    R"cpp(
+      R"cpp(
       struct $Class[[S]] {
         $Primitive[[float]] $Field[[Value]];
         $Class[[S]] *$Field[[Next]];
@@ -488,6 +488,21 @@
         // Highlights references to BindingDecls.
         $Variable[[B1]]++;
       }
+    )cpp",
+      R"cpp(
+      template<class $TemplateParameter[[T]]>
+      class $Class[[A]] {
+        using $TemplateParameter[[TemplateParam1]] = $TemplateParameter[[T]];
+        typedef $TemplateParameter[[T]] $TemplateParameter[[TemplateParam2]];
+        using $Primitive[[IntType]] = $Primitive[[int]];
+
+        // These typedefs are not yet highlighted, their types are complicated.
+        using Pointer = $TemplateParameter[[T]] *;
+        using LVReference = $TemplateParameter[[T]] &;
+        using RVReference = $TemplateParameter[[T]]&&;
+        using Array = $TemplateParameter[[T]]*[3];
+        using MemberPointer = $Primitive[[int]] (A::*)($Primitive[[int]]);
+      };
     )cpp"};
   for (const auto &TestCase : TestCases) {
     checkHighlightings(TestCase);