diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-05 02:33:27 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-12-05 02:33:27 +0000 |
| commit | 1d21a07ca11b79694b4bcade1ebcef14254fb431 (patch) | |
| tree | 7e1144c9dee739d94bc0108e2e90f44f6db39059 /clang/lib/Serialization/ASTReader.cpp | |
| parent | 66d7791176fef493bb4dc7fcd6929e7aab6135c6 (diff) | |
| download | bcm5719-llvm-1d21a07ca11b79694b4bcade1ebcef14254fb431.tar.gz bcm5719-llvm-1d21a07ca11b79694b4bcade1ebcef14254fb431.zip | |
[modules] Instead of storing absolute paths in a .pcm file, store the path to
the root of the module and use paths relative to that directory wherever
possible. This is a step towards allowing explicit modules to be relocated
without being rebuilt, which is important for some kinds of distributed builds,
for good paths in diagnostics, and for appropriate .d output.
llvm-svn: 223443
Diffstat (limited to 'clang/lib/Serialization/ASTReader.cpp')
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 136 |
1 files changed, 71 insertions, 65 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b253704a361..7baeba78c4e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1029,7 +1029,7 @@ void ASTReader::Error(unsigned DiagID, /// \brief Read the line table in the source manager block. /// \returns true if there was an error. bool ASTReader::ParseLineTable(ModuleFile &F, - SmallVectorImpl<uint64_t> &Record) { + const RecordData &Record) { unsigned Idx = 0; LineTableInfo &LineTable = SourceMgr.getLineTable(); @@ -1037,10 +1037,7 @@ bool ASTReader::ParseLineTable(ModuleFile &F, std::map<int, int> FileIDs; for (int I = 0, N = Record[Idx++]; I != N; ++I) { // Extract the file name - unsigned FilenameLen = Record[Idx++]; - std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen); - Idx += FilenameLen; - MaybeAddSystemRootToFilename(F, Filename); + auto Filename = ReadPath(F, Record, Idx); FileIDs[I] = LineTable.getLineTableFilenameID(Filename); } @@ -1483,11 +1480,11 @@ ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { return llvm::hash_combine(ikey.Size, ikey.ModTime); } - + HeaderFileInfoTrait::internal_key_type HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) { internal_key_type ikey = { FE->getSize(), FE->getModificationTime(), - FE->getName() }; + FE->getName(), /*Imported*/false }; return ikey; } @@ -1495,14 +1492,24 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { if (a.Size != b.Size || a.ModTime != b.ModTime) return false; - if (strcmp(a.Filename, b.Filename) == 0) + if (llvm::sys::path::is_absolute(a.Filename) && + strcmp(a.Filename, b.Filename) == 0) return true; // Determine whether the actual files are equivalent. FileManager &FileMgr = Reader.getFileManager(); - const FileEntry *FEA = FileMgr.getFile(a.Filename); - const FileEntry *FEB = FileMgr.getFile(b.Filename); - return (FEA && FEA == FEB); + auto GetFile = [&](const internal_key_type &Key) -> const FileEntry* { + if (!Key.Imported) + return FileMgr.getFile(Key.Filename); + + std::string Resolved = Key.Filename; + Reader.ResolveImportedPath(M, Resolved); + return FileMgr.getFile(Resolved); + }; + + const FileEntry *FEA = GetFile(a); + const FileEntry *FEB = GetFile(b); + return FEA && FEA == FEB; } std::pair<unsigned, unsigned> @@ -1520,6 +1527,7 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d)); ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d)); ikey.Filename = (const char *)d; + ikey.Imported = true; return ikey; } @@ -1559,11 +1567,13 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, FileManager &FileMgr = Reader.getFileManager(); ModuleMap &ModMap = Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - // FIXME: This is wrong. We should track the filename as written; this - // information should be propagated through the SUBMODULE_HEADER etc - // records rather than from here. + // FIXME: This information should be propagated through the + // SUBMODULE_HEADER etc records rather than from here. // FIXME: We don't ever mark excluded headers. - Module::Header H = { key.Filename, FileMgr.getFile(key.Filename) }; + std::string Filename = key.Filename; + if (key.Imported) + Reader.ResolveImportedPath(M, Filename); + Module::Header H = { key.Filename, FileMgr.getFile(Filename) }; ModMap.addHeader(Mod, H, HFI.getHeaderRole()); } } @@ -2084,14 +2094,14 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { off_t StoredSize; time_t StoredTime; bool Overridden; - + assert(Record[0] == ID && "Bogus stored ID or offset"); StoredSize = static_cast<off_t>(Record[1]); StoredTime = static_cast<time_t>(Record[2]); Overridden = static_cast<bool>(Record[3]); Filename = Blob; - MaybeAddSystemRootToFilename(F, Filename); - + ResolveImportedPath(F, Filename); + InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden }; return R; } @@ -2229,46 +2239,24 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { return IF; } -const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) { - ModuleFile &M = ModuleMgr.getPrimaryModule(); - std::string Filename = filenameStrRef; - MaybeAddSystemRootToFilename(M, Filename); - const FileEntry *File = FileMgr.getFile(Filename); - if (File == nullptr && !M.OriginalDir.empty() && !CurrentDir.empty() && - M.OriginalDir != CurrentDir) { - std::string resolved = resolveFileRelativeToOriginalDir(Filename, - M.OriginalDir, - CurrentDir); - if (!resolved.empty()) - File = FileMgr.getFile(resolved); - } - - return File; +/// \brief If we are loading a relocatable PCH or module file, and the filename +/// is not an absolute path, add the system or module root to the beginning of +/// the file name. +void ASTReader::ResolveImportedPath(ModuleFile &M, std::string &Filename) { + // Resolve relative to the base directory, if we have one. + if (!M.BaseDirectory.empty()) + return ResolveImportedPath(Filename, M.BaseDirectory); } -/// \brief If we are loading a relocatable PCH file, and the filename is -/// not an absolute path, add the system root to the beginning of the file -/// name. -void ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M, - std::string &Filename) { - // If this is not a relocatable PCH file, there's nothing to do. - if (!M.RelocatablePCH) - return; - +void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) { if (Filename.empty() || llvm::sys::path::is_absolute(Filename)) return; - if (isysroot.empty()) { - // If no system root was given, default to '/' - Filename.insert(Filename.begin(), '/'); - return; - } - - unsigned Length = isysroot.size(); - if (isysroot[Length - 1] != '/') + unsigned Length = Prefix.size(); + if (Prefix[Length - 1] != '/') Filename.insert(Filename.begin(), '/'); - Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end()); + Filename.insert(Filename.begin(), Prefix.begin(), Prefix.end()); } ASTReader::ASTReadResult @@ -2388,6 +2376,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, } F.RelocatablePCH = Record[4]; + // Relative paths in a relocatable PCH are relative to our sysroot. + if (F.RelocatablePCH) + F.BaseDirectory = isysroot.empty() ? "/" : isysroot; const std::string &CurBranch = getClangFullRepositoryVersion(); StringRef ASTBranch = Blob; @@ -2418,10 +2409,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, off_t StoredSize = (off_t)Record[Idx++]; time_t StoredModTime = (time_t)Record[Idx++]; ASTFileSignature StoredSignature = Record[Idx++]; - unsigned Length = Record[Idx++]; - SmallString<128> ImportedFile(Record.begin() + Idx, - Record.begin() + Idx + Length); - Idx += Length; + auto ImportedFile = ReadPath(F, Record, Idx); // Load the AST file. switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded, @@ -2505,7 +2493,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, F.OriginalSourceFileID = FileID::get(Record[0]); F.ActualOriginalSourceFileName = Blob; F.OriginalSourceFileName = F.ActualOriginalSourceFileName; - MaybeAddSystemRootToFilename(F, F.OriginalSourceFileName); + ResolveImportedPath(F, F.OriginalSourceFileName); break; case ORIGINAL_FILE_ID: @@ -2522,6 +2510,10 @@ ASTReader::ReadControlBlock(ModuleFile &F, Listener->ReadModuleName(F.ModuleName); break; + case MODULE_DIRECTORY: + F.BaseDirectory = Blob; + break; + case MODULE_MAP_FILE: if (ASTReadResult Result = ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities)) @@ -3342,7 +3334,7 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities) { unsigned Idx = 0; - F.ModuleMapPath = ReadString(Record, Idx); + F.ModuleMapPath = ReadPath(F, Record, Idx); if (F.Kind == MK_ExplicitModule) { // For an explicitly-loaded module, we don't care whether the original @@ -3389,7 +3381,7 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, llvm::SmallPtrSet<const FileEntry *, 1> AdditionalStoredMaps; for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) { // FIXME: we should use input files rather than storing names. - std::string Filename = ReadString(Record, Idx); + std::string Filename = ReadPath(F, Record, Idx); const FileEntry *F = FileMgr.getFile(Filename, false, false); if (F == nullptr) { @@ -4256,6 +4248,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, // Scan for ORIGINAL_FILE inside the control block. RecordData Record; + std::string ModuleDir; while (1) { llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); if (Entry.Kind == llvm::BitstreamEntry::EndBlock) @@ -4280,9 +4273,14 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, case MODULE_NAME: Listener.ReadModuleName(Blob); break; + case MODULE_DIRECTORY: + ModuleDir = Blob; + break; case MODULE_MAP_FILE: { unsigned Idx = 0; - Listener.ReadModuleMapFile(ReadString(Record, Idx)); + auto Path = ReadString(Record, Idx); + ResolveImportedPath(Path, ModuleDir); + Listener.ReadModuleMapFile(Path); break; } case LANGUAGE_OPTIONS: @@ -4344,7 +4342,10 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) { case INPUT_FILE: bool Overridden = static_cast<bool>(Record[3]); - shouldContinue = Listener.visitInputFile(Blob, isSystemFile, Overridden); + std::string Filename = Blob; + ResolveImportedPath(Filename, ModuleDir); + shouldContinue = + Listener.visitInputFile(Filename, isSystemFile, Overridden); break; } if (!shouldContinue) @@ -4361,11 +4362,9 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, while (Idx < N) { // Read information about the AST file. Idx += 5; // ImportLoc, Size, ModTime, Signature - unsigned Length = Record[Idx++]; - SmallString<128> ImportedFile(Record.begin() + Idx, - Record.begin() + Idx + Length); - Idx += Length; - Listener.visitImport(ImportedFile); + std::string Filename = ReadString(Record, Idx); + ResolveImportedPath(Filename, ModuleDir); + Listener.visitImport(Filename); } break; } @@ -8050,6 +8049,13 @@ std::string ASTReader::ReadString(const RecordData &Record, unsigned &Idx) { return Result; } +std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record, + unsigned &Idx) { + std::string Filename = ReadString(Record, Idx); + ResolveImportedPath(F, Filename); + return Filename; +} + VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, unsigned &Idx) { unsigned Major = Record[Idx++]; |

