@@ -2037,9 +2037,9 @@ HeaderFileInfoTrait::getFile(const internal_key_type &Key) {
20372037 if (!Key.Imported )
20382038 return FileMgr.getOptionalFileRef (Key.Filename );
20392039
2040- std::string Resolved = std::string (Key. Filename );
2041- Reader.ResolveImportedPath (M, Resolved );
2042- return FileMgr.getOptionalFileRef (Resolved);
2040+ auto Resolved =
2041+ ASTReader::ResolveImportedPath ( Reader.getPathBuf (), Key. Filename , M );
2042+ return FileMgr.getOptionalFileRef (* Resolved);
20432043}
20442044
20452045unsigned HeaderFileInfoTrait::ComputeHash (internal_key_ref ikey) {
@@ -2502,11 +2502,12 @@ InputFileInfo ASTReader::getInputFileInfo(ModuleFile &F, unsigned ID) {
25022502 std::tie (R.FilenameAsRequested , R.Filename ) = [&]() {
25032503 uint16_t AsRequestedLength = Record[7 ];
25042504
2505- std::string NameAsRequested = Blob.substr (0 , AsRequestedLength). str ( );
2506- std::string Name = Blob.substr (AsRequestedLength). str ( );
2505+ StringRef NameAsRequestedRef = Blob.substr (0 , AsRequestedLength);
2506+ StringRef NameRef = Blob.substr (AsRequestedLength);
25072507
2508- ResolveImportedPath (F, NameAsRequested);
2509- ResolveImportedPath (F, Name);
2508+ std::string NameAsRequested =
2509+ ResolveImportedPathAndAllocate (PathBuf, NameAsRequestedRef, F);
2510+ std::string Name = ResolveImportedPathAndAllocate (PathBuf, NameRef, F);
25102511
25112512 if (Name.empty ())
25122513 Name = NameAsRequested;
@@ -2736,23 +2737,38 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
27362737 return IF;
27372738}
27382739
2739- // / If we are loading a relocatable PCH or module file, and the filename
2740- // / is not an absolute path, add the system or module root to the beginning of
2741- // / the file name.
2742- void ASTReader::ResolveImportedPath (ModuleFile &M, std::string &Filename) {
2743- // Resolve relative to the base directory, if we have one.
2744- if (!M.BaseDirectory .empty ())
2745- return ResolveImportedPath (Filename, M.BaseDirectory );
2740+ ASTReader::TemporarilyOwnedStringRef
2741+ ASTReader::ResolveImportedPath (SmallString<0 > &Buf, StringRef Path,
2742+ ModuleFile &ModF) {
2743+ return ResolveImportedPath (Buf, Path, ModF.BaseDirectory );
27462744}
27472745
2748- void ASTReader::ResolveImportedPath (std::string &Filename, StringRef Prefix) {
2749- if (Filename.empty () || llvm::sys::path::is_absolute (Filename) ||
2750- Filename == " <built-in>" || Filename == " <command line>" )
2751- return ;
2746+ ASTReader::TemporarilyOwnedStringRef
2747+ ASTReader::ResolveImportedPath (SmallString<0 > &Buf, StringRef Path,
2748+ StringRef Prefix) {
2749+ assert (Buf.capacity () != 0 && " Overlapping ResolveImportedPath calls" );
2750+
2751+ if (Prefix.empty () || Path.empty () || llvm::sys::path::is_absolute (Path) ||
2752+ Path == " <built-in>" || Path == " <command line>" )
2753+ return {Path, Buf};
2754+
2755+ Buf.clear ();
2756+ llvm::sys::path::append (Buf, Prefix, Path);
2757+ StringRef ResolvedPath{Buf.data (), Buf.size ()};
2758+ return {ResolvedPath, Buf};
2759+ }
27522760
2753- SmallString<128 > Buffer;
2754- llvm::sys::path::append (Buffer, Prefix, Filename);
2755- Filename.assign (Buffer.begin (), Buffer.end ());
2761+ std::string ASTReader::ResolveImportedPathAndAllocate (SmallString<0 > &Buf,
2762+ StringRef P,
2763+ ModuleFile &ModF) {
2764+ return ResolveImportedPathAndAllocate (Buf, P, ModF.BaseDirectory );
2765+ }
2766+
2767+ std::string ASTReader::ResolveImportedPathAndAllocate (SmallString<0 > &Buf,
2768+ StringRef P,
2769+ StringRef Prefix) {
2770+ auto ResolvedPath = ResolveImportedPath (Buf, P, Prefix);
2771+ return ResolvedPath->str ();
27562772}
27572773
27582774static bool isDiagnosedResult (ASTReader::ASTReadResult ARR, unsigned Caps) {
@@ -3183,8 +3199,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
31833199 case ORIGINAL_FILE:
31843200 F.OriginalSourceFileID = FileID::get (Record[0 ]);
31853201 F.ActualOriginalSourceFileName = std::string (Blob);
3186- F.OriginalSourceFileName = F. ActualOriginalSourceFileName ;
3187- ResolveImportedPath (F , F.OriginalSourceFileName );
3202+ F.OriginalSourceFileName = ResolveImportedPathAndAllocate (
3203+ PathBuf , F.ActualOriginalSourceFileName , F );
31883204 break ;
31893205
31903206 case ORIGINAL_FILE_ID:
@@ -5474,6 +5490,8 @@ bool ASTReader::readASTFileControlBlock(
54745490 RecordData Record;
54755491 std::string ModuleDir;
54765492 bool DoneWithControlBlock = false ;
5493+ SmallString<0 > PathBuf;
5494+ PathBuf.reserve (256 );
54775495 while (!DoneWithControlBlock) {
54785496 Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance ();
54795497 if (!MaybeEntry) {
@@ -5556,9 +5574,9 @@ bool ASTReader::readASTFileControlBlock(
55565574 break ;
55575575 case MODULE_MAP_FILE: {
55585576 unsigned Idx = 0 ;
5559- auto Path = ReadString (Record, Idx);
5560- ResolveImportedPath (Path , ModuleDir);
5561- Listener.ReadModuleMapFile (Path);
5577+ std::string PathStr = ReadString (Record, Idx);
5578+ auto Path = ResolveImportedPath (PathBuf, PathStr , ModuleDir);
5579+ Listener.ReadModuleMapFile (* Path);
55625580 break ;
55635581 }
55645582 case INPUT_FILE_OFFSETS: {
@@ -5605,10 +5623,9 @@ bool ASTReader::readASTFileControlBlock(
56055623 break ;
56065624 case INPUT_FILE:
56075625 bool Overridden = static_cast <bool >(Record[3 ]);
5608- std::string Filename = std::string (Blob);
5609- ResolveImportedPath (Filename, ModuleDir);
5626+ auto Filename = ResolveImportedPath (PathBuf, Blob, ModuleDir);
56105627 shouldContinue = Listener.visitInputFile (
5611- Filename, isSystemFile, Overridden, /* IsExplicitModule*/ false );
5628+ * Filename, isSystemFile, Overridden, /* IsExplicitModule= */ false );
56125629 break ;
56135630 }
56145631 if (!shouldContinue)
@@ -5643,12 +5660,12 @@ bool ASTReader::readASTFileControlBlock(
56435660 // Skip Size, ModTime and Signature
56445661 Idx += 1 + 1 + ASTFileSignature::size;
56455662 std::string ModuleName = ReadString (Record, Idx);
5646- std::string Filename = ReadString (Record, Idx);
5647- ResolveImportedPath (Filename , ModuleDir);
5663+ std::string FilenameStr = ReadString (Record, Idx);
5664+ auto Filename = ResolveImportedPath (PathBuf, FilenameStr , ModuleDir);
56485665 std::string CacheKey = ReadString (Record, Idx);
56495666 if (!CacheKey.empty ())
5650- Listener.readModuleCacheKey (ModuleName, Filename, CacheKey);
5651- Listener.visitImport (ModuleName, Filename);
5667+ Listener.readModuleCacheKey (ModuleName, * Filename, CacheKey);
5668+ Listener.visitImport (ModuleName, * Filename);
56525669 }
56535670 break ;
56545671 }
@@ -5916,9 +5933,8 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
59165933 // FIXME: This doesn't work for framework modules as `Filename` is the
59175934 // name as written in the module file and does not include
59185935 // `Headers/`, so this path will never exist.
5919- std::string Filename = std::string (Blob);
5920- ResolveImportedPath (F, Filename);
5921- if (auto Umbrella = PP.getFileManager ().getOptionalFileRef (Filename)) {
5936+ auto Filename = ResolveImportedPath (PathBuf, Blob, F);
5937+ if (auto Umbrella = PP.getFileManager ().getOptionalFileRef (*Filename)) {
59225938 if (!CurrentModule->getUmbrellaHeaderAsWritten ()) {
59235939 // FIXME: NameAsWritten
59245940 ModMap.setUmbrellaHeaderAsWritten (CurrentModule, *Umbrella, Blob, " " );
@@ -5946,18 +5962,16 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
59465962 break ;
59475963
59485964 case SUBMODULE_TOPHEADER: {
5949- std::string HeaderName (Blob);
5950- ResolveImportedPath (F, HeaderName);
5951- CurrentModule->addTopHeaderFilename (HeaderName);
5965+ auto HeaderName = ResolveImportedPath (PathBuf, Blob, F);
5966+ CurrentModule->addTopHeaderFilename (*HeaderName);
59525967 break ;
59535968 }
59545969
59555970 case SUBMODULE_UMBRELLA_DIR: {
59565971 // See comments in SUBMODULE_UMBRELLA_HEADER
5957- std::string Dirname = std::string (Blob);
5958- ResolveImportedPath (F, Dirname);
5972+ auto Dirname = ResolveImportedPath (PathBuf, Blob, F);
59595973 if (auto Umbrella =
5960- PP.getFileManager ().getOptionalDirectoryRef (Dirname)) {
5974+ PP.getFileManager ().getOptionalDirectoryRef (* Dirname)) {
59615975 if (!CurrentModule->getUmbrellaDirAsWritten ()) {
59625976 // FIXME: NameAsWritten
59635977 ModMap.setUmbrellaDirAsWritten (CurrentModule, *Umbrella, Blob, " " );
@@ -9503,17 +9517,13 @@ std::string ASTReader::ReadString(const RecordDataImpl &Record, unsigned &Idx) {
95039517
95049518std::string ASTReader::ReadPath (ModuleFile &F, const RecordData &Record,
95059519 unsigned &Idx) {
9506- std::string Filename = ReadString (Record, Idx);
9507- ResolveImportedPath (F, Filename);
9508- return Filename;
9520+ return ReadPath (F.BaseDirectory , Record, Idx);
95099521}
95109522
95119523std::string ASTReader::ReadPath (StringRef BaseDirectory,
95129524 const RecordData &Record, unsigned &Idx) {
95139525 std::string Filename = ReadString (Record, Idx);
9514- if (!BaseDirectory.empty ())
9515- ResolveImportedPath (Filename, BaseDirectory);
9516- return Filename;
9526+ return ResolveImportedPathAndAllocate (PathBuf, Filename, BaseDirectory);
95179527}
95189528
95199529VersionTuple ASTReader::ReadVersionTuple (const RecordData &Record,
@@ -10380,6 +10390,8 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
1038010390 UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) {
1038110391 SourceMgr.setExternalSLocEntrySource (this );
1038210392
10393+ PathBuf.reserve (256 );
10394+
1038310395 for (const auto &Ext : Extensions) {
1038410396 auto BlockName = Ext->getExtensionMetadata ().BlockName ;
1038510397 auto Known = ModuleFileExtensions.find (BlockName);
0 commit comments