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
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;
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
- bool ParseLineTable(ModuleFile &F, const RecordData &Record);
+ bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
bool ReadSourceManagerBlock(ModuleFile &F);
llvm::BitstreamCursor &SLocCursorForID(int ID);
SourceLocation getImportLocation(ModuleFile *F);
// \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);
/// \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;
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);
/// 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,
/// \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<char> &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);
/// \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";
}
/// \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<uint64_t> &Record) {
unsigned Idx = 0;
LineTableInfo &LineTable = SourceMgr.getLineTable();
std::map<int, int> 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);
}
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;
}
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<unsigned, 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;
}
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());
}
}
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;
- ResolveImportedPath(F, Filename);
-
+ MaybeAddSystemRootToFilename(F, Filename);
+
InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden };
return R;
}
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
}
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;
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,
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:
Listener->ReadModuleName(F.ModuleName);
break;
- case MODULE_DIRECTORY:
- F.BaseDirectory = Blob;
- break;
-
case MODULE_MAP_FILE:
if (ASTReadResult Result =
ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities))
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
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 = ReadPath(F, Record, Idx);
+ std::string Filename = ReadString(Record, Idx);
const FileEntry *F =
FileMgr.getFile(Filename, false, false);
if (F == nullptr) {
// 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)
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:
switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
case INPUT_FILE:
bool Overridden = static_cast<bool>(Record[3]);
- std::string Filename = Blob;
- ResolveImportedPath(Filename, ModuleDir);
- shouldContinue =
- Listener.visitInputFile(Filename, isSystemFile, Overridden);
+ shouldContinue = Listener.visitInputFile(Blob, isSystemFile, Overridden);
break;
}
if (!shouldContinue)
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;
}
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++];
///
/// 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 {
off_t Size;
time_t ModTime;
const char *Filename;
- bool Imported;
};
typedef const internal_key_type &internal_key_ref;
///
/// \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;
}
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,
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
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);
}
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);
}
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();
WriteInputFiles(Context.SourceMgr,
PP.getHeaderSearchInfo().getHeaderSearchOpts(),
+ isysroot,
PP.getLangOpts().Modules);
Stream.ExitBlock();
}
void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
HeaderSearchOptions &HSOpts,
+ StringRef isysroot,
bool Modules) {
using namespace llvm;
Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
// 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();
// 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());
}
/// \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<const FileEntry *, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
(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;
/// 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.
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();
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);
Record.insert(Record.end(), Str.begin(), Str.end());
}
-bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &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());
Context = nullptr;
PP = nullptr;
this->WritingModule = nullptr;
- this->BaseDirectory.clear();
WritingAST = false;
}
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);