Skip to content

Commit 3a4c4d0

Browse files
authored
Merge pull request #28100 from gottesmm/pr-b169c1785bc8360aa9d4661c79b7061aec94e6a5
[semantics] Add support for annotating VarDecls with @_semantics.
2 parents 53e61a9 + fe257d5 commit 3a4c4d0

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ DECL_ATTR(inline, Inline,
203203
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
204204
20)
205205
DECL_ATTR(_semantics, Semantics,
206-
OnAbstractFunction | OnSubscript | OnNominalType |
206+
OnAbstractFunction | OnSubscript | OnNominalType | OnVar |
207207
AllowMultipleAttributes | UserInaccessible |
208208
ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
209209
21)

include/swift/AST/Decl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5185,6 +5185,20 @@ class VarDecl : public AbstractStorageDecl {
51855185
/// backing property will be treated as the member-initialized property.
51865186
bool isMemberwiseInitialized(bool preferDeclaredProperties) const;
51875187

5188+
/// Return the range of semantics attributes attached to this VarDecl.
5189+
auto getSemanticsAttrs() const
5190+
-> decltype(getAttrs().getAttributes<SemanticsAttr>()) {
5191+
return getAttrs().getAttributes<SemanticsAttr>();
5192+
}
5193+
5194+
/// Returns true if this VarDelc has the string \p attrValue as a semantics
5195+
/// attribute.
5196+
bool hasSemanticsAttr(StringRef attrValue) const {
5197+
return llvm::any_of(getSemanticsAttrs(), [&](const SemanticsAttr *attr) {
5198+
return attrValue.equals(attr->Value);
5199+
});
5200+
}
5201+
51885202
// Implement isa/cast/dyncast/etc.
51895203
static bool classof(const Decl *D) {
51905204
return D->getKind() == DeclKind::Var || D->getKind() == DeclKind::Param;

lib/Parse/ParseDecl.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,14 +1263,6 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
12631263
return false;
12641264
}
12651265

1266-
// Diagnose using @_semantics in a local scope. These don't
1267-
// actually work.
1268-
if (CurDeclContext->isLocalContext()) {
1269-
// Emit an error, but do not discard the attribute. This enables
1270-
// better recovery in the parser.
1271-
diagnose(Loc, diag::attr_only_at_non_local_scope, AttrName);
1272-
}
1273-
12741266
if (!DiscardAttribute)
12751267
Attributes.add(new (Context) SemanticsAttr(Value.getValue(), AtLoc,
12761268
AttrRange,

test/attr/attr_semantics.swift

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
func duplicatesemantics() {}
66

77
func func_with_nested_semantics_1() {
8-
@_semantics("exit") // expected-error {{attribute '_semantics' can only be used in a non-local scope}}
8+
@_semantics("exit")
99
func exit(_ code : UInt32) -> Void
1010
exit(0)
1111
}
@@ -15,7 +15,7 @@ func func_with_nested_semantics_1() {
1515
func somethingThatShouldParseFine() {}
1616

1717
func func_with_nested_semantics_2() {
18-
@_semantics("exit") // expected-error {{attribute '_semantics' can only be used in a non-local scope}}
18+
@_semantics("exit")
1919
func exit(_ code : UInt32) -> Void
2020
exit(0)
2121
}
@@ -32,3 +32,34 @@ enum EnumWithSemantics {}
3232
@_semantics("struct1")
3333
@_semantics("struct2")
3434
struct StructWithDuplicateSemantics {}
35+
36+
@_semantics("globalVar1")
37+
@_semantics("globalVar2")
38+
var globalVarWithSemantics : Int = 5
39+
40+
@_semantics("globalLet1")
41+
@_semantics("globalLet2")
42+
let globalLetWithSemantics : Int = 5
43+
44+
func varDeclLocalVars() {
45+
@_semantics("localVar1")
46+
@_semantics("localVar2")
47+
var localVarWithSemantics : Int = 5
48+
localVarWithSemantics = 6
49+
let _ = localVarWithSemantics
50+
51+
@_semantics("localLet1")
52+
@_semantics("localLet2")
53+
let localLetWithSemantics : Int = 5
54+
let _ = localLetWithSemantics
55+
}
56+
57+
struct IVarTest {
58+
@_semantics("localVar1")
59+
@_semantics("localVar2")
60+
var localVarWithSemantics : Int = 5
61+
62+
@_semantics("localLet1")
63+
@_semantics("localLet2")
64+
let localLetWithSemantics : Int = 5
65+
}

0 commit comments

Comments
 (0)