mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
[Serialization] Add precomputed layout table for hidden types
Add the module-format machinery that lets a Swift library record the physical layout of hidden types (currently limited to C types imported via internal bridging header). into binary modules, so downstream consumers can pull the layouts of these hidden types without loading the internal dependency. To test this, this change also added a frontend action to print hidden types' layouts from both the module under compilation and all the modules being imported.
This commit is contained in:
@@ -1125,6 +1125,74 @@ bool ModuleFileSharedCore::readIndexBlock(llvm::BitstreamCursor &cursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ModuleFileSharedCore::readHiddenTypeLayoutsBlock(
|
||||
llvm::BitstreamCursor &cursor) {
|
||||
if (llvm::Error Err = cursor.EnterSubBlock(HIDDEN_TYPE_LAYOUTS_BLOCK_ID)) {
|
||||
consumeError(std::move(Err));
|
||||
return false;
|
||||
}
|
||||
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
StringRef blobData;
|
||||
|
||||
while (!cursor.AtEndOfStream()) {
|
||||
Expected<llvm::BitstreamEntry> maybeEntry = cursor.advance();
|
||||
if (!maybeEntry) {
|
||||
consumeError(maybeEntry.takeError());
|
||||
return false;
|
||||
}
|
||||
llvm::BitstreamEntry entry = maybeEntry.get();
|
||||
switch (entry.Kind) {
|
||||
case llvm::BitstreamEntry::EndBlock:
|
||||
return true;
|
||||
|
||||
case llvm::BitstreamEntry::Error:
|
||||
return false;
|
||||
|
||||
case llvm::BitstreamEntry::SubBlock:
|
||||
// Unexpected sub-block; skip for forward compatibility.
|
||||
if (cursor.SkipBlock())
|
||||
return false;
|
||||
break;
|
||||
|
||||
case llvm::BitstreamEntry::Record: {
|
||||
scratch.clear();
|
||||
blobData = {};
|
||||
Expected<unsigned> maybeKind =
|
||||
cursor.readRecord(entry.ID, scratch, &blobData);
|
||||
if (!maybeKind) {
|
||||
consumeError(maybeKind.takeError());
|
||||
return false;
|
||||
}
|
||||
unsigned kind = maybeKind.get();
|
||||
if (kind != hidden_type_layouts_block::HIDDEN_TYPE_LAYOUT) {
|
||||
// Unknown record kind, ignore for forward compatibility.
|
||||
break;
|
||||
}
|
||||
if (scratch.size() < 5)
|
||||
return false;
|
||||
|
||||
AbstractTypeLayout layout;
|
||||
layout.size = scratch[0];
|
||||
layout.alignment = scratch[1];
|
||||
layout.stride = scratch[2];
|
||||
layout.bitwiseCopyable = scratch[3] != 0;
|
||||
layout.isOpaque = scratch[4] != 0;
|
||||
layout.mangledName = blobData.str();
|
||||
|
||||
// StringMap owns its keys (copies blobData). If a duplicate entry
|
||||
// appears the module is malformed.
|
||||
auto result = HiddenTypeLayouts.try_emplace(blobData, std::move(layout));
|
||||
if (!result.second)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<ModuleFileSharedCore::SerializedDeclCommentTable>
|
||||
ModuleFileSharedCore::readDeclCommentTable(ArrayRef<uint64_t> fields,
|
||||
StringRef blobData) const {
|
||||
@@ -1901,6 +1969,14 @@ ModuleFileSharedCore::ModuleFileSharedCore(
|
||||
break;
|
||||
}
|
||||
|
||||
case HIDDEN_TYPE_LAYOUTS_BLOCK_ID: {
|
||||
if (!readHiddenTypeLayoutsBlock(cursor)) {
|
||||
info.status = error(Status::Malformed);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SIL_INDEX_BLOCK_ID: {
|
||||
// Save the cursor.
|
||||
SILIndexCursor = cursor;
|
||||
|
||||
Reference in New Issue
Block a user