Mercurial > hg > CbC > CbC_llvm
diff clang/lib/Parse/ParseExpr.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 79ff65ed7e25 |
children | 173fe712db74 1f2b6ac9f198 |
line wrap: on
line diff
--- a/clang/lib/Parse/ParseExpr.cpp Wed Jul 21 10:27:27 2021 +0900 +++ b/clang/lib/Parse/ParseExpr.cpp Wed Nov 09 17:45:10 2022 +0900 @@ -400,7 +400,7 @@ SourceLocation ColonLoc; auto SavedType = PreferredType; - while (1) { + while (true) { // Every iteration may rely on a preferred type for the whole expression. PreferredType = SavedType; // If this token has a lower precedence than we are allowed to parse (e.g. @@ -791,6 +791,7 @@ /// [GNU] '__builtin_FUNCTION' '(' ')' /// [GNU] '__builtin_LINE' '(' ')' /// [CLANG] '__builtin_COLUMN' '(' ')' +/// [GNU] '__builtin_source_location' '(' ')' /// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')' /// [GNU] '__null' /// [OBJC] '[' objc-message-expr ']' @@ -942,9 +943,8 @@ ParenParseOption ParenExprType; switch (ParseKind) { case CastParseKind::UnaryExprOnly: - if (!getLangOpts().CPlusPlus) - ParenExprType = CompoundLiteral; - LLVM_FALLTHROUGH; + assert(getLangOpts().CPlusPlus && "not possible to get here in C"); + [[fallthrough]]; case CastParseKind::AnyCastExpr: ParenExprType = ParenParseOption::CastExpr; break; @@ -1003,7 +1003,12 @@ break; case tok::kw_nullptr: - Diag(Tok, diag::warn_cxx98_compat_nullptr); + if (getLangOpts().CPlusPlus) + Diag(Tok, diag::warn_cxx98_compat_nullptr); + else + Diag(Tok, getLangOpts().C2x ? diag::warn_c17_compat_nullptr + : diag::ext_c_nullptr); + Res = Actions.ActOnCXXNullPtrLiteral(ConsumeToken()); break; @@ -1037,9 +1042,10 @@ return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, isVectorLiteral, NotPrimaryExpression); - case tok::identifier: { // primary-expression: identifier - // unqualified-id: identifier - // constant: enumeration-constant + case tok::identifier: + ParseIdentifier: { // primary-expression: identifier + // unqualified-id: identifier + // constant: enumeration-constant // Turn a potentially qualified name into a annot_typename or // annot_cxxscope if it would be valid. This handles things like x::y, etc. if (getLangOpts().CPlusPlus) { @@ -1067,6 +1073,7 @@ REVERTIBLE_TYPE_TRAIT(__is_array); REVERTIBLE_TYPE_TRAIT(__is_assignable); REVERTIBLE_TYPE_TRAIT(__is_base_of); + REVERTIBLE_TYPE_TRAIT(__is_bounded_array); REVERTIBLE_TYPE_TRAIT(__is_class); REVERTIBLE_TYPE_TRAIT(__is_complete_type); REVERTIBLE_TYPE_TRAIT(__is_compound); @@ -1092,15 +1099,18 @@ REVERTIBLE_TYPE_TRAIT(__is_nothrow_assignable); REVERTIBLE_TYPE_TRAIT(__is_nothrow_constructible); REVERTIBLE_TYPE_TRAIT(__is_nothrow_destructible); + REVERTIBLE_TYPE_TRAIT(__is_nullptr); REVERTIBLE_TYPE_TRAIT(__is_object); REVERTIBLE_TYPE_TRAIT(__is_pod); REVERTIBLE_TYPE_TRAIT(__is_pointer); REVERTIBLE_TYPE_TRAIT(__is_polymorphic); REVERTIBLE_TYPE_TRAIT(__is_reference); + REVERTIBLE_TYPE_TRAIT(__is_referenceable); REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_same); REVERTIBLE_TYPE_TRAIT(__is_scalar); + REVERTIBLE_TYPE_TRAIT(__is_scoped_enum); REVERTIBLE_TYPE_TRAIT(__is_sealed); REVERTIBLE_TYPE_TRAIT(__is_signed); REVERTIBLE_TYPE_TRAIT(__is_standard_layout); @@ -1108,10 +1118,14 @@ REVERTIBLE_TYPE_TRAIT(__is_trivially_assignable); REVERTIBLE_TYPE_TRAIT(__is_trivially_constructible); REVERTIBLE_TYPE_TRAIT(__is_trivially_copyable); + REVERTIBLE_TYPE_TRAIT(__is_unbounded_array); REVERTIBLE_TYPE_TRAIT(__is_union); REVERTIBLE_TYPE_TRAIT(__is_unsigned); REVERTIBLE_TYPE_TRAIT(__is_void); REVERTIBLE_TYPE_TRAIT(__is_volatile); +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ + REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); +#include "clang/Basic/TransformTypeTraits.def" #undef REVERTIBLE_TYPE_TRAIT #undef RTT_JOIN } @@ -1211,7 +1225,8 @@ DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ, Actions.getASTContext().getPrintingPolicy()); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); + Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::TypeName); TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) @@ -1303,6 +1318,7 @@ case tok::kw___builtin_FILE: case tok::kw___builtin_FUNCTION: case tok::kw___builtin_LINE: + case tok::kw___builtin_source_location: if (NotPrimaryExpression) *NotPrimaryExpression = true; // This parses the complete suffix; we can return early. @@ -1354,7 +1370,8 @@ // Special treatment because of member pointers SourceLocation SavedLoc = ConsumeToken(); PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc); - Res = ParseCastExpression(AnyCastExpr, true); + + Res = ParseCastExpression(AnyCastExpr, /*isAddressOfOperand=*/true); if (!Res.isInvalid()) { Expr *Arg = Res.get(); Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); @@ -1379,7 +1396,8 @@ Res = ParseCastExpression(AnyCastExpr); if (!Res.isInvalid()) { Expr *Arg = Res.get(); - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Arg, + isAddressOfOperand); if (Res.isInvalid()) Res = Actions.CreateRecoveryExpr(SavedLoc, Arg->getEndLoc(), Arg); } @@ -1410,7 +1428,7 @@ case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')' if (!getLangOpts().C11) Diag(Tok, diag::ext_c11_feature) << Tok.getName(); - LLVM_FALLTHROUGH; + [[fallthrough]]; case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')' case tok::kw___alignof: // unary-expression: '__alignof' unary-expression // unary-expression: '__alignof' '(' type-name ')' @@ -1488,7 +1506,8 @@ PrevSpec, DiagID, Type, Actions.getASTContext().getPrintingPolicy()); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); + Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::TypeName); TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); if (Ty.isInvalid()) break; @@ -1498,7 +1517,7 @@ Ty.get(), nullptr); break; } - LLVM_FALLTHROUGH; + [[fallthrough]]; case tok::annot_decltype: case tok::kw_char: @@ -1513,6 +1532,7 @@ case tok::kw___int64: case tok::kw___int128: case tok::kw__ExtInt: + case tok::kw__BitInt: case tok::kw_signed: case tok::kw_unsigned: case tok::kw_half: @@ -1521,7 +1541,9 @@ case tok::kw___bf16: case tok::kw__Float16: case tok::kw___float128: + case tok::kw___ibm128: case tok::kw_void: + case tok::kw_auto: case tok::kw_typename: case tok::kw_typeof: case tok::kw___vector: @@ -1586,9 +1608,9 @@ // cast expression. CXXScopeSpec SS; ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, + /*ObjectHasErrors=*/false, /*EnteringContext=*/false); - AnnotateTemplateIdTokenAsType(SS); + AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, isVectorLiteral, NotPrimaryExpression); @@ -1607,14 +1629,14 @@ // translate it into a type and continue parsing as a cast // expression. CXXScopeSpec SS; - AnnotateTemplateIdTokenAsType(SS); + AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::Yes); return ParseCastExpression(ParseKind, isAddressOfOperand, NotCastExpr, isTypeCast, isVectorLiteral, NotPrimaryExpression); } // Fall through to treat the template-id as an id-expression. - LLVM_FALLTHROUGH; + [[fallthrough]]; } case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id @@ -1732,6 +1754,17 @@ PreferredType.get(Tok.getLocation())); return ExprError(); } +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/Basic/TransformTypeTraits.def" + // HACK: libstdc++ uses some of the transform-type-traits as alias + // templates, so we need to work around this. + if (!NextToken().is(tok::l_paren)) { + Tok.setKind(tok::identifier); + Diag(Tok, diag::ext_keyword_as_ident) + << Tok.getIdentifierInfo()->getName() << 0; + goto ParseIdentifier; + } + goto ExpectedExpression; case tok::l_square: if (getLangOpts().CPlusPlus11) { if (getLangOpts().ObjC) { @@ -1757,8 +1790,9 @@ Res = ParseObjCMessageExpression(); break; } - LLVM_FALLTHROUGH; + [[fallthrough]]; default: + ExpectedExpression: NotCastExpr = true; return ExprError(); } @@ -1788,7 +1822,7 @@ if (Tok.isAtStartOfLine()) return Res; - LLVM_FALLTHROUGH; + [[fallthrough]]; case tok::period: case tok::arrow: break; @@ -1833,6 +1867,7 @@ /// primary-expression /// postfix-expression '[' expression ']' /// postfix-expression '[' braced-init-list ']' +/// postfix-expression '[' expression-list [opt] ']' [C++2b 12.4.5] /// postfix-expression '(' argument-expression-list[opt] ')' /// postfix-expression '.' identifier /// postfix-expression '->' identifier @@ -1851,7 +1886,7 @@ // parsed, see if there are any postfix-expression pieces here. SourceLocation Loc; auto SavedType = PreferredType; - while (1) { + while (true) { // Each iteration relies on preferred type for the whole expression. PreferredType = SavedType; switch (Tok.getKind()) { @@ -1875,7 +1910,7 @@ break; } // Fall through; this isn't a message send. - LLVM_FALLTHROUGH; + [[fallthrough]]; default: // Not a postfix-expression suffix. return LHS; @@ -1896,30 +1931,58 @@ (void)Actions.CorrectDelayedTyposInExpr(LHS); return ExprError(); } - BalancedDelimiterTracker T(*this, tok::l_square); T.consumeOpen(); Loc = T.getOpenLocation(); - ExprResult Idx, Length, Stride; + ExprResult Length, Stride; SourceLocation ColonLocFirst, ColonLocSecond; + ExprVector ArgExprs; + bool HasError = false; PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get()); - if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { - Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); - Idx = ParseBraceInitializer(); - } else if (getLangOpts().OpenMP) { + + // We try to parse a list of indexes in all language mode first + // and, in we find 0 or one index, we try to parse an OpenMP array + // section. This allow us to support C++2b multi dimensional subscript and + // OpenMp sections in the same language mode. + if (!getLangOpts().OpenMP || Tok.isNot(tok::colon)) { + if (!getLangOpts().CPlusPlus2b) { + ExprResult Idx; + if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { + Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); + Idx = ParseBraceInitializer(); + } else { + Idx = ParseExpression(); // May be a comma expression + } + LHS = Actions.CorrectDelayedTyposInExpr(LHS); + Idx = Actions.CorrectDelayedTyposInExpr(Idx); + if (Idx.isInvalid()) { + HasError = true; + } else { + ArgExprs.push_back(Idx.get()); + } + } else if (Tok.isNot(tok::r_square)) { + CommaLocsTy CommaLocs; + if (ParseExpressionList(ArgExprs, CommaLocs)) { + LHS = Actions.CorrectDelayedTyposInExpr(LHS); + HasError = true; + } + assert( + (ArgExprs.empty() || ArgExprs.size() == CommaLocs.size() + 1) && + "Unexpected number of commas!"); + } + } + + if (ArgExprs.size() <= 1 && getLangOpts().OpenMP) { ColonProtectionRAIIObject RAII(*this); - // Parse [: or [ expr or [ expr : - if (!Tok.is(tok::colon)) { - // [ expr - Idx = ParseExpression(); - } if (Tok.is(tok::colon)) { // Consume ':' ColonLocFirst = ConsumeToken(); if (Tok.isNot(tok::r_square) && (getLangOpts().OpenMP < 50 || - ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) + ((Tok.isNot(tok::colon) && getLangOpts().OpenMP >= 50)))) { Length = ParseExpression(); + Length = Actions.CorrectDelayedTyposInExpr(Length); + } } if (getLangOpts().OpenMP >= 50 && (OMPClauseKind == llvm::omp::Clause::OMPC_to || @@ -1931,27 +1994,23 @@ Stride = ParseExpression(); } } - } else - Idx = ParseExpression(); + } SourceLocation RLoc = Tok.getLocation(); - LHS = Actions.CorrectDelayedTyposInExpr(LHS); - Idx = Actions.CorrectDelayedTyposInExpr(Idx); - Length = Actions.CorrectDelayedTyposInExpr(Length); - if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() && + + if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && !Stride.isInvalid() && Tok.is(tok::r_square)) { if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { LHS = Actions.ActOnOMPArraySectionExpr( - LHS.get(), Loc, Idx.get(), ColonLocFirst, ColonLocSecond, - Length.get(), Stride.get(), RLoc); + LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], + ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc); } else { LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, - Idx.get(), RLoc); + ArgExprs, RLoc); } } else { LHS = ExprError(); - Idx = ExprError(); } // Match the ']'. @@ -2017,7 +2076,7 @@ CommaLocsTy CommaLocs; auto RunSignatureHelp = [&]() -> QualType { QualType PreferredType = Actions.ProduceCallSignatureHelp( - getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation()); + LHS.get(), ArgExprs, PT.getOpenLocation()); CalledSignatureHelp = true; return PreferredType; }; @@ -2239,6 +2298,13 @@ /// typeof ( expressions ) /// typeof ( type-name ) /// [GNU/C++] typeof unary-expression +/// [C2x] typeof-specifier: +/// typeof '(' typeof-specifier-argument ')' +/// typeof_unqual '(' typeof-specifier-argument ')' +/// +/// typeof-specifier-argument: +/// expression +/// type-name /// /// [OpenCL 1.1 6.11.12] vec_step built-in function: /// vec_step ( expressions ) @@ -2250,8 +2316,9 @@ ParsedType &CastTy, SourceRange &CastRange) { - assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_sizeof, tok::kw___alignof, - tok::kw_alignof, tok::kw__Alignof, tok::kw_vec_step, + assert(OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual, tok::kw_sizeof, + tok::kw___alignof, tok::kw_alignof, tok::kw__Alignof, + tok::kw_vec_step, tok::kw___builtin_omp_required_simd_align) && "Not a typeof/sizeof/alignof/vec_step expression!"); @@ -2266,7 +2333,8 @@ if (isTypeIdUnambiguously()) { DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); + Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::TypeName); ParseDeclarator(DeclaratorInfo); SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); @@ -2286,7 +2354,8 @@ } isCastExpr = false; - if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { + if (OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) && + !getLangOpts().CPlusPlus) { Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo() << tok::l_paren; return ExprError(); @@ -2312,7 +2381,8 @@ return ExprEmpty(); } - if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { + if (getLangOpts().CPlusPlus || + !OpTok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual)) { // GNU typeof in C requires the expression to be parenthesized. Not so for // sizeof/alignof or in C++. Therefore, the parenthesized expression is // the start of a unary-expression, but doesn't include any postfix @@ -2331,7 +2401,7 @@ /// a parameter. ExprResult Parser::ParseSYCLUniqueStableNameExpression() { assert(Tok.is(tok::kw___builtin_sycl_unique_stable_name) && - "Not __bulitin_sycl_unique_stable_name"); + "Not __builtin_sycl_unique_stable_name"); SourceLocation OpLoc = ConsumeToken(); BalancedDelimiterTracker T(*this, tok::l_paren); @@ -2480,6 +2550,7 @@ /// [GNU] '__builtin_FUNCTION' '(' ')' /// [GNU] '__builtin_LINE' '(' ')' /// [CLANG] '__builtin_COLUMN' '(' ')' +/// [GNU] '__builtin_source_location' '(' ')' /// [OCL] '__builtin_astype' '(' assignment-expression ',' type-name ')' /// /// [GNU] offsetof-member-designator: @@ -2556,7 +2627,7 @@ Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); // FIXME: This loop leaks the index expressions on error. - while (1) { + while (true) { if (Tok.is(tok::period)) { // offsetof-member-designator: offsetof-member-designator '.' identifier Comps.push_back(Sema::OffsetOfComponent()); @@ -2702,7 +2773,8 @@ case tok::kw___builtin_COLUMN: case tok::kw___builtin_FILE: case tok::kw___builtin_FUNCTION: - case tok::kw___builtin_LINE: { + case tok::kw___builtin_LINE: + case tok::kw___builtin_source_location: { // Attempt to consume the r-paren. if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected) << tok::r_paren; @@ -2719,6 +2791,8 @@ return SourceLocExpr::Line; case tok::kw___builtin_COLUMN: return SourceLocExpr::Column; + case tok::kw___builtin_source_location: + return SourceLocExpr::SourceLocStruct; default: llvm_unreachable("invalid keyword"); } @@ -2836,7 +2910,8 @@ // None of these cases should fall through with an invalid Result // unless they've already reported an error. if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { - Diag(Tok, diag::ext_gnu_statement_expr); + Diag(Tok, OpenLoc.isMacroID() ? diag::ext_gnu_statement_expr_macro + : diag::ext_gnu_statement_expr); checkCompoundToken(OpenLoc, tok::l_paren, CompoundToken::StmtExprBegin); @@ -2924,7 +2999,8 @@ // Parse the type declarator. DeclSpec DS(AttrFactory); ParseSpecifierQualifierList(DS); - Declarator DeclaratorInfo(DS, DeclaratorContext::TypeName); + Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::TypeName); ParseDeclarator(DeclaratorInfo); // If our type is followed by an identifier and either ':' or ']', then @@ -3241,7 +3317,7 @@ Ty = nullptr; } else { ColonProtectionRAIIObject X(*this); - TypeResult TR = ParseTypeName(); + TypeResult TR = ParseTypeName(nullptr, DeclaratorContext::Association); if (TR.isInvalid()) { SkipUntil(tok::r_paren, StopAtSemi); return ExprError(); @@ -3354,9 +3430,11 @@ /// \endverbatim bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, SmallVectorImpl<SourceLocation> &CommaLocs, - llvm::function_ref<void()> ExpressionStarts) { + llvm::function_ref<void()> ExpressionStarts, + bool FailImmediatelyOnInvalidExpr, + bool EarlyTypoCorrection) { bool SawError = false; - while (1) { + while (true) { if (ExpressionStarts) ExpressionStarts(); @@ -3367,6 +3445,9 @@ } else Expr = ParseAssignmentExpression(); + if (EarlyTypoCorrection) + Expr = Actions.CorrectDelayedTyposInExpr(Expr); + if (Tok.is(tok::ellipsis)) Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken()); else if (Tok.is(tok::code_completion)) { @@ -3380,8 +3461,10 @@ break; } if (Expr.isInvalid()) { + SawError = true; + if (FailImmediatelyOnInvalidExpr) + break; SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch); - SawError = true; } else { Exprs.push_back(Expr.get()); } @@ -3416,14 +3499,16 @@ bool Parser::ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, SmallVectorImpl<SourceLocation> &CommaLocs) { - while (1) { + while (true) { ExprResult Expr = ParseAssignmentExpression(); if (Expr.isInvalid()) return true; Exprs.push_back(Expr.get()); - if (Tok.isNot(tok::comma)) + // We might be parsing the LHS of a fold-expression. If we reached the fold + // operator, stop. + if (Tok.isNot(tok::comma) || NextToken().is(tok::ellipsis)) return false; // Move to the next argument, remember where the comma was. @@ -3452,7 +3537,8 @@ ParseSpecifierQualifierList(DS); // Parse the block-declarator. - Declarator DeclaratorInfo(DS, DeclaratorContext::BlockLiteral); + Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::BlockLiteral); DeclaratorInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); ParseDeclarator(DeclaratorInfo); @@ -3491,7 +3577,8 @@ // Parse the return type if present. DeclSpec DS(AttrFactory); - Declarator ParamInfo(DS, DeclaratorContext::BlockLiteral); + Declarator ParamInfo(DS, ParsedAttributesView::none(), + DeclaratorContext::BlockLiteral); ParamInfo.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); // FIXME: Since the return type isn't actually parsed, it can't be used to // fill ParamInfo with an initial valid range, so do it manually.