]> granicus.if.org Git - clang/commitdiff
Push nested-name-specifier source location information into template
authorDouglas Gregor <dgregor@apple.com>
Wed, 2 Mar 2011 17:09:35 +0000 (17:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 2 Mar 2011 17:09:35 +0000 (17:09 +0000)
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

12 files changed:
include/clang/AST/RecursiveASTVisitor.h
include/clang/AST/TemplateBase.h
lib/AST/TemplateBase.cpp
lib/AST/TypeLoc.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateDeduction.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/Index/annotate-nested-name-specifier.cpp
test/SemaCXX/nested-name-spec-locations.cpp
tools/libclang/CIndex.cpp

index 9abb78bbf301a169e4b88cf7a638b0ad50c74fe8..daa61c93d67cfeb0789b3541b183527057d0f8bb 100644 (file)
@@ -606,6 +606,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
 
   case TemplateArgument::Template:
   case TemplateArgument::TemplateExpansion:
+    if (ArgLoc.getTemplateQualifierLoc())
+      TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+                                            ArgLoc.getTemplateQualifierLoc()));
     return getDerived().TraverseTemplateName(
                                          Arg.getAsTemplateOrTemplatePattern());
 
index a4e074e083f624919f31762420a39ad4e74e4425..821b4fcbb168b7aa079c2b5e708b4bf986089002 100644 (file)
@@ -362,7 +362,10 @@ private:
     Expr *Expression;
     TypeSourceInfo *Declarator;
     struct {
-      unsigned QualifierRange[2];
+      // FIXME: We'd like to just use the qualifier in the TemplateName,
+      // but template arguments get canonicalized too quickly.
+      NestedNameSpecifier *Qualifier;
+      void *QualifierLocData;
       unsigned TemplateNameLoc;
       unsigned EllipsisLoc;
     } Template;
@@ -375,12 +378,12 @@ public:
   
   TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
   
-  TemplateArgumentLocInfo(SourceRange QualifierRange, 
+  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
                           SourceLocation TemplateNameLoc,
                           SourceLocation EllipsisLoc)
   {
-    Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
-    Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
+    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
+    Template.QualifierLocData = QualifierLoc.getOpaqueData();
     Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
     Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
   }
@@ -393,10 +396,9 @@ public:
     return Expression;
   }
 
-  SourceRange getTemplateQualifierRange() const {
-    return SourceRange(
-                SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
-                SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
+  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
+    return NestedNameSpecifierLoc(Template.Qualifier, 
+                                  Template.QualifierLocData);
   }
   
   SourceLocation getTemplateNameLoc() const {
@@ -433,11 +435,10 @@ public:
   }
 
   TemplateArgumentLoc(const TemplateArgument &Argument, 
-                      SourceRange QualifierRange,
+                      NestedNameSpecifierLoc QualifierLoc,
                       SourceLocation TemplateNameLoc,
                       SourceLocation EllipsisLoc = SourceLocation())
-    : Argument(Argument), 
-      LocInfo(QualifierRange, TemplateNameLoc, EllipsisLoc) {
+    : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
     assert(Argument.getKind() == TemplateArgument::Template ||
            Argument.getKind() == TemplateArgument::TemplateExpansion);
   }
@@ -477,10 +478,10 @@ public:
     return LocInfo.getAsExpr();
   }
   
-  SourceRange getTemplateQualifierRange() const {
+  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
     assert(Argument.getKind() == TemplateArgument::Template ||
            Argument.getKind() == TemplateArgument::TemplateExpansion);
-    return LocInfo.getTemplateQualifierRange();
+    return LocInfo.getTemplateQualifierLoc();
   }
   
   SourceLocation getTemplateNameLoc() const {
index 1764f4ab1f03a915dd3c15e2cfe319f9c279213d..b57f10b0c64392078d808ca7abbec17fc8d1b09f 100644 (file)
@@ -356,14 +356,14 @@ SourceRange TemplateArgumentLoc::getSourceRange() const {
       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 @@ TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
     Ellipsis = getTemplateEllipsisLoc();
     NumExpansions = Argument.getNumTemplateExpansions();
     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
-                               getTemplateQualifierRange(),
+                               getTemplateQualifierLoc(),
                                getTemplateNameLoc());
     
   case TemplateArgument::Declaration:
index 4f066d2de2d26ee9768c3279b7e4a99f29a1cd7a..d42f42ed15472d14887a1a71937ec849c6a49dfc 100644 (file)
@@ -291,13 +291,22 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
       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;
+    }        
     }
   }
 }
index 0d290969dbec2995b59d7902db29520d8ae64bfe..90b0d7e29b58e1d1037aab5f5431cb4ffc6e08e2 100644 (file)
@@ -469,7 +469,8 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
     else
       TArg = Template;
     return TemplateArgumentLoc(TArg,
-                               Arg.getScopeSpec().getRange(),
+                               Arg.getScopeSpec().getWithLocInContext(
+                                                              SemaRef.Context),
                                Arg.getLocation(),
                                Arg.getEllipsisLoc());
   }
@@ -2201,6 +2202,9 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
 /// \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 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
                              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 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
                                    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 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
       return TemplateArgumentLoc();
 
     ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
-                                                        TemplateLoc,
-                                                        RAngleLoc,
-                                                        NonTypeParm,
-                                                        Converted);
+                                                  TemplateLoc,
+                                                  RAngleLoc,
+                                                  NonTypeParm,
+                                                  Converted);
     if (Arg.isInvalid())
       return TemplateArgumentLoc();
 
@@ -2272,16 +2285,20 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
   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 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
         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 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
         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
index 139fafb346f99618469252e40aad066ad431b197..c3d4362a16df79e5aae46a594224cb4ad4479fda 100644 (file)
@@ -1728,11 +1728,24 @@ getTrivialTemplateArgumentLoc(Sema &S,
     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());
index fe1e9aa9d242a21eb67e8a61eab58aec5af27e64..ce633cde2a52b3f2295f717ea766bbf5e36a7141 100644 (file)
@@ -2285,7 +2285,7 @@ public:
       return TemplateArgumentLoc(TemplateArgument(
                                           Pattern.getArgument().getAsTemplate(),
                                                   NumExpansions),
-                                 Pattern.getTemplateQualifierRange(),
+                                 Pattern.getTemplateQualifierLoc(),
                                  Pattern.getTemplateNameLoc(),
                                  EllipsisLoc);
         
@@ -2841,12 +2841,25 @@ void TreeTransform<Derived>::InventTemplateArgumentLoc(
     break;
 
   case TemplateArgument::Template:
-    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
-    break;
-
-  case TemplateArgument::TemplateExpansion:
-    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc, 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::Expression:
     Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
@@ -2905,14 +2918,20 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
   }
 
   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;
   }
index 8ac4c15bd334d9f25e3f7640710e545bd173b86c..98dd4c2fd662ac2c75f002f2a48d61e38114b963 100644 (file)
@@ -3678,16 +3678,18 @@ ASTReader::GetTemplateArgumentLocInfo(PerFileData &F,
   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:
index a8b203eb29e74854d67cd387aac476fe0da37c7f..90849d77faff21fba6b049ea2c24c83aee96a47a 100644 (file)
@@ -3246,11 +3246,11 @@ void ASTWriter::AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
     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;
index 150a34af1b788a7a768aa763751d3e28d0de61cc..b2f6a26e611fd341c5adaf203420ccae63d48fde 100644 (file)
@@ -110,7 +110,23 @@ struct X6 {
   typedef class outer_alias::inner::vector<type>::template rebind<type>::other type4;
 };
 
-// RUN: c-index-test -test-annotate-tokens=%s:13:1:111:1 %s | FileCheck %s
+namespace outer {
+  namespace inner {
+    template<typename T, template<class> class TT>
+    struct apply_meta {
+      typedef typename TT<T>::type type;
+    };
+  }
+}
+
+template<typename T, typename U>
+struct X7 {
+  typedef T T_type;
+  typedef U U_type;
+  typedef outer_alias::inner::apply_meta<T_type, U_type::template apply> type;
+};
+
+// RUN: c-index-test -test-annotate-tokens=%s:13:1:128:1 %s | FileCheck %s
 
 // CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12]
 // CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11
@@ -404,3 +420,21 @@ struct X6 {
 // CHECK: Punctuation: "::" [110:72 - 110:74] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Identifier: "other" [110:74 - 110:79] TypedefDecl=type4:110:80 (Definition)
 // CHECK: Identifier: "type4" [110:80 - 110:85] TypedefDecl=type4:110:80 (Definition)
+
+// Template template arguments
+// CHECK: Keyword: "typedef" [126:3 - 126:10] ClassTemplate=X7:123:8 (Definition)
+// CHECK: Identifier: "outer_alias" [126:11 - 126:22] NamespaceRef=outer_alias:10:11
+// CHECK: Punctuation: "::" [126:22 - 126:24] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "inner" [126:24 - 126:29] NamespaceRef=inner:114:13
+// CHECK: Punctuation: "::" [126:29 - 126:31] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "apply_meta" [126:31 - 126:41] TemplateRef=apply_meta:116:12
+// CHECK: Punctuation: "<" [126:41 - 126:42] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "T_type" [126:42 - 126:48] TypeRef=T_type:124:13
+// CHECK: Punctuation: "," [126:48 - 126:49] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "U_type" [126:50 - 126:56] TypeRef=U_type:125:13
+// CHECK: Punctuation: "::" [126:56 - 126:58] TypedefDecl=type:126:74 (Definition)
+// CHECK: Keyword: "template" [126:58 - 126:66] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "apply" [126:67 - 126:72] TypedefDecl=type:126:74 (Definition)
+// CHECK: Punctuation: ">" [126:72 - 126:73] TypedefDecl=type:126:74 (Definition)
+// CHECK: Identifier: "type" [126:74 - 126:78] TypedefDecl=type:126:74 (Definition)
+
index d543f335e7474085376915a2a10b3e098ce6fa44..6398e249a4fe2e7b91fda5747fa03d65f212a806 100644 (file)
@@ -128,3 +128,21 @@ struct DependentTemplateSpecializationTypeTester4 {
 };
 
 DependentTemplateSpecializationTypeTester4<HasApply, int> DTSTCheck4; // expected-note{{in instantiation of template class}}
+
+template<template<class T> class TTP>
+struct AcceptedTemplateTemplateParameter {
+};
+
+template<typename T, typename U>
+struct DependentTemplateTemplateArgumentTester {
+  typedef AcceptedTemplateTemplateParameter<
+            T::
+            template apply<
+              typename add_reference<U>::type
+              * // expected-error{{declared as a pointer to a reference of type}}
+            >::
+            template X>
+    type;
+};
+
+DependentTemplateTemplateArgumentTester<HasApply, int> DTTACheck; // expected-note{{in instantiation of template class}}
index 8a7dd4d7ea29d648657a68622bdf84e9f65b49a5..ad3f1df105d17c019a2d826ca6f25054f4b98a81 100644 (file)
@@ -1319,6 +1319,9 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
   
   case TemplateArgument::Template:
   case TemplateArgument::TemplateExpansion:
+    if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
+      return true;
+      
     return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 
                              TAL.getTemplateNameLoc());
   }