From aa8362e18eab808b975eddc5489e1e2e311dce85 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Fri, 5 Dec 2014 14:52:04 +0000 Subject: [PATCH] Temporarily reverting r223443 due to bot breakage. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223465 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Serialization/ASTBitCodes.h | 5 +- include/clang/Serialization/ASTReader.h | 14 +- include/clang/Serialization/ASTWriter.h | 25 +-- include/clang/Serialization/Module.h | 3 - lib/Serialization/ASTReader.cpp | 136 ++++++++-------- lib/Serialization/ASTReaderInternals.h | 5 +- lib/Serialization/ASTWriter.cpp | 186 +++++++++------------- 7 files changed, 153 insertions(+), 221 deletions(-) diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index d8629c2dde..85495839d3 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -291,10 +291,7 @@ namespace clang { MODULE_MAP_FILE = 14, /// \brief Record code for the signature that identifiers this AST file. - SIGNATURE = 15, - - /// \brief Record code for the module build directory. - MODULE_DIRECTORY = 16, + SIGNATURE = 15 }; /// \brief Record types that occur within the input-files block diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 91ad34bd1c..1b0347e91f 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1113,11 +1113,12 @@ private: serialization::InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true); -public: - void ResolveImportedPath(ModuleFile &M, std::string &Filename); - static void ResolveImportedPath(std::string &Filename, StringRef Prefix); + /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take + /// into account all the necessary relocations. + const FileEntry *getFileEntry(StringRef filename); + + void MaybeAddSystemRootToFilename(ModuleFile &M, std::string &Filename); -private: struct ImportedModule { ModuleFile *Mod; ModuleFile *ImportedBy; @@ -1140,7 +1141,7 @@ private: const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); - bool ParseLineTable(ModuleFile &F, const RecordData &Record); + bool ParseLineTable(ModuleFile &F, SmallVectorImpl &Record); bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); SourceLocation getImportLocation(ModuleFile *F); @@ -2044,9 +2045,6 @@ public: // \brief Read a string static std::string ReadString(const RecordData &Record, unsigned &Idx); - // \brief Read a path - std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx); - /// \brief Read a version tuple. static VersionTuple ReadVersionTuple(const RecordData &Record, unsigned &Idx); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 9907fae676..20e9935c0c 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -111,10 +111,7 @@ private: /// \brief The module we're currently writing, if any. Module *WritingModule; - - /// \brief The base directory for any relative paths we emit. - std::string BaseDirectory; - + /// \brief Indicates when the AST writing is actively performing /// serialization, rather than just queueing updates. bool WritingAST; @@ -460,11 +457,13 @@ private: StringRef isysroot, const std::string &OutputFile); void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, + StringRef isysroot, bool Modules); void WriteSourceManagerBlock(SourceManager &SourceMgr, - const Preprocessor &PP); + const Preprocessor &PP, + StringRef isysroot); void WritePreprocessor(const Preprocessor &PP, bool IsModule); - void WriteHeaderSearch(const HeaderSearch &HS); + void WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot); void WritePreprocessorDetail(PreprocessingRecord &PPRec); void WriteSubmodules(Module *WritingModule); @@ -540,8 +539,7 @@ public: /// writing a precompiled header. /// /// \param isysroot if non-empty, write a relocatable file whose headers - /// are relative to the given system root. If we're writing a module, its - /// build directory will be used in preference to this if both are available. + /// are relative to the given system root. void WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, @@ -688,17 +686,6 @@ public: /// \brief Add a string to the given record. void AddString(StringRef Str, RecordDataImpl &Record); - /// \brief Convert a path from this build process into one that is appropriate - /// for emission in the module file. - bool PreparePathForOutput(SmallVectorImpl &Path); - - /// \brief Add a path to the given record. - void AddPath(StringRef Path, RecordDataImpl &Record); - - /// \brief Emit the current record with the given path as a blob. - void EmitRecordWithPath(unsigned Abbrev, RecordDataImpl &Record, - StringRef Path); - /// \brief Add a version tuple to the given record void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index 426cec5dd7..f6889cfe8e 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -125,9 +125,6 @@ public: /// \brief The name of the module. std::string ModuleName; - /// \brief The base directory of the module. - std::string BaseDirectory; - std::string getTimestampFilename() const { return FileName + ".timestamp"; } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 7baeba78c4..b253704a36 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/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, - const RecordData &Record) { + SmallVectorImpl &Record) { unsigned Idx = 0; LineTableInfo &LineTable = SourceMgr.getLineTable(); @@ -1037,7 +1037,10 @@ bool ASTReader::ParseLineTable(ModuleFile &F, std::map FileIDs; for (int I = 0, N = Record[Idx++]; I != N; ++I) { // Extract the file name - auto Filename = ReadPath(F, Record, Idx); + unsigned FilenameLen = Record[Idx++]; + std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen); + Idx += FilenameLen; + MaybeAddSystemRootToFilename(F, Filename); FileIDs[I] = LineTable.getLineTableFilenameID(Filename); } @@ -1480,11 +1483,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(), /*Imported*/false }; + FE->getName() }; return ikey; } @@ -1492,24 +1495,14 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { if (a.Size != b.Size || a.ModTime != b.ModTime) return false; - if (llvm::sys::path::is_absolute(a.Filename) && - strcmp(a.Filename, b.Filename) == 0) + if (strcmp(a.Filename, b.Filename) == 0) return true; // Determine whether the actual files are equivalent. FileManager &FileMgr = Reader.getFileManager(); - 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; + const FileEntry *FEA = FileMgr.getFile(a.Filename); + const FileEntry *FEB = FileMgr.getFile(b.Filename); + return (FEA && FEA == FEB); } std::pair @@ -1527,7 +1520,6 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { ikey.Size = off_t(endian::readNext(d)); ikey.ModTime = time_t(endian::readNext(d)); ikey.Filename = (const char *)d; - ikey.Imported = true; return ikey; } @@ -1567,13 +1559,11 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, FileManager &FileMgr = Reader.getFileManager(); ModuleMap &ModMap = Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - // FIXME: This information should be propagated through the - // SUBMODULE_HEADER etc records rather than from here. + // 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: We don't ever mark excluded headers. - std::string Filename = key.Filename; - if (key.Imported) - Reader.ResolveImportedPath(M, Filename); - Module::Header H = { key.Filename, FileMgr.getFile(Filename) }; + Module::Header H = { key.Filename, FileMgr.getFile(key.Filename) }; ModMap.addHeader(Mod, H, HFI.getHeaderRole()); } } @@ -2094,14 +2084,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(Record[1]); StoredTime = static_cast(Record[2]); Overridden = static_cast(Record[3]); Filename = Blob; - ResolveImportedPath(F, Filename); - + MaybeAddSystemRootToFilename(F, Filename); + InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden }; return R; } @@ -2239,24 +2229,46 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { return IF; } -/// \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); +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; } -void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) { +/// \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; + if (Filename.empty() || llvm::sys::path::is_absolute(Filename)) return; - unsigned Length = Prefix.size(); - if (Prefix[Length - 1] != '/') + if (isysroot.empty()) { + // If no system root was given, default to '/' + Filename.insert(Filename.begin(), '/'); + return; + } + + unsigned Length = isysroot.size(); + if (isysroot[Length - 1] != '/') Filename.insert(Filename.begin(), '/'); - Filename.insert(Filename.begin(), Prefix.begin(), Prefix.end()); + Filename.insert(Filename.begin(), isysroot.begin(), isysroot.end()); } ASTReader::ASTReadResult @@ -2376,9 +2388,6 @@ 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; @@ -2409,7 +2418,10 @@ ASTReader::ReadControlBlock(ModuleFile &F, off_t StoredSize = (off_t)Record[Idx++]; time_t StoredModTime = (time_t)Record[Idx++]; ASTFileSignature StoredSignature = Record[Idx++]; - auto ImportedFile = ReadPath(F, Record, Idx); + unsigned Length = Record[Idx++]; + SmallString<128> ImportedFile(Record.begin() + Idx, + Record.begin() + Idx + Length); + Idx += Length; // Load the AST file. switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded, @@ -2493,7 +2505,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, F.OriginalSourceFileID = FileID::get(Record[0]); F.ActualOriginalSourceFileName = Blob; F.OriginalSourceFileName = F.ActualOriginalSourceFileName; - ResolveImportedPath(F, F.OriginalSourceFileName); + MaybeAddSystemRootToFilename(F, F.OriginalSourceFileName); break; case ORIGINAL_FILE_ID: @@ -2510,10 +2522,6 @@ 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)) @@ -3334,7 +3342,7 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities) { unsigned Idx = 0; - F.ModuleMapPath = ReadPath(F, Record, Idx); + F.ModuleMapPath = ReadString(Record, Idx); if (F.Kind == MK_ExplicitModule) { // For an explicitly-loaded module, we don't care whether the original @@ -3381,7 +3389,7 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, llvm::SmallPtrSet AdditionalStoredMaps; for (unsigned I = 0, N = Record[Idx++]; I < N; ++I) { // FIXME: we should use input files rather than storing names. - std::string Filename = ReadPath(F, Record, Idx); + std::string Filename = ReadString(Record, Idx); const FileEntry *F = FileMgr.getFile(Filename, false, false); if (F == nullptr) { @@ -4248,7 +4256,6 @@ 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) @@ -4273,14 +4280,9 @@ 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; - auto Path = ReadString(Record, Idx); - ResolveImportedPath(Path, ModuleDir); - Listener.ReadModuleMapFile(Path); + Listener.ReadModuleMapFile(ReadString(Record, Idx)); break; } case LANGUAGE_OPTIONS: @@ -4342,10 +4344,7 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) { case INPUT_FILE: bool Overridden = static_cast(Record[3]); - std::string Filename = Blob; - ResolveImportedPath(Filename, ModuleDir); - shouldContinue = - Listener.visitInputFile(Filename, isSystemFile, Overridden); + shouldContinue = Listener.visitInputFile(Blob, isSystemFile, Overridden); break; } if (!shouldContinue) @@ -4362,9 +4361,11 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, while (Idx < N) { // Read information about the AST file. Idx += 5; // ImportLoc, Size, ModTime, Signature - std::string Filename = ReadString(Record, Idx); - ResolveImportedPath(Filename, ModuleDir); - Listener.visitImport(Filename); + unsigned Length = Record[Idx++]; + SmallString<128> ImportedFile(Record.begin() + Idx, + Record.begin() + Idx + Length); + Idx += Length; + Listener.visitImport(ImportedFile); } break; } @@ -8049,13 +8050,6 @@ 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++]; diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index 2f0d37e77c..60494b16d3 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -194,8 +194,8 @@ typedef llvm::OnDiskChainedHashTable /// /// The on-disk hash table contains a mapping from each header path to /// information about that header (how many times it has been included, its -/// controlling macro, etc.). Note that we actually hash based on the size -/// and mtime, and support "deep" comparisons of file names based on current +/// controlling macro, etc.). Note that we actually hash based on the +/// filename, and support "deep" comparisons of file names based on current /// inode numbers, so that the search can cope with non-normalized path names /// and symlinks. class HeaderFileInfoTrait { @@ -211,7 +211,6 @@ public: off_t Size; time_t ModTime; const char *Filename; - bool Imported; }; typedef const internal_key_type &internal_key_ref; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index adecf9dab7..5ffb259b0a 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1063,44 +1063,33 @@ void ASTWriter::WriteBlockInfoBlock() { /// /// \param Filename the file name to adjust. /// -/// \param BaseDir When non-NULL, the PCH file is a relocatable AST file and -/// the returned filename will be adjusted by this root directory. +/// \param isysroot When non-NULL, the PCH file is a relocatable PCH file and +/// the returned filename will be adjusted by this system root. /// /// \returns either the original filename (if it needs no adjustment) or the /// adjusted filename (which points into the @p Filename parameter). static const char * -adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) { +adjustFilenameForRelocatablePCH(const char *Filename, StringRef isysroot) { assert(Filename && "No file name to adjust?"); - if (BaseDir.empty()) + if (isysroot.empty()) return Filename; // Verify that the filename and the system root have the same prefix. unsigned Pos = 0; - for (; Filename[Pos] && Pos < BaseDir.size(); ++Pos) - if (Filename[Pos] != BaseDir[Pos]) + for (; Filename[Pos] && Pos < isysroot.size(); ++Pos) + if (Filename[Pos] != isysroot[Pos]) return Filename; // Prefixes don't match. // We hit the end of the filename before we hit the end of the system root. if (!Filename[Pos]) return Filename; - // If there's not a path separator at the end of the base directory nor - // immediately after it, then this isn't within the base directory. - if (!llvm::sys::path::is_separator(Filename[Pos])) { - if (!llvm::sys::path::is_separator(BaseDir.back())) - return Filename; - } else { - // If the file name has a '/' at the current position, skip over the '/'. - // We distinguish relative paths from absolute paths by the - // absence of '/' at the beginning of relative paths. - // - // FIXME: This is wrong. We distinguish them by asking if the path is - // absolute, which isn't the same thing. And there might be multiple '/'s - // in a row. Use a better mechanism to indicate whether we have emitted an - // absolute or relative path. + // If the file name has a '/' at the current position, skip over the '/'. + // We distinguish sysroot-based includes from absolute includes by the + // absence of '/' at the beginning of sysroot-based includes. + if (Filename[Pos] == '/') ++Pos; - } return Filename + Pos; } @@ -1137,8 +1126,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Record.push_back(VERSION_MINOR); Record.push_back(CLANG_VERSION_MAJOR); Record.push_back(CLANG_VERSION_MINOR); - assert((!WritingModule || isysroot.empty()) && - "writing module as a relocatable PCH?"); Record.push_back(!isysroot.empty()); Record.push_back(ASTHasCompilerErrors); Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record, @@ -1149,8 +1136,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Record.push_back(getSignature()); Stream.EmitRecord(SIGNATURE, Record); + // Module name if (WritingModule) { - // Module name BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name @@ -1160,42 +1147,25 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name); } - if (WritingModule && WritingModule->Directory) { - // Module directory. - BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); - Abbrev->Add(BitCodeAbbrevOp(MODULE_DIRECTORY)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory - unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev); - RecordData Record; - Record.push_back(MODULE_DIRECTORY); - - SmallString<128> BaseDir(WritingModule->Directory->getName()); - Context.getSourceManager().getFileManager().FixupRelativePath(BaseDir); - llvm::sys::fs::make_absolute(BaseDir); - Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir); - - // Write out all other paths relative to the base directory if possible. - BaseDirectory.assign(BaseDir.begin(), BaseDir.end()); - } else if (!isysroot.empty()) { - // Write out paths relative to the sysroot if possible. - BaseDirectory = isysroot; - } - // Module map file if (WritingModule) { Record.clear(); + auto addModMap = [&](const FileEntry *F) { + SmallString<128> ModuleMap(F->getName()); + llvm::sys::fs::make_absolute(ModuleMap); + AddString(ModuleMap.str(), Record); + }; auto &Map = PP.getHeaderSearchInfo().getModuleMap(); // Primary module map file. - AddPath(Map.getModuleMapFileForUniquing(WritingModule)->getName(), Record); + addModMap(Map.getModuleMapFileForUniquing(WritingModule)); // Additional module map files. - if (auto *AdditionalModMaps = - Map.getAdditionalModuleMapFiles(WritingModule)) { + if (auto *AdditionalModMaps = Map.getAdditionalModuleMapFiles(WritingModule)) { Record.push_back(AdditionalModMaps->size()); for (const FileEntry *F : *AdditionalModMaps) - AddPath(F->getName(), Record); + addModMap(F); } else { Record.push_back(0); } @@ -1219,7 +1189,9 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Record.push_back((*M)->File->getSize()); Record.push_back((*M)->File->getModificationTime()); Record.push_back((*M)->Signature); - AddPath((*M)->FileName, Record); + const std::string &FileName = (*M)->FileName; + Record.push_back(FileName.size()); + Record.append(FileName.begin(), FileName.end()); } Stream.EmitRecord(IMPORTS, Record); } @@ -1367,10 +1339,17 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name unsigned FileAbbrevCode = Stream.EmitAbbrev(FileAbbrev); + SmallString<128> MainFilePath(MainFile->getName()); + + llvm::sys::fs::make_absolute(MainFilePath); + + const char *MainFileNameStr = MainFilePath.c_str(); + MainFileNameStr = adjustFilenameForRelocatablePCH(MainFileNameStr, + isysroot); Record.clear(); Record.push_back(ORIGINAL_FILE); Record.push_back(SM.getMainFileID().getOpaqueValue()); - EmitRecordWithPath(FileAbbrevCode, Record, MainFile->getName()); + Stream.EmitRecordWithBlob(FileAbbrevCode, Record, MainFileNameStr); } Record.clear(); @@ -1396,6 +1375,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, WriteInputFiles(Context.SourceMgr, PP.getHeaderSearchInfo().getHeaderSearchOpts(), + isysroot, PP.getLangOpts().Modules); Stream.ExitBlock(); } @@ -1411,6 +1391,7 @@ namespace { void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, + StringRef isysroot, bool Modules) { using namespace llvm; Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4); @@ -1481,8 +1462,23 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, // Whether this file was overridden. Record.push_back(Entry.BufferOverridden); - EmitRecordWithPath(IFAbbrevCode, Record, Entry.File->getName()); - } + // Turn the file name into an absolute path, if it isn't already. + const char *Filename = Entry.File->getName(); + SmallString<128> FilePath(Filename); + + // Ask the file manager to fixup the relative path for us. This will + // honor the working directory. + SourceMgr.getFileManager().FixupRelativePath(FilePath); + + // FIXME: This call to make_absolute shouldn't be necessary, the + // call to FixupRelativePath should always return an absolute path. + llvm::sys::fs::make_absolute(FilePath); + Filename = FilePath.c_str(); + + Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); + + Stream.EmitRecordWithBlob(IFAbbrevCode, Record, Filename); + } Stream.ExitBlock(); @@ -1592,9 +1588,6 @@ namespace { // The hash is based only on size/time of the file, so that the reader can // match even when symlinking or excess path elements ("foo/../", "../") // change the form of the name. However, complete path is still the key. - // - // FIXME: Using the mtime here will cause problems for explicit module - // imports. return llvm::hash_combine(key.FE->getSize(), key.FE->getModificationTime()); } @@ -1675,7 +1668,7 @@ namespace { /// \brief Write the header search block for the list of files that /// /// \param HS The header search structure to save. -void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { +void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) { SmallVector FilesByUID; HS.getFileMgr().GetUniqueIDMapping(FilesByUID); @@ -1699,16 +1692,17 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { (HFI.isModuleHeader && !HFI.isCompilingModuleHeader)) continue; - // Massage the file path into an appropriate form. + // Turn the file name into an absolute path, if it isn't already. const char *Filename = File->getName(); - SmallString<128> FilenameTmp(Filename); - if (PreparePathForOutput(FilenameTmp)) { - // If we performed any translation on the file name at all, we need to - // save this string, since the generator will refer to it later. - Filename = strdup(FilenameTmp.c_str()); + Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); + + // If we performed any translation on the file name at all, we need to + // save this string, since the generator will refer to it later. + if (Filename != File->getName()) { + Filename = strdup(Filename); SavedStrings.push_back(Filename); } - + HeaderFileInfoTrait::key_type key = { File, Filename }; Generator.insert(key, HFI, GeneratorTrait); ++NumHeaderSearchEntries; @@ -1758,7 +1752,8 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { /// errors), we probably won't have to create file entries for any of /// the files in the AST. void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, - const Preprocessor &PP) { + const Preprocessor &PP, + StringRef isysroot) { RecordData Record; // Enter the source manager block. @@ -1907,10 +1902,17 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, LineTableInfo &LineTable = SourceMgr.getLineTable(); Record.clear(); - // Emit the file names. + // Emit the file names Record.push_back(LineTable.getNumFilenames()); - for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) - AddPath(LineTable.getFilename(I), Record); + for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) { + // Emit the file name + const char *Filename = LineTable.getFilename(I); + Filename = adjustFilenameForRelocatablePCH(Filename, isysroot); + unsigned FilenameLen = Filename? strlen(Filename) : 0; + Record.push_back(FilenameLen); + if (FilenameLen) + Record.insert(Record.end(), Filename, Filename + FilenameLen); + } // Emit the line entries for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end(); @@ -2541,7 +2543,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Record.clear(); for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) { unsigned ImportedID = getSubmoduleID(Mod->Imports[I]); - assert(ImportedID && "Unknown submodule!"); + assert(ImportedID && "Unknown submodule!"); Record.push_back(ImportedID); } Stream.EmitRecord(SUBMODULE_IMPORTS, Record); @@ -4075,47 +4077,6 @@ void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) { Record.insert(Record.end(), Str.begin(), Str.end()); } -bool ASTWriter::PreparePathForOutput(SmallVectorImpl &Path) { - bool Changed = false; - - if (!llvm::sys::path::is_absolute(StringRef(Path.data(), Path.size()))) { - // Ask the file manager to fixup the relative path for us. This will - // honor the working directory. - if (Context) - Context->getSourceManager().getFileManager().FixupRelativePath(Path); - - // We want an absolute path even if we weren't given a spelling for the - // current working directory. - llvm::sys::fs::make_absolute(Path); - - Changed = true; - } - - // Remove a prefix to make the path relative, if relevant. - const char *PathBegin = Path.data(); - const char *PathPtr = - adjustFilenameForRelocatableAST(PathBegin, BaseDirectory); - if (PathPtr != PathBegin) { - Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin)); - Changed = true; - } - - return Changed; -} - -void ASTWriter::AddPath(StringRef Path, RecordDataImpl &Record) { - SmallString<128> FilePath(Path); - PreparePathForOutput(FilePath); - AddString(FilePath, Record); -} - -void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataImpl &Record, - StringRef Path) { - SmallString<128> FilePath(Path); - PreparePathForOutput(FilePath); - Stream.EmitRecordWithBlob(Abbrev, Record, FilePath); -} - void ASTWriter::AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record) { Record.push_back(Version.getMajor()); @@ -4200,7 +4161,6 @@ void ASTWriter::WriteAST(Sema &SemaRef, Context = nullptr; PP = nullptr; this->WritingModule = nullptr; - this->BaseDirectory.clear(); WritingAST = false; } @@ -4591,11 +4551,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); WriteCXXBaseSpecifiersOffsets(); WriteFileDeclIDsMap(); - WriteSourceManagerBlock(Context.getSourceManager(), PP); + WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); WriteComments(); WritePreprocessor(PP, isModule); - WriteHeaderSearch(PP.getHeaderSearchInfo()); + WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); WriteIdentifierTable(PP, SemaRef.IdResolver, isModule); -- 2.40.0