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/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 1764f4a..b57f10b 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -356,14 +356,14 @@
       return SourceRange();
 
   case TemplateArgument::Template:
-    if (getTemplateQualifierRange().isValid())
-      return SourceRange(getTemplateQualifierRange().getBegin(), 
+    if (getTemplateQualifierLoc())
+      return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
                          getTemplateNameLoc());
     return SourceRange(getTemplateNameLoc());
 
   case TemplateArgument::TemplateExpansion:
-    if (getTemplateQualifierRange().isValid())
-      return SourceRange(getTemplateQualifierRange().getBegin(), 
+    if (getTemplateQualifierLoc())
+      return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 
                          getTemplateEllipsisLoc());
     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
 
@@ -425,7 +425,7 @@
     Ellipsis = getTemplateEllipsisLoc();
     NumExpansions = Argument.getNumTemplateExpansions();
     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
-                               getTemplateQualifierRange(),
+                               getTemplateQualifierLoc(),
                                getTemplateNameLoc());
     
   case TemplateArgument::Declaration:
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 4f066d2..d42f42e 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -291,13 +291,22 @@
       break;
         
     case TemplateArgument::Template:
-      ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc, 
-                                            SourceLocation());
-      break;
+    case TemplateArgument::TemplateExpansion: {
+      NestedNameSpecifierLocBuilder Builder;
+      TemplateName Template = Args[i].getAsTemplate();
+      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
+      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
       
-    case TemplateArgument::TemplateExpansion:
-      ArgInfos[i] = TemplateArgumentLocInfo(SourceRange(Loc), Loc, Loc);
+      ArgInfos[i] = TemplateArgumentLocInfo(
+                                           Builder.getWithLocInContext(Context),
+                                            Loc, 
+                                Args[i].getKind() == TemplateArgument::Template
+                                            ? SourceLocation()
+                                            : Loc);
       break;
+    }        
     }
   }
 }
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;
   }
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 8ac4c15..98dd4c2 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3678,16 +3678,18 @@
   case TemplateArgument::Type:
     return GetTypeSourceInfo(F, Record, Index);
   case TemplateArgument::Template: {
-    SourceRange QualifierRange = ReadSourceRange(F, Record, Index);
+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
+                                                                     Index);
     SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
-    return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc,
+    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc,
                                    SourceLocation());
   }
   case TemplateArgument::TemplateExpansion: {
-    SourceRange QualifierRange = ReadSourceRange(F, Record, Index);
+    NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, 
+                                                                     Index);
     SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
     SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
-    return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, 
+    return TemplateArgumentLocInfo(QualifierLoc, TemplateNameLoc, 
                                    EllipsisLoc);
   }
   case TemplateArgument::Null:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index a8b203e..90849d7 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3246,11 +3246,11 @@
     AddTypeSourceInfo(Arg.getAsTypeSourceInfo(), Record);
     break;
   case TemplateArgument::Template:
-    AddSourceRange(Arg.getTemplateQualifierRange(), Record);
+    AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record);
     AddSourceLocation(Arg.getTemplateNameLoc(), Record);
     break;
   case TemplateArgument::TemplateExpansion:
-    AddSourceRange(Arg.getTemplateQualifierRange(), Record);
+    AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc(), Record);
     AddSourceLocation(Arg.getTemplateNameLoc(), Record);
     AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record);
     break;