[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