mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #34612 from xymus/dont-skip-nested-types
[Sema] Add flag to optimize building swiftmodule files preserving type info for LLDB
This commit is contained in:
@@ -391,7 +391,7 @@ protected:
|
|||||||
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
|
SWIFT_INLINE_BITFIELD(SubscriptDecl, VarDecl, 2,
|
||||||
StaticSpelling : 2
|
StaticSpelling : 2
|
||||||
);
|
);
|
||||||
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1,
|
SWIFT_INLINE_BITFIELD(AbstractFunctionDecl, ValueDecl, 3+8+1+1+1+1+1+1+1,
|
||||||
/// \see AbstractFunctionDecl::BodyKind
|
/// \see AbstractFunctionDecl::BodyKind
|
||||||
BodyKind : 3,
|
BodyKind : 3,
|
||||||
|
|
||||||
@@ -415,7 +415,11 @@ protected:
|
|||||||
Synthesized : 1,
|
Synthesized : 1,
|
||||||
|
|
||||||
/// Whether this member's body consists of a single expression.
|
/// Whether this member's body consists of a single expression.
|
||||||
HasSingleExpressionBody : 1
|
HasSingleExpressionBody : 1,
|
||||||
|
|
||||||
|
/// Whether peeking into this function detected nested type declarations.
|
||||||
|
/// This is set when skipping over the decl at parsing.
|
||||||
|
HasNestedTypeDeclarations : 1
|
||||||
);
|
);
|
||||||
|
|
||||||
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2+1,
|
SWIFT_INLINE_BITFIELD(FuncDecl, AbstractFunctionDecl, 1+1+2+1+1+2+1,
|
||||||
@@ -5544,6 +5548,7 @@ protected:
|
|||||||
Bits.AbstractFunctionDecl.Throws = Throws;
|
Bits.AbstractFunctionDecl.Throws = Throws;
|
||||||
Bits.AbstractFunctionDecl.Synthesized = false;
|
Bits.AbstractFunctionDecl.Synthesized = false;
|
||||||
Bits.AbstractFunctionDecl.HasSingleExpressionBody = false;
|
Bits.AbstractFunctionDecl.HasSingleExpressionBody = false;
|
||||||
|
Bits.AbstractFunctionDecl.HasNestedTypeDeclarations = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBodyKind(BodyKind K) {
|
void setBodyKind(BodyKind K) {
|
||||||
@@ -5690,6 +5695,16 @@ public:
|
|||||||
setBody(S, BodyKind::Parsed);
|
setBody(S, BodyKind::Parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Was there a nested type declaration detected when parsing this
|
||||||
|
/// function was skipped?
|
||||||
|
bool hasNestedTypeDeclarations() const {
|
||||||
|
return Bits.AbstractFunctionDecl.HasNestedTypeDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHasNestedTypeDeclarations(bool value) {
|
||||||
|
Bits.AbstractFunctionDecl.HasNestedTypeDeclarations = value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Note that parsing for the body was delayed.
|
/// Note that parsing for the body was delayed.
|
||||||
///
|
///
|
||||||
/// The function should return the body statement and a flag indicating
|
/// The function should return the body statement and a flag indicating
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ enum class FunctionBodySkipping : uint8_t {
|
|||||||
None,
|
None,
|
||||||
/// Only non-inlinable function bodies should be skipped.
|
/// Only non-inlinable function bodies should be skipped.
|
||||||
NonInlinable,
|
NonInlinable,
|
||||||
|
/// Only non-inlinable functions bodies without type definitions should
|
||||||
|
/// be skipped.
|
||||||
|
NonInlinableWithoutTypes,
|
||||||
/// All function bodies should be skipped, where not otherwise required
|
/// All function bodies should be skipped, where not otherwise required
|
||||||
/// for type inference.
|
/// for type inference.
|
||||||
All
|
All
|
||||||
|
|||||||
@@ -301,6 +301,10 @@ def experimental_skip_non_inlinable_function_bodies:
|
|||||||
Flag<["-"], "experimental-skip-non-inlinable-function-bodies">,
|
Flag<["-"], "experimental-skip-non-inlinable-function-bodies">,
|
||||||
Flags<[FrontendOption, HelpHidden]>,
|
Flags<[FrontendOption, HelpHidden]>,
|
||||||
HelpText<"Skip type-checking and SIL generation for non-inlinable function bodies">;
|
HelpText<"Skip type-checking and SIL generation for non-inlinable function bodies">;
|
||||||
|
def experimental_skip_non_inlinable_function_bodies_without_types:
|
||||||
|
Flag<["-"], "experimental-skip-non-inlinable-function-bodies-without-types">,
|
||||||
|
Flags<[FrontendOption, HelpHidden]>,
|
||||||
|
HelpText<"Skip work on non-inlinable function bodies that do not declare nested types">;
|
||||||
def profile_stats_events: Flag<["-"], "profile-stats-events">,
|
def profile_stats_events: Flag<["-"], "profile-stats-events">,
|
||||||
Flags<[FrontendOption, HelpHidden]>,
|
Flags<[FrontendOption, HelpHidden]>,
|
||||||
HelpText<"Profile changes to stats in -stats-output-dir">;
|
HelpText<"Profile changes to stats in -stats-output-dir">;
|
||||||
|
|||||||
@@ -687,7 +687,10 @@ public:
|
|||||||
|
|
||||||
/// Skip a braced block (e.g. function body). The current token must be '{'.
|
/// Skip a braced block (e.g. function body). The current token must be '{'.
|
||||||
/// Returns \c true if the parser hit the eof before finding matched '}'.
|
/// Returns \c true if the parser hit the eof before finding matched '}'.
|
||||||
bool skipBracedBlock();
|
///
|
||||||
|
/// Set \c HasNestedTypeDeclarations to true if a token for a type
|
||||||
|
/// declaration is detected in the skipped block.
|
||||||
|
bool skipBracedBlock(bool &HasNestedTypeDeclarations);
|
||||||
|
|
||||||
/// Skip over SIL decls until we encounter the start of a Swift decl or eof.
|
/// Skip over SIL decls until we encounter the start of a Swift decl or eof.
|
||||||
void skipSILUntilSwiftDecl();
|
void skipSILUntilSwiftDecl();
|
||||||
|
|||||||
@@ -195,7 +195,9 @@ bool ArgsToFrontendOptionsConverter::convert(
|
|||||||
|
|
||||||
if (FrontendOptions::doesActionGenerateIR(Opts.RequestedAction) &&
|
if (FrontendOptions::doesActionGenerateIR(Opts.RequestedAction) &&
|
||||||
(Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) ||
|
(Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) ||
|
||||||
Args.hasArg(OPT_experimental_skip_all_function_bodies))) {
|
Args.hasArg(OPT_experimental_skip_all_function_bodies) ||
|
||||||
|
Args.hasArg(
|
||||||
|
OPT_experimental_skip_non_inlinable_function_bodies_without_types))) {
|
||||||
Diags.diagnose(SourceLoc(), diag::cannot_emit_ir_skipping_function_bodies);
|
Diags.diagnose(SourceLoc(), diag::cannot_emit_ir_skipping_function_bodies);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -729,6 +729,12 @@ static bool ParseTypeCheckerArgs(TypeCheckerOptions &Opts, ArgList &Args,
|
|||||||
Opts.DebugTimeExpressions |=
|
Opts.DebugTimeExpressions |=
|
||||||
Args.hasArg(OPT_debug_time_expression_type_checking);
|
Args.hasArg(OPT_debug_time_expression_type_checking);
|
||||||
|
|
||||||
|
// Check for SkipFunctionBodies arguments in order from skipping less to
|
||||||
|
// skipping more.
|
||||||
|
if (Args.hasArg(
|
||||||
|
OPT_experimental_skip_non_inlinable_function_bodies_without_types))
|
||||||
|
Opts.SkipFunctionBodies = FunctionBodySkipping::NonInlinableWithoutTypes;
|
||||||
|
|
||||||
// If asked to perform InstallAPI, go ahead and enable non-inlinable function
|
// If asked to perform InstallAPI, go ahead and enable non-inlinable function
|
||||||
// body skipping.
|
// body skipping.
|
||||||
if (Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) ||
|
if (Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) ||
|
||||||
|
|||||||
@@ -3519,10 +3519,12 @@ static void diagnoseOperatorFixityAttributes(Parser &P,
|
|||||||
static unsigned skipUntilMatchingRBrace(Parser &P,
|
static unsigned skipUntilMatchingRBrace(Parser &P,
|
||||||
bool &HasPoundDirective,
|
bool &HasPoundDirective,
|
||||||
bool &HasOperatorDeclarations,
|
bool &HasOperatorDeclarations,
|
||||||
bool &HasNestedClassDeclarations) {
|
bool &HasNestedClassDeclarations,
|
||||||
|
bool &HasNestedTypeDeclarations) {
|
||||||
HasPoundDirective = false;
|
HasPoundDirective = false;
|
||||||
HasOperatorDeclarations = false;
|
HasOperatorDeclarations = false;
|
||||||
HasNestedClassDeclarations = false;
|
HasNestedClassDeclarations = false;
|
||||||
|
HasNestedTypeDeclarations = false;
|
||||||
|
|
||||||
unsigned OpenBraces = 1;
|
unsigned OpenBraces = 1;
|
||||||
|
|
||||||
@@ -3541,6 +3543,10 @@ static unsigned skipUntilMatchingRBrace(Parser &P,
|
|||||||
|
|
||||||
HasPoundDirective |= P.Tok.isAny(tok::pound_sourceLocation, tok::pound_line,
|
HasPoundDirective |= P.Tok.isAny(tok::pound_sourceLocation, tok::pound_line,
|
||||||
tok::pound_if, tok::pound_else, tok::pound_endif, tok::pound_elseif);
|
tok::pound_if, tok::pound_else, tok::pound_endif, tok::pound_elseif);
|
||||||
|
|
||||||
|
HasNestedTypeDeclarations |= P.Tok.isAny(tok::kw_class, tok::kw_struct,
|
||||||
|
tok::kw_enum);
|
||||||
|
|
||||||
if (P.consumeIf(tok::l_brace)) {
|
if (P.consumeIf(tok::l_brace)) {
|
||||||
++OpenBraces;
|
++OpenBraces;
|
||||||
continue;
|
continue;
|
||||||
@@ -4819,10 +4825,12 @@ bool Parser::canDelayMemberDeclParsing(bool &HasOperatorDeclarations,
|
|||||||
// we can't lazily parse.
|
// we can't lazily parse.
|
||||||
BacktrackingScope BackTrack(*this);
|
BacktrackingScope BackTrack(*this);
|
||||||
bool HasPoundDirective;
|
bool HasPoundDirective;
|
||||||
|
bool HasNestedTypeDeclarations;
|
||||||
skipUntilMatchingRBrace(*this,
|
skipUntilMatchingRBrace(*this,
|
||||||
HasPoundDirective,
|
HasPoundDirective,
|
||||||
HasOperatorDeclarations,
|
HasOperatorDeclarations,
|
||||||
HasNestedClassDeclarations);
|
HasNestedClassDeclarations,
|
||||||
|
HasNestedTypeDeclarations);
|
||||||
if (!HasPoundDirective)
|
if (!HasPoundDirective)
|
||||||
BackTrack.cancelBacktrack();
|
BackTrack.cancelBacktrack();
|
||||||
return !BackTrack.willBacktrack();
|
return !BackTrack.willBacktrack();
|
||||||
@@ -5510,7 +5518,7 @@ static ParameterList *parseOptionalAccessorArgument(SourceLoc SpecifierLoc,
|
|||||||
return ParameterList::create(P.Context, StartLoc, param, EndLoc);
|
return ParameterList::create(P.Context, StartLoc, param, EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::skipBracedBlock() {
|
bool Parser::skipBracedBlock(bool &HasNestedTypeDeclarations) {
|
||||||
SyntaxParsingContext disabled(SyntaxContext);
|
SyntaxParsingContext disabled(SyntaxContext);
|
||||||
SyntaxContext->disable();
|
SyntaxContext->disable();
|
||||||
consumeToken(tok::l_brace);
|
consumeToken(tok::l_brace);
|
||||||
@@ -5524,7 +5532,8 @@ bool Parser::skipBracedBlock() {
|
|||||||
unsigned OpenBraces = skipUntilMatchingRBrace(*this,
|
unsigned OpenBraces = skipUntilMatchingRBrace(*this,
|
||||||
HasPoundDirectives,
|
HasPoundDirectives,
|
||||||
HasOperatorDeclarations,
|
HasOperatorDeclarations,
|
||||||
HasNestedClassDeclarations);
|
HasNestedClassDeclarations,
|
||||||
|
HasNestedTypeDeclarations);
|
||||||
if (consumeIf(tok::r_brace))
|
if (consumeIf(tok::r_brace))
|
||||||
--OpenBraces;
|
--OpenBraces;
|
||||||
return OpenBraces != 0;
|
return OpenBraces != 0;
|
||||||
@@ -6420,11 +6429,13 @@ void Parser::consumeAbstractFunctionBody(AbstractFunctionDecl *AFD,
|
|||||||
BodyRange.Start = Tok.getLoc();
|
BodyRange.Start = Tok.getLoc();
|
||||||
|
|
||||||
// Advance the parser to the end of the block; '{' ... '}'.
|
// Advance the parser to the end of the block; '{' ... '}'.
|
||||||
skipBracedBlock();
|
bool HasNestedTypeDeclarations;
|
||||||
|
skipBracedBlock(HasNestedTypeDeclarations);
|
||||||
|
|
||||||
BodyRange.End = PreviousLoc;
|
BodyRange.End = PreviousLoc;
|
||||||
|
|
||||||
AFD->setBodyDelayed(BodyRange);
|
AFD->setBodyDelayed(BodyRange);
|
||||||
|
AFD->setHasNestedTypeDeclarations(HasNestedTypeDeclarations);
|
||||||
|
|
||||||
if (isCodeCompletionFirstPass() &&
|
if (isCodeCompletionFirstPass() &&
|
||||||
SourceMgr.rangeContainsCodeCompletionLoc(BodyRange)) {
|
SourceMgr.rangeContainsCodeCompletionLoc(BodyRange)) {
|
||||||
|
|||||||
@@ -2351,6 +2351,14 @@ public:
|
|||||||
FunctionBodySkipping::All)
|
FunctionBodySkipping::All)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// If we want all types (for LLDB) we can't skip functions with nested
|
||||||
|
// types. We could probably improve upon this and type-check only the
|
||||||
|
// nested types instead for better performances.
|
||||||
|
if (AFD->hasNestedTypeDeclarations() &&
|
||||||
|
getASTContext().TypeCheckerOpts.SkipFunctionBodies ==
|
||||||
|
FunctionBodySkipping::NonInlinableWithoutTypes)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Only skip functions where their body won't be serialized
|
// Only skip functions where their body won't be serialized
|
||||||
return AFD->getResilienceExpansion() != ResilienceExpansion::Minimal;
|
return AFD->getResilienceExpansion() != ResilienceExpansion::Minimal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
// Check -emit-ir and -c are invalid when skipping function bodies
|
// Check -emit-ir and -c are invalid when skipping function bodies
|
||||||
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
// RUN: not %target-swift-frontend -c %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
// RUN: not %target-swift-frontend -c %s -experimental-skip-non-inlinable-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
|
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-non-inlinable-function-bodies-without-types %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
|
// RUN: not %target-swift-frontend -c %s -experimental-skip-non-inlinable-function-bodies-without-types %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
// RUN: not %target-swift-frontend -emit-ir %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
// RUN: not %target-swift-frontend -c %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
// RUN: not %target-swift-frontend -c %s -experimental-skip-all-function-bodies %s 2>&1 | %FileCheck %s --check-prefix ERROR
|
||||||
// ERROR: -experimental-skip-*-function-bodies do not support emitting IR
|
// ERROR: -experimental-skip-*-function-bodies do not support emitting IR
|
||||||
@@ -13,21 +15,23 @@
|
|||||||
// WARNING: module 'SwiftOnoneSupport' cannot be built with -experimental-skip-non-inlinable-function-bodies; this option has been automatically disabled
|
// WARNING: module 'SwiftOnoneSupport' cannot be built with -experimental-skip-non-inlinable-function-bodies; this option has been automatically disabled
|
||||||
|
|
||||||
// Check skipped bodies are neither typechecked nor SILgen'd
|
// Check skipped bodies are neither typechecked nor SILgen'd
|
||||||
// RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -experimental-skip-non-inlinable-function-bodies -debug-forbid-typecheck-prefix INLINENOTYPECHECK %s -o %t/Skip.noninlinable.sil
|
// RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -experimental-skip-non-inlinable-function-bodies -debug-forbid-typecheck-prefix NEVERTYPECHECK -debug-forbid-typecheck-prefix INLINENOTYPECHECK %s -o %t/Skip.noninlinable.sil
|
||||||
// RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -O -experimental-skip-all-function-bodies -debug-forbid-typecheck-prefix ALLNOTYPECHECK %s -o %t/Skip.all.sil
|
// RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -experimental-skip-non-inlinable-function-bodies-without-types -debug-forbid-typecheck-prefix NEVERTYPECHECK -debug-forbid-typecheck-prefix TYPESNOTYPECHECK %s -o %t/Skip.withouttypes.sil
|
||||||
// %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY < %t/Skip.noninlinable.sil
|
// RUN: %target-swift-frontend -emit-sil -emit-sorted-sil -experimental-skip-all-function-bodies -debug-forbid-typecheck-prefix NEVERTYPECHECK -debug-forbid-typecheck-prefix ALLNOTYPECHECK %s -o %t/Skip.all.sil
|
||||||
// %FileCheck %s --check-prefixes CHECK,CHECK-ALL-ONLY < %t/Skip.all.sil
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY,CHECK-NONINLINE-SIL < %t/Skip.noninlinable.sil
|
||||||
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-WITHOUTTYPES-ONLY,CHECK-NONINLINE-SIL < %t/Skip.withouttypes.sil
|
||||||
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-ALL-ONLY < %t/Skip.all.sil
|
||||||
|
|
||||||
// Emit the module interface and check it against the same set of strings.
|
// Emit the module interface and check it against the same set of strings.
|
||||||
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.noninlinable.swiftinterface -experimental-skip-non-inlinable-function-bodies
|
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.noninlinable.swiftinterface -experimental-skip-non-inlinable-function-bodies
|
||||||
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY < %t/Skip.noninlinable.swiftinterface
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY,CHECK-NONINLINE-TEXTUAL < %t/Skip.noninlinable.swiftinterface
|
||||||
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.all.swiftinterface -experimental-skip-all-function-bodies
|
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.all.swiftinterface -experimental-skip-all-function-bodies
|
||||||
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-ALL-ONLY < %t/Skip.all.swiftinterface
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-ALL-ONLY,CHECK-NONINLINE-TEXTUAL < %t/Skip.all.swiftinterface
|
||||||
|
|
||||||
// Emit the module interface normally, it should be the same as when skipping
|
// Emit the module interface normally, it should be the same as when skipping
|
||||||
// non-inlinable.
|
// non-inlinable.
|
||||||
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.swiftinterface
|
// RUN: %target-swift-frontend -typecheck %s -enable-library-evolution -emit-module-interface-path %t/Skip.swiftinterface
|
||||||
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY < %t/Skip.swiftinterface
|
// RUN: %FileCheck %s --check-prefixes CHECK,CHECK-NONINLINE-ONLY,CHECK-NONINLINE-TEXTUAL < %t/Skip.swiftinterface
|
||||||
// RUN: diff -u %t/Skip.noninlinable.swiftinterface %t/Skip.swiftinterface
|
// RUN: diff -u %t/Skip.noninlinable.swiftinterface %t/Skip.swiftinterface
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
@@ -58,16 +62,14 @@ public class InlinableDeinit {
|
|||||||
@_fixed_layout
|
@_fixed_layout
|
||||||
public class InlineAlwaysDeinit {
|
public class InlineAlwaysDeinit {
|
||||||
@inline(__always) deinit {
|
@inline(__always) deinit {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) deinit body") // CHECK-NOT: "@inline(__always) deinit body"
|
_blackHole("@inline(__always) deinit body") // CHECK-NOT: "@inline(__always) deinit body"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NormalDeinit {
|
public class NormalDeinit {
|
||||||
deinit {
|
deinit {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK = 1
|
|
||||||
_blackHole("regular deinit body") // CHECK-NOT: "regular deinit body"
|
_blackHole("regular deinit body") // CHECK-NOT: "regular deinit body"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,52 +82,44 @@ public class NormalDeinit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always) public func inlineAlwaysFunc() {
|
@inline(__always) public func inlineAlwaysFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) func body") // CHECK-NOT: "@inline(__always) func body"
|
_blackHole("@inline(__always) func body") // CHECK-NOT: "@inline(__always) func body"
|
||||||
}
|
}
|
||||||
|
|
||||||
func internalFunc() {
|
func internalFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("internal func body") // CHECK-NOT: "internal func body"
|
_blackHole("internal func body") // CHECK-NOT: "internal func body"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func publicFunc() {
|
public func publicFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("public func body") // CHECK-NOT: "public func body"
|
_blackHole("public func body") // CHECK-NOT: "public func body"
|
||||||
}
|
}
|
||||||
|
|
||||||
private func privateFunc() {
|
private func privateFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("private func body") // CHECK-NOT: "private func body"
|
_blackHole("private func body") // CHECK-NOT: "private func body"
|
||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always) public func inlineAlwaysLocalTypeFunc() {
|
@inline(__always) public func inlineAlwaysLocalTypeFunc() {
|
||||||
let ALLNOTYPECHECK_outerLocal = 1
|
let NEVERTYPECHECK_outerLocal = 1
|
||||||
let INLINENOTYPECHECK_outerLocal = 1
|
|
||||||
|
|
||||||
typealias InlineAlwaysLocalType = Int
|
typealias InlineAlwaysLocalType = Int
|
||||||
_blackHole("@inline(__always) func body with local type") // CHECK-NOT: "@inline(__always) func body with local type"
|
_blackHole("@inline(__always) func body with local type") // CHECK-NOT: "@inline(__always) func body with local type"
|
||||||
func takesInlineAlwaysLocalType(_ x: InlineAlwaysLocalType) {
|
func takesInlineAlwaysLocalType(_ x: InlineAlwaysLocalType) {
|
||||||
let ALLNOTYPECHECK_innerLocal = 1
|
let NEVERTYPECHECK_innerLocal = 1
|
||||||
let INLINENOTYPECHECK_innerLocal = 1
|
|
||||||
_blackHole("nested func body inside @inline(__always) func body taking local type") // CHECK-NOT: "nested func body inside @inline(__always) func body taking local type"
|
_blackHole("nested func body inside @inline(__always) func body taking local type") // CHECK-NOT: "nested func body inside @inline(__always) func body taking local type"
|
||||||
}
|
}
|
||||||
takesInlineAlwaysLocalType(0)
|
takesInlineAlwaysLocalType(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func publicLocalTypeFunc() {
|
public func publicLocalTypeFunc() {
|
||||||
let ALLNOTYPECHECK_outerLocal = 1
|
let NEVERTYPECHECK_outerLocal = 1
|
||||||
let INLINENOTYPECHECK_outerLocal = 1
|
|
||||||
|
|
||||||
typealias LocalType = Int
|
typealias LocalType = Int
|
||||||
_blackHole("public func body with local type") // CHECK-NOT: "public func body with local type"
|
_blackHole("public func body with local type") // CHECK-NOT: "public func body with local type"
|
||||||
func takesLocalType(_ x: LocalType) {
|
func takesLocalType(_ x: LocalType) {
|
||||||
let ALLNOTYPECHECK_innerLocal = 1
|
let NEVERTYPECHECK_innerLocal = 1
|
||||||
let INLINENOTYPECHECK_innerLocal = 1
|
|
||||||
_blackHole("nested func body inside public func body taking local type") // CHECK-NOT: "nested func body inside public func body taking local type"
|
_blackHole("nested func body inside public func body taking local type") // CHECK-NOT: "nested func body inside public func body taking local type"
|
||||||
}
|
}
|
||||||
takesLocalType(0)
|
takesLocalType(0)
|
||||||
@@ -188,6 +182,57 @@ public func inlinableNestedLocalTypeFunc() {
|
|||||||
nestedFunc()
|
nestedFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func funcWithEnum() {
|
||||||
|
let INLINENOTYPECHECK_local = 1
|
||||||
|
let ALLNOTYPECHECK_local = 1
|
||||||
|
_blackHole("func with enum body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "func with enum body"
|
||||||
|
// CHECK-NONINLINE-ONLY-NOT: "func with enum body"
|
||||||
|
// CHECK-ALL-ONLY-NOT: "func with enum body"
|
||||||
|
enum E {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func funcWithClass() {
|
||||||
|
let INLINENOTYPECHECK_local = 1
|
||||||
|
let ALLNOTYPECHECK_local = 1
|
||||||
|
_blackHole("func with class body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "func with class body"
|
||||||
|
// CHECK-NONINLINE-ONLY-NOT: "func with class body"
|
||||||
|
// CHECK-ALL-ONLY-NOT: "func with class body"
|
||||||
|
class C {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func funcWithStruct() {
|
||||||
|
let INLINENOTYPECHECK_local = 1
|
||||||
|
let ALLNOTYPECHECK_local = 1
|
||||||
|
_blackHole("func with struct body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "func with struct body"
|
||||||
|
// CHECK-NONINLINE-ONLY-NOT: "func with struct body"
|
||||||
|
// CHECK-ALL-ONLY-NOT: "func with struct body"
|
||||||
|
struct S {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func funcWithNestedFuncs() {
|
||||||
|
let INLINENOTYPECHECK_local = 1
|
||||||
|
let ALLNOTYPECHECK_local = 1
|
||||||
|
_blackHole("func with nested funcs body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "func with nested funcs body"
|
||||||
|
// CHECK-NONINLINE-ONLY-NOT: "func with nested funcs body"
|
||||||
|
// CHECK-ALL-ONLY-NOT: "func with nested funcs body"
|
||||||
|
|
||||||
|
func bar() {
|
||||||
|
_blackHole("nested func body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "nested func body"
|
||||||
|
// FIXME: We could skip this nested function.
|
||||||
|
}
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
_blackHole("nested func with type body")
|
||||||
|
// CHECK-WITHOUTTYPES-ONLY: "nested func with type body"
|
||||||
|
struct S {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct Struct {
|
public struct Struct {
|
||||||
@inlinable public var inlinableVar: Int {
|
@inlinable public var inlinableVar: Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let ALLNOTYPECHECK_local = 1
|
||||||
@@ -206,8 +251,7 @@ public struct Struct {
|
|||||||
|
|
||||||
@inline(__always)
|
@inline(__always)
|
||||||
public func inlineAlwaysFunc() {
|
public func inlineAlwaysFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) method body") // CHECK-NOT: "@inline(__always) method body"
|
_blackHole("@inline(__always) method body") // CHECK-NOT: "@inline(__always) method body"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,13 +280,6 @@ public struct Struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var didSetVar: Int = 1 {
|
|
||||||
didSet {
|
|
||||||
// Body typechecked regardless
|
|
||||||
_blackHole("didSet body") // CHECK-NOT: "didSet body"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@_transparent
|
@_transparent
|
||||||
public func transparentFunc() {
|
public func transparentFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let ALLNOTYPECHECK_local = 1
|
||||||
@@ -252,20 +289,17 @@ public struct Struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func internalFunc() {
|
func internalFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("internal method body") // CHECK-NOT: "internal method body"
|
_blackHole("internal method body") // CHECK-NOT: "internal method body"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func publicFunc() {
|
public func publicFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("public method body") // CHECK-NOT: "public method body"
|
_blackHole("public method body") // CHECK-NOT: "public method body"
|
||||||
}
|
}
|
||||||
|
|
||||||
private func privateFunc() {
|
private func privateFunc() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("private method body") // CHECK-NOT: "private method body"
|
_blackHole("private method body") // CHECK-NOT: "private method body"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +310,14 @@ public struct Struct {
|
|||||||
// CHECK-ALL-ONLY-NOT: "@_transparent init body"
|
// CHECK-ALL-ONLY-NOT: "@_transparent init body"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var didSetVar: Int = 1 {
|
||||||
|
didSet {
|
||||||
|
// Body typechecked regardless
|
||||||
|
_blackHole("didSet body") // CHECK-NONINLINE-SIL: "didSet body"
|
||||||
|
// CHECK-NONINLINE-TEXTUAL-NOT: "didSet body"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@inlinable public init() {
|
@inlinable public init() {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let ALLNOTYPECHECK_local = 1
|
||||||
_blackHole("@inlinable init body")
|
_blackHole("@inlinable init body")
|
||||||
@@ -284,26 +326,22 @@ public struct Struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always) public init(a: Int) {
|
@inline(__always) public init(a: Int) {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) init body") // CHECK-NOT: "@inline(__always) init body"
|
_blackHole("@inline(__always) init body") // CHECK-NOT: "@inline(__always) init body"
|
||||||
}
|
}
|
||||||
|
|
||||||
init(c: Int) {
|
init(c: Int) {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("internal init body") // CHECK-NOT: "internal init body"
|
_blackHole("internal init body") // CHECK-NOT: "internal init body"
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(d: Int) {
|
public init(d: Int) {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("public init body") // CHECK-NOT: "public init body"
|
_blackHole("public init body") // CHECK-NOT: "public init body"
|
||||||
}
|
}
|
||||||
|
|
||||||
private init(e: Int) {
|
private init(e: Int) {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("private init body") // CHECK-NOT: "private init body"
|
_blackHole("private init body") // CHECK-NOT: "private init body"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,8 +354,7 @@ public struct Struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always) public subscript(a: Int, b: Int) -> Int {
|
@inline(__always) public subscript(a: Int, b: Int) -> Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) subscript getter") // CHECK-NOT: "@inline(__always) subscript getter"
|
_blackHole("@inline(__always) subscript getter") // CHECK-NOT: "@inline(__always) subscript getter"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -333,36 +370,31 @@ public struct Struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
subscript(a: Int, b: Int, c: Int, d: Int) -> Int {
|
subscript(a: Int, b: Int, c: Int, d: Int) -> Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("internal subscript getter") // CHECK-NOT: "internal subscript getter"
|
_blackHole("internal subscript getter") // CHECK-NOT: "internal subscript getter"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public subscript(a: Int, b: Int, c: Int, d: Int, e: Int) -> Int {
|
public subscript(a: Int, b: Int, c: Int, d: Int, e: Int) -> Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("public subscript getter") // CHECK-NOT: "public subscript getter"
|
_blackHole("public subscript getter") // CHECK-NOT: "public subscript getter"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private subscript(e: Int) -> Int {
|
private subscript(e: Int) -> Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("private subscript getter") // CHECK-NOT: "private subscript getter"
|
_blackHole("private subscript getter") // CHECK-NOT: "private subscript getter"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@inline(__always) public var inlineAlwaysVar: Int {
|
@inline(__always) public var inlineAlwaysVar: Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) getter body") // CHECK-NOT: "@inline(__always) getter body"
|
_blackHole("@inline(__always) getter body") // CHECK-NOT: "@inline(__always) getter body"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public var publicVar: Int {
|
public var publicVar: Int {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("public getter body") // CHECK-NOT: "public getter body"
|
_blackHole("public getter body") // CHECK-NOT: "public getter body"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -370,8 +402,7 @@ public struct Struct {
|
|||||||
public var inlineAlwaysSetter: Int {
|
public var inlineAlwaysSetter: Int {
|
||||||
get { 0 }
|
get { 0 }
|
||||||
@inline(__always) set {
|
@inline(__always) set {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) setter body") // CHECK-NOT: "@inline(__always) setter body"
|
_blackHole("@inline(__always) setter body") // CHECK-NOT: "@inline(__always) setter body"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,8 +410,7 @@ public struct Struct {
|
|||||||
public var regularSetter: Int {
|
public var regularSetter: Int {
|
||||||
get { 0 }
|
get { 0 }
|
||||||
set {
|
set {
|
||||||
let ALLNOTYPECHECK_local = 1
|
let NEVERTYPECHECK_local = 1
|
||||||
let INLINENOTYPECHECK_local = 1
|
|
||||||
_blackHole("@inline(__always) setter body") // CHECK-NOT: "regular setter body"
|
_blackHole("@inline(__always) setter body") // CHECK-NOT: "regular setter body"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user