Skip to content

Commit d176cbf

Browse files
committed
[Sema] SwiftAttr in some situations should be handled as a declaration attribute
Adjust `SwiftAttr` handling to determine when attribute should be handled as a type or declaration attribute i.e. if attribute is attached to a declarator or declaration name, it should be handled as a declaration attribute.
1 parent 32e5bdd commit d176cbf

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

clang/lib/Sema/SemaType.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7438,16 +7438,55 @@ static bool HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
74387438
return false;
74397439
}
74407440

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+
74437446
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+
}
74447464

74457465
StringRef Str;
74467466
if (!S.checkStringLiteralArgumentAttr(PAttr, 0, Str)) {
74477467
PAttr.setInvalid();
74487468
return;
74497469
}
74507470

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+
74517490
auto *A = ::new (S.Context) SwiftAttrAttr(S.Context, PAttr, Str);
74527491
QT = State.getAttributedType(A, QT, QT);
74537492
PAttr.setUsedAsTypeAttr();
@@ -8835,7 +8874,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
88358874
}
88368875

88378876
case ParsedAttr::AT_SwiftAttr: {
8838-
HandleSwiftAttr(state, type, attr);
8877+
HandleSwiftAttr(state, TAL, type, attr);
88398878
break;
88408879
}
88418880

clang/test/AST/attr-swift_attr.m

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@ @interface Contact
1616
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@sendable"
1717

1818
#define SWIFT_SENDABLE __attribute__((swift_attr("@Sendable")))
19-
#define MAIN_ACTOR __attribute__((swift_attr("@MainActor")))
2019

2120
@interface InTypeContext
2221
- (nullable id)test:(nullable SWIFT_SENDABLE id)obj SWIFT_SENDABLE;
2322
@end
2423

2524
// CHECK-LABEL: InterfaceDecl {{.*}} InTypeContext
2625
// CHECK-NEXT: MethodDecl {{.*}} - test: 'id _Nullable':'id'
27-
// CHECK-NEXT: ParmVarDecl {{.*}} obj 'id _Nullable':'id'
26+
// CHECK-NEXT: ParmVarDecl {{.*}} obj 'SWIFT_SENDABLE id _Nullable':'id'
2827
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"
2928

3029
@interface Generic<T: SWIFT_SENDABLE id>
@@ -38,3 +37,11 @@ @interface Generic<T: SWIFT_SENDABLE id>
3837
// CHECK-LABEL: TypedefDecl {{.*}} Alias 'Generic<id>'
3938
// CHECK-NEXT: ObjectType {{.*}} 'Generic<id>'
4039
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"
40+
41+
SWIFT_SENDABLE
42+
typedef struct {
43+
void *ptr;
44+
} SendableStruct;
45+
46+
// CHECK-LABEL: TypedefDecl {{.*}} SendableStruct 'struct SendableStruct':'SendableStruct'
47+
// CHECK: SwiftAttrAttr {{.*}} "@Sendable"

0 commit comments

Comments
 (0)