@@ -7438,16 +7438,55 @@ static bool HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
7438
7438
return false ;
7439
7439
}
7440
7440
7441
- static void HandleSwiftAttr (TypeProcessingState &State, QualType &QT,
7442
- ParsedAttr &PAttr) {
7441
+ static void HandleSwiftAttr (TypeProcessingState &State, TypeAttrLocation TAL,
7442
+ QualType &QT, ParsedAttr &PAttr) {
7443
+ if (TAL == TAL_DeclName)
7444
+ return ;
7445
+
7443
7446
Sema &S = State.getSema ();
7447
+ auto &D = State.getDeclarator ();
7448
+
7449
+ // If the attribute appears in declaration specifiers
7450
+ // it should be handled as a declaration attribute,
7451
+ // unless it's associated with a type or a function
7452
+ // prototype (i.e. appears on a parameter or result type).
7453
+ if (State.isProcessingDeclSpec ()) {
7454
+ if (!(D.isPrototypeContext () ||
7455
+ D.getContext () == DeclaratorContext::TypeName))
7456
+ return ;
7457
+
7458
+ if (auto *chunk = D.getInnermostNonParenChunk ()) {
7459
+ moveAttrFromListToList (PAttr, State.getCurrentAttributes (),
7460
+ const_cast <DeclaratorChunk *>(chunk)->getAttrs ());
7461
+ return ;
7462
+ }
7463
+ }
7444
7464
7445
7465
StringRef Str;
7446
7466
if (!S.checkStringLiteralArgumentAttr (PAttr, 0 , Str)) {
7447
7467
PAttr.setInvalid ();
7448
7468
return ;
7449
7469
}
7450
7470
7471
+ // If the attribute as attached to a paren move it closer to
7472
+ // the declarator. This can happen in block declarations when
7473
+ // an attribute is placed before `^` i.e. `(__attribute__((...)) ^)`.
7474
+ //
7475
+ // Note that it's actually invalid to use GNU style attributes
7476
+ // in a block but such cases are currently handled gracefully
7477
+ // but the parser and behavior should be consistent between
7478
+ // cases when attribute appears before/after block's result
7479
+ // type and inside (^).
7480
+ if (TAL == TAL_DeclChunk) {
7481
+ auto chunkIdx = State.getCurrentChunkIndex ();
7482
+ if (chunkIdx >= 1 &&
7483
+ D.getTypeObject (chunkIdx).Kind == DeclaratorChunk::Paren) {
7484
+ moveAttrFromListToList (PAttr, State.getCurrentAttributes (),
7485
+ D.getTypeObject (chunkIdx - 1 ).getAttrs ());
7486
+ return ;
7487
+ }
7488
+ }
7489
+
7451
7490
auto *A = ::new (S.Context ) SwiftAttrAttr (S.Context , PAttr, Str);
7452
7491
QT = State.getAttributedType (A, QT, QT);
7453
7492
PAttr.setUsedAsTypeAttr ();
@@ -8835,7 +8874,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
8835
8874
}
8836
8875
8837
8876
case ParsedAttr::AT_SwiftAttr: {
8838
- HandleSwiftAttr (state, type, attr);
8877
+ HandleSwiftAttr (state, TAL, type, attr);
8839
8878
break ;
8840
8879
}
8841
8880
0 commit comments