From e4ab3d44e9682749c5defe49210af560489cb066 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i@maskray.me>
Date: Wed, 19 Sep 2018 13:05:52 -0700
Subject: [PATCH] Improve VarDef::type for textDocument/typeDefinition

---
 index_tests/foobar.cc                         |  42 +------
 index_tests/lambdas/lambda.cc                 |   4 +-
 ...ace_template_type_usage_folded_into_one.cc |  40 +------
 index_tests/templates/specialization.cc       |  71 ++----------
 ...mplate_class_type_usage_folded_into_one.cc |  40 +------
 .../template_type_usage_folded_into_one.cc    |  40 +------
 .../usage/type_usage_as_template_parameter.cc |  42 +------
 ...ype_usage_as_template_parameter_complex.cc |  14 +--
 ...type_usage_as_template_parameter_simple.cc |  21 +---
 src/indexer.cc                                | 103 ++++++++----------
 10 files changed, 78 insertions(+), 339 deletions(-)

diff --git a/index_tests/foobar.cc b/index_tests/foobar.cc
index e92f23cf..4b9d2f65 100644
--- a/index_tests/foobar.cc
+++ b/index_tests/foobar.cc
@@ -31,23 +31,6 @@ OUTPUT:
       "vars": [],
       "instances": [],
       "uses": ["9:5-9:6|0|1|4|-1"]
-    }, {
-      "usr": 7074603899792463171,
-      "detailed_name": "Inner",
-      "qual_name_offset": 0,
-      "short_name": "Inner",
-      "kind": 26,
-      "declarations": [],
-      "spell": "6:10-6:15|0|1|2|-1",
-      "extent": "6:3-6:18|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [16721564935990383768],
-      "uses": []
     }, {
       "usr": 10528472276654770367,
       "detailed_name": "struct Foo {}",
@@ -63,25 +46,8 @@ OUTPUT:
       "types": [13938528237873543349],
       "funcs": [],
       "vars": [],
-      "instances": [],
-      "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"]
-    }, {
-      "usr": 11976530632376795217,
-      "detailed_name": "Foo",
-      "qual_name_offset": 0,
-      "short_name": "Foo",
-      "kind": 26,
-      "declarations": [],
-      "spell": "5:8-5:11|0|1|2|-1",
-      "extent": "4:1-7:2|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
       "instances": [12028309045033782423],
-      "uses": []
+      "uses": ["9:1-9:4|0|1|4|-1", "10:1-10:4|0|1|4|-1"]
     }, {
       "usr": 13892793056005362145,
       "detailed_name": "enum B {}",
@@ -114,7 +80,7 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [16721564935990383768],
       "uses": ["9:9-9:14|0|1|4|-1"]
     }],
   "usr2var": [{
@@ -125,7 +91,7 @@ OUTPUT:
       "declarations": [],
       "spell": "10:8-10:9|0|1|2|-1",
       "extent": "10:1-10:9|0|1|0|-1",
-      "type": 11976530632376795217,
+      "type": 10528472276654770367,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -137,7 +103,7 @@ OUTPUT:
       "declarations": [],
       "spell": "9:15-9:16|0|1|2|-1",
       "extent": "9:1-9:16|0|1|0|-1",
-      "type": 7074603899792463171,
+      "type": 13938528237873543349,
       "uses": [],
       "kind": 13,
       "storage": 0
diff --git a/index_tests/lambdas/lambda.cc b/index_tests/lambdas/lambda.cc
index 2f5371f9..b4e58a30 100644
--- a/index_tests/lambdas/lambda.cc
+++ b/index_tests/lambdas/lambda.cc
@@ -65,10 +65,8 @@ OUTPUT:
       "detailed_name": "",
       "qual_name_offset": 0,
       "short_name": "",
-      "kind": 26,
+      "kind": 0,
       "declarations": [],
-      "spell": "4:22-4:23|4259594751088586730|3|2|-1",
-      "extent": "4:22-4:23|4259594751088586730|3|0|-1",
       "alias_of": 0,
       "bases": [],
       "derived": [],
diff --git a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc
index c7ce4fae..b3144b08 100644
--- a/index_tests/templates/namespace_template_type_usage_folded_into_one.cc
+++ b/index_tests/templates/namespace_template_type_usage_folded_into_one.cc
@@ -13,40 +13,6 @@ OUTPUT:
   "skipped_ranges": [],
   "usr2func": [],
   "usr2type": [{
-      "usr": 3948666349864691553,
-      "detailed_name": "Foo",
-      "qual_name_offset": 0,
-      "short_name": "Foo",
-      "kind": 26,
-      "declarations": [],
-      "spell": "3:9-3:12|11072669167287398027|2|2|-1",
-      "extent": "2:3-3:15|11072669167287398027|2|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [3182917058194750998],
-      "uses": []
-    }, {
-      "usr": 8224244241460152567,
-      "detailed_name": "Foo",
-      "qual_name_offset": 0,
-      "short_name": "Foo",
-      "kind": 26,
-      "declarations": [],
-      "spell": "3:9-3:12|11072669167287398027|2|2|-1",
-      "extent": "2:3-3:15|11072669167287398027|2|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [15768138241775955040],
-      "uses": []
-    }, {
       "usr": 11072669167287398027,
       "detailed_name": "namespace ns {}",
       "qual_name_offset": 10,
@@ -82,7 +48,7 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [15768138241775955040, 3182917058194750998],
       "uses": ["5:3-5:6|11072669167287398027|2|4|-1", "6:3-6:6|11072669167287398027|2|4|-1"]
     }],
   "usr2var": [{
@@ -93,7 +59,7 @@ OUTPUT:
       "declarations": [],
       "spell": "6:13-6:14|11072669167287398027|2|1026|-1",
       "extent": "6:3-6:14|11072669167287398027|2|0|-1",
-      "type": 3948666349864691553,
+      "type": 14042997404480181958,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -105,7 +71,7 @@ OUTPUT:
       "declarations": [],
       "spell": "5:12-5:13|11072669167287398027|2|1026|-1",
       "extent": "5:3-5:13|11072669167287398027|2|0|-1",
-      "type": 8224244241460152567,
+      "type": 14042997404480181958,
       "uses": [],
       "kind": 13,
       "storage": 0
diff --git a/index_tests/templates/specialization.cc b/index_tests/templates/specialization.cc
index d597a78c..52cfe543 100644
--- a/index_tests/templates/specialization.cc
+++ b/index_tests/templates/specialization.cc
@@ -132,7 +132,7 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [2933643612409209903],
       "uses": ["7:1-7:9|0|1|4|-1"]
     }, {
       "usr": 1663022413889915338,
@@ -151,23 +151,6 @@ OUTPUT:
       "vars": [],
       "instances": [15931696253641284761],
       "uses": ["26:7-26:13|0|1|4|-1", "33:1-33:7|0|1|4|-1"]
-    }, {
-      "usr": 3231449734830406187,
-      "detailed_name": "function",
-      "qual_name_offset": 0,
-      "short_name": "function",
-      "kind": 26,
-      "declarations": [],
-      "spell": "5:7-5:15|0|1|2|-1",
-      "extent": "4:1-5:30|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [2933643612409209903],
-      "uses": []
     }, {
       "usr": 5760043510674081814,
       "detailed_name": "struct Z1 {}",
@@ -200,7 +183,7 @@ OUTPUT:
       "types": [],
       "funcs": [18107614608385228556],
       "vars": [],
-      "instances": [],
+      "instances": [5792869548777559988],
       "uses": ["21:16-21:22|0|1|4|-1", "30:1-30:7|0|1|4|-1", "32:1-32:7|0|1|4|-1"]
     }, {
       "usr": 9201299975592934124,
@@ -236,40 +219,6 @@ OUTPUT:
       "vars": [],
       "instances": [],
       "uses": ["26:14-26:16|0|1|4|-1", "33:8-33:10|0|1|4|-1"]
-    }, {
-      "usr": 11153492883079050853,
-      "detailed_name": "vector",
-      "qual_name_offset": 0,
-      "short_name": "vector",
-      "kind": 26,
-      "declarations": [],
-      "spell": "17:7-17:13|0|1|2|-1",
-      "extent": "16:1-17:20|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [86949563628772958],
-      "uses": []
-    }, {
-      "usr": 13322943937025195708,
-      "detailed_name": "vector",
-      "qual_name_offset": 0,
-      "short_name": "vector",
-      "kind": 26,
-      "declarations": [],
-      "spell": "12:7-12:13|0|1|2|-1",
-      "extent": "11:1-14:2|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [5792869548777559988],
-      "uses": []
     }, {
       "usr": 14111105212951082474,
       "detailed_name": "T",
@@ -304,13 +253,11 @@ OUTPUT:
       "uses": []
     }, {
       "usr": 15440970074034693939,
-      "detailed_name": "vector",
+      "detailed_name": "",
       "qual_name_offset": 0,
-      "short_name": "vector",
-      "kind": 26,
+      "short_name": "",
+      "kind": 0,
       "declarations": [],
-      "spell": "21:16-21:22|0|1|2|-1",
-      "extent": "21:1-21:26|0|1|0|-1",
       "alias_of": 0,
       "bases": [],
       "derived": [],
@@ -349,7 +296,7 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [86949563628772958],
       "uses": ["31:1-31:7|0|1|4|-1"]
     }],
   "usr2var": [{
@@ -360,7 +307,7 @@ OUTPUT:
       "declarations": [],
       "spell": "31:14-31:17|0|1|2|-1",
       "extent": "31:1-31:17|0|1|0|-1",
-      "type": 11153492883079050853,
+      "type": 16155717907537731864,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -372,7 +319,7 @@ OUTPUT:
       "declarations": [],
       "spell": "7:21-7:22|0|1|2|-1",
       "extent": "7:1-7:22|0|1|0|-1",
-      "type": 3231449734830406187,
+      "type": 218068462278884837,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -409,7 +356,7 @@ OUTPUT:
       "declarations": [],
       "spell": "30:14-30:16|0|1|2|-1",
       "extent": "30:1-30:16|0|1|0|-1",
-      "type": 13322943937025195708,
+      "type": 7440942986741176606,
       "uses": [],
       "kind": 13,
       "storage": 0
diff --git a/index_tests/templates/template_class_type_usage_folded_into_one.cc b/index_tests/templates/template_class_type_usage_folded_into_one.cc
index e1b1b829..09bc2e7c 100644
--- a/index_tests/templates/template_class_type_usage_folded_into_one.cc
+++ b/index_tests/templates/template_class_type_usage_folded_into_one.cc
@@ -50,23 +50,6 @@ OUTPUT:
       "vars": [],
       "instances": [],
       "uses": ["9:5-9:6|0|1|4|-1"]
-    }, {
-      "usr": 7074603899792463171,
-      "detailed_name": "Inner",
-      "qual_name_offset": 0,
-      "short_name": "Inner",
-      "kind": 26,
-      "declarations": [],
-      "spell": "6:10-6:15|0|1|2|-1",
-      "extent": "6:3-6:18|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [16721564935990383768],
-      "uses": []
     }, {
       "usr": 10528472276654770367,
       "detailed_name": "struct Foo {}",
@@ -116,25 +99,8 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [16721564935990383768, 12028309045033782423],
       "uses": ["9:9-9:14|0|1|4|-1", "10:9-10:14|0|1|4|-1"]
-    }, {
-      "usr": 15961308565836244174,
-      "detailed_name": "Inner",
-      "qual_name_offset": 0,
-      "short_name": "Inner",
-      "kind": 26,
-      "declarations": [],
-      "spell": "6:10-6:15|0|1|2|-1",
-      "extent": "6:3-6:18|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [12028309045033782423],
-      "uses": []
     }],
   "usr2var": [{
       "usr": 12028309045033782423,
@@ -144,7 +110,7 @@ OUTPUT:
       "declarations": [],
       "spell": "10:15-10:16|0|1|2|-1",
       "extent": "10:1-10:16|0|1|0|-1",
-      "type": 15961308565836244174,
+      "type": 13938528237873543349,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -156,7 +122,7 @@ OUTPUT:
       "declarations": [],
       "spell": "9:15-9:16|0|1|2|-1",
       "extent": "9:1-9:16|0|1|0|-1",
-      "type": 7074603899792463171,
+      "type": 13938528237873543349,
       "uses": [],
       "kind": 13,
       "storage": 0
diff --git a/index_tests/templates/template_type_usage_folded_into_one.cc b/index_tests/templates/template_type_usage_folded_into_one.cc
index bb9745e8..fb719179 100644
--- a/index_tests/templates/template_type_usage_folded_into_one.cc
+++ b/index_tests/templates/template_type_usage_folded_into_one.cc
@@ -11,23 +11,6 @@ OUTPUT:
   "skipped_ranges": [],
   "usr2func": [],
   "usr2type": [{
-      "usr": 5123806965838456033,
-      "detailed_name": "Foo",
-      "qual_name_offset": 0,
-      "short_name": "Foo",
-      "kind": 26,
-      "declarations": [],
-      "spell": "2:7-2:10|0|1|2|-1",
-      "extent": "1:1-2:13|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [16721564935990383768],
-      "uses": []
-    }, {
       "usr": 10528472276654770367,
       "detailed_name": "class Foo {}",
       "qual_name_offset": 6,
@@ -42,25 +25,8 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [16721564935990383768, 12028309045033782423],
       "uses": ["4:1-4:4|0|1|4|-1", "5:1-5:4|0|1|4|-1"]
-    }, {
-      "usr": 14134940367505932005,
-      "detailed_name": "Foo",
-      "qual_name_offset": 0,
-      "short_name": "Foo",
-      "kind": 26,
-      "declarations": [],
-      "spell": "2:7-2:10|0|1|2|-1",
-      "extent": "1:1-2:13|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [12028309045033782423],
-      "uses": []
     }],
   "usr2var": [{
       "usr": 12028309045033782423,
@@ -70,7 +36,7 @@ OUTPUT:
       "declarations": [],
       "spell": "5:11-5:12|0|1|2|-1",
       "extent": "5:1-5:12|0|1|0|-1",
-      "type": 14134940367505932005,
+      "type": 10528472276654770367,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -82,7 +48,7 @@ OUTPUT:
       "declarations": [],
       "spell": "4:10-4:11|0|1|2|-1",
       "extent": "4:1-4:11|0|1|0|-1",
-      "type": 5123806965838456033,
+      "type": 10528472276654770367,
       "uses": [],
       "kind": 13,
       "storage": 0
diff --git a/index_tests/usage/type_usage_as_template_parameter.cc b/index_tests/usage/type_usage_as_template_parameter.cc
index 5c4dc824..169d5ad4 100644
--- a/index_tests/usage/type_usage_as_template_parameter.cc
+++ b/index_tests/usage/type_usage_as_template_parameter.cc
@@ -46,25 +46,8 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [12857919739649552168, 18075066956054788088, 3364438781074774169],
       "uses": ["6:8-6:18|0|1|4|-1", "7:8-7:18|0|1|4|-1", "9:1-9:11|0|1|4|-1", "10:3-10:13|16359708726068806331|3|4|-1"]
-    }, {
-      "usr": 4186953406371619898,
-      "detailed_name": "unique_ptr",
-      "qual_name_offset": 0,
-      "short_name": "unique_ptr",
-      "kind": 26,
-      "declarations": [],
-      "spell": "2:7-2:17|0|1|2|-1",
-      "extent": "1:1-2:20|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [18075066956054788088, 3364438781074774169],
-      "uses": []
     }, {
       "usr": 4750332761459066907,
       "detailed_name": "struct S {}",
@@ -82,23 +65,6 @@ OUTPUT:
       "vars": [],
       "instances": [],
       "uses": ["7:19-7:20|0|1|4|-1", "9:12-9:13|0|1|4|-1", "10:14-10:15|16359708726068806331|3|4|-1"]
-    }, {
-      "usr": 16848604152578034754,
-      "detailed_name": "unique_ptr",
-      "qual_name_offset": 0,
-      "short_name": "unique_ptr",
-      "kind": 26,
-      "declarations": [],
-      "spell": "2:7-2:17|0|1|2|-1",
-      "extent": "1:1-2:20|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
-      "instances": [12857919739649552168],
-      "uses": []
     }],
   "usr2var": [{
       "usr": 3364438781074774169,
@@ -108,7 +74,7 @@ OUTPUT:
       "declarations": [],
       "spell": "10:18-10:23|16359708726068806331|3|2|-1",
       "extent": "10:3-10:23|16359708726068806331|3|0|-1",
-      "type": 4186953406371619898,
+      "type": 3286534761799572592,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -120,7 +86,7 @@ OUTPUT:
       "declarations": [],
       "spell": "6:25-6:27|0|1|2|-1",
       "extent": "6:1-6:27|0|1|0|-1",
-      "type": 16848604152578034754,
+      "type": 3286534761799572592,
       "uses": [],
       "kind": 13,
       "storage": 2
@@ -132,7 +98,7 @@ OUTPUT:
       "declarations": [],
       "spell": "7:22-7:24|0|1|2|-1",
       "extent": "7:1-7:24|0|1|0|-1",
-      "type": 4186953406371619898,
+      "type": 3286534761799572592,
       "uses": [],
       "kind": 13,
       "storage": 2
diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc
index 0b4e20e0..a49ccb84 100644
--- a/index_tests/usage/type_usage_as_template_parameter_complex.cc
+++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc
@@ -202,7 +202,7 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
+      "instances": [2933643612409209903, 500112618220246],
       "uses": []
     }, {
       "usr": 15041163540773201510,
@@ -223,20 +223,18 @@ OUTPUT:
       "uses": ["79:21-79:24|0|1|4|-1"]
     }, {
       "usr": 18153735331422331128,
-      "detailed_name": "unique_ptr",
-      "qual_name_offset": 0,
+      "detailed_name": "template<> class unique_ptr<unique_ptr<S1, S2>, S2>",
+      "qual_name_offset": 17,
       "short_name": "unique_ptr",
       "kind": 5,
       "declarations": [],
-      "spell": "2:7-2:17|0|1|2|-1",
-      "extent": "1:1-2:17|0|1|0|-1",
       "alias_of": 0,
       "bases": [],
       "derived": [],
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [2933643612409209903, 500112618220246],
+      "instances": [],
       "uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"]
     }],
   "usr2var": [{
@@ -247,7 +245,7 @@ OUTPUT:
       "declarations": [],
       "spell": "54:39-54:44|18320186404467436976|3|2|-1",
       "extent": "54:3-54:44|18320186404467436976|3|0|-1",
-      "type": 18153735331422331128,
+      "type": 14209198335088845323,
       "uses": [],
       "kind": 13,
       "storage": 0
@@ -257,7 +255,7 @@ OUTPUT:
       "qual_name_offset": 42,
       "short_name": "f",
       "declarations": ["15:43-15:44|15:1-15:44|0|1|1|-1"],
-      "type": 18153735331422331128,
+      "type": 14209198335088845323,
       "uses": [],
       "kind": 13,
       "storage": 1
diff --git a/index_tests/usage/type_usage_as_template_parameter_simple.cc b/index_tests/usage/type_usage_as_template_parameter_simple.cc
index 1893c26e..9f7c8da2 100644
--- a/index_tests/usage/type_usage_as_template_parameter_simple.cc
+++ b/index_tests/usage/type_usage_as_template_parameter_simple.cc
@@ -26,25 +26,8 @@ OUTPUT:
       "types": [],
       "funcs": [],
       "vars": [],
-      "instances": [],
-      "uses": ["6:8-6:18|0|1|4|-1"]
-    }, {
-      "usr": 4186953406371619898,
-      "detailed_name": "unique_ptr",
-      "qual_name_offset": 0,
-      "short_name": "unique_ptr",
-      "kind": 26,
-      "declarations": [],
-      "spell": "2:7-2:17|0|1|2|-1",
-      "extent": "1:1-2:20|0|1|0|-1",
-      "alias_of": 0,
-      "bases": [],
-      "derived": [],
-      "types": [],
-      "funcs": [],
-      "vars": [],
       "instances": [3398408600781120939],
-      "uses": []
+      "uses": ["6:8-6:18|0|1|4|-1"]
     }, {
       "usr": 4750332761459066907,
       "detailed_name": "struct S",
@@ -69,7 +52,7 @@ OUTPUT:
       "declarations": [],
       "spell": "6:22-6:25|0|1|2|-1",
       "extent": "6:1-6:25|0|1|0|-1",
-      "type": 4186953406371619898,
+      "type": 3286534761799572592,
       "uses": [],
       "kind": 13,
       "storage": 2
diff --git a/src/indexer.cc b/src/indexer.cc
index 61209256..4a1a1b2c 100644
--- a/src/indexer.cc
+++ b/src/indexer.cc
@@ -271,41 +271,6 @@ try_again:
   return D;
 }
 
-const Decl *GetSpecialized(const Decl *D) {
-  if (!D)
-    return D;
-  Decl *Template = nullptr;
-  if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
-    if (const ClassTemplatePartialSpecializationDecl *PartialSpec =
-            dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
-      Template = PartialSpec->getSpecializedTemplate();
-    else if (const ClassTemplateSpecializationDecl *ClassSpec =
-                 dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
-      llvm::PointerUnion<ClassTemplateDecl *,
-                         ClassTemplatePartialSpecializationDecl *>
-          Result = ClassSpec->getSpecializedTemplateOrPartial();
-      if (Result.is<ClassTemplateDecl *>())
-        Template = Result.get<ClassTemplateDecl *>();
-      else
-        Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
-
-    } else
-      Template = CXXRecord->getInstantiatedFromMemberClass();
-  } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
-    Template = Function->getPrimaryTemplate();
-    if (!Template)
-      Template = Function->getInstantiatedFromMemberFunction();
-  } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
-    if (Var->isStaticDataMember())
-      Template = Var->getInstantiatedFromStaticDataMember();
-  } else if (const RedeclarableTemplateDecl *Tmpl =
-                 dyn_cast<RedeclarableTemplateDecl>(D))
-    Template = Tmpl->getInstantiatedFromMemberTemplate();
-  else
-    return nullptr;
-  return Template;
-}
-
 bool ValidateRecord(const RecordDecl *RD) {
   for (const auto *I : RD->fields()) {
     QualType FQT = I->getType();
@@ -763,33 +728,51 @@ public:
             var->def.type = usr1;
             db->ToType(usr1).instances.push_back(usr);
           } else {
-            for (const Decl *D1 = GetTypeDecl(T); D1; D1 = GetSpecialized(D1)) {
+            for (const Decl *D1 = GetTypeDecl(T); D1; ) {
+              if (auto *R1 = dyn_cast<CXXRecordDecl>(D1)) {
+                if (auto *S1 = dyn_cast<ClassTemplateSpecializationDecl>(D1)) {
+                  if (!S1->getTypeAsWritten()) {
+                    llvm::PointerUnion<ClassTemplateDecl *,
+                                       ClassTemplatePartialSpecializationDecl *>
+                        Result = S1->getSpecializedTemplateOrPartial();
+                    if (Result.is<ClassTemplateDecl *>())
+                      D1 = Result.get<ClassTemplateDecl *>();
+                    else
+                      D1 = Result.get<ClassTemplatePartialSpecializationDecl *>();
+                    continue;
+                  }
+                } else if (auto *D2 = R1->getInstantiatedFromMemberClass()) {
+                  D1 = D2;
+                  continue;
+                }
+              } else if (auto *TP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
+                // e.g. TemplateTypeParmDecl is not handled by
+                // handleDeclOccurence.
+                SourceRange R1 = D1->getSourceRange();
+                if (SM.getFileID(R1.getBegin()) == LocFID) {
+                  IndexParam::DeclInfo *info1;
+                  Usr usr1 = GetUsr(D1, &info1);
+                  IndexType &type1 = db->ToType(usr1);
+                  SourceLocation L1 = D1->getLocation();
+                  type1.def.spell =
+                      GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
+                             Role::Definition);
+                  type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
+                                            LexDC, Role::None);
+                  type1.def.detailed_name = Intern(info1->short_name);
+                  type1.def.short_name_size = int16_t(info1->short_name.size());
+                  type1.def.kind = lsSymbolKind::TypeParameter;
+                  var->def.type = usr1;
+                  type1.instances.push_back(usr);
+                  break;
+                }
+              }
+
               IndexParam::DeclInfo *info1;
               Usr usr1 = GetUsr(D1, &info1);
-              auto it = db->usr2type.find(usr1);
-              if (it != db->usr2type.end()) {
-                var->def.type = usr1;
-                it->second.instances.push_back(usr);
-                break;
-              }
-              // e.g. TemplateTypeParmDecl is not handled by
-              // handleDeclOccurence.
-              SourceRange R1 = D1->getSourceRange();
-              if (SM.getFileID(R1.getBegin()) == LocFID) {
-                IndexType &type1 = db->ToType(usr1);
-                SourceLocation L1 = D1->getLocation();
-                type1.def.spell =
-                    GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
-                           Role::Definition);
-                type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
-                                          LexDC, Role::None);
-                type1.def.detailed_name = Intern(info1->short_name);
-                type1.def.short_name_size = int16_t(info1->short_name.size());
-                type1.def.kind = lsSymbolKind::TypeParameter;
-                var->def.type = usr1;
-                type1.instances.push_back(usr);
-                break;
-              }
+              var->def.type = usr1;
+              db->ToType(usr1).instances.push_back(usr);
+              break;
             }
           }
         }