Mercurial > hg > CbC > CbC_llvm
diff clang/lib/Parse/ParseTemplate.cpp @ 221:79ff65ed7e25
LLVM12 Original
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 15 Jun 2021 19:15:29 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line diff
--- a/clang/lib/Parse/ParseTemplate.cpp Tue Jun 15 19:13:43 2021 +0900 +++ b/clang/lib/Parse/ParseTemplate.cpp Tue Jun 15 19:15:29 2021 +0900 @@ -22,6 +22,16 @@ #include "llvm/Support/TimeProfiler.h" using namespace clang; +/// Re-enter a possible template scope, creating as many template parameter +/// scopes as necessary. +/// \return The number of template parameter scopes entered. +unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) { + return Actions.ActOnReenterTemplateScope(D, [&] { + S.Enter(Scope::TemplateParamScope); + return Actions.getCurScope(); + }); +} + /// Parse a template declaration, explicit instantiation, or /// explicit specialization. Decl *Parser::ParseDeclarationStartingWithTemplate( @@ -67,8 +77,7 @@ assert(Tok.isOneOf(tok::kw_export, tok::kw_template) && "Token does not start a template declaration."); - // Enter template-parameter scope. - ParseScope TemplateParmScope(this, Scope::TemplateParamScope); + MultiParseScope TemplateParamScopes(*this); // Tell the action that names should be checked in the context of // the declaration to come. @@ -116,7 +125,8 @@ // Parse the '<' template-parameter-list '>' SourceLocation LAngleLoc, RAngleLoc; SmallVector<NamedDecl*, 4> TemplateParams; - if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), + if (ParseTemplateParameters(TemplateParamScopes, + CurTemplateDepthTracker.getDepth(), TemplateParams, LAngleLoc, RAngleLoc)) { // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); @@ -131,9 +141,8 @@ if (TryConsumeToken(tok::kw_requires)) { OptionalRequiresClauseConstraintER = - Actions.CorrectDelayedTyposInExpr( - ParseConstraintLogicalOrExpression( - /*IsTrailingRequiresClause=*/false)); + Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression( + /*IsTrailingRequiresClause=*/false)); if (!OptionalRequiresClauseConstraintER.isUsable()) { // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); @@ -150,9 +159,6 @@ TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get())); } while (Tok.isOneOf(tok::kw_export, tok::kw_template)); - unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope; - ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization); - // Parse the actual template declaration. if (Tok.is(tok::kw_concept)) return ParseConceptDefinition( @@ -191,7 +197,7 @@ return ParseStaticAssertDeclaration(DeclEnd); } - if (Context == DeclaratorContext::MemberContext) { + if (Context == DeclaratorContext::Member) { // We are parsing a member template. ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo, &DiagsFromTParams); @@ -272,7 +278,7 @@ // Function definitions are only allowed at file scope and in C++ classes. // The C++ inline method definition case is handled elsewhere, so we only // need to handle the file scope definition case. - if (Context != DeclaratorContext::FileContext) { + if (Context != DeclaratorContext::File) { Diag(Tok, diag::err_function_definition_not_allowed); SkipMalformedDecl(); return nullptr; @@ -430,8 +436,9 @@ /// /// \returns true if an error occurred, false otherwise. bool Parser::ParseTemplateParameters( - unsigned Depth, SmallVectorImpl<NamedDecl *> &TemplateParams, - SourceLocation &LAngleLoc, SourceLocation &RAngleLoc) { + MultiParseScope &TemplateScopes, unsigned Depth, + SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc, + SourceLocation &RAngleLoc) { // Get the template parameter list. if (!TryConsumeToken(tok::less, LAngleLoc)) { Diag(Tok.getLocation(), diag::err_expected_less_after) << "template"; @@ -440,8 +447,11 @@ // Try to parse the template parameter list. bool Failed = false; - if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) + // FIXME: Missing greatergreatergreater support. + if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) { + TemplateScopes.Enter(Scope::TemplateParamScope); Failed = ParseTemplateParameterList(Depth, TemplateParams); + } if (Tok.is(tok::greatergreater)) { // No diagnostic required here: a template-parameter-list can only be @@ -635,7 +645,7 @@ // probably meant to write the type of a NTTP. DeclSpec DS(getAttrFactory()); DS.SetTypeSpecError(); - Declarator D(DS, DeclaratorContext::TemplateParamContext); + Declarator D(DS, DeclaratorContext::TemplateParam); D.SetIdentifier(nullptr, Tok.getLocation()); D.setInvalidType(true); NamedDecl *ErrorParam = Actions.ActOnNonTypeTemplateParameter( @@ -810,9 +820,9 @@ SourceLocation EqualLoc; ParsedType DefaultArg; if (TryConsumeToken(tok::equal, EqualLoc)) - DefaultArg = ParseTypeName(/*Range=*/nullptr, - DeclaratorContext::TemplateTypeArgContext) - .get(); + DefaultArg = + ParseTypeName(/*Range=*/nullptr, DeclaratorContext::TemplateTypeArg) + .get(); NamedDecl *NewDecl = Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc, @@ -850,9 +860,9 @@ SmallVector<NamedDecl*,8> TemplateParams; SourceLocation LAngleLoc, RAngleLoc; { - ParseScope TemplateParmScope(this, Scope::TemplateParamScope); - if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, - RAngleLoc)) { + MultiParseScope TemplateParmScope(*this); + if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams, + LAngleLoc, RAngleLoc)) { return nullptr; } } @@ -956,7 +966,7 @@ DeclSpecContext::DSC_template_param); // Parse this as a typename. - Declarator ParamDecl(DS, DeclaratorContext::TemplateParamContext); + Declarator ParamDecl(DS, DeclaratorContext::TemplateParam); ParseDeclarator(ParamDecl); if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) { Diag(Tok.getLocation(), diag::err_expected_template_parameter); @@ -1516,7 +1526,7 @@ /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument); if (isCXXTypeId(TypeIdAsTemplateArgument)) { TypeResult TypeArg = ParseTypeName( - /*Range=*/nullptr, DeclaratorContext::TemplateArgContext); + /*Range=*/nullptr, DeclaratorContext::TemplateArg); return Actions.ActOnTemplateTypeArgument(TypeArg); } @@ -1630,40 +1640,22 @@ Sema::ContextRAII GlobalSavedContext( Actions, Actions.Context.getTranslationUnitDecl()); - SmallVector<ParseScope*, 4> TemplateParamScopeStack; + MultiParseScope Scopes(*this); + + // Get the list of DeclContexts to reenter. + SmallVector<DeclContext*, 4> DeclContextsToReenter; + for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit(); + DC = DC->getLexicalParent()) + DeclContextsToReenter.push_back(DC); - // Get the list of DeclContexts to reenter. For inline methods, we only want - // to push the DeclContext of the outermost class. This matches the way the - // parser normally parses bodies of inline methods when the outermost class is - // complete. - struct ContainingDC { - ContainingDC(DeclContext *DC, bool ShouldPush) : Pair(DC, ShouldPush) {} - llvm::PointerIntPair<DeclContext *, 1, bool> Pair; - DeclContext *getDC() { return Pair.getPointer(); } - bool shouldPushDC() { return Pair.getInt(); } - }; - SmallVector<ContainingDC, 4> DeclContextsToReenter; - DeclContext *DD = FunD; - DeclContext *NextContaining = Actions.getContainingDC(DD); - while (DD && !DD->isTranslationUnit()) { - bool ShouldPush = DD == NextContaining; - DeclContextsToReenter.push_back({DD, ShouldPush}); - if (ShouldPush) - NextContaining = Actions.getContainingDC(DD); - DD = DD->getLexicalParent(); - } - - // Reenter template scopes from outermost to innermost. - for (ContainingDC CDC : reverse(DeclContextsToReenter)) { - TemplateParamScopeStack.push_back( - new ParseScope(this, Scope::TemplateParamScope)); - unsigned NumParamLists = Actions.ActOnReenterTemplateScope( - getCurScope(), cast<Decl>(CDC.getDC())); - CurTemplateDepthTracker.addDepth(NumParamLists); - if (CDC.shouldPushDC()) { - TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); - Actions.PushDeclContext(Actions.getCurScope(), CDC.getDC()); - } + // Reenter scopes from outermost to innermost. + for (DeclContext *DC : reverse(DeclContextsToReenter)) { + CurTemplateDepthTracker.addDepth( + ReenterTemplateScopes(Scopes, cast<Decl>(DC))); + Scopes.Enter(Scope::DeclScope); + // We'll reenter the function context itself below. + if (DC != FunD) + Actions.PushDeclContext(Actions.getCurScope(), DC); } assert(!LPT.Toks.empty() && "Empty body!"); @@ -1684,8 +1676,7 @@ Scope::CompoundStmtScope); // Recreate the containing function DeclContext. - Sema::ContextRAII FunctionSavedContext(Actions, - Actions.getContainingDC(FunD)); + Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent()); Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); @@ -1709,13 +1700,6 @@ } else Actions.ActOnFinishFunctionBody(LPT.D, nullptr); } - - // Exit scopes. - FnScope.Exit(); - SmallVectorImpl<ParseScope *>::reverse_iterator I = - TemplateParamScopeStack.rbegin(); - for (; I != TemplateParamScopeStack.rend(); ++I) - delete *I; } /// Lex a delayed template function for late parsing.