@@ -1943,7 +1943,11 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(
19431943
19441944 ParsedTemplateInfo TemplateInfo;
19451945 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext (Context);
1946- ParseDeclarationSpecifiers (DS, TemplateInfo, AS_none, DSContext);
1946+ // FIXME: Why is PSoon true?
1947+ LateParsedAttrList BoundsSafetyLateAttrs (
1948+ /* PSoon=*/ true , /* LateAttrParseExperimentalExtOnly=*/ true );
1949+ ParseDeclarationSpecifiers (DS, TemplateInfo, AS_none, DSContext,
1950+ &BoundsSafetyLateAttrs);
19471951
19481952 // If we had a free-standing type definition with a missing semicolon, we
19491953 // may get this far before the problem becomes obvious.
@@ -2725,12 +2729,12 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
27252729
27262730void Parser::ParseSpecifierQualifierList (
27272731 DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
2728- AccessSpecifier AS, DeclSpecContext DSC) {
2732+ AccessSpecifier AS, DeclSpecContext DSC, LateParsedAttrList *LateAttrs ) {
27292733 ParsedTemplateInfo TemplateInfo;
27302734 // / specifier-qualifier-list is a subset of declaration-specifiers. Just
27312735 // / parse declaration-specifiers and complain about extra stuff.
27322736 // / TODO: diagnose attribute-specifiers and alignment-specifiers.
2733- ParseDeclarationSpecifiers (DS, TemplateInfo, AS, DSC, nullptr ,
2737+ ParseDeclarationSpecifiers (DS, TemplateInfo, AS, DSC, LateAttrs ,
27342738 AllowImplicitTypename);
27352739
27362740 // Validate declspec for type-name.
@@ -3136,15 +3140,37 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
31363140 }
31373141}
31383142
3139- void Parser::DistributeCLateParsedAttrs (Decl *Dcl,
3143+ void Parser::DistributeCLateParsedAttrs (Declarator &D, Decl *Dcl,
31403144 LateParsedAttrList *LateAttrs) {
31413145 if (!LateAttrs)
31423146 return ;
31433147
3148+ unsigned NestedLevel = 0 ;
3149+ for (unsigned i = 0 ; i < D.getNumTypeObjects (); ++i) {
3150+ DeclaratorChunk &DC = D.getTypeObject (i);
3151+
3152+ switch (DC.Kind ) {
3153+ case DeclaratorChunk::Pointer:
3154+ case DeclaratorChunk::Array:
3155+ break ;
3156+ default :
3157+ continue ;
3158+ }
3159+
3160+ // Extract `LateParsedAttribute *` from `DeclaratorChunk`.
3161+ for (auto *OpaqueLA : DC.LateAttrList ) {
3162+ auto *LA = static_cast <LateParsedAttribute *>(OpaqueLA);
3163+ LA->NestedTypeLevel = NestedLevel;
3164+ LateAttrs->push_back (LA);
3165+ }
3166+ NestedLevel++;
3167+ }
3168+
3169+ // Attach `Decl *` to each `LateParsedAttribute *`.
31443170 if (Dcl) {
3145- for (auto *LateAttr : *LateAttrs) {
3146- if (LateAttr ->Decls .empty ())
3147- LateAttr ->addDecl (Dcl);
3171+ for (auto *LA : *LateAttrs) {
3172+ if (LA ->Decls .empty ())
3173+ LA ->addDecl (Dcl);
31483174 }
31493175 }
31503176}
@@ -3217,12 +3243,6 @@ void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
32173243 ArgExprs.push_back (ArgExpr.get ());
32183244 Parens.consumeClose ();
32193245
3220- ASTContext &Ctx = Actions.getASTContext ();
3221-
3222- ArgExprs.push_back (IntegerLiteral::Create (
3223- Ctx, llvm::APInt (Ctx.getTypeSize (Ctx.getSizeType ()), 0 ),
3224- Ctx.getSizeType (), SourceLocation ()));
3225-
32263246 Attrs.addNew (&AttrName, SourceRange (AttrNameLoc, Parens.getCloseLocation ()),
32273247 AttributeScopeInfo (), ArgExprs.data (), ArgExprs.size (), Form);
32283248}
@@ -4706,7 +4726,8 @@ void Parser::ParseStructDeclaration(
47064726 MaybeParseCXX11Attributes (Attrs);
47074727
47084728 // Parse the common specifier-qualifiers-list piece.
4709- ParseSpecifierQualifierList (DS);
4729+ ParseSpecifierQualifierList (DS, AS_none, DeclSpecContext::DSC_normal,
4730+ LateFieldAttrs);
47104731
47114732 // If there are no declarators, this is a free-standing declaration
47124733 // specifier. Let the actions module cope with it.
@@ -4768,7 +4789,7 @@ void Parser::ParseStructDeclaration(
47684789 // We're done with this declarator; invoke the callback.
47694790 Decl *Field = FieldsCallback (DeclaratorInfo);
47704791 if (Field)
4771- DistributeCLateParsedAttrs (Field, LateFieldAttrs);
4792+ DistributeCLateParsedAttrs (DeclaratorInfo. D , Field, LateFieldAttrs);
47724793
47734794 // If we don't have a comma, it is either the end of the list (a ';')
47744795 // or an error, bail out.
@@ -4825,7 +4846,8 @@ void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
48254846 SourceLocation (), ParsedAttr::Form::GNU (), nullptr );
48264847
48274848 for (auto *D : LA.Decls )
4828- Actions.ActOnFinishDelayedAttribute (getCurScope (), D, Attrs);
4849+ Actions.ActOnFinishDelayedAttribute (getCurScope (), D, Attrs,
4850+ LA.NestedTypeLevel );
48294851
48304852 // Due to a parsing error, we either went over the cached tokens or
48314853 // there are still cached tokens left, so we skip the leftover tokens.
@@ -6124,7 +6146,8 @@ bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,
61246146
61256147void Parser::ParseTypeQualifierListOpt (
61266148 DeclSpec &DS, unsigned AttrReqs, bool AtomicOrPtrauthAllowed,
6127- bool IdentifierRequired, llvm::function_ref<void ()> CodeCompletionHandler) {
6149+ bool IdentifierRequired, llvm::function_ref<void ()> CodeCompletionHandler,
6150+ LateParsedAttrList *LateAttrs) {
61286151 if ((AttrReqs & AR_CXX11AttributesParsed) &&
61296152 isAllowedCXX11AttributeSpecifier ()) {
61306153 ParsedAttributes Attrs (AttrFactory);
@@ -6266,7 +6289,9 @@ void Parser::ParseTypeQualifierListOpt(
62666289 // recovery is graceful.
62676290 if (AttrReqs & AR_GNUAttributesParsed ||
62686291 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6269- ParseGNUAttributes (DS.getAttributes ());
6292+
6293+ assert (!LateAttrs || LateAttrs->lateAttrParseExperimentalExtOnly ());
6294+ ParseGNUAttributes (DS.getAttributes (), LateAttrs);
62706295 continue ; // do *not* consume the next token!
62716296 }
62726297 // otherwise, FALL THROUGH!
@@ -6447,21 +6472,33 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
64476472 ((D.getContext () != DeclaratorContext::CXXNew)
64486473 ? AR_GNUAttributesParsed
64496474 : AR_GNUAttributesParsedAndRejected);
6475+ LateParsedAttrList LateAttrs (/* PSoon=*/ true ,
6476+ /* LateAttrParseExperimentalExtOnly=*/ true );
64506477 ParseTypeQualifierListOpt (DS, Reqs, /* AtomicOrPtrauthAllowed=*/ true ,
6451- !D.mayOmitIdentifier ());
6478+ !D.mayOmitIdentifier (), {}, &LateAttrs );
64526479 D.ExtendWithDeclSpec (DS);
64536480
64546481 // Recursively parse the declarator.
64556482 Actions.runWithSufficientStackSpace (
64566483 D.getBeginLoc (), [&] { ParseDeclaratorInternal (D, DirectDeclParser); });
6457- if (Kind == tok::star)
6484+ if (Kind == tok::star) {
6485+ DeclaratorChunk::LateAttrListTy OpaqueLateAttrList;
6486+ if (getLangOpts ().ExperimentalLateParseAttributes && !LateAttrs.empty ()) {
6487+ if (!D.isFunctionDeclarator ()) {
6488+ for (auto LA : LateAttrs) {
6489+ OpaqueLateAttrList.push_back (LA);
6490+ }
6491+ }
6492+ LateAttrs.clear ();
6493+ }
64586494 // Remember that we parsed a pointer type, and remember the type-quals.
64596495 D.AddTypeInfo (DeclaratorChunk::getPointer (
64606496 DS.getTypeQualifiers (), Loc, DS.getConstSpecLoc (),
64616497 DS.getVolatileSpecLoc (), DS.getRestrictSpecLoc (),
64626498 DS.getAtomicSpecLoc (), DS.getUnalignedSpecLoc ()),
6463- std::move (DS.getAttributes ()), SourceLocation ());
6464- else
6499+ std::move (DS.getAttributes ()), SourceLocation (),
6500+ OpaqueLateAttrList);
6501+ } else
64656502 // Remember that we parsed a Block type, and remember the type-quals.
64666503 D.AddTypeInfo (
64676504 DeclaratorChunk::getBlockPointer (DS.getTypeQualifiers (), Loc),
0 commit comments