[cfe-commits] r67659 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseDeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp

Douglas Gregor dgregor at apple.com
Tue Mar 24 17:14:12 PDT 2009


Author: dgregor
Date: Tue Mar 24 19:13:59 2009
New Revision: 67659

URL: http://llvm.org/viewvc/llvm-project?rev=67659&view=rev
Log:
In Parser::ParseClassSpecifier, don't conflate a NULL declaration with
failure to perform a declaration. Instead, explicitly note semantic
failures that occur during template parsing with a DeclResult. Fixes
PR3872.


Modified:
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=67659&r1=67658&r2=67659&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Mar 24 19:13:59 2009
@@ -85,6 +85,7 @@
   typedef ActionResult<2> TypeResult;
   typedef ActionResult<3> BaseResult;
   typedef ActionResult<4> MemInitResult;
+  typedef ActionResult<5> DeclResult;
 
   /// Same, but with ownership.
   typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
@@ -1169,7 +1170,7 @@
 
   /// \brief Process the declaration or definition of a class template
   /// with the given template parameter lists.
-  virtual DeclTy *
+  virtual DeclResult
   ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
                      SourceLocation KWLoc, const CXXScopeSpec &SS,
                      IdentifierInfo *Name, SourceLocation NameLoc,
@@ -1247,7 +1248,7 @@
   /// common for users to provide the wrong number of template
   /// parameter lists (such as a missing \c template<> prior to a
   /// specialization); the parser does not check this condition.
-  virtual DeclTy *
+  virtual DeclResult
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                    SourceLocation KWLoc, 
                                    const CXXScopeSpec &SS,

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=67659&r1=67658&r2=67659&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Mar 24 19:13:59 2009
@@ -431,7 +431,7 @@
   }
 
   // Create the tag portion of the class or class template.
-  DeclTy *TagOrTempDecl;
+  Action::DeclResult TagOrTempResult;
   if (TemplateId && TK != Action::TK_Reference) {
     // Explicit specialization or class template partial
     // specialization. Let semantic analysis decide.
@@ -439,7 +439,7 @@
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->getTemplateArgIsType(),
                                        TemplateId->NumArgs);
-    TagOrTempDecl 
+    TagOrTempResult
       = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
                        StartLoc, SS,
                        TemplateId->Template, 
@@ -454,25 +454,26 @@
                                  TemplateParams? TemplateParams->size() : 0));
     TemplateId->Destroy();
   } else if (TemplateParams && TK != Action::TK_Reference)
-    TagOrTempDecl = Actions.ActOnClassTemplate(CurScope, TagType, TK, StartLoc,
-                                               SS, Name, NameLoc, Attr,
+    TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK, 
+                                                 StartLoc, SS, Name, NameLoc, 
+                                                 Attr,
                        Action::MultiTemplateParamsArg(Actions, 
                                                       &(*TemplateParams)[0],
                                                       TemplateParams->size()));
   else
-    TagOrTempDecl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 
+    TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 
                                      NameLoc, Attr);
 
   // Parse the optional base clause (C++ only).
   if (getLang().CPlusPlus && Tok.is(tok::colon))
-    ParseBaseClause(TagOrTempDecl);
+    ParseBaseClause(TagOrTempResult.get());
 
   // If there is a body, parse it and inform the actions module.
   if (Tok.is(tok::l_brace))
     if (getLang().CPlusPlus)
-      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempDecl);
+      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
     else
-      ParseStructUnionBody(StartLoc, TagType, TagOrTempDecl);
+      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
   else if (TK == Action::TK_Definition) {
     // FIXME: Complain that we have a base-specifier list but no
     // definition.
@@ -480,9 +481,10 @@
   }
 
   const char *PrevSpec = 0;
-  if (!TagOrTempDecl)
+  if (TagOrTempResult.isInvalid())
     DS.SetTypeSpecError();
-  else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl))
+  else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, 
+                              TagOrTempResult.get()))
     Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 }
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=67659&r1=67658&r2=67659&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 24 19:13:59 2009
@@ -1704,7 +1704,7 @@
   bool CheckTemplateParameterList(TemplateParameterList *NewParams,
                                   TemplateParameterList *OldParams);
 
-  virtual DeclTy *
+  virtual DeclResult
   ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
                      SourceLocation KWLoc, const CXXScopeSpec &SS,
                      IdentifierInfo *Name, SourceLocation NameLoc,
@@ -1731,7 +1731,7 @@
                                              SourceLocation TemplateNameLoc,
                                              SourceRange ScopeSpecifierRange);
 
-  virtual DeclTy *
+  virtual DeclResult
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                    SourceLocation KWLoc, 
                                    const CXXScopeSpec &SS,

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=67659&r1=67658&r2=67659&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Mar 24 19:13:59 2009
@@ -361,7 +361,7 @@
                                        (Decl**)Params, NumParams, RAngleLoc);
 }
 
-Sema::DeclTy *
+Sema::DeclResult
 Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
                          SourceLocation KWLoc, const CXXScopeSpec &SS,
                          IdentifierInfo *Name, SourceLocation NameLoc,
@@ -373,7 +373,7 @@
 
   // Check that we can declare a template here.
   if (CheckTemplateDeclScope(S, TemplateParameterLists))
-    return 0;
+    return true;
 
   TagDecl::TagKind Kind;
   switch (TagSpec) {
@@ -386,7 +386,7 @@
   // There is no such thing as an unnamed class template.
   if (!Name) {
     Diag(KWLoc, diag::err_template_unnamed_class);
-    return 0;
+    return true;
   }
 
   // Find any previous declaration with this name.
@@ -418,7 +418,7 @@
     if (!TemplateParameterListsAreEqual(TemplateParams,
                                    PrevClassTemplate->getTemplateParameters(),
                                         /*Complain=*/true))
-      return 0;
+      return true;
 
     // C++ [temp.class]p4:
     //   In a redeclaration, partial specialization, explicit
@@ -429,7 +429,7 @@
     if (PrevRecordDecl->getTagKind() != Kind) {
       Diag(KWLoc, diag::err_use_with_wrong_tag) << Name;
       Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
-      return 0;
+      return true;
     }
 
 
@@ -440,7 +440,7 @@
         Diag(Def->getLocation(), diag::note_previous_definition);
         // FIXME: Would it make sense to try to "forget" the previous
         // definition, as part of error recovery?
-        return 0;
+        return true;
       }
     }
   } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
@@ -456,7 +456,7 @@
     //   in (14.5.4).
     Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-    return 0;
+    return true;
   }
 
   // Check the template parameter list of this declaration, possibly
@@ -1767,7 +1767,7 @@
   return false;
 }
 
-Sema::DeclTy *
+Sema::DeclResult
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
                                        SourceLocation KWLoc, 
                                        const CXXScopeSpec &SS,
@@ -1783,7 +1783,7 @@
   ClassTemplateDecl *ClassTemplate 
     = dyn_cast_or_null<ClassTemplateDecl>(static_cast<Decl *>(TemplateD));
   if (!ClassTemplate)
-    return 0;
+    return true;
 
   // Check the validity of the template headers that introduce this
   // template.
@@ -1796,18 +1796,14 @@
   else {
     TemplateParameterList *TemplateParams 
       = static_cast<TemplateParameterList*>(*TemplateParameterLists.get());
-    if (TemplateParameterLists.size() > 1) {
-      Diag(TemplateParams->getTemplateLoc(),
-           diag::err_template_spec_extra_headers);
-      return 0;
-    }
+    if (TemplateParameterLists.size() > 1)
+      return Diag(TemplateParams->getTemplateLoc(),
+                  diag::err_template_spec_extra_headers);
 
-    if (TemplateParams->size() > 0) {
+    if (TemplateParams->size() > 0)
       // FIXME: No support for class template partial specialization.
-      Diag(TemplateParams->getTemplateLoc(), 
-           diag::unsup_template_partial_spec);
-      return 0;
-    }
+      return Diag(TemplateParams->getTemplateLoc(), 
+                  diag::unsup_template_partial_spec);
   }
 
   // Check that the specialization uses the same tag kind as the
@@ -1836,7 +1832,7 @@
   if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc, 
                                 &TemplateArgs[0], TemplateArgs.size(),
                                 RAngleLoc, ConvertedTemplateArgs))
-    return 0;
+    return true;
 
   assert((ConvertedTemplateArgs.size() == 
             ClassTemplate->getTemplateParameters()->size()) &&
@@ -1858,7 +1854,7 @@
   if (CheckClassTemplateSpecializationScope(ClassTemplate, PrevDecl,
                                             TemplateNameLoc, 
                                             SS.getRange()))
-    return 0;
+    return true;
 
   if (PrevDecl && PrevDecl->getSpecializationKind() == TSK_Undeclared) {
     // Since the only prior class template specialization with these
@@ -1902,7 +1898,7 @@
         << Specialization << Range;
       Diag(Def->getLocation(), diag::note_previous_definition);
       Specialization->setInvalidDecl();
-      return 0;
+      return true;
     }
   }
 





More information about the cfe-commits mailing list