Revert "Revert "[index] Handle properly C++14's template variables.""

This reverts commit 3cd084159645e4ef5560c3db16be697ef6718e3d.
The API has been cherry-picked.
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index d98d7c0..4126bb6 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -91,6 +91,25 @@
       Info.SubKinds |= (unsigned)SymbolSubKind::TemplateSpecialization;
     }
 
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    Info.Kind = SymbolKind::Variable;
+    if (isa<CXXRecordDecl>(D->getDeclContext())) {
+      Info.Kind = SymbolKind::StaticProperty;
+      Info.Lang = SymbolLanguage::CXX;
+    }
+    if (isa<VarTemplatePartialSpecializationDecl>(D)) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+      Info.SubKinds |= (unsigned)SymbolSubKind::TemplatePartialSpecialization;
+    } else if (isa<VarTemplateSpecializationDecl>(D)) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+      Info.SubKinds |= (unsigned)SymbolSubKind::TemplateSpecialization;
+    } else if (VD->getDescribedVarTemplate()) {
+      Info.Lang = SymbolLanguage::CXX;
+      Info.SubKinds |= (unsigned)SymbolSubKind::Generic;
+    }
+
   } else {
     switch (D->getKind()) {
     case Decl::Import:
@@ -101,16 +120,6 @@
     case Decl::Function:
       Info.Kind = SymbolKind::Function;
       break;
-    case Decl::ParmVar:
-      Info.Kind = SymbolKind::Variable;
-      break;
-    case Decl::Var:
-      Info.Kind = SymbolKind::Variable;
-      if (isa<CXXRecordDecl>(D->getDeclContext())) {
-        Info.Kind = SymbolKind::StaticProperty;
-        Info.Lang = SymbolLanguage::CXX;
-      }
-      break;
     case Decl::Field:
       Info.Kind = SymbolKind::Field;
       if (const CXXRecordDecl *
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index 21869d8..e623a49 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -130,9 +130,10 @@
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     TKind = SD->getSpecializationKind();
-  }
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     TKind = FD->getTemplateSpecializationKind();
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    TKind = VD->getTemplateSpecializationKind();
   }
   switch (TKind) {
     case TSK_Undeclared:
@@ -164,9 +165,10 @@
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
     return SD->getTemplateInstantiationPattern();
-  }
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     return FD->getTemplateInstantiationPattern();
+  } else if (auto *VD = dyn_cast<VarDecl>(D)) {
+    return VD->getTemplateInstantiationPattern();
   }
   return nullptr;
 }
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index bec777d..58f61c3 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -286,6 +286,15 @@
 
   VisitDeclContext(D->getDeclContext());
 
+  if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
+    Out << "@VT";
+    VisitTemplateParameterList(VarTmpl->getTemplateParameters());
+  } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
+             = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
+    Out << "@VP";
+    VisitTemplateParameterList(PartialSpec->getTemplateParameters());
+  }
+
   // Variables always have simple names.
   StringRef s = D->getName();
 
@@ -297,6 +306,17 @@
     IgnoreResults = true;
   else
     Out << '@' << s;
+
+  // For a template specialization, mangle the template arguments.
+  if (const VarTemplateSpecializationDecl *Spec
+                              = dyn_cast<VarTemplateSpecializationDecl>(D)) {
+    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    Out << '>';
+    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+      Out << '#';
+      VisitTemplateArgument(Args.get(I));
+    }
+  }
 }
 
 void USRGenerator::VisitNonTypeTemplateParmDecl(
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 61b9675..7db5d53 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -1,4 +1,4 @@
-// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
 
 template <typename TemplArg>
 class TemplCls {
@@ -29,3 +29,14 @@
 // CHECK: [[@LINE+2]]:7 | function/C | operator new | c:@F@operator new#l# | __Znwm |
 // CHECK: [[@LINE+1]]:20 | type-alias/C | size_t | {{.*}} | Ref |
 void* operator new(size_t sz);
+
+// CHECK: [[@LINE+1]]:37 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Def | rel: 0
+template<typename T> static const T tmplVar = T(0);
+// CHECK: [[@LINE+1]]:29 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Def | rel: 0
+template<> static const int tmplVar<int> = 0;
+// CHECK: [[@LINE+2]]:5 | variable/C | gvi | c:@gvi | _gvi | Def | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen,TS)/C++ | tmplVar | c:index-source.cpp@tmplVar>#I | __ZL7tmplVarIiE | Ref,Read | rel: 0
+int gvi = tmplVar<int>;
+// CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0
+// CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read | rel: 0
+int gvf = tmplVar<float>;