[cfe-commits] r97570 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Sema/SemaDecl.cpp test/SemaTemplate/template-decl-fail.cpp

Douglas Gregor dgregor at apple.com
Tue Mar 2 09:53:14 PST 2010


Author: dgregor
Date: Tue Mar  2 11:53:14 2010
New Revision: 97570

URL: http://llvm.org/viewvc/llvm-project?rev=97570&view=rev
Log:
Diagnose the declaration of enum templates. Also, be a bit more
careful about value-dependent enumerators. Fixes PR5786.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaTemplate/template-decl-fail.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=97570&r1=97569&r2=97570&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Mar  2 11:53:14 2010
@@ -300,6 +300,7 @@
     "explicit template instantiation cannot have a definition; if this "
     "definition is meant to be an explicit specialization, add '<>' after the "
     "'template' keyword">;
+def err_enum_template : Error<"enumeration cannot be a template">;
 
 // Constructor template diagnostics.
 def err_out_of_line_constructor_template_id : Error<

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=97570&r1=97569&r2=97570&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Mar  2 11:53:14 2010
@@ -1115,7 +1115,7 @@
   void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
 
   void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
-                          AccessSpecifier AS = AS_none);
+                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),                          AccessSpecifier AS = AS_none);
   void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
   void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
                             DeclPtrTy TagDecl);

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=97570&r1=97569&r2=97570&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Mar  2 11:53:14 2010
@@ -738,7 +738,7 @@
 
       // Parse this as a tag as if the missing tag were present.
       if (TagKind == tok::kw_enum)
-        ParseEnumSpecifier(Loc, DS, AS);
+        ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
       else
         ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
       return true;
@@ -1306,7 +1306,7 @@
     // enum-specifier:
     case tok::kw_enum:
       ConsumeToken();
-      ParseEnumSpecifier(Loc, DS, AS);
+      ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
       continue;
 
     // cv-qualifier:
@@ -1572,7 +1572,7 @@
   // enum-specifier:
   case tok::kw_enum:
     ConsumeToken();
-    ParseEnumSpecifier(Loc, DS);
+    ParseEnumSpecifier(Loc, DS, TemplateInfo, AS_none);
     return true;
 
   // cv-qualifier:
@@ -1850,6 +1850,7 @@
 /// [C++]   'enum' '::'[opt] nested-name-specifier[opt] identifier
 ///
 void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
+                                const ParsedTemplateInfo &TemplateInfo,
                                 AccessSpecifier AS) {
   // Parse the tag portion of this.
   if (Tok.is(tok::code_completion)) {
@@ -1888,6 +1889,15 @@
     return;
   }
 
+  // enums cannot be templates.
+  if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
+    Diag(Tok, diag::err_enum_template);
+
+    // Skip the rest of this declarator, up until the comma or semicolon.
+    SkipUntil(tok::comma, true);
+    return;      
+  }
+
   // If an identifier is present, consume and remember it.
   IdentifierInfo *Name = 0;
   SourceLocation NameLoc;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=97570&r1=97569&r2=97570&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar  2 11:53:14 2010
@@ -5757,12 +5757,13 @@
   llvm::APSInt EnumVal(IntWidth);
   QualType EltTy;
   if (Val) {
-    if (Enum->isDependentType())
+    if (Enum->isDependentType() || Val->isTypeDependent())
       EltTy = Context.DependentTy;
     else {
       // C99 6.7.2.2p2: Make sure we have an integer constant expression.
       SourceLocation ExpLoc;
-      if (VerifyIntegerConstantExpression(Val, &EnumVal)) {
+      if (!Val->isValueDependent() &&
+          VerifyIntegerConstantExpression(Val, &EnumVal)) {
         Val = 0;
       } else {        
         if (!getLangOptions().CPlusPlus) {
@@ -5864,7 +5865,7 @@
     }
   }
 
-  if (!Enum->isDependentType()) {
+  if (!EltTy->isDependentType()) {
     // Make the enumerator value match the signedness and size of the 
     // enumerator's type.
     EnumVal.zextOrTrunc(Context.getTypeSize(EltTy));

Modified: cfe/trunk/test/SemaTemplate/template-decl-fail.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/template-decl-fail.cpp?rev=97570&r1=97569&r2=97570&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/template-decl-fail.cpp (original)
+++ cfe/trunk/test/SemaTemplate/template-decl-fail.cpp Tue Mar  2 11:53:14 2010
@@ -1,3 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}
+
+template<typename T>
+enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \
+                      // expected-error{{declaration does not declare anything}}
+





More information about the cfe-commits mailing list