diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 4ff1ac175df0..bd47d9df0829 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -85,6 +85,7 @@ public: 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 @@ public: /// \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 @@ public: /// 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, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index ec91d71b086d..d2d8c1eeaedc 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -431,7 +431,7 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, } // 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 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, TemplateId->getTemplateArgs(), TemplateId->getTemplateArgIsType(), TemplateId->NumArgs); - TagOrTempDecl + TagOrTempResult = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK, StartLoc, SS, TemplateId->Template, @@ -454,25 +454,26 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, 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 @@ void Parser::ParseClassSpecifier(DeclSpec &DS, } 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; } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 46df1c767427..6b9012b487a4 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1704,7 +1704,7 @@ public: 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 @@ public: SourceLocation TemplateNameLoc, SourceRange ScopeSpecifierRange); - virtual DeclTy * + virtual DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index fd39a9150f98..24b35ee5f57b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -361,7 +361,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth, (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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, // 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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, // 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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, 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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, 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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, 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 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, // 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 @@ Sema::CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate, return false; } -Sema::DeclTy * +Sema::DeclResult Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -1783,7 +1783,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, ClassTemplateDecl *ClassTemplate = dyn_cast_or_null(static_cast(TemplateD)); if (!ClassTemplate) - return 0; + return true; // Check the validity of the template headers that introduce this // template. @@ -1796,18 +1796,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, else { TemplateParameterList *TemplateParams = static_cast(*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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, 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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, 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 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, << Specialization << Range; Diag(Def->getLocation(), diag::note_previous_definition); Specialization->setInvalidDecl(); - return 0; + return true; } }