Reinstate the introduction of source-location information for
nested-name-speciciers within elaborated type names, e.g.,
 
  enum clang::NestedNameSpecifier::SpecifierKind

Fixes in this iteration include:

  (1) Compute the type-source range properly for a dependent template
  specialization type that starts with "template template-id ::", as
  in a member access expression

    dep->template f<T>::f()

  This is a latent bug I triggered with this change (because now we're
  checking the computed source ranges for dependent template
  specialization types). But the real problem was...

  (2) Make sure to set the qualifier range on a dependent template
  specialization type appropriately. This will go away once we push
  nested-name-specifier locations into dependent template
  specialization types, but it was the source of the
  valgrind errors on the buildbots.
  

llvm-svn: 126765
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 8eb628f..6139aae 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -675,6 +675,7 @@
     SpecTL.setRAngleLoc(RAngleLoc);
     SpecTL.setKeywordLoc(SourceLocation());
     SpecTL.setNameLoc(TemplateNameLoc);
+    SpecTL.setQualifierRange(SS.getRange());
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0629717..9d90499 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -17,6 +17,7 @@
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "TypeLocBuilder.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -61,7 +62,8 @@
 ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
                              Scope *S, CXXScopeSpec *SS,
                              bool isClassName, bool HasTrailingDot,
-                             ParsedType ObjectTypePtr) {
+                             ParsedType ObjectTypePtr,
+                             bool WantNontrivialTypeSourceInfo) {
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = 0;
   if (ObjectTypePtr) {
@@ -87,11 +89,15 @@
         
         // We know from the grammar that this name refers to a type,
         // so build a dependent node to describe the type.
+        if (WantNontrivialTypeSourceInfo)
+          return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get();
+        
+        NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context);
         QualType T =
-          CheckTypenameType(ETK_None, SourceLocation(),
-                            SS->getWithLocInContext(Context),
+          CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
                             II, NameLoc);
-        return ParsedType::make(T);
+        
+          return ParsedType::make(T);
       }
       
       return ParsedType();
@@ -190,9 +196,21 @@
     if (T.isNull())
       T = Context.getTypeDeclType(TD);
     
-    if (SS)
-      T = getElaboratedType(ETK_None, *SS, T);
-    
+    if (SS && SS->isNotEmpty()) {
+      if (WantNontrivialTypeSourceInfo) {
+        // Construct a type with type-source information.
+        TypeLocBuilder Builder;
+        Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+        
+        T = getElaboratedType(ETK_None, *SS, T);
+        ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+        ElabTL.setKeywordLoc(SourceLocation());
+        ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
+        return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+      } else {
+        T = getElaboratedType(ETK_None, *SS, T);
+      }
+    }
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     if (!HasTrailingDot)
       T = Context.getObjCInterfaceType(IDecl);
@@ -264,7 +282,9 @@
         Diag(Result->getLocation(), diag::note_previous_decl)
           << Result->getDeclName();
         
-        SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS);
+        SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS,
+                                    false, false, ParsedType(),
+                                    /*NonTrivialTypeSourceInfo=*/true);
         return true;
       }
     } else if (Lookup.empty()) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1a7604f..f760f3f 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6930,7 +6930,7 @@
     } else {
       ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
       TL.setKeywordLoc(TagLoc);
-      TL.setQualifierRange(SS.getRange());
+      TL.setQualifierLoc(QualifierLoc);
       cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(NameLoc);
     }
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index afb7817..a710f94 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1821,12 +1821,12 @@
 
   ElaboratedTypeKeyword Keyword
     = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
-  QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
+  QualType ElabType = Context.getElaboratedType(Keyword, SS.getScopeRep(), Type);
 
   TypeSourceInfo *ElabDI = Context.CreateTypeSourceInfo(ElabType);
   ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(ElabDI->getTypeLoc());
   TL.setKeywordLoc(TagLoc);
-  TL.setQualifierRange(SS.getRange());
+  TL.setQualifierLoc(SS.getWithLocInContext(Context));
   TL.getNamedTypeLoc().initializeFullCopy(DI->getTypeLoc());
   return CreateParsedType(ElabType, ElabDI);
 }
@@ -5910,8 +5910,8 @@
       << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
-  QualType T = CheckTypenameType(ETK_Typename, TypenameLoc, QualifierLoc,
-                                 II, IdLoc);
+  QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None,
+                                 TypenameLoc, QualifierLoc, II, IdLoc);
   if (T.isNull())
     return true;
 
@@ -5924,7 +5924,7 @@
   } else {
     ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
     TL.setKeywordLoc(TypenameLoc);
-    TL.setQualifierRange(SS.getRange());
+    TL.setQualifierLoc(QualifierLoc);
     cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
   }
 
@@ -5996,7 +5996,8 @@
   T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
   ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
   TL.setKeywordLoc(TypenameLoc);
-  TL.setQualifierRange(SS.getRange());
+  TL.setQualifierLoc(SS.getWithLocInContext(Context));
+  
   TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
   return CreateParsedType(T, TSI);
 }
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index ae0ac9c..c0f130d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -730,7 +730,8 @@
     /// elaborated type.
     QualType RebuildElaboratedType(SourceLocation KeywordLoc,
                                    ElaboratedTypeKeyword Keyword,
-                                   NestedNameSpecifier *NNS, QualType T);
+                                   NestedNameSpecifierLoc QualifierLoc,
+                                   QualType T);
 
     TemplateName TransformTemplateName(TemplateName Name,
                                        QualType ObjectType = QualType(),
@@ -892,7 +893,7 @@
 QualType
 TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
                                             ElaboratedTypeKeyword Keyword,
-                                            NestedNameSpecifier *NNS,
+                                            NestedNameSpecifierLoc QualifierLoc,
                                             QualType T) {
   if (const TagType *TT = T->getAs<TagType>()) {
     TagDecl* TD = TT->getDecl();
@@ -918,7 +919,8 @@
 
   return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(KeywordLoc,
                                                                     Keyword,
-                                                                    NNS, T);
+                                                                  QualifierLoc,
+                                                                    T);
 }
 
 TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name,
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 9d35b1a..afd118e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2237,7 +2237,7 @@
                        ? DS.getTypeSpecTypeLoc()
                        : SourceLocation());
       const CXXScopeSpec& SS = DS.getTypeSpecScope();
-      TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange());
+      TL.setQualifierLoc(SS.getWithLocInContext(Context));
       Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
     }
     void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c7a11de..5485dfb 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -723,8 +723,11 @@
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildElaboratedType(SourceLocation KeywordLoc,
                                  ElaboratedTypeKeyword Keyword,
-                                 NestedNameSpecifier *NNS, QualType Named) {
-    return SemaRef.Context.getElaboratedType(Keyword, NNS, Named);
+                                 NestedNameSpecifierLoc QualifierLoc,
+                                 QualType Named) {
+    return SemaRef.Context.getElaboratedType(Keyword, 
+                                         QualifierLoc.getNestedNameSpecifier(), 
+                                             Named);
   }
 
   /// \brief Build a new typename type that refers to a template-id.
@@ -4436,12 +4439,12 @@
                                                 ElaboratedTypeLoc TL) {
   const ElaboratedType *T = TL.getTypePtr();
 
-  NestedNameSpecifier *NNS = 0;
+  NestedNameSpecifierLoc QualifierLoc;
   // NOTE: the qualifier in an ElaboratedType is optional.
-  if (T->getQualifier() != 0) {
-    NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
-                                                    TL.getQualifierRange());
-    if (!NNS)
+  if (TL.getQualifierLoc()) {
+    QualifierLoc 
+      = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
+    if (!QualifierLoc)
       return QualType();
   }
 
@@ -4451,18 +4454,18 @@
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
-      NNS != T->getQualifier() ||
+      QualifierLoc != TL.getQualifierLoc() ||
       NamedT != T->getNamedType()) {
     Result = getDerived().RebuildElaboratedType(TL.getKeywordLoc(),
-                                                T->getKeyword(), NNS, NamedT);
+                                                T->getKeyword(), 
+                                                QualifierLoc, NamedT);
     if (Result.isNull())
       return QualType();
   }
 
   ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
   NewTL.setKeywordLoc(TL.getKeywordLoc());
-  NewTL.setQualifierRange(TL.getQualifierRange());
-
+  NewTL.setQualifierLoc(QualifierLoc);
   return Result;
 }
 
@@ -4550,7 +4553,7 @@
 
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(QualifierLoc.getSourceRange());
+    NewTL.setQualifierLoc(QualifierLoc);
   } else {
     DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
@@ -4621,7 +4624,12 @@
     // Copy information relevant to the elaborated type.
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(TL.getQualifierRange());
+    
+    // FIXME: DependentTemplateSpecializationType needs better source-location
+    // info.
+    NestedNameSpecifierLocBuilder Builder;
+    Builder.MakeTrivial(SemaRef.Context, NNS, TL.getQualifierRange());
+    NewTL.setQualifierLoc(Builder.getWithLocInContext(SemaRef.Context));
   } else {
     TypeLoc NewTL(Result, TL.getOpaqueData());
     TLB.pushFullCopy(NewTL);