Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -45,6 +45,8 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Config/llvm-config.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/BLAKE3.h" +#include "llvm/Support/Base64.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Compression.h" @@ -2479,13 +2481,38 @@ return; } - llvm::sys::path::append( - Path, - Twine(llvm::sys::path::filename(Input.getFilename())) + ".%%%%.json"); + // Append the Input basename and a .XXXXXXXXXX.json suffix, where + // X is base64-ish and derived from the Input and Output filenames. + auto AppendBasenameAndHash = [](SmallString<256> &Path, + const InputInfo &Input, + const InputInfo &Output) { + llvm::TruncatedBLAKE3<8> Hash; + llvm::BLAKE3Result<8> HashResult; + Hash.update(llvm::StringRef(Input.getFilename())); + // Simpler value separation than that of HashBuilder, so external tools + // can deduce the filename easier: + Hash.update('\0'); + Hash.update(llvm::StringRef(Output.getFilename())); + Hash.final(HashResult); + + std::string Base64Hash = llvm::encodeBase64(HashResult); + // Base64: 8 * 1.33 (encoding efficiency) > 10 + Base64Hash.resize(10); + // Make the base64 string filesystem and url safe by mapping + to - + // and / to _, see RFC 4648#section-5 + for (char &c : Base64Hash) { + c = (c == '+') ? '-' : ((c == '/') ? '_' : c); + } + llvm::sys::path::append( + Path, Twine(llvm::sys::path::filename(Input.getFilename())) + "." + + StringRef(Base64Hash) + ".json"); + }; + + AppendBasenameAndHash(Path, Input, Output); + int FD; - SmallString<256> TempPath; - Err = llvm::sys::fs::createUniqueFile(Path, FD, TempPath, - llvm::sys::fs::OF_Text); + Err = llvm::sys::fs::openFileForWrite( + Path, FD, llvm::sys::fs::CD_CreateAlways, llvm::sys::fs::OF_Text); if (Err) { Driver.Diag(diag::err_drv_compilationdatabase) << Path << Err.message(); return;