Push nested-name-specifier source location information into template
template arguments. I believe that this is the last place in the AST
where we were storing a source range for a nested-name-specifier
rather than a proper nested-name-specifier location structure. (Yay!)

There is still a lot of cleanup to do in the TreeTransform, which
doesn't take advantage of nested-name-specifiers with source-location
information everywhere it could.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126844 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 0d29096..90b0d7e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -469,7 +469,8 @@
     else
       TArg = Template;
     return TemplateArgumentLoc(TArg,
-                               Arg.getScopeSpec().getRange(),
+                               Arg.getScopeSpec().getWithLocInContext(
+                                                              SemaRef.Context),
                                Arg.getLocation(),
                                Arg.getEllipsisLoc());
   }
@@ -2201,6 +2202,9 @@
 /// \param Converted the list of template arguments provided for template
 /// parameters that precede \p Param in the template parameter list.
 ///
+/// \param QualifierLoc The nested-name-specifier, with source-location 
+/// information, which will also be instantiated and updated.
+///
 /// \returns the substituted template argument, or NULL if an error occurred.
 static TemplateName
 SubstDefaultTemplateArgument(Sema &SemaRef,
@@ -2208,7 +2212,8 @@
                              SourceLocation TemplateLoc,
                              SourceLocation RAngleLoc,
                              TemplateTemplateParmDecl *Param,
-                       llvm::SmallVectorImpl<TemplateArgument> &Converted) {
+                       llvm::SmallVectorImpl<TemplateArgument> &Converted,
+                             NestedNameSpecifierLoc &QualifierLoc) {
   TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
                                     Converted.data(), Converted.size());
 
@@ -2220,6 +2225,14 @@
                                    Converted.size(),
                                    SourceRange(TemplateLoc, RAngleLoc));
 
+  // Substitute into the nested-name-specifier first, 
+  if (QualifierLoc) {
+    QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, 
+                                                       AllTemplateArgs);
+    if (!QualifierLoc)
+      return TemplateName();
+  }
+  
   return SemaRef.SubstTemplateName(
                       Param->getDefaultArgument().getArgument().getAsTemplate(),
                               Param->getDefaultArgument().getTemplateNameLoc(),
@@ -2256,10 +2269,10 @@
       return TemplateArgumentLoc();
 
     ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
-                                                        TemplateLoc,
-                                                        RAngleLoc,
-                                                        NonTypeParm,
-                                                        Converted);
+                                                  TemplateLoc,
+                                                  RAngleLoc,
+                                                  NonTypeParm,
+                                                  Converted);
     if (Arg.isInvalid())
       return TemplateArgumentLoc();
 
@@ -2272,16 +2285,20 @@
   if (!TempTempParm->hasDefaultArgument())
     return TemplateArgumentLoc();
 
+
+  NestedNameSpecifierLoc QualifierLoc
+    = TempTempParm->getDefaultArgument().getTemplateQualifierLoc();
   TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
                                                     TemplateLoc,
                                                     RAngleLoc,
                                                     TempTempParm,
-                                                    Converted);
+                                                    Converted,
+                                                    QualifierLoc);
   if (TName.isNull())
     return TemplateArgumentLoc();
 
   return TemplateArgumentLoc(TemplateArgument(TName),
-                TempTempParm->getDefaultArgument().getTemplateQualifierRange(),
+                TempTempParm->getDefaultArgument().getTemplateQualifierLoc(),
                 TempTempParm->getDefaultArgument().getTemplateNameLoc());
 }
 
@@ -2392,11 +2409,8 @@
         DeclarationNameInfo NameInfo(DTN->getIdentifier(),
                                      Arg.getTemplateNameLoc());
 
-        // FIXME: TemplateArgumentLoc should store a NestedNameSpecifierLoc
-        // for the template name.
         CXXScopeSpec SS;
-        SS.MakeTrivial(Context, DTN->getQualifier(), 
-                       Arg.getTemplateQualifierRange());
+        SS.Adopt(Arg.getTemplateQualifierLoc());
         Expr *E = DependentScopeDeclRefExpr::Create(Context,
                                                 SS.getWithLocInContext(Context),
                                                     NameInfo);
@@ -2665,17 +2679,19 @@
         break;
       }
 
+      NestedNameSpecifierLoc QualifierLoc
+        = TempParm->getDefaultArgument().getTemplateQualifierLoc();
       TemplateName Name = SubstDefaultTemplateArgument(*this, Template,
                                                        TemplateLoc,
                                                        RAngleLoc,
                                                        TempParm,
-                                                       Converted);
+                                                       Converted,
+                                                       QualifierLoc);
       if (Name.isNull())
         return true;
 
-      Arg = TemplateArgumentLoc(TemplateArgument(Name),
-                  TempParm->getDefaultArgument().getTemplateQualifierRange(),
-                  TempParm->getDefaultArgument().getTemplateNameLoc());
+      Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc,
+                           TempParm->getDefaultArgument().getTemplateNameLoc());
     }
 
     // Introduce an instantiation record that describes where we are using
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 139fafb..c3d4362 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1728,11 +1728,24 @@
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
-  case TemplateArgument::Template:
-    return TemplateArgumentLoc(Arg, SourceRange(), Loc);
-
-  case TemplateArgument::TemplateExpansion:
-    return TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc);
+    case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion: {
+      NestedNameSpecifierLocBuilder Builder;
+      TemplateName Template = Arg.getAsTemplate();
+      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+        Builder.MakeTrivial(S.Context, DTN->getQualifier(), Loc);
+      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+        Builder.MakeTrivial(S.Context, QTN->getQualifier(), Loc);
+      
+      if (Arg.getKind() == TemplateArgument::Template)
+        return TemplateArgumentLoc(Arg, 
+                                   Builder.getWithLocInContext(S.Context),
+                                   Loc);
+      
+      
+      return TemplateArgumentLoc(Arg, Builder.getWithLocInContext(S.Context),
+                                 Loc, Loc);
+    }
 
   case TemplateArgument::Expression:
     return TemplateArgumentLoc(Arg, Arg.getAsExpr());
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index fe1e9aa..ce633cd 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2285,7 +2285,7 @@
       return TemplateArgumentLoc(TemplateArgument(
                                           Pattern.getArgument().getAsTemplate(),
                                                   NumExpansions),
-                                 Pattern.getTemplateQualifierRange(),
+                                 Pattern.getTemplateQualifierLoc(),
                                  Pattern.getTemplateNameLoc(),
                                  EllipsisLoc);
         
@@ -2841,12 +2841,25 @@
     break;
 
   case TemplateArgument::Template:
-    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
+  case TemplateArgument::TemplateExpansion: {
+    NestedNameSpecifierLocBuilder Builder;
+    TemplateName Template = Arg.getAsTemplate();
+    if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+      Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc);
+    else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+      Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc);
+        
+    if (Arg.getKind() == TemplateArgument::Template)
+      Output = TemplateArgumentLoc(Arg, 
+                                   Builder.getWithLocInContext(SemaRef.Context),
+                                   Loc);
+    else
+      Output = TemplateArgumentLoc(Arg, 
+                                   Builder.getWithLocInContext(SemaRef.Context),
+                                   Loc, Loc);
+    
     break;
-
-  case TemplateArgument::TemplateExpansion:
-    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc);
-    break;
+  }
 
   case TemplateArgument::Expression:
     Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
@@ -2905,14 +2918,20 @@
   }
 
   case TemplateArgument::Template: {
+    NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
+    if (QualifierLoc) {
+      QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+      if (!QualifierLoc)
+        return true;
+    }
+    
     TemporaryBase Rebase(*this, Input.getLocation(), DeclarationName());    
     TemplateName Template
       = getDerived().TransformTemplateName(Arg.getAsTemplate());
     if (Template.isNull())
       return true;
     
-    Output = TemplateArgumentLoc(TemplateArgument(Template),
-                                 Input.getTemplateQualifierRange(),
+    Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc,
                                  Input.getTemplateNameLoc());
     return false;
   }