Skip to content

Commit 34779d4

Browse files
authored
Merge pull request #61789 from xymus/serial-rebuilt-bit
[Serialization] Write in the binary swiftmodule file whether it was rebuilt from a swiftinterface
2 parents e2b904e + 41ec454 commit 34779d4

File tree

12 files changed

+73
-13
lines changed

12 files changed

+73
-13
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
617617
HasAnyUnavailableValues : 1
618618
);
619619

620-
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1,
620+
SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1,
621621
/// If the module is compiled as static library.
622622
StaticLibrary : 1,
623623

@@ -632,6 +632,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
632632
/// \sa ResilienceStrategy
633633
RawResilienceStrategy : 1,
634634

635+
/// Whether the module was rebuilt from a module interface instead of being
636+
/// build from the full source.
637+
IsBuiltFromInterface : 1,
638+
635639
/// Whether all imports have been resolved. Used to detect circular imports.
636640
HasResolvedImports : 1,
637641

include/swift/AST/Module.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,15 @@ class ModuleDecl
544544
Bits.ModuleDecl.IsSystemModule = flag;
545545
}
546546

547+
/// Returns true if the module was rebuilt from a module interface instead
548+
/// of being build from the full source.
549+
bool isBuiltFromInterface() const {
550+
return Bits.ModuleDecl.IsBuiltFromInterface;
551+
}
552+
void setIsBuiltFromInterface(bool flag = true) {
553+
Bits.ModuleDecl.IsBuiltFromInterface = flag;
554+
}
555+
547556
/// Returns true if this module is a non-Swift module that was imported into
548557
/// Swift.
549558
///

include/swift/Serialization/Validation.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class ExtendedValidationInfo {
114114
unsigned IsTestable : 1;
115115
unsigned ResilienceStrategy : 2;
116116
unsigned IsImplicitDynamicEnabled : 1;
117+
unsigned IsBuiltFromInterface : 1;
117118
unsigned IsAllowModuleWithCompilerErrorsEnabled : 1;
118119
unsigned IsConcurrencyChecked : 1;
119120
} Bits;
@@ -163,6 +164,10 @@ class ExtendedValidationInfo {
163164
void setResilienceStrategy(ResilienceStrategy resilience) {
164165
Bits.ResilienceStrategy = unsigned(resilience);
165166
}
167+
bool isBuiltFromInterface() const { return Bits.IsBuiltFromInterface; }
168+
void setIsBuiltFromInterface(bool val) {
169+
Bits.IsBuiltFromInterface = val;
170+
}
166171
bool isAllowModuleWithCompilerErrorsEnabled() {
167172
return Bits.IsAllowModuleWithCompilerErrorsEnabled;
168173
}

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ std::error_code ExplicitModuleInterfaceBuilder::buildSwiftModuleFromInterface(
249249

250250
SILOptions &SILOpts = Invocation.getSILOptions();
251251
auto Mod = Instance.getMainModule();
252+
Mod->setIsBuiltFromInterface(true);
252253
auto &TC = Instance.getSILTypes();
253254
auto SILMod = performASTLowering(Mod, TC, SILOpts);
254255
if (!SILMod) {

lib/Serialization/ModuleFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@ class ModuleFile
517517
return ResilienceStrategy(Core->Bits.ResilienceStrategy);
518518
}
519519

520+
bool isBuiltFromInterface() const {
521+
return Core->Bits.IsBuiltFromInterface;
522+
}
523+
520524
/// Whether this module is compiled with implicit dynamic.
521525
bool isImplicitDynamicEnabled() const {
522526
return Core->Bits.IsImplicitDynamicEnabled;

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
151151
options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy);
152152
extendedInfo.setResilienceStrategy(ResilienceStrategy(Strategy));
153153
break;
154+
case options_block::IS_BUILT_FROM_INTERFACE:
155+
extendedInfo.setIsBuiltFromInterface(true);
156+
break;
154157
case options_block::IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED:
155158
extendedInfo.setAllowModuleWithCompilerErrorsEnabled(true);
156159
break;
@@ -581,12 +584,17 @@ void ModuleFileSharedCore::fatal(llvm::Error error) const {
581584
}
582585

583586
void ModuleFileSharedCore::outputDiagnosticInfo(llvm::raw_ostream &os) const {
584-
os << "module '" << Name << "' with full misc version '" << MiscVersion
585-
<< "'";
587+
bool resilient = ResilienceStrategy(Bits.ResilienceStrategy) ==
588+
ResilienceStrategy::Resilient;
589+
os << "module '" << Name
590+
<< "', builder version '" << MiscVersion
591+
<< "', built from "
592+
<< (Bits.IsBuiltFromInterface? "swiftinterface": "source")
593+
<< ", " << (resilient? "resilient": "non-resilient");
586594
if (Bits.IsAllowModuleWithCompilerErrorsEnabled)
587-
os << " (built with -experimental-allow-module-with-compiler-errors)";
595+
os << ", built with -experimental-allow-module-with-compiler-errors";
588596
if (ModuleInputBuffer)
589-
os << " at '" << ModuleInputBuffer->getBufferIdentifier() << "'";
597+
os << ", loaded from '" << ModuleInputBuffer->getBufferIdentifier() << "'";
590598
}
591599

592600
ModuleFileSharedCore::~ModuleFileSharedCore() { }
@@ -1319,6 +1327,7 @@ ModuleFileSharedCore::ModuleFileSharedCore(
13191327
Bits.IsTestable = extInfo.isTestable();
13201328
Bits.ResilienceStrategy = unsigned(extInfo.getResilienceStrategy());
13211329
Bits.IsImplicitDynamicEnabled = extInfo.isImplicitDynamicEnabled();
1330+
Bits.IsBuiltFromInterface = extInfo.isBuiltFromInterface();
13221331
Bits.IsAllowModuleWithCompilerErrorsEnabled =
13231332
extInfo.isAllowModuleWithCompilerErrorsEnabled();
13241333
Bits.IsConcurrencyChecked = extInfo.isConcurrencyChecked();

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ class ModuleFileSharedCore {
347347
/// Discriminator for resilience strategy.
348348
unsigned ResilienceStrategy : 2;
349349

350+
/// Whether the module was rebuilt from a module interface instead of being
351+
/// build from the full source.
352+
unsigned IsBuiltFromInterface: 1;
353+
350354
/// Whether this module is compiled with implicit dynamic.
351355
unsigned IsImplicitDynamicEnabled: 1;
352356

@@ -357,7 +361,7 @@ class ModuleFileSharedCore {
357361
unsigned IsConcurrencyChecked: 1;
358362

359363
// Explicitly pad out to the next word boundary.
360-
unsigned : 5;
364+
unsigned : 4;
361365
} Bits = {};
362366
static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small");
363367

lib/Serialization/ModuleFormat.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 718; // element archetype
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 719; // isBuiltFromInterface
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -826,6 +826,7 @@ namespace options_block {
826826
RESILIENCE_STRATEGY,
827827
ARE_PRIVATE_IMPORTS_ENABLED,
828828
IS_IMPLICIT_DYNAMIC_ENABLED,
829+
IS_BUILT_FROM_INTERFACE,
829830
IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED,
830831
MODULE_ABI_NAME,
831832
IS_CONCURRENCY_CHECKED,
@@ -871,6 +872,10 @@ namespace options_block {
871872
BCFixed<2>
872873
>;
873874

875+
using IsBuiltFromInterfaceLayout = BCRecordLayout<
876+
IS_BUILT_FROM_INTERFACE
877+
>;
878+
874879
using IsAllowModuleWithCompilerErrorsEnabledLayout = BCRecordLayout<
875880
IS_ALLOW_MODULE_WITH_COMPILER_ERRORS_ENABLED
876881
>;

lib/Serialization/Serialization.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,11 @@ void Serializer::writeHeader(const SerializationOptions &options) {
10491049
Strategy.emit(ScratchRecord, unsigned(M->getResilienceStrategy()));
10501050
}
10511051

1052+
if (M->isBuiltFromInterface()) {
1053+
options_block::IsBuiltFromInterfaceLayout BuiltFromInterface(Out);
1054+
BuiltFromInterface.emit(ScratchRecord);
1055+
}
1056+
10521057
if (allowCompilerErrors()) {
10531058
options_block::IsAllowModuleWithCompilerErrorsEnabledLayout
10541059
AllowErrors(Out);

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST(
770770
M.setImplicitDynamicEnabled();
771771
if (loadedModuleFile->hasIncrementalInfo())
772772
M.setHasIncrementalInfo();
773+
if (loadedModuleFile->isBuiltFromInterface())
774+
M.setIsBuiltFromInterface();
773775
if (!loadedModuleFile->getModuleABIName().empty())
774776
M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName()));
775777
if (loadedModuleFile->isConcurrencyChecked())

test/Serialization/Recovery/crash-recovery.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ public class Sub: Base {
1919
// CHECK-CRASH-LABEL: *** DESERIALIZATION FAILURE ***
2020
// CHECK-CRASH-LABEL: *** If any module named here was modified in the SDK, please delete the ***
2121
// CHECK-CRASH-LABEL: *** new swiftmodule files from the SDK and keep only swiftinterfaces. ***
22-
// CHECK-CRASH: module 'Lib' with full misc version {{.*}}4.1.50
22+
// CHECK-CRASH: module 'Lib', builder version {{.*}}4.1.50
2323
// CHECK-CRASH: could not find 'disappearingMethod()' in parent class

test/Serialization/Recovery/crash-xref.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
// RUN: %empty-directory(%t/partials)
55
// RUN: %empty-directory(%t/normal)
66
// RUN: %empty-directory(%t/errors)
7+
// RUN: %empty-directory(%t/cache)
78

89
/// Compile module A with a type and an empty module B.
9-
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/A.swiftmodule -module-name A -D LIB
10-
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/B.swiftmodule -module-name B
10+
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/A.swiftmodule -module-name A -D LIB -enable-library-evolution
11+
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/B.swiftmodule -module-name B -enable-library-evolution
1112

1213
/// Compile a client using the type from A.
13-
// RUN: %target-swift-frontend %s -emit-module-path %t/normal/Client.swiftmodule -module-name Client -D CLIENT -I %t/partials
14+
// RUN: %target-swift-frontend %s -emit-module-path %t/normal/Client.swiftmodule -module-name Client -D CLIENT -I %t/partials -enable-library-evolution -emit-module-interface-path %t/normal/Client.swiftinterface
1415
// RUN: %target-swift-frontend %s -emit-module-path %t/errors/Client.swiftmodule -module-name Client -D CLIENT -I %t/partials -experimental-allow-module-with-compiler-errors
1516

17+
/// Force rebuilding from the swiftinterface.
18+
// RUN: mv %t/normal/Client.swiftmodule %t/swap-Client.swiftmodule
19+
// RUN: echo "import Client" | %target-swift-frontend -typecheck - -I %t/partials -I %t/normal -module-cache-path %t/cache/
20+
//2> /dev/null
21+
// RUN: mv %t/swap-Client.swiftmodule %t/normal/Client.swiftmodule
22+
1623
/// Swap A and B around! A is now empty and B defines the type.
1724
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/A.swiftmodule -module-name A
1825
// RUN: %target-swift-frontend %s -emit-module-path %t/partials/B.swiftmodule -module-name B -D LIB
@@ -25,7 +32,7 @@
2532
// NORMALFAILURE-LABEL: *** DESERIALIZATION FAILURE ***
2633
// NORMALFAILURE-LABEL: *** If any module named here was modified in the SDK, please delete the ***
2734
// NORMALFAILURE-LABEL: *** new swiftmodule files from the SDK and keep only swiftinterfaces. ***
28-
// NORMALFAILURE-NEXT: module 'Client' with full misc version {{.*}}'
35+
// NORMALFAILURE-NEXT: module 'Client', builder version {{.*}}', built from source, resilient, loaded from
2936
// NORMALFAILURE-NEXT: Could not deserialize type for 'foo()'
3037
// NORMALFAILURE-NEXT: Caused by: top-level value not found
3138
// NORMALFAILURE-NEXT: Cross-reference to module 'A'
@@ -37,14 +44,19 @@
3744
// ALLOWFAILURE-LABEL: *** DESERIALIZATION FAILURE ***
3845
// ALLOWFAILURE-LABEL: *** If any module named here was modified in the SDK, please delete the ***
3946
// ALLOWFAILURE-LABEL: *** new swiftmodule files from the SDK and keep only swiftinterfaces. ***
40-
// ALLOWFAILURE-NEXT: module 'Client' with full misc version {{.*}}' (built with -experimental-allow-module-with-compiler-errors)
47+
// ALLOWFAILURE-NEXT: module 'Client', builder version {{.*}}', built from source, non-resilient, built with -experimental-allow-module-with-compiler-errors, loaded from
4148
// ALLOWFAILURE-NEXT: Could not deserialize type for 'foo()'
4249
// ALLOWFAILURE-NEXT: Caused by: top-level value not found
4350
// ALLOWFAILURE-NEXT: Cross-reference to module 'A'
4451
// ALLOWFAILURE-NEXT: ... SomeType
4552
// ALLOWFAILURE-NEXT: Notes:
4653
// ALLOWFAILURE-NEXT: * There is a matching 'SomeType' in module 'B'. If this is imported from clang, please make sure the header is part of a single clang module.
4754

55+
/// Test a swiftmodule rebuilt from the swiftinterface.
56+
// RUN: not --crash %target-swift-frontend -emit-sil %t/cache/Client-*.swiftmodule -module-name Client -I %t/partials -disable-deserialization-recovery 2> %t/cache_stderr
57+
// RUN: cat %t/cache_stderr | %FileCheck %s -check-prefixes=CACHEFAILURE
58+
// CACHEFAILURE: module 'Client', builder version {{.*}}', built from swiftinterface, resilient
59+
4860
#if LIB
4961
public struct SomeType {
5062
public init() {}

0 commit comments

Comments
 (0)