aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/PCHReader.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-17 00:12:06 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-17 00:12:06 +0000
commitfbd4bf16341c1b23181c829ef2630d9a643e793c (patch)
tree8d2793ef0e31e1e4286c617413def59f1fab30fe /lib/Frontend/PCHReader.cpp
parent0ea4dfd0eb56b065460c1696933748e765120fe0 (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.cpp163
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;
}