[cfe-commits] r104409 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/dependent-base-classes.cpp test/SemaTemplate/dependent-template-recover.cpp

Douglas Gregor dgregor at apple.com
Fri May 21 16:43:39 PDT 2010


Author: dgregor
Date: Fri May 21 18:43:39 2010
New Revision: 104409

URL: http://llvm.org/viewvc/llvm-project?rev=104409&view=rev
Log:
Improve recovery when we see a dependent template name that is missing
the required "template" keyword, using the same heuristics we do for
dependent template names in member access expressions, e.g.,

test/SemaTemplate/dependent-template-recover.cpp:11:8: error: use 'template'
      keyword to treat 'getAs' as a dependent template name
    T::getAs<U>();
       ^
       template 

Fixes PR5404.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp
    cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri May 21 18:43:39 2010
@@ -1463,7 +1463,7 @@
                                SourceLocation TemplateKWLoc = SourceLocation(),
                                bool AllowTypeAnnotation = true);
   void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
-  bool IsTemplateArgumentList();
+  bool IsTemplateArgumentList(unsigned Skip = 0);
   bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
   ParsedTemplateArgument ParseTemplateTemplateArgument();
   ParsedTemplateArgument ParseTemplateArgument();

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri May 21 18:43:39 2010
@@ -307,6 +307,31 @@
                                     SourceLocation(), false))
           return true;
         continue;
+      } 
+      
+      if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) && 
+          IsTemplateArgumentList(1)) {
+        // We have something like t::getAs<T>, where getAs is a 
+        // member of an unknown specialization. However, this will only
+        // parse correctly as a template, so suggest the keyword 'template'
+        // before 'getAs' and treat this as a dependent template name.
+        Diag(Tok.getLocation(), diag::err_missing_dependent_template_keyword)
+          << II.getName()
+          << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
+        
+        Template = Actions.ActOnDependentTemplateName(Tok.getLocation(), SS, 
+                                                      TemplateName, ObjectType,
+                                                      EnteringContext);
+        if (!Template.get())
+          return true;     
+        
+        // Consume the identifier.
+        ConsumeToken();
+        if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, &SS,
+                                    TemplateName, SourceLocation(), false))
+          return true;
+        
+        continue;        
       }
     }
 

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri May 21 18:43:39 2010
@@ -971,12 +971,17 @@
 /// \brief Determine whether the current tokens can only be parsed as a 
 /// template argument list (starting with the '<') and never as a '<' 
 /// expression.
-bool Parser::IsTemplateArgumentList() {
+bool Parser::IsTemplateArgumentList(unsigned Skip) {
   struct AlwaysRevertAction : TentativeParsingAction {
     AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
     ~AlwaysRevertAction() { Revert(); }
   } Tentative(*this);
   
+  while (Skip) {
+    ConsumeToken();
+    --Skip;
+  }
+  
   // '<'
   if (!Tok.is(tok::less))
     return false;

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri May 21 18:43:39 2010
@@ -175,6 +175,7 @@
                                        TemplateNameKind &SuggestedKind) {
   // We can't recover unless there's a dependent scope specifier preceding the
   // template name.
+  // FIXME: Typo correction?
   if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
       computeDeclContext(*SS))
     return false;

Modified: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp Fri May 21 18:43:39 2010
@@ -6,7 +6,7 @@
 };
 
 template<typename T, typename U>
-struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}}
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
 
 template<typename T>
 struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}

Modified: cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp Fri May 21 18:43:39 2010
@@ -8,6 +8,9 @@
     t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
     t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
 
+    T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+    t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+
     // FIXME: We can't recover from these yet
     (*t).f2<N>(); // expected-error{{expected expression}}
     (*t).f2<0>(); // expected-error{{expected expression}}





More information about the cfe-commits mailing list