Skip to content

Commit 6f17412

Browse files
committed
[clang/AST] Make it possible to use SwiftAttr in type context
Expands allowed use of SwiftAttr to type context from declarations only, this enables use of the attribute on generic parameters, in Objective-C blocks, typedefs etc.
1 parent fcc9d4a commit 6f17412

File tree

6 files changed

+64
-2
lines changed

6 files changed

+64
-2
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2519,7 +2519,7 @@ def SwiftAsyncName : InheritableAttr {
25192519
let Documentation = [SwiftAsyncNameDocs];
25202520
}
25212521

2522-
def SwiftAttr : InheritableAttr {
2522+
def SwiftAttr : DeclOrTypeAttr {
25232523
let Spellings = [GNU<"swift_attr">];
25242524
let Args = [StringArgument<"Attribute">];
25252525
let Documentation = [SwiftAttrDocs];

clang/lib/AST/TypePrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,14 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
17841784
return;
17851785
}
17861786

1787+
if (T->getAttrKind() == attr::SwiftAttr) {
1788+
if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {
1789+
OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()
1790+
<< "\")))";
1791+
}
1792+
return;
1793+
}
1794+
17871795
OS << " __attribute__((";
17881796
switch (T->getAttrKind()) {
17891797
#define TYPE_ATTR(NAME)
@@ -1826,6 +1834,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
18261834
case attr::AnnotateType:
18271835
case attr::WebAssemblyFuncref:
18281836
case attr::ArmStreaming:
1837+
case attr::SwiftAttr:
18291838
llvm_unreachable("This attribute should have been handled already");
18301839

18311840
case attr::NSReturnsRetained:

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6347,11 +6347,16 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
63476347
}
63486348

63496349
static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6350+
if (AL.isInvalid() || AL.isUsedAsTypeAttr())
6351+
return;
6352+
63506353
// Make sure that there is a string literal as the annotation's single
63516354
// argument.
63526355
StringRef Str;
6353-
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
6356+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str)) {
6357+
AL.setInvalid();
63546358
return;
6359+
}
63556360

63566361
D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
63576362
}

clang/lib/Sema/SemaType.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7438,6 +7438,21 @@ static bool HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
74387438
return false;
74397439
}
74407440

7441+
static void HandleSwiftAttr(TypeProcessingState &State, QualType &QT,
7442+
ParsedAttr &PAttr) {
7443+
Sema &S = State.getSema();
7444+
7445+
StringRef Str;
7446+
if (!S.checkStringLiteralArgumentAttr(PAttr, 0, Str)) {
7447+
PAttr.setInvalid();
7448+
return;
7449+
}
7450+
7451+
auto *A = ::new (S.Context) SwiftAttrAttr(S.Context, PAttr, Str);
7452+
QT = State.getAttributedType(A, QT, QT);
7453+
PAttr.setUsedAsTypeAttr();
7454+
}
7455+
74417456
/// Rebuild an attributed type without the nullability attribute on it.
74427457
static QualType rebuildAttributedTypeWithoutNullability(ASTContext &ctx,
74437458
QualType type) {
@@ -8819,6 +8834,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
88198834
break;
88208835
}
88218836

8837+
case ParsedAttr::AT_SwiftAttr: {
8838+
HandleSwiftAttr(state, type, attr);
8839+
break;
8840+
}
8841+
88228842
MS_TYPE_ATTRS_CASELIST:
88238843
if (!handleMSPointerTypeQualifierAttr(state, attr, type))
88248844
attr.setUsedAsTypeAttr();

clang/test/AST/attr-swift_attr.m

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,27 @@ @interface Contact
1414

1515
// CHECK-LABEL: InterfaceDecl {{.*}} Contact
1616
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@sendable"
17+
18+
#define SWIFT_SENDABLE __attribute__((swift_attr("@Sendable")))
19+
#define MAIN_ACTOR __attribute__((swift_attr("@MainActor")))
20+
21+
@interface InTypeContext
22+
- (nullable id)test:(nullable SWIFT_SENDABLE id)obj SWIFT_SENDABLE;
23+
@end
24+
25+
// CHECK-LABEL: InterfaceDecl {{.*}} InTypeContext
26+
// CHECK-NEXT: MethodDecl {{.*}} - test: 'id _Nullable':'id'
27+
// CHECK-NEXT: ParmVarDecl {{.*}} obj 'id _Nullable':'id'
28+
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"
29+
30+
@interface Generic<T: SWIFT_SENDABLE id>
31+
@end
32+
33+
// CHECK-LABEL: InterfaceDecl {{.*}} Generic
34+
// CHECK-NEXT: TypeParamDecl {{.*}} T bounded 'SWIFT_SENDABLE id':'id'
35+
36+
typedef SWIFT_SENDABLE Generic<id> Alias;
37+
38+
// CHECK-LABEL: TypedefDecl {{.*}} Alias 'Generic<id>'
39+
// CHECK-NEXT: ObjectType {{.*}} 'Generic<id>'
40+
// CHECK-NEXT: SwiftAttrAttr {{.*}} "@Sendable"

clang/test/SemaObjC/validate-attr-swift_attr.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ @interface I
99
__attribute__((swift_attr(1)))
1010
@interface J
1111
@end
12+
13+
@interface Error<T: __attribute__((swift_attr(1))) id>
14+
// expected-error@-1 {{'swift_attr' attribute requires a string}}
15+
@end

0 commit comments

Comments
 (0)