[cfe-commits] r85616 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td lib/Parse/ParseDeclCXX.cpp test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp test/CXX/temp/temp.spec/temp.explicit/p5.cpp test/Parser/cxx-template-decl.cpp
Douglas Gregor
dgregor at apple.com
Fri Oct 30 14:46:59 PDT 2009
Author: dgregor
Date: Fri Oct 30 16:46:58 2009
New Revision: 85616
URL: http://llvm.org/viewvc/llvm-project?rev=85616&view=rev
Log:
Improve diagnostics when parsing something like
template<> struct foo<int> { ... };
where "foo" does not refer to a template. Fixes PR3844.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
cfe/trunk/test/Parser/cxx-template-decl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=85616&r1=85615&r2=85616&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Oct 30 16:46:58 2009
@@ -282,6 +282,8 @@
"typename specifier refers to a non-template">;
def err_expected_type_name_after_typename : Error<
"expected an identifier or template-id after '::'">;
+def err_explicit_spec_non_template : Error<
+ "explicit specialization of non-template %select{class|struct|union}0 %1">;
def err_variadic_templates : Error<
"variadic templates are only allowed in C++0x">;
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=85616&r1=85615&r2=85616&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Oct 30 16:46:58 2009
@@ -589,6 +589,8 @@
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Diag(Tok, diag::err_expected_ident);
+ TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
+
// Parse the (optional) class name or simple-template-id.
IdentifierInfo *Name = 0;
SourceLocation NameLoc;
@@ -596,6 +598,42 @@
if (Tok.is(tok::identifier)) {
Name = Tok.getIdentifierInfo();
NameLoc = ConsumeToken();
+
+ if (Tok.is(tok::less)) {
+ // The name was supposed to refer to a template, but didn't.
+ // Eat the template argument list and try to continue parsing this as
+ // a class (or template thereof).
+ TemplateArgList TemplateArgs;
+ TemplateArgIsTypeList TemplateArgIsType;
+ TemplateArgLocationList TemplateArgLocations;
+ SourceLocation LAngleLoc, RAngleLoc;
+ if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
+ true, LAngleLoc,
+ TemplateArgs, TemplateArgIsType,
+ TemplateArgLocations, RAngleLoc)) {
+ // We couldn't parse the template argument list at all, so don't
+ // try to give any location information for the list.
+ LAngleLoc = RAngleLoc = SourceLocation();
+ }
+
+ Diag(NameLoc, diag::err_explicit_spec_non_template)
+ << (TagType == DeclSpec::TST_class? 0
+ : TagType == DeclSpec::TST_struct? 1
+ : 2)
+ << Name
+ << SourceRange(LAngleLoc, RAngleLoc);
+
+ // If this is an explicit specialization, strip off the last template
+ // parameter list, since we've removed its template arguments.
+ if (TemplateParams && TemplateParams->size() > 1) {
+ TemplateParams->pop_back();
+ } else {
+ TemplateParams = 0;
+ const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
+ = ParsedTemplateInfo::NonTemplate;
+ }
+
+ }
} else if (Tok.is(tok::annot_template_id)) {
TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
NameLoc = ConsumeToken();
@@ -660,7 +698,6 @@
// Create the tag portion of the class or class template.
Action::DeclResult TagOrTempResult = true; // invalid
Action::TypeResult TypeResult = true; // invalid
- TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
// FIXME: When TUK == TUK_Reference and we have a template-id, we need
// to turn that template-id into a type.
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp?rev=85616&r1=85615&r2=85616&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp Fri Oct 30 16:46:58 2009
@@ -4,8 +4,7 @@
template<class T> class X;
}
-// FIXME: this diagnostic is terrible (PR3844).
-template<> class X<int> { /* ... */ }; // expected-error {{unqualified-id}}
+template<> class X<int> { /* ... */ }; // expected-error {{non-template class 'X'}}
namespace N {
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p5.cpp?rev=85616&r1=85615&r2=85616&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.explicit/p5.cpp Fri Oct 30 16:46:58 2009
@@ -6,8 +6,7 @@
};
}
-// FIXME: poor diagnostic
-template class Z<int>; // expected-error{{unqualified-id}}
+template class Z<int>; // expected-error{{non-template class 'Z'}}
// FIXME: This example from the standard is wrong; note posted to CWG reflector
// on 10/27/2009
Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=85616&r1=85615&r2=85616&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Fri Oct 30 16:46:58 2009
@@ -92,3 +92,7 @@
int x;
A< typeof(x>1) > a;
}
+
+
+// PR3844
+template <> struct S<int> { }; // expected-error{{explicit specialization of non-template struct 'S'}}
More information about the cfe-commits
mailing list