Fixed instantiation of DependentScopeDeclRefExpr.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149868 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index fcc417a..40c5a4f 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -2022,7 +2022,7 @@
                                       SourceLocation TemplateKWLoc,
                                       const DeclarationNameInfo &NameInfo,
                                       bool ADL,
-                                      const TemplateArgumentListInfo &Args,
+                                      const TemplateArgumentListInfo *Args,
                                       UnresolvedSetIterator Begin,
                                       UnresolvedSetIterator End);
 
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 8aca77f..b4bbd7f 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -2369,7 +2369,6 @@
                                   bool HasTrailingLParen);
 
   ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                               SourceLocation TemplateKWLoc,
                                          const DeclarationNameInfo &NameInfo);
   ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
@@ -4001,12 +4000,12 @@
                                  SourceLocation TemplateKWLoc,
                                  LookupResult &R,
                                  bool RequiresADL,
-                               const TemplateArgumentListInfo &TemplateArgs);
+                               const TemplateArgumentListInfo *TemplateArgs);
 
   ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
                                           SourceLocation TemplateKWLoc,
                                const DeclarationNameInfo &NameInfo,
-                               const TemplateArgumentListInfo &TemplateArgs);
+                               const TemplateArgumentListInfo *TemplateArgs);
 
   TemplateNameKind ActOnDependentTemplateName(Scope *S,
                                               CXXScopeSpec &SS,
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index af8498d..df223eb 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -200,15 +200,17 @@
                              SourceLocation TemplateKWLoc,
                              const DeclarationNameInfo &NameInfo,
                              bool ADL,
-                             const TemplateArgumentListInfo &Args,
-                             UnresolvedSetIterator Begin, 
-                             UnresolvedSetIterator End) 
+                             const TemplateArgumentListInfo *Args,
+                             UnresolvedSetIterator Begin,
+                             UnresolvedSetIterator End)
 {
+  assert(Args || TemplateKWLoc.isValid());
+  unsigned num_args = Args ? Args->size() : 0;
   void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
-                         ASTTemplateKWAndArgsInfo::sizeFor(Args.size()));
+                         ASTTemplateKWAndArgsInfo::sizeFor(num_args));
   return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
                                         TemplateKWLoc, NameInfo,
-                                        ADL, /*Overload*/ true, &Args,
+                                        ADL, /*Overload*/ true, Args,
                                         Begin, End, /*StdIsAssociated=*/false);
 }
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 15dfb0b..a47421d 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1652,8 +1652,8 @@
                                              R, TemplateArgs);
   }
 
-  if (TemplateArgs)
-    return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, *TemplateArgs);
+  if (TemplateArgs || TemplateKWLoc.isValid())
+    return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs);
 
   return BuildDeclarationNameExpr(SS, R, ADL);
 }
@@ -1664,11 +1664,11 @@
 /// this path.
 ExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                        SourceLocation TemplateKWLoc,
                                         const DeclarationNameInfo &NameInfo) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
-    return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, 0);
+    return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
+                                     NameInfo, /*TemplateArgs=*/0);
 
   if (RequireCompleteDeclContext(SS, DC))
     return ExprError();
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 1545d6e..92cf619 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -232,8 +232,8 @@
   case IMA_Mixed_StaticContext:
   case IMA_Unresolved_StaticContext:
   case IMA_Field_Uneval_Context:
-    if (TemplateArgs)
-      return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, *TemplateArgs);
+    if (TemplateArgs || TemplateKWLoc.isValid())
+      return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
     return BuildDeclarationNameExpr(SS, R, false);
 
   case IMA_Error_StaticContext:
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 5fe136a..fa10381 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9310,9 +9310,9 @@
   if ((*R.begin())->isCXXClassMember())
     NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc,
                                                     R, ExplicitTemplateArgs);
-  else if (ExplicitTemplateArgs)
+  else if (ExplicitTemplateArgs || TemplateKWLoc.isValid())
     NewFn = SemaRef.BuildTemplateIdExpr(SS, TemplateKWLoc, R, false,
-                                        *ExplicitTemplateArgs);
+                                        ExplicitTemplateArgs);
   else
     NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false);
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 86c5a5b..44480a4 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -2203,7 +2203,7 @@
                                      SourceLocation TemplateKWLoc,
                                      LookupResult &R,
                                      bool RequiresADL,
-                                 const TemplateArgumentListInfo &TemplateArgs) {
+                                 const TemplateArgumentListInfo *TemplateArgs) {
   // FIXME: Can we do any checking at this point? I guess we could check the
   // template arguments that we have against the template name, if the template
   // name refers to a single template. That's not a terribly common case,
@@ -2237,13 +2237,13 @@
 Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
                                    SourceLocation TemplateKWLoc,
                                    const DeclarationNameInfo &NameInfo,
-                             const TemplateArgumentListInfo &TemplateArgs) {
+                             const TemplateArgumentListInfo *TemplateArgs) {
+  assert(TemplateArgs || TemplateKWLoc.isValid());
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) ||
       DC->isDependentContext() ||
       RequireCompleteDeclContext(SS, DC))
-    return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo,
-                                     &TemplateArgs);
+    return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
 
   bool MemberOfUnknownSpecialization;
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 6bbb831..806b878 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2032,12 +2032,11 @@
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
-    if (TemplateArgs)
+    if (TemplateArgs || TemplateKWLoc.isValid())
       return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc,
-                                                    NameInfo, *TemplateArgs);
+                                                    NameInfo, TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, TemplateKWLoc,
-                                                       NameInfo);
+    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo);
   }
 
   /// \brief Build a new template-id expression.
@@ -2048,7 +2047,7 @@
                                    SourceLocation TemplateKWLoc,
                                    LookupResult &R,
                                    bool RequiresADL,
-                              const TemplateArgumentListInfo &TemplateArgs) {
+                              const TemplateArgumentListInfo *TemplateArgs) {
     return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
                                          TemplateArgs);
   }
@@ -7361,8 +7360,9 @@
 
   SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
 
-  // If we have no template arguments, it's a normal declaration name.
-  if (!Old->hasExplicitTemplateArgs())
+  // If we have neither explicit template arguments, nor the template keyword,
+  // it's a normal declaration name.
+  if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
     return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
 
   // If we have template arguments, rebuild them, then rebuild the
@@ -7374,7 +7374,7 @@
     return ExprError();
 
   return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
-                                            Old->requiresADL(), TransArgs);
+                                            Old->requiresADL(), &TransArgs);
 }
 
 template<typename Derived>
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index de8d7f6..4416f92 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -82,3 +82,17 @@
     x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
   }
 };
+
+struct A {
+  template<int I>
+  struct B {
+    static void b1();
+  };
+};
+
+template<int I>
+void f5() {
+  A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
+}
+
+template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
diff --git a/test/SemaTemplate/template-id-printing.cpp b/test/SemaTemplate/template-id-printing.cpp
index 3b9e251..047589b 100644
--- a/test/SemaTemplate/template-id-printing.cpp
+++ b/test/SemaTemplate/template-id-printing.cpp
@@ -130,3 +130,12 @@
 }
 
 } // namespace DSME
+
+namespace DSDRE_withImplicitTemplateArgs {
+
+template <typename T> void foo() {
+  // CHECK: T::template bar();
+  T::template bar();
+}
+
+} // namespace DSDRE_withImplicitTemplateArgs