@@ -1185,36 +1185,51 @@ static bool cleanPathForOutput(FileManager &FileMgr,
11851185 return Changed | llvm::sys::path::remove_dots (Path);
11861186}
11871187
1188- // / Adjusts the given filename to only write out the portion of the filename
1189- // / that is not part of the base directory.
1188+ // / Adjusts the given filename to only write out the portion of the
1189+ // / filename that is not part of the system root directory.
11901190// /
11911191// / \param Filename the file name to adjust.
11921192// /
1193- // / \param BasePath When not empty , the AST file is relocatable and the returned
1194- // / filename will be adjusted to be relative to this path .
1193+ // / \param BaseDir When non-NULL , the PCH file is a relocatable AST file and
1194+ // / the returned filename will be adjusted by this root directory .
11951195// /
1196- // / \returns true when \c Filename was adjusted, false otherwise.
1197- static bool adjustFilenameForRelocatableAST (SmallVectorImpl<char > &Filename,
1198- StringRef BasePath) {
1199- auto FileIt = llvm::sys::path::begin ({Filename.begin (), Filename.size ()});
1200- auto FileEnd = llvm::sys::path::end ({Filename.begin (), Filename.size ()});
1201-
1202- auto BaseIt = llvm::sys::path::begin (BasePath);
1203- auto BaseEnd = llvm::sys::path::end (BasePath);
1204-
1205- for (; FileIt != FileEnd && BaseIt != BaseEnd; ++FileIt, ++BaseIt)
1206- if (*FileIt != *BaseIt)
1207- return false ;
1208-
1209- if (FileIt == FileEnd)
1210- return false ;
1211-
1212- SmallString<128 > Clean;
1213- for (; FileIt != FileEnd; ++FileIt)
1214- llvm::sys::path::append (Clean, *FileIt);
1196+ // / \returns either the original filename (if it needs no adjustment) or the
1197+ // / adjusted filename (which points into the @p Filename parameter).
1198+ static const char *
1199+ adjustFilenameForRelocatableAST (const char *Filename, StringRef BaseDir) {
1200+ assert (Filename && " No file name to adjust?" );
1201+
1202+ if (BaseDir.empty ())
1203+ return Filename;
1204+
1205+ // Verify that the filename and the system root have the same prefix.
1206+ unsigned Pos = 0 ;
1207+ for (; Filename[Pos] && Pos < BaseDir.size (); ++Pos)
1208+ if (Filename[Pos] != BaseDir[Pos])
1209+ return Filename; // Prefixes don't match.
1210+
1211+ // We hit the end of the filename before we hit the end of the system root.
1212+ if (!Filename[Pos])
1213+ return Filename;
1214+
1215+ // If there's not a path separator at the end of the base directory nor
1216+ // immediately after it, then this isn't within the base directory.
1217+ if (!llvm::sys::path::is_separator (Filename[Pos])) {
1218+ if (!llvm::sys::path::is_separator (BaseDir.back ()))
1219+ return Filename;
1220+ } else {
1221+ // If the file name has a '/' at the current position, skip over the '/'.
1222+ // We distinguish relative paths from absolute paths by the
1223+ // absence of '/' at the beginning of relative paths.
1224+ //
1225+ // FIXME: This is wrong. We distinguish them by asking if the path is
1226+ // absolute, which isn't the same thing. And there might be multiple '/'s
1227+ // in a row. Use a better mechanism to indicate whether we have emitted an
1228+ // absolute or relative path.
1229+ ++Pos;
1230+ }
12151231
1216- Filename.assign (Clean.begin (), Clean.end ());
1217- return true ;
1232+ return Filename + Pos;
12181233}
12191234
12201235std::pair<ASTFileSignature, ASTFileSignature>
@@ -1697,7 +1712,11 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
16971712
16981713 AddString (HSOpts.Sysroot , Record);
16991714 AddString (HSOpts.ResourceDir , Record);
1700- AddPath (HSOpts.ModuleCachePath , Record);
1715+
1716+ SmallString<256 > ModuleCachePath (HSOpts.ModuleCachePath );
1717+ (void )cleanPathForOutput (PP.getFileManager (), ModuleCachePath);
1718+ AddString (ModuleCachePath, Record);
1719+
17011720 AddString (HSOpts.ModuleUserBuildPath , Record);
17021721 Record.push_back (HSOpts.DisableModuleHash );
17031722 Record.push_back (HSOpts.ImplicitModuleMaps );
@@ -5327,8 +5346,16 @@ bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) {
53275346 return false ;
53285347
53295348 bool Changed = cleanPathForOutput (PP->getFileManager (), Path);
5330- if (adjustFilenameForRelocatableAST (Path, BaseDirectory))
5349+
5350+ // Remove a prefix to make the path relative, if relevant.
5351+ const char *PathBegin = Path.data ();
5352+ const char *PathPtr =
5353+ adjustFilenameForRelocatableAST (PathBegin, BaseDirectory);
5354+ if (PathPtr != PathBegin) {
5355+ Path.erase (Path.begin (), Path.begin () + (PathPtr - PathBegin));
53315356 Changed = true ;
5357+ }
5358+
53325359 return Changed;
53335360}
53345361
0 commit comments