diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-07-17 00:12:06 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2010-07-17 00:12:06 +0000 |
commit | fbd4bf16341c1b23181c829ef2630d9a643e793c (patch) | |
tree | 8d2793ef0e31e1e4286c617413def59f1fab30fe /lib/Frontend/PCHReader.cpp | |
parent | 0ea4dfd0eb56b065460c1696933748e765120fe0 (diff) |
Teach the PCH reader to load the dependency when encountering a chain metadata record. WIP
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHReader.cpp')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 163 |
1 files changed, 86 insertions, 77 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 7b95b8909a..6111037c9d 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1447,6 +1447,39 @@ PCHReader::ReadPCHBlock(PerFileData &F) { default: // Default behavior: ignore. break; + case pch::METADATA: { + if (Record[0] != pch::VERSION_MAJOR) { + Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old + : diag::warn_pch_version_too_new); + return IgnorePCH; + } + + RelocatablePCH = Record[4]; + if (Listener) { + std::string TargetTriple(BlobStart, BlobLen); + if (Listener->ReadTargetTriple(TargetTriple)) + return IgnorePCH; + } + break; + } + + case pch::CHAINED_METADATA: { + if (Record[0] != pch::VERSION_MAJOR) { + Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old + : diag::warn_pch_version_too_new); + return IgnorePCH; + } + + // Load the chained file. + switch(ReadPCHCore(llvm::StringRef(BlobStart, BlobLen))) { + case Failure: return Failure; + // If we have to ignore the dependency, we'll have to ignore this too. + case IgnorePCH: return IgnorePCH; + case Success: break; + } + break; + } + case pch::TYPE_OFFSET: if (!TypesLoaded.empty()) { Error("duplicate TYPE_OFFSET record in PCH file"); @@ -1470,22 +1503,6 @@ PCHReader::ReadPCHBlock(PerFileData &F) { return IgnorePCH; break; - case pch::METADATA: { - if (Record[0] != pch::VERSION_MAJOR) { - Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old - : diag::warn_pch_version_too_new); - return IgnorePCH; - } - - RelocatablePCH = Record[4]; - if (Listener) { - std::string TargetTriple(BlobStart, BlobLen); - if (Listener->ReadTargetTriple(TargetTriple)) - return IgnorePCH; - } - break; - } - case pch::IDENTIFIER_TABLE: IdentifierTableData = BlobStart; if (Record[0]) { @@ -1658,64 +1675,13 @@ PCHReader::ReadPCHBlock(PerFileData &F) { } PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) { - switch(OpenPCH(FileName)) { + switch(ReadPCHCore(FileName)) { case Failure: return Failure; case IgnorePCH: return IgnorePCH; case Success: break; } - PerFileData &F = *Chain.back(); - llvm::BitstreamCursor &Stream = F.Stream; - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); - - if (Code != llvm::bitc::ENTER_SUBBLOCK) { - Error("invalid record at top-level of PCH file"); - return Failure; - } - - unsigned BlockID = Stream.ReadSubBlockID(); - - // We only know the PCH subblock ID. - switch (BlockID) { - case llvm::bitc::BLOCKINFO_BLOCK_ID: - if (Stream.ReadBlockInfoBlock()) { - Error("malformed BlockInfoBlock in PCH file"); - return Failure; - } - break; - case pch::PCH_BLOCK_ID: - switch (ReadPCHBlock(F)) { - case Success: - break; - - case Failure: - return Failure; - - case IgnorePCH: - // FIXME: We could consider reading through to the end of this - // PCH block, skipping subblocks, to see if there are other - // PCH blocks elsewhere. - - // Clear out any preallocated source location entries, so that - // the source manager does not try to resolve them later. - SourceMgr.ClearPreallocatedSLocEntries(); - - // Remove the stat cache. - if (F.StatCache) - FileMgr.removeStatCache((PCHStatCache*)F.StatCache); - - return IgnorePCH; - } - break; - default: - if (Stream.SkipBlock()) { - Error("malformed block record in PCH file"); - return Failure; - } - break; - } - } + // Here comes stuff that we only do once the entire chain is loaded. // Check the predefines buffers. if (CheckPredefinesBuffers()) @@ -1762,7 +1728,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) { return Success; } -PCHReader::PCHReadResult PCHReader::OpenPCH(llvm::StringRef FileName) { +PCHReader::PCHReadResult PCHReader::ReadPCHCore(llvm::StringRef FileName) { Chain.push_back(new PerFileData()); PerFileData &F = *Chain.back(); @@ -1793,15 +1759,58 @@ PCHReader::PCHReadResult PCHReader::OpenPCH(llvm::StringRef FileName) { Diag(diag::err_not_a_pch_file) << FileName; return Failure; } - return Success; -} -PCHReader::PCHReadResult PCHReader::ReadChainedPCH(llvm::StringRef FileName) { - switch(OpenPCH(FileName)) { - case Failure: return Failure; - case IgnorePCH: return IgnorePCH; - case Success: break; + while (!Stream.AtEndOfStream()) { + unsigned Code = Stream.ReadCode(); + + if (Code != llvm::bitc::ENTER_SUBBLOCK) { + Error("invalid record at top-level of PCH file"); + return Failure; + } + + unsigned BlockID = Stream.ReadSubBlockID(); + + // We only know the PCH subblock ID. + switch (BlockID) { + case llvm::bitc::BLOCKINFO_BLOCK_ID: + if (Stream.ReadBlockInfoBlock()) { + Error("malformed BlockInfoBlock in PCH file"); + return Failure; + } + break; + case pch::PCH_BLOCK_ID: + switch (ReadPCHBlock(F)) { + case Success: + break; + + case Failure: + return Failure; + + case IgnorePCH: + // FIXME: We could consider reading through to the end of this + // PCH block, skipping subblocks, to see if there are other + // PCH blocks elsewhere. + + // Clear out any preallocated source location entries, so that + // the source manager does not try to resolve them later. + SourceMgr.ClearPreallocatedSLocEntries(); + + // Remove the stat cache. + if (F.StatCache) + FileMgr.removeStatCache((PCHStatCache*)F.StatCache); + + return IgnorePCH; + } + break; + default: + if (Stream.SkipBlock()) { + Error("malformed block record in PCH file"); + return Failure; + } + break; + } } + return Success; } |