Skip to content

Commit dab2bca

Browse files
committed
Use capacity to express optionality, check lifetime even in static functions, prevent using rvalue-ref
1 parent cc83e1d commit dab2bca

File tree

2 files changed

+84
-65
lines changed

2 files changed

+84
-65
lines changed

clang/include/clang/Serialization/ASTReader.h

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,50 +1342,48 @@ class ASTReader
13421342
serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
13431343
bool Complain = true);
13441344

1345-
/// Buffer we use as temporary storage backing resolved paths.
1346-
std::optional<SmallString<0>> PathBuf;
1345+
/// The buffer used as the temporary backing storage for resolved paths.
1346+
SmallString<0> PathBuf;
13471347

1348-
/// A RAII wrapper around \c StringRef that temporarily takes ownership of the
1349-
/// underlying buffer and gives it back on destruction.
1348+
/// A wrapper around StringRef that temporarily borrows the underlying buffer.
13501349
class TemporarilyOwnedStringRef {
13511350
StringRef String;
1352-
llvm::SaveAndRestore<std::optional<SmallString<0>>> TemporaryLoan;
1351+
llvm::SaveAndRestore<SmallString<0>> UnderlyingBuffer;
13531352

13541353
public:
1355-
TemporarilyOwnedStringRef(StringRef S, std::optional<SmallString<0>> &Buf)
1356-
: String(S), TemporaryLoan(Buf, {}) {}
1354+
TemporarilyOwnedStringRef(StringRef S, SmallString<0> &UnderlyingBuffer)
1355+
: String(S), UnderlyingBuffer(UnderlyingBuffer, {}) {}
13571356

1358-
/// Returns the wrapped \c StringRef that must be outlived by \c this.
1359-
const StringRef *operator->() const { return &String; }
1360-
/// Returns the wrapped \c StringRef that must be outlived by \c this.
1361-
const StringRef &operator*() const { return String; }
1357+
/// Return the wrapped \c StringRef that must be outlived by \c this.
1358+
const StringRef *operator->() const & { return &String; }
1359+
const StringRef &operator*() const & { return String; }
1360+
1361+
/// Make it harder to get a \c StringRef that outlives \c this.
1362+
const StringRef *operator->() && = delete;
1363+
const StringRef &operator*() && = delete;
13621364
};
13631365

13641366
public:
1365-
/// Resolve \c Path in the context of module file \c M. The return value must
1366-
/// be destroyed before another call to \c ResolveImportPath.
1367-
TemporarilyOwnedStringRef ResolveImportedPath(StringRef Path, ModuleFile &M) {
1368-
return ResolveImportedPath(Path, M.BaseDirectory);
1369-
}
1370-
/// Resolve \c Path in the context of the \c Prefix directory. The return
1371-
/// value must be destroyed before another call to \c ResolveImportPath.
1372-
TemporarilyOwnedStringRef ResolveImportedPath(StringRef Path,
1373-
StringRef Prefix) {
1374-
assert(PathBuf && "Multiple overlapping calls to ResolveImportedPath");
1375-
StringRef ResolvedPath = ResolveImportedPath(*PathBuf, Path, Prefix);
1376-
return {ResolvedPath, PathBuf};
1377-
}
1367+
/// Get the buffer for resolving paths.
1368+
SmallString<0> &getPathBuf() { return PathBuf; }
13781369

1379-
/// Resolve \c Path in the context of module file \c M. The \c Buffer must
1380-
/// outlive the returned \c StringRef.
1381-
static StringRef ResolveImportedPath(SmallVectorImpl<char> &Buffer,
1382-
StringRef Path, ModuleFile &M) {
1383-
return ResolveImportedPath(Buffer, Path, M.BaseDirectory);
1384-
}
1385-
/// Resolve \c Path in the context of the \c Prefix directory. The \c Buffer
1386-
/// must outlive the returned \c StringRef.
1387-
static StringRef ResolveImportedPath(SmallVectorImpl<char> &Buffer,
1388-
StringRef Path, StringRef Prefix);
1370+
/// Resolve \c Path in the context of module file \c M. The return value
1371+
/// must go out of scope before the next call to \c ResolveImportedPath.
1372+
static TemporarilyOwnedStringRef
1373+
ResolveImportedPath(SmallString<0> &Buf, StringRef Path, ModuleFile &ModF);
1374+
/// Resolve \c Path in the context of the \c Prefix directory. The return
1375+
/// value must go out of scope before the next call to \c ResolveImportedPath.
1376+
static TemporarilyOwnedStringRef
1377+
ResolveImportedPath(SmallString<0> &Buf, StringRef Path, StringRef Prefix);
1378+
1379+
/// Resolve \c Path in the context of module file \c M.
1380+
static std::string ResolveImportedPathAndAllocate(SmallString<0> &Buf,
1381+
StringRef Path,
1382+
ModuleFile &ModF);
1383+
/// Resolve \c Path in the context of the \c Prefix directory.
1384+
static std::string ResolveImportedPathAndAllocate(SmallString<0> &Buf,
1385+
StringRef Path,
1386+
StringRef Prefix);
13891387

13901388
/// Returns the first key declaration for the given declaration. This
13911389
/// is one that is formerly-canonical (or still canonical) and whose module

clang/lib/Serialization/ASTReader.cpp

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,7 +2048,8 @@ HeaderFileInfoTrait::getFile(const internal_key_type &Key) {
20482048
if (!Key.Imported)
20492049
return FileMgr.getOptionalFileRef(Key.Filename);
20502050

2051-
auto Resolved = Reader.ResolveImportedPath(Key.Filename, M);
2051+
auto Resolved =
2052+
ASTReader::ResolveImportedPath(Reader.getPathBuf(), Key.Filename, M);
20522053
return FileMgr.getOptionalFileRef(*Resolved);
20532054
}
20542055

@@ -2512,10 +2513,12 @@ InputFileInfo ASTReader::getInputFileInfo(ModuleFile &F, unsigned ID) {
25122513
std::tie(R.FilenameAsRequested, R.Filename) = [&]() {
25132514
uint16_t AsRequestedLength = Record[7];
25142515

2516+
StringRef NameAsRequestedRef = Blob.substr(0, AsRequestedLength);
2517+
StringRef NameRef = Blob.substr(AsRequestedLength);
2518+
25152519
std::string NameAsRequested =
2516-
ResolveImportedPath(Blob.substr(0, AsRequestedLength), F)->str();
2517-
std::string Name =
2518-
ResolveImportedPath(Blob.substr(AsRequestedLength), F)->str();
2520+
ResolveImportedPathAndAllocate(PathBuf, NameAsRequestedRef, F);
2521+
std::string Name = ResolveImportedPathAndAllocate(PathBuf, NameRef, F);
25192522

25202523
if (Name.empty())
25212524
Name = NameAsRequested;
@@ -2741,18 +2744,38 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
27412744
return IF;
27422745
}
27432746

2744-
/// If we are loading a relocatable PCH or module file, and the filename
2745-
/// is not an absolute path, add the system or module root to the beginning of
2746-
/// the file name.
2747-
StringRef ASTReader::ResolveImportedPath(SmallVectorImpl<char> &Buffer,
2748-
StringRef Path, StringRef Prefix) {
2747+
ASTReader::TemporarilyOwnedStringRef
2748+
ASTReader::ResolveImportedPath(SmallString<0> &Buf, StringRef Path,
2749+
ModuleFile &ModF) {
2750+
return ResolveImportedPath(Buf, Path, ModF.BaseDirectory);
2751+
}
2752+
2753+
ASTReader::TemporarilyOwnedStringRef
2754+
ASTReader::ResolveImportedPath(SmallString<0> &Buf, StringRef Path,
2755+
StringRef Prefix) {
2756+
assert(Buf.capacity() != 0 && "Overlapping ResolveImportedPath calls");
2757+
27492758
if (Prefix.empty() || Path.empty() || llvm::sys::path::is_absolute(Path) ||
27502759
Path == "<built-in>" || Path == "<command line>")
2751-
return Path;
2760+
return {Path, Buf};
27522761

2753-
Buffer.clear();
2754-
llvm::sys::path::append(Buffer, Prefix, Path);
2755-
return {Buffer.data(), Buffer.size()};
2762+
Buf.clear();
2763+
llvm::sys::path::append(Buf, Prefix, Path);
2764+
StringRef ResolvedPath{Buf.data(), Buf.size()};
2765+
return {ResolvedPath, Buf};
2766+
}
2767+
2768+
std::string ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf,
2769+
StringRef P,
2770+
ModuleFile &ModF) {
2771+
return ResolveImportedPathAndAllocate(Buf, P, ModF.BaseDirectory);
2772+
}
2773+
2774+
std::string ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf,
2775+
StringRef P,
2776+
StringRef Prefix) {
2777+
auto ResolvedPath = ResolveImportedPath(Buf, P, Prefix);
2778+
return ResolvedPath->str();
27562779
}
27572780

27582781
static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) {
@@ -3180,8 +3203,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
31803203
case ORIGINAL_FILE:
31813204
F.OriginalSourceFileID = FileID::get(Record[0]);
31823205
F.ActualOriginalSourceFileName = std::string(Blob);
3183-
F.OriginalSourceFileName =
3184-
ResolveImportedPath(F.ActualOriginalSourceFileName, F)->str();
3206+
F.OriginalSourceFileName = ResolveImportedPathAndAllocate(
3207+
PathBuf, F.ActualOriginalSourceFileName, F);
31853208
break;
31863209

31873210
case ORIGINAL_FILE_ID:
@@ -5470,7 +5493,8 @@ bool ASTReader::readASTFileControlBlock(
54705493
RecordData Record;
54715494
std::string ModuleDir;
54725495
bool DoneWithControlBlock = false;
5473-
SmallString<256> PathBuf;
5496+
SmallString<0> PathBuf;
5497+
PathBuf.reserve(256);
54745498
while (!DoneWithControlBlock) {
54755499
Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
54765500
if (!MaybeEntry) {
@@ -5554,8 +5578,8 @@ bool ASTReader::readASTFileControlBlock(
55545578
case MODULE_MAP_FILE: {
55555579
unsigned Idx = 0;
55565580
std::string PathStr = ReadString(Record, Idx);
5557-
StringRef Path = ResolveImportedPath(PathBuf, PathStr, ModuleDir);
5558-
Listener.ReadModuleMapFile(Path);
5581+
auto Path = ResolveImportedPath(PathBuf, PathStr, ModuleDir);
5582+
Listener.ReadModuleMapFile(*Path);
55595583
break;
55605584
}
55615585
case INPUT_FILE_OFFSETS: {
@@ -5602,9 +5626,9 @@ bool ASTReader::readASTFileControlBlock(
56025626
break;
56035627
case INPUT_FILE:
56045628
bool Overridden = static_cast<bool>(Record[3]);
5605-
StringRef Filename = ResolveImportedPath(PathBuf, Blob, ModuleDir);
5629+
auto Filename = ResolveImportedPath(PathBuf, Blob, ModuleDir);
56065630
shouldContinue = Listener.visitInputFile(
5607-
Filename, isSystemFile, Overridden, /*IsExplicitModule*/false);
5631+
*Filename, isSystemFile, Overridden, /*IsExplicitModule*/false);
56085632
break;
56095633
}
56105634
if (!shouldContinue)
@@ -5640,9 +5664,8 @@ bool ASTReader::readASTFileControlBlock(
56405664
Idx += 1 + 1 + ASTFileSignature::size;
56415665
std::string ModuleName = ReadString(Record, Idx);
56425666
std::string FilenameStr = ReadString(Record, Idx);
5643-
StringRef Filename =
5644-
ResolveImportedPath(PathBuf, FilenameStr, ModuleDir);
5645-
Listener.visitImport(ModuleName, Filename);
5667+
auto Filename = ResolveImportedPath(PathBuf, FilenameStr, ModuleDir);
5668+
Listener.visitImport(ModuleName, *Filename);
56465669
}
56475670
break;
56485671
}
@@ -5895,7 +5918,7 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58955918
// FIXME: This doesn't work for framework modules as `Filename` is the
58965919
// name as written in the module file and does not include
58975920
// `Headers/`, so this path will never exist.
5898-
auto Filename = ResolveImportedPath(Blob, F);
5921+
auto Filename = ResolveImportedPath(PathBuf, Blob, F);
58995922
if (auto Umbrella = PP.getFileManager().getOptionalFileRef(*Filename)) {
59005923
if (!CurrentModule->getUmbrellaHeaderAsWritten()) {
59015924
// FIXME: NameAsWritten
@@ -5924,14 +5947,14 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
59245947
break;
59255948

59265949
case SUBMODULE_TOPHEADER: {
5927-
auto HeaderName = ResolveImportedPath(Blob, F);
5950+
auto HeaderName = ResolveImportedPath(PathBuf, Blob, F);
59285951
CurrentModule->addTopHeaderFilename(*HeaderName);
59295952
break;
59305953
}
59315954

59325955
case SUBMODULE_UMBRELLA_DIR: {
59335956
// See comments in SUBMODULE_UMBRELLA_HEADER
5934-
auto Dirname = ResolveImportedPath(Blob, F);
5957+
auto Dirname = ResolveImportedPath(PathBuf, Blob, F);
59355958
if (auto Umbrella =
59365959
PP.getFileManager().getOptionalDirectoryRef(*Dirname)) {
59375960
if (!CurrentModule->getUmbrellaDirAsWritten()) {
@@ -9588,14 +9611,13 @@ std::string ASTReader::ReadString(const RecordDataImpl &Record, unsigned &Idx) {
95889611

95899612
std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record,
95909613
unsigned &Idx) {
9591-
std::string Filename = ReadString(Record, Idx);
9592-
return ResolveImportedPath(Filename, F)->str();
9614+
return ReadPath(F.BaseDirectory, Record, Idx);
95939615
}
95949616

95959617
std::string ASTReader::ReadPath(StringRef BaseDirectory,
95969618
const RecordData &Record, unsigned &Idx) {
95979619
std::string Filename = ReadString(Record, Idx);
9598-
return ResolveImportedPath(Filename, BaseDirectory)->str();
9620+
return ResolveImportedPathAndAllocate(PathBuf, Filename, BaseDirectory);
95999621
}
96009622

96019623
VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
@@ -10500,8 +10522,7 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
1050010522
UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) {
1050110523
SourceMgr.setExternalSLocEntrySource(this);
1050210524

10503-
PathBuf.emplace();
10504-
PathBuf->reserve(256);
10525+
PathBuf.reserve(256);
1050510526

1050610527
for (const auto &Ext : Extensions) {
1050710528
auto BlockName = Ext->getExtensionMetadata().BlockName;

0 commit comments

Comments
 (0)