Skip to content

Commit b6ba804

Browse files
committed
Revert "[clang][modules] Move UNHASHED_CONTROL_BLOCK up in the AST file"
This reverts commit 7d15657.
1 parent fe355a4 commit b6ba804

File tree

7 files changed

+60
-126
lines changed

7 files changed

+60
-126
lines changed

clang/include/clang/Basic/Module.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,6 @@ struct ASTFileSignature : std::array<uint8_t, 20> {
8181
return Sentinel;
8282
}
8383

84-
static ASTFileSignature createDummy() {
85-
ASTFileSignature Dummy;
86-
Dummy.fill(0x00);
87-
return Dummy;
88-
}
89-
9084
template <typename InputIt>
9185
static ASTFileSignature create(InputIt First, InputIt Last) {
9286
assert(std::distance(First, Last) == size &&

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace serialization {
4141
/// Version 4 of AST files also requires that the version control branch and
4242
/// revision match exactly, since there is no backward compatibility of
4343
/// AST files at this time.
44-
const unsigned VERSION_MAJOR = 29;
44+
const unsigned VERSION_MAJOR = 28;
4545

4646
/// AST file minor version number supported by this version of
4747
/// Clang.

clang/include/clang/Serialization/ASTWriter.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,10 @@ class ASTWriter : public ASTDeserializationListener,
128128
/// The module we're currently writing, if any.
129129
Module *WritingModule = nullptr;
130130

131-
/// The byte range representing all the UNHASHED_CONTROL_BLOCK.
132-
std::pair<uint64_t, uint64_t> UnhashedControlBlockRange;
133-
/// The bit offset of the AST block hash blob.
134-
uint64_t ASTBlockHashOffset = 0;
135-
/// The bit offset of the signature blob.
136-
uint64_t SignatureOffset = 0;
137-
138-
/// The bit offset of the first bit inside the AST_BLOCK.
131+
/// The offset of the first bit inside the AST_BLOCK.
139132
uint64_t ASTBlockStartOffset = 0;
140133

141-
/// The byte range representing all the AST_BLOCK.
134+
/// The range representing all the AST_BLOCK.
142135
std::pair<uint64_t, uint64_t> ASTBlockRange;
143136

144137
/// The base directory for any relative paths we emit.
@@ -502,11 +495,12 @@ class ASTWriter : public ASTDeserializationListener,
502495
StringRef isysroot);
503496

504497
/// Write out the signature and diagnostic options, and return the signature.
505-
void writeUnhashedControlBlock(Preprocessor &PP, ASTContext &Context);
506-
ASTFileSignature backpatchSignature();
498+
ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
499+
ASTContext &Context);
507500

508501
/// Calculate hash of the pcm content.
509-
std::pair<ASTFileSignature, ASTFileSignature> createSignature() const;
502+
static std::pair<ASTFileSignature, ASTFileSignature>
503+
createSignature(StringRef AllBytes, StringRef ASTBlockBytes);
510504

511505
void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
512506
void WriteSourceManagerBlock(SourceManager &SourceMgr,

clang/lib/Serialization/ASTReader.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4734,6 +4734,12 @@ ASTReader::ReadASTCore(StringRef FileName,
47344734
ShouldFinalizePCM = true;
47354735
return Success;
47364736

4737+
case UNHASHED_CONTROL_BLOCK_ID:
4738+
// This block is handled using look-ahead during ReadControlBlock. We
4739+
// shouldn't get here!
4740+
Error("malformed block record in AST file");
4741+
return Failure;
4742+
47374743
default:
47384744
if (llvm::Error Err = Stream.SkipBlock()) {
47394745
Error(std::move(Err));
@@ -4853,18 +4859,13 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
48534859
}
48544860
switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) {
48554861
case SIGNATURE:
4856-
if (F) {
4857-
F->Signature = ASTFileSignature::create(Blob.begin(), Blob.end());
4858-
assert(F->Signature != ASTFileSignature::createDummy() &&
4859-
"Dummy AST file signature not backpatched in ASTWriter.");
4860-
}
4862+
if (F)
4863+
F->Signature = ASTFileSignature::create(Record.begin(), Record.end());
48614864
break;
48624865
case AST_BLOCK_HASH:
4863-
if (F) {
4864-
F->ASTBlockHash = ASTFileSignature::create(Blob.begin(), Blob.end());
4865-
assert(F->ASTBlockHash != ASTFileSignature::createDummy() &&
4866-
"Dummy AST block hash not backpatched in ASTWriter.");
4867-
}
4866+
if (F)
4867+
F->ASTBlockHash =
4868+
ASTFileSignature::create(Record.begin(), Record.end());
48684869
break;
48694870
case DIAGNOSTIC_OPTIONS: {
48704871
bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
@@ -5166,12 +5167,9 @@ static ASTFileSignature readASTFileSignature(StringRef PCH) {
51665167
consumeError(MaybeRecord.takeError());
51675168
return ASTFileSignature();
51685169
}
5169-
if (SIGNATURE == MaybeRecord.get()) {
5170-
auto Signature = ASTFileSignature::create(Blob.begin(), Blob.end());
5171-
assert(Signature != ASTFileSignature::createDummy() &&
5172-
"Dummy AST file signature not backpatched in ASTWriter.");
5173-
return Signature;
5174-
}
5170+
if (SIGNATURE == MaybeRecord.get())
5171+
return ASTFileSignature::create(Record.begin(),
5172+
Record.begin() + ASTFileSignature::size);
51755173
}
51765174
}
51775175

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 26 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,97 +1120,50 @@ adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) {
11201120
}
11211121

11221122
std::pair<ASTFileSignature, ASTFileSignature>
1123-
ASTWriter::createSignature() const {
1124-
StringRef AllBytes(Buffer.data(), Buffer.size());
1125-
1123+
ASTWriter::createSignature(StringRef AllBytes, StringRef ASTBlockBytes) {
11261124
llvm::SHA1 Hasher;
1127-
Hasher.update(AllBytes.slice(ASTBlockRange.first, ASTBlockRange.second));
1125+
Hasher.update(ASTBlockBytes);
11281126
ASTFileSignature ASTBlockHash = ASTFileSignature::create(Hasher.result());
11291127

1130-
// Add the remaining bytes:
1131-
// 1. Before the unhashed control block.
1132-
Hasher.update(AllBytes.slice(0, UnhashedControlBlockRange.first));
1133-
// 2. Between the unhashed control block and the AST block.
1128+
// Add the remaining bytes (i.e. bytes before the unhashed control block that
1129+
// are not part of the AST block).
1130+
Hasher.update(
1131+
AllBytes.take_front(ASTBlockBytes.bytes_end() - AllBytes.bytes_begin()));
11341132
Hasher.update(
1135-
AllBytes.slice(UnhashedControlBlockRange.second, ASTBlockRange.first));
1136-
// 3. After the AST block.
1137-
Hasher.update(AllBytes.slice(ASTBlockRange.second, StringRef::npos));
1133+
AllBytes.take_back(AllBytes.bytes_end() - ASTBlockBytes.bytes_end()));
11381134
ASTFileSignature Signature = ASTFileSignature::create(Hasher.result());
11391135

11401136
return std::make_pair(ASTBlockHash, Signature);
11411137
}
11421138

1143-
ASTFileSignature ASTWriter::backpatchSignature() {
1144-
if (!WritingModule ||
1145-
!PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent)
1146-
return {};
1147-
1148-
// For implicit modules, write the hash of the PCM as its signature.
1149-
1150-
auto BackpatchSignatureAt = [&](const ASTFileSignature &S, uint64_t BitNo) {
1151-
using WordT = unsigned;
1152-
std::array<WordT, sizeof(ASTFileSignature) / sizeof(WordT)> Words;
1153-
static_assert(sizeof(Words) == sizeof(S));
1154-
std::memcpy(Words.data(), S.data(), sizeof(ASTFileSignature));
1155-
for (WordT Word : Words) {
1156-
Stream.BackpatchWord(BitNo, Word);
1157-
BitNo += sizeof(WordT) * 8;
1158-
}
1159-
};
1160-
1161-
ASTFileSignature ASTBlockHash;
1162-
ASTFileSignature Signature;
1163-
std::tie(ASTBlockHash, Signature) = createSignature();
1164-
1165-
BackpatchSignatureAt(ASTBlockHash, ASTBlockHashOffset);
1166-
BackpatchSignatureAt(Signature, SignatureOffset);
1167-
1168-
return Signature;
1169-
}
1170-
1171-
void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
1172-
ASTContext &Context) {
1139+
ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
1140+
ASTContext &Context) {
11731141
using namespace llvm;
11741142

11751143
// Flush first to prepare the PCM hash (signature).
11761144
Stream.FlushToWord();
1177-
UnhashedControlBlockRange.first = Stream.GetCurrentBitNo() >> 3;
1145+
auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
11781146

11791147
// Enter the block and prepare to write records.
11801148
RecordData Record;
11811149
Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
11821150

11831151
// For implicit modules, write the hash of the PCM as its signature.
1152+
ASTFileSignature Signature;
11841153
if (WritingModule &&
11851154
PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
1186-
// At this point, we don't know the actual signature of the file or the AST
1187-
// block - we're only able to compute those at the end of the serialization
1188-
// process. Let's store dummy signatures for now, and replace them with the
1189-
// real ones later on.
1190-
// The bitstream VBR-encodes record elements, which makes backpatching them
1191-
// really difficult. Let's store the signatures as blobs instead - they are
1192-
// guaranteed to be word-aligned, and we control their format/encoding.
1193-
auto Dummy = ASTFileSignature::createDummy();
1194-
SmallString<128> Blob{Dummy.begin(), Dummy.end()};
1195-
1196-
auto Abbrev = std::make_shared<BitCodeAbbrev>();
1197-
Abbrev->Add(BitCodeAbbrevOp(AST_BLOCK_HASH));
1198-
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1199-
unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1200-
1201-
Abbrev = std::make_shared<BitCodeAbbrev>();
1202-
Abbrev->Add(BitCodeAbbrevOp(SIGNATURE));
1203-
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1204-
unsigned SignatureAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1205-
1206-
Record.push_back(AST_BLOCK_HASH);
1207-
Stream.EmitRecordWithBlob(ASTBlockHashAbbrev, Record, Blob);
1208-
ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1155+
ASTFileSignature ASTBlockHash;
1156+
auto ASTBlockStartByte = ASTBlockRange.first >> 3;
1157+
auto ASTBlockByteLength = (ASTBlockRange.second >> 3) - ASTBlockStartByte;
1158+
std::tie(ASTBlockHash, Signature) = createSignature(
1159+
StringRef(Buffer.begin(), StartOfUnhashedControl),
1160+
StringRef(Buffer.begin() + ASTBlockStartByte, ASTBlockByteLength));
1161+
1162+
Record.append(ASTBlockHash.begin(), ASTBlockHash.end());
1163+
Stream.EmitRecord(AST_BLOCK_HASH, Record);
12091164
Record.clear();
1210-
1211-
Record.push_back(SIGNATURE);
1212-
Stream.EmitRecordWithBlob(SignatureAbbrev, Record, Blob);
1213-
SignatureOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1165+
Record.append(Signature.begin(), Signature.end());
1166+
Stream.EmitRecord(SIGNATURE, Record);
12141167
Record.clear();
12151168
}
12161169

@@ -1279,7 +1232,7 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
12791232

12801233
// Leave the options block.
12811234
Stream.ExitBlock();
1282-
UnhashedControlBlockRange.second = Stream.GetCurrentBitNo() >> 3;
1235+
return Signature;
12831236
}
12841237

12851238
/// Write the control block.
@@ -4737,7 +4690,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
47374690

47384691
ASTContext &Context = SemaRef.Context;
47394692
Preprocessor &PP = SemaRef.PP;
4740-
writeUnhashedControlBlock(PP, Context);
47414693

47424694
collectNonAffectingInputFiles();
47434695

@@ -4886,7 +4838,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
48864838

48874839
// Write the remaining AST contents.
48884840
Stream.FlushToWord();
4889-
ASTBlockRange.first = Stream.GetCurrentBitNo() >> 3;
4841+
ASTBlockRange.first = Stream.GetCurrentBitNo();
48904842
Stream.EnterSubblock(AST_BLOCK_ID, 5);
48914843
ASTBlockStartOffset = Stream.GetCurrentBitNo();
48924844

@@ -5239,13 +5191,13 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
52395191
Stream.EmitRecord(STATISTICS, Record);
52405192
Stream.ExitBlock();
52415193
Stream.FlushToWord();
5242-
ASTBlockRange.second = Stream.GetCurrentBitNo() >> 3;
5194+
ASTBlockRange.second = Stream.GetCurrentBitNo();
52435195

52445196
// Write the module file extension blocks.
52455197
for (const auto &ExtWriter : ModuleFileExtensionWriters)
52465198
WriteModuleFileExtension(SemaRef, *ExtWriter);
52475199

5248-
return backpatchSignature();
5200+
return writeUnhashedControlBlock(PP, Context);
52495201
}
52505202

52515203
void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {

clang/lib/Serialization/GlobalModuleIndex.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -697,12 +697,9 @@ llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
697697
}
698698

699699
// Get Signature.
700-
if (State == DiagnosticOptionsBlock && Code == SIGNATURE) {
701-
auto Signature = ASTFileSignature::create(Blob.begin(), Blob.end());
702-
assert(Signature != ASTFileSignature::createDummy() &&
703-
"Dummy AST file signature not backpatched in ASTWriter.");
704-
getModuleFileInfo(File).Signature = Signature;
705-
}
700+
if (State == DiagnosticOptionsBlock && Code == SIGNATURE)
701+
getModuleFileInfo(File).Signature = ASTFileSignature::create(
702+
Record.begin(), Record.begin() + ASTFileSignature::size);
706703

707704
// We don't care about this record.
708705
}

clang/test/Modules/ASTSignature.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
// RUN: rm -rf %t
2-
// RUN: %clang_cc1 -iquote %S/Inputs/ASTHash/ -fsyntax-only \
3-
// RUN: -fmodules -fimplicit-module-maps -fmodules-strict-context-hash \
2+
// RUN: %clang_cc1 -iquote %S/Inputs/ASTHash/ -fsyntax-only -fmodules \
3+
// RUN: -fimplicit-module-maps -fmodules-strict-context-hash \
44
// RUN: -fmodules-cache-path=%t -fdisable-module-hash %s
55
// RUN: cp %t/MyHeader2.pcm %t1.pcm
66
// RUN: rm -rf %t
77
// RUN: %clang_cc1 -nostdinc++ -iquote %S/Inputs/ASTHash/ -fsyntax-only \
88
// RUN: -fmodules -fimplicit-module-maps -fmodules-strict-context-hash \
99
// RUN: -fmodules-cache-path=%t -fdisable-module-hash %s
1010
// RUN: cp %t/MyHeader2.pcm %t2.pcm
11-
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t1.pcm > %t1.dump
12-
// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t2.pcm > %t2.dump
11+
// RUN: llvm-bcanalyzer --dump --disable-histogram %t1.pcm > %t1.dump
12+
// RUN: llvm-bcanalyzer --dump --disable-histogram %t2.pcm > %t2.dump
1313
// RUN: cat %t1.dump %t2.dump | FileCheck %s
1414

1515
#include "my_header_2.h"
1616

1717
my_int var = 42;
1818

19-
// CHECK: <AST_BLOCK_HASH abbrevid={{[0-9]+}}/> blob data = '[[AST_BLOCK_HASH:.*]]'
20-
// CHECK: <SIGNATURE abbrevid={{[0-9]+}}/> blob data = '[[SIGNATURE:.*]]'
21-
// CHECK: <AST_BLOCK_HASH abbrevid={{[0-9]+}}/> blob data = '[[AST_BLOCK_HASH]]'
22-
// CHECK-NOT: <SIGNATURE abbrevid={{[0-9]+}}/> blob data = '[[SIGNATURE]]'
23-
// The modules built by this test are designed to yield the same AST but distinct AST files.
24-
// If this test fails, it means that either the AST block has become non-relocatable,
25-
// or the file signature stopped hashing some parts of the AST file.
19+
// CHECK: [[AST_BLOCK_HASH:<AST_BLOCK_HASH .*>]]
20+
// CHECK: [[SIGNATURE:<SIGNATURE .*>]]
21+
// CHECK: [[AST_BLOCK_HASH]]
22+
// CHECK-NOT: [[SIGNATURE]]
23+
// The modules built by this test are designed to yield the same AST. If this
24+
// test fails, it means that the AST block is has become non-relocatable.

0 commit comments

Comments
 (0)