Skip to content

Commit 6e44005

Browse files
committed
AST: Allow @inline(__always)/@inline(never) to be applied to properties and subscripts
Previously we only permitted it on the accessor itself, but there is no reason not to allow it on the storage declaration. Fixes <https://bugs.swift.org/browse/SR-3624> / <rdar://problem/31865137>.
1 parent f6c2caf commit 6e44005

File tree

6 files changed

+50
-96
lines changed

6 files changed

+50
-96
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ SIMPLE_DECL_ATTR(unsafe_no_objc_tagged_pointer, UnsafeNoObjCTaggedPointer,
179179
UserInaccessible,
180180
19)
181181
DECL_ATTR(inline, Inline,
182-
OnFunc | OnAccessor | OnConstructor,
182+
OnVar | OnSubscript | OnAbstractFunction,
183183
20)
184184
DECL_ATTR(_semantics, Semantics,
185185
OnAbstractFunction | OnSubscript |

lib/SIL/SILDeclRef.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -528,26 +528,47 @@ IsSerialized_t SILDeclRef::isSerialized() const {
528528
return IsNotSerialized;
529529
}
530530

531-
/// \brief True if the function has noinline attribute.
531+
/// \brief True if the function has an @inline(never) attribute.
532532
bool SILDeclRef::isNoinline() const {
533533
if (!hasDecl())
534534
return false;
535-
if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
536-
if (InlineA->getKind() == InlineKind::Never)
535+
536+
auto *decl = getDecl();
537+
if (auto *attr = decl->getAttrs().getAttribute<InlineAttr>())
538+
if (attr->getKind() == InlineKind::Never)
537539
return true;
538-
if (auto *semanticsA = getDecl()->getAttrs().getAttribute<SemanticsAttr>())
539-
if (semanticsA->Value.equals("keypath.entry"))
540+
541+
if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
542+
auto *storage = accessorDecl->getStorage();
543+
if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
544+
if (attr->getKind() == InlineKind::Never)
545+
return true;
546+
}
547+
548+
if (auto *attr = decl->getAttrs().getAttribute<SemanticsAttr>())
549+
if (attr->Value.equals("keypath.entry"))
540550
return true;
551+
541552
return false;
542553
}
543554

544-
/// \brief True if the function has noinline attribute.
555+
/// \brief True if the function has the @inline(__always) attribute.
545556
bool SILDeclRef::isAlwaysInline() const {
546557
if (!hasDecl())
547558
return false;
548-
if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
549-
if (InlineA->getKind() == InlineKind::Always)
559+
560+
auto *decl = getDecl();
561+
if (auto attr = decl->getAttrs().getAttribute<InlineAttr>())
562+
if (attr->getKind() == InlineKind::Always)
550563
return true;
564+
565+
if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
566+
auto *storage = accessorDecl->getStorage();
567+
if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
568+
if (attr->getKind() == InlineKind::Always)
569+
return true;
570+
}
571+
551572
return false;
552573
}
553574

test/SILGen/functions.swift

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
// RUN: %target-swift-emit-silgen -module-name functions -Xllvm -sil-full-demangle -parse-stdlib -parse-as-library -enable-sil-ownership %s | %FileCheck %s
32

43
import Swift // just for Optional
@@ -422,27 +421,6 @@ func applyTransparent(_ x: Bool) -> Bool {
422421
@inline(never)
423422
func noinline_callee() {}
424423

425-
// CHECK-LABEL: sil hidden [always_inline] @$s9functions20always_inline_calleeyyF : $@convention(thin) () -> ()
426-
@inline(__always)
427-
func always_inline_callee() {}
428-
429-
// CHECK-LABEL: sil [always_inline] @$s9functions27public_always_inline_calleeyyF : $@convention(thin) () -> ()
430-
@inline(__always)
431-
public func public_always_inline_callee() {}
432-
433-
protocol AlwaysInline {
434-
func alwaysInlined()
435-
}
436-
437-
// CHECK-LABEL: sil hidden [always_inline] @$s9functions19AlwaysInlinedMemberV06alwaysC0{{[_0-9a-zA-Z]*}}F : $@convention(method) (AlwaysInlinedMember) -> () {
438-
439-
// protocol witness for functions.AlwaysInline.alwaysInlined <A : functions.AlwaysInline>(functions.AlwaysInline.Self)() -> () in conformance functions.AlwaysInlinedMember : functions.AlwaysInline in functions
440-
// CHECK-LABEL: sil private [transparent] [thunk] [always_inline] @$s9functions19AlwaysInlinedMemberVAA0B6InlineA2aDP06alwaysC0{{[_0-9a-zA-Z]*}}FTW : $@convention(witness_method: AlwaysInline) (@in_guaranteed AlwaysInlinedMember) -> () {
441-
struct AlwaysInlinedMember : AlwaysInline {
442-
@inline(__always)
443-
func alwaysInlined() {}
444-
}
445-
446424
// CHECK-LABEL: sil hidden [Onone] @$s9functions10onone_funcyyF : $@convention(thin) () -> ()
447425
@_optimize(none)
448426
func onone_func() {}

test/SILGen/inlinable_attribute.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,21 @@ private class PrivateDerivedFromPublic : PublicBase {}
129129

130130
// CHECK-LABEL: sil private @$s19inlinable_attribute21PrivateDerivedFromUFI{{.+}}LLC5horseAdA5HorseC_tcfc : $@convention(method) (@owned Horse, @owned PrivateDerivedFromUFI) -> @owned PrivateDerivedFromUFI
131131
private class PrivateDerivedFromUFI : UFIBase {}
132+
133+
// Make sure that nested functions are also serializable.
134+
135+
// CHECK-LABEL: sil [serialized] @$s19inlinable_attribute3basyyF
136+
@inlinable
137+
public func bas() {
138+
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF
139+
func zim() {
140+
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF
141+
func zang() { }
142+
}
143+
144+
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3bas{{[_0-9a-zA-Z]*}}U_
145+
let zung = {
146+
// CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF
147+
func zippity() { }
148+
}
149+
}

test/SILGen/nested-function-fragility.swift

Lines changed: 0 additions & 63 deletions
This file was deleted.

test/attr/attributes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,12 @@ func func_type_attribute_with_space(x: @convention (c) () -> Int) {} // OK. Know
214214
var thinFunc : @thin () -> () // expected-error {{attribute is not supported}}
215215

216216
@inline(never) func nolineFunc() {}
217-
@inline(never) var noinlineVar : Int // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
217+
@inline(never) var noinlineVar : Int { return 0 }
218218
@inline(never) class FooClass { // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
219219
}
220220

221221
@inline(__always) func AlwaysInlineFunc() {}
222-
@inline(__always) var alwaysInlineVar : Int // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
222+
@inline(__always) var alwaysInlineVar : Int { return 0 }
223223
@inline(__always) class FooClass2 { // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
224224
}
225225

0 commit comments

Comments
 (0)