Push nested-name-specifier source-location information into dependent
template specialization types. There are still a few rough edges to
clean up with some of the parser actions dropping
nested-name-specifiers too early.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126776 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 6139aae..d92f759 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -663,8 +663,8 @@
     assert(DTN->getQualifier()
              == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
     QualType T = Context.getDependentTemplateSpecializationType(ETK_None,
-                                                                DTN->getQualifier(),
-                                                                DTN->getIdentifier(),
+                                                          DTN->getQualifier(),
+                                                          DTN->getIdentifier(),
                                                                 TemplateArgs);
     
     // Create source-location information for this type.
@@ -675,7 +675,7 @@
     SpecTL.setRAngleLoc(RAngleLoc);
     SpecTL.setKeywordLoc(SourceLocation());
     SpecTL.setNameLoc(TemplateNameLoc);
-    SpecTL.setQualifierRange(SS.getRange());
+    SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index a710f94..16edbf7 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1767,7 +1767,11 @@
     SpecTL.setNameLoc(TemplateLoc);
     SpecTL.setLAngleLoc(LAngleLoc);
     SpecTL.setRAngleLoc(RAngleLoc);
-    SpecTL.setQualifierRange(TemplateLoc); // FIXME: nested-name-specifier loc
+    
+    // FIXME: Poor nested-name-specifier source-location information.
+    CXXScopeSpec SS;
+    SS.MakeTrivial(Context, DTN->getQualifier(), TemplateLoc);
+    SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
     for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
@@ -5967,12 +5971,10 @@
     SpecTL.setLAngleLoc(LAngleLoc);
     SpecTL.setRAngleLoc(RAngleLoc);
     SpecTL.setKeywordLoc(TypenameLoc);
+    SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
     SpecTL.setNameLoc(TemplateNameLoc);
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
-    
-    // FIXME: Nested-name-specifier source locations.
-    SpecTL.setQualifierRange(SS.getRange());
     return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
   }
   
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index afd118e..a2f1a6b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2276,8 +2276,7 @@
                        ? DS.getTypeSpecTypeLoc()
                        : SourceLocation());
       const CXXScopeSpec& SS = DS.getTypeSpecScope();
-      TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange());
-      // FIXME: load appropriate source location.
+      TL.setQualifierLoc(SS.getWithLocInContext(Context));
       TL.setNameLoc(DS.getTypeSpecTypeLoc());
     }
 
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 5485dfb..bd1e676 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -498,6 +498,11 @@
                                       DependentTemplateSpecializationTypeLoc TL,
                                                NestedNameSpecifier *Prefix);
 
+  QualType 
+  TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+                                               DependentTemplateSpecializationTypeLoc TL,
+                                         NestedNameSpecifierLoc QualifierLoc);
+
   /// \brief Transforms the parameters of a function type into the
   /// given vectors.
   ///
@@ -768,6 +773,48 @@
     return SemaRef.Context.getElaboratedType(Keyword, Qualifier, T);
   }
 
+  /// \brief Build a new typename type that refers to a template-id.
+  ///
+  /// By default, builds a new DependentNameType type from the
+  /// nested-name-specifier and the given type. Subclasses may override
+  /// this routine to provide different behavior.
+  QualType RebuildDependentTemplateSpecializationType(
+                                          ElaboratedTypeKeyword Keyword,
+                                          NestedNameSpecifierLoc QualifierLoc,
+                                          const IdentifierInfo *Name,
+                                          SourceLocation NameLoc,
+                                        const TemplateArgumentListInfo &Args) {
+    // Rebuild the template name.
+    // TODO: avoid TemplateName abstraction
+    TemplateName InstName 
+      = getDerived().RebuildTemplateName(QualifierLoc.getNestedNameSpecifier(),
+                                         QualifierLoc.getSourceRange(), *Name, 
+                                         QualType(), 0);
+    
+    if (InstName.isNull())
+      return QualType();
+    
+    // If it's still dependent, make a dependent specialization.
+    if (InstName.getAsDependentTemplateName())
+      return SemaRef.Context.getDependentTemplateSpecializationType(Keyword, 
+                                          QualifierLoc.getNestedNameSpecifier(), 
+                                                                    Name, 
+                                                                    Args);
+    
+    // Otherwise, make an elaborated type wrapping a non-dependent
+    // specialization.
+    QualType T =
+    getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
+    if (T.isNull()) return QualType();
+    
+    if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == 0)
+      return T;
+    
+    return SemaRef.Context.getElaboratedType(Keyword, 
+                                       QualifierLoc.getNestedNameSpecifier(), 
+                                             T);
+  }
+
   /// \brief Build a new typename type that refers to an identifier.
   ///
   /// By default, performs semantic analysis when building the typename type
@@ -4405,7 +4452,12 @@
     DependentTemplateSpecializationTypeLoc NewTL
       = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(TL.getQualifierRange());
+    
+    // FIXME: Poor nested-name-specifier source-location information.
+    CXXScopeSpec SS;
+    SS.MakeTrivial(SemaRef.Context, 
+                   DTN->getQualifier(), TL.getQualifierLoc().getSourceRange());
+    NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
     NewTL.setNameLoc(TL.getNameLoc());
     NewTL.setLAngleLoc(TL.getLAngleLoc());
     NewTL.setRAngleLoc(TL.getRAngleLoc());
@@ -4567,18 +4619,16 @@
 QualType TreeTransform<Derived>::
           TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
                                  DependentTemplateSpecializationTypeLoc TL) {
-  const DependentTemplateSpecializationType *T = TL.getTypePtr();
-
-  NestedNameSpecifier *NNS = 0;
-  if (T->getQualifier()) {
-    NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
-                                                    TL.getQualifierRange());
-    if (!NNS)
+  NestedNameSpecifierLoc QualifierLoc;
+  if (TL.getQualifierLoc()) {
+    QualifierLoc
+      = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
+    if (!QualifierLoc)
       return QualType();
   }
             
   return getDerived()
-           .TransformDependentTemplateSpecializationType(TLB, TL, NNS);
+           .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
 }
 
 template<typename Derived>
@@ -4586,6 +4636,7 @@
           TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
                                  DependentTemplateSpecializationTypeLoc TL,
                                                   NestedNameSpecifier *NNS) {
+  // FIXME: This routine needs to go away.
   const DependentTemplateSpecializationType *T = TL.getTypePtr();
 
   TemplateArgumentListInfo NewTemplateArgs;
@@ -4603,7 +4654,7 @@
   QualType Result
     = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
                                                               NNS,
-                                                        TL.getQualifierRange(),
+                                        TL.getQualifierLoc().getSourceRange(),
                                                             T->getIdentifier(),
                                                               TL.getNameLoc(),
                                                               NewTemplateArgs);
@@ -4628,7 +4679,8 @@
     // FIXME: DependentTemplateSpecializationType needs better source-location
     // info.
     NestedNameSpecifierLocBuilder Builder;
-    Builder.MakeTrivial(SemaRef.Context, NNS, TL.getQualifierRange());
+    Builder.MakeTrivial(SemaRef.Context, 
+                        NNS, TL.getQualifierLoc().getSourceRange());
     NewTL.setQualifierLoc(Builder.getWithLocInContext(SemaRef.Context));
   } else {
     TypeLoc NewTL(Result, TL.getOpaqueData());
@@ -4638,6 +4690,55 @@
 }
 
 template<typename Derived>
+QualType TreeTransform<Derived>::
+TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
+                                   DependentTemplateSpecializationTypeLoc TL,
+                                       NestedNameSpecifierLoc QualifierLoc) {
+  const DependentTemplateSpecializationType *T = TL.getTypePtr();
+  
+  TemplateArgumentListInfo NewTemplateArgs;
+  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
+  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+  
+  typedef TemplateArgumentLocContainerIterator<
+  DependentTemplateSpecializationTypeLoc> ArgIterator;
+  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
+                                              ArgIterator(TL, TL.getNumArgs()),
+                                              NewTemplateArgs))
+    return QualType();
+  
+  QualType Result
+    = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
+                                                              QualifierLoc,
+                                                            T->getIdentifier(),
+                                                            TL.getNameLoc(),
+                                                            NewTemplateArgs);
+  if (Result.isNull())
+    return QualType();
+  
+  if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
+    QualType NamedT = ElabT->getNamedType();
+    
+    // Copy information relevant to the template specialization.
+    TemplateSpecializationTypeLoc NamedTL
+    = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
+    NamedTL.setLAngleLoc(TL.getLAngleLoc());
+    NamedTL.setRAngleLoc(TL.getRAngleLoc());
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+      NamedTL.setArgLocInfo(I, TL.getArgLocInfo(I));
+    
+    // Copy information relevant to the elaborated type.
+    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+    NewTL.setKeywordLoc(TL.getKeywordLoc());
+    NewTL.setQualifierLoc(QualifierLoc);
+  } else {
+    TypeLoc NewTL(Result, TL.getOpaqueData());
+    TLB.pushFullCopy(NewTL);
+  }
+  return Result;
+}
+
+template<typename Derived>
 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
                                                       PackExpansionTypeLoc TL) {
   QualType Pattern