Push nested-name-specifier source-location information into dependent
template specialization types. This also required some parser tweaks,
since we were losing track of the nested-name-specifier's source
location information in several places in the parser. Other notable
changes this required:

  - Sema::ActOnTagTemplateIdType now type-checks and forms the
    appropriate type nodes (+ source-location information) for an
    elaborated-type-specifier ending in a template-id. Previously, we
    used a combination of ActOnTemplateIdType and
    ActOnTagTemplateIdType that resulted in an ElaboratedType wrapped
    around a DependentTemplateSpecializationType, which duplicated the
    keyword ("class", "struct", etc.) and nested-name-specifier
    storage.

  - Sema::ActOnTemplateIdType now gets a nested-name-specifier, which
    it places into the returned type-source location information.

  - Sema::ActOnDependentTag now creates types with source-location
    information.

llvm-svn: 126808
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 532c318..50ba705 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1013,7 +1013,7 @@
         ConsumeToken(); // The C++ scope.
         assert(Tok.is(tok::annot_template_id) &&
                "ParseOptionalCXXScopeSpecifier not working");
-        AnnotateTemplateIdTokenAsType(&SS);
+        AnnotateTemplateIdTokenAsType();
         continue;
       }
 
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 78fe4d2..f634424 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -508,14 +508,14 @@
 ///         simple-template-id
 ///
 Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
-                                          CXXScopeSpec *SS) {
+                                          CXXScopeSpec &SS) {
   // Check whether we have a template-id that names a type.
   if (Tok.is(tok::annot_template_id)) {
     TemplateIdAnnotation *TemplateId
       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
     if (TemplateId->Kind == TNK_Type_template ||
         TemplateId->Kind == TNK_Dependent_template_name) {
-      AnnotateTemplateIdTokenAsType(SS);
+      AnnotateTemplateIdTokenAsType();
 
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
       ParsedType Type = getTypeAnnotation(Tok);
@@ -544,7 +544,7 @@
     TemplateNameKind TNK = TNK_Type_template;
     TemplateTy Template;
     if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
-                                             SS, Template, TNK)) {
+                                             &SS, Template, TNK)) {
       Diag(IdLoc, diag::err_unknown_template_name)
         << Id;
     }
@@ -561,7 +561,7 @@
                                 SourceLocation(), true))
       return true;
     if (TNK == TNK_Dependent_template_name)
-      AnnotateTemplateIdTokenAsType(SS);
+      AnnotateTemplateIdTokenAsType();
 
     // If we didn't end up with a typename token, there's nothing more we
     // can do.
@@ -577,7 +577,7 @@
   }
 
   // We have an identifier; check whether it is actually a type.
-  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true,
+  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
                                         false, ParsedType(),
                                         /*NonTrivialTypeSourceInfo=*/true);
   if (!Type) {
@@ -592,7 +592,7 @@
   DeclSpec DS;
   DS.SetRangeStart(IdLoc);
   DS.SetRangeEnd(EndLocation);
-  DS.getTypeSpecScope() = *SS;
+  DS.getTypeSpecScope() = SS;
 
   const char *PrevSpec = 0;
   unsigned DiagID;
@@ -739,7 +739,7 @@
       // a class (or template thereof).
       TemplateArgList TemplateArgs;
       SourceLocation LAngleLoc, RAngleLoc;
-      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
+      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
                                            true, LAngleLoc,
                                            TemplateArgs, RAngleLoc)) {
         // We couldn't parse the template argument list at all, so don't
@@ -781,7 +781,8 @@
     TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
     NameLoc = ConsumeToken();
 
-    if (TemplateId->Kind != TNK_Type_template) {
+    if (TemplateId->Kind != TNK_Type_template &&
+        TemplateId->Kind != TNK_Dependent_template_name) {
       // The template-name in the simple-template-id refers to
       // something other than a class template. Give an appropriate
       // error message and skip to the ';'.
@@ -893,15 +894,14 @@
     } else if (TUK == Sema::TUK_Reference ||
                (TUK == Sema::TUK_Friend &&
                 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
-      TypeResult
-        = Actions.ActOnTemplateIdType(TemplateId->Template,
-                                      TemplateId->TemplateNameLoc,
-                                      TemplateId->LAngleLoc,
-                                      TemplateArgsPtr,
-                                      TemplateId->RAngleLoc);
-
-      TypeResult = Actions.ActOnTagTemplateIdType(SS, TypeResult, TUK,
-                                                  TagType, StartLoc);
+      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, 
+                                                  StartLoc, 
+                                                  TemplateId->SS,
+                                                  TemplateId->Template,
+                                                  TemplateId->TemplateNameLoc,
+                                                  TemplateId->LAngleLoc,
+                                                  TemplateArgsPtr,
+                                                  TemplateId->RAngleLoc);                                                  
     } else {
       // This is an explicit specialization or a class template
       // partial specialization.
@@ -1197,7 +1197,7 @@
 
   // Parse the class-name.
   SourceLocation EndLocation;
-  TypeResult BaseType = ParseClassName(EndLocation, &SS);
+  TypeResult BaseType = ParseClassName(EndLocation, SS);
   if (BaseType.isInvalid())
     return true;
 
@@ -1958,7 +1958,7 @@
       = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
     if (TemplateId->Kind == TNK_Type_template ||
         TemplateId->Kind == TNK_Dependent_template_name) {
-      AnnotateTemplateIdTokenAsType(&SS);
+      AnnotateTemplateIdTokenAsType();
       assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
       TemplateTypeTy = getTypeAnnotation(Tok);
     }
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 616c251..4a155a3 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -904,7 +904,7 @@
         // cast expression.
         CXXScopeSpec SS;
         ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
-        AnnotateTemplateIdTokenAsType(&SS);
+        AnnotateTemplateIdTokenAsType();
         return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
                                    NotCastExpr, TypeOfCast);
       }
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0e23e43..eef2f5e 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -173,7 +173,7 @@
                                                                     ObjectType, 
                                                                 EnteringContext,
                                                                     Template)) {
-        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+        if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 
                                     TemplateKWLoc, false))
           return true;
       } else
@@ -312,7 +312,7 @@
         // specializations) still want to see the original template-id
         // token.
         ConsumeToken();
-        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+        if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 
                                     SourceLocation(), false))
           return true;
         continue;
@@ -335,7 +335,7 @@
                                                    EnteringContext, Template)) {
           // Consume the identifier.
           ConsumeToken();
-          if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 
+          if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName, 
                                       SourceLocation(), false))
             return true;                
         }
@@ -1164,7 +1164,7 @@
   TemplateArgList TemplateArgs;
   if (Tok.is(tok::less) &&
       ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
-                                       &SS, true, LAngleLoc,
+                                       SS, true, LAngleLoc,
                                        TemplateArgs,
                                        RAngleLoc))
     return true;
@@ -1187,6 +1187,7 @@
       TemplateId->TemplateNameLoc = Id.StartLocation;
     }
 
+    TemplateId->SS = SS;
     TemplateId->Template = Template;
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
@@ -1206,7 +1207,7 @@
   
   // Constructor and destructor names.
   TypeResult Type
-    = Actions.ActOnTemplateIdType(Template, NameLoc,
+    = Actions.ActOnTemplateIdType(SS, Template, NameLoc,
                                   LAngleLoc, TemplateArgsPtr,
                                   RAngleLoc);
   if (Type.isInvalid())
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 59ced8b0..799c617 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -661,7 +661,7 @@
 bool
 Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
                                          SourceLocation TemplateNameLoc,
-                                         const CXXScopeSpec *SS,
+                                         const CXXScopeSpec &SS,
                                          bool ConsumeLastToken,
                                          SourceLocation &LAngleLoc,
                                          TemplateArgList &TemplateArgs,
@@ -756,7 +756,7 @@
 /// formed, this function returns true.
 ///
 bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
-                                     const CXXScopeSpec *SS,
+                                     CXXScopeSpec &SS,
                                      UnqualifiedId &TemplateName,
                                      SourceLocation TemplateKWLoc,
                                      bool AllowTypeAnnotation) {
@@ -790,7 +790,8 @@
   // Build the annotation token.
   if (TNK == TNK_Type_template && AllowTypeAnnotation) {
     TypeResult Type
-      = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
+      = Actions.ActOnTemplateIdType(SS, 
+                                    Template, TemplateNameLoc,
                                     LAngleLoc, TemplateArgsPtr,
                                     RAngleLoc);
     if (Type.isInvalid()) {
@@ -803,8 +804,8 @@
 
     Tok.setKind(tok::annot_typename);
     setTypeAnnotation(Tok, Type.get());
-    if (SS && SS->isNotEmpty())
-      Tok.setLocation(SS->getBeginLoc());
+    if (SS.isNotEmpty())
+      Tok.setLocation(SS.getBeginLoc());
     else if (TemplateKWLoc.isValid())
       Tok.setLocation(TemplateKWLoc);
     else
@@ -823,6 +824,7 @@
       TemplateId->Name = 0;
       TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
     }
+    TemplateId->SS = SS;
     TemplateId->Template = Template;
     TemplateId->Kind = TNK;
     TemplateId->LAngleLoc = LAngleLoc;
@@ -854,7 +856,7 @@
 /// If there was a failure when forming the type from the template-id,
 /// a type annotation token will still be created, but will have a
 /// NULL type pointer to signify an error.
-void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
+void Parser::AnnotateTemplateIdTokenAsType() {
   assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");
 
   TemplateIdAnnotation *TemplateId
@@ -868,7 +870,8 @@
                                      TemplateId->NumArgs);
 
   TypeResult Type
-    = Actions.ActOnTemplateIdType(TemplateId->Template,
+    = Actions.ActOnTemplateIdType(TemplateId->SS,
+                                  TemplateId->Template,
                                   TemplateId->TemplateNameLoc,
                                   TemplateId->LAngleLoc,
                                   TemplateArgsPtr,
@@ -876,8 +879,8 @@
   // Create the new "type" annotation token.
   Tok.setKind(tok::annot_typename);
   setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get());
-  if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
-    Tok.setLocation(SS->getBeginLoc());
+  if (TemplateId->SS.isNotEmpty()) // it was a C++ qualified type name.
+    Tok.setLocation(TemplateId->SS.getBeginLoc());
   // End location stays the same
 
   // Replace the template-id annotation token, and possible the scope-specifier
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index a603c37..1099327 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -907,7 +907,7 @@
     if (TemplateId->Kind != TNK_Type_template)
       return TPResult::False();
     CXXScopeSpec SS;
-    AnnotateTemplateIdTokenAsType(&SS);
+    AnnotateTemplateIdTokenAsType();
     assert(Tok.is(tok::annot_typename));
     goto case_typename;
   }
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index ba3c03c..eb78db0 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1129,7 +1129,7 @@
                                    Template, MemberOfUnknownSpecialization)) {
         // Consume the identifier.
         ConsumeToken();
-        if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) {
+        if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName)) {
           // If an unrecoverable error occurred, we need to return true here,
           // because the token stream is in a damaged state.  We may not return
           // a valid identifier.
@@ -1152,7 +1152,7 @@
       // template-id annotation in a context where we weren't allowed
       // to produce a type annotation token. Update the template-id
       // annotation token to a type annotation token now.
-      AnnotateTemplateIdTokenAsType(&SS);
+      AnnotateTemplateIdTokenAsType();
       return false;
     }
   }