Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/include/clang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ class CompilerInvocation : public CompilerInvocationBase {
}
/// @}

/// Visitation.
/// @{
/// Visits paths stored in the invocation. The callback may return true to
/// short-circuit the visitation, or return false to continue visiting. This
/// is allowed to mutate the visited paths.
void visitPaths(llvm::function_ref<bool(std::string &)> Callback);
/// @}

/// Create a compiler invocation from a list of input options.
/// \returns true on success.
///
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5804,6 +5804,9 @@ void CompilerInvocationBase::visitPathsImpl(
for (auto &Entry : HeaderSearchOpts.UserEntries)
if (Entry.IgnoreSysRoot)
RETURN_IF(Entry.Path);
// TODO: Consider upstreaming this.
for (auto &Prefix : HeaderSearchOpts.SystemHeaderPrefixes)
RETURN_IF(Prefix.Prefix);
RETURN_IF(HeaderSearchOpts.ResourceDir);
RETURN_IF(HeaderSearchOpts.ModuleCachePath);
RETURN_IF(HeaderSearchOpts.ModuleUserBuildPath);
Expand Down Expand Up @@ -5837,6 +5840,7 @@ void CompilerInvocationBase::visitPathsImpl(
// Filesystem options.
auto &FileSystemOpts = *this->FSOpts;
RETURN_IF(FileSystemOpts.WorkingDir);
RETURN_IF(FileSystemOpts.CASFileSystemWorkingDirectory);

// Codegen options.
auto &CodeGenOpts = *this->CodeGenOpts;
Expand Down Expand Up @@ -5864,6 +5868,14 @@ void CompilerInvocationBase::visitPaths(
[&Callback](std::string &Path) { return Callback(StringRef(Path)); });
}

void CompilerInvocation::visitPaths(
llvm::function_ref<bool(std::string &)> Callback) {
// Unlike the copy-on-write variant (and therefore potentially also the base
// class), regular CompilerInvocation does not share the option objects with
// anyone else. This makes the potential mutation in the callback safe.
visitPathsImpl(Callback);
}

void CompilerInvocationBase::generateCC1CommandLine(
ArgumentConsumer Consumer) const {
llvm::Triple T(getTargetOpts().Triple);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ Error IncludeTreeActionController::initialize(

addReversePrefixMappingFileSystem(PrefixMapper, ScanInstance);

// TODO: Confirm why it's not enough to do this in
// DepscanPrefixMapping::remapInvocationPaths.
// These are written in the predefines buffer, so we need to remap them.
for (std::string &Include : PPOpts.Includes)
PrefixMapper.mapInPlace(Include);
Expand Down
96 changes: 10 additions & 86 deletions clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,94 +145,18 @@ void DepscanPrefixMapping::remapInvocationPaths(CompilerInvocation &Invocation,
FrontendOpts.PathPrefixMappings.emplace_back(Map.Old, Map.New);
}

auto mapInPlaceAll = [&](std::vector<std::string> &Vector) {
for (auto &Path : Vector)
Mapper.mapInPlace(Path);
};

auto &FileSystemOpts = Invocation.getFileSystemOpts();
Mapper.mapInPlace(FileSystemOpts.CASFileSystemWorkingDirectory);

// Remap header search.
auto &HeaderSearchOpts = Invocation.getHeaderSearchOpts();
Mapper.mapInPlace(HeaderSearchOpts.Sysroot);
for (auto &Entry : HeaderSearchOpts.UserEntries)
if (Entry.IgnoreSysRoot)
Mapper.mapInPlace(Entry.Path);

for (auto &Prefix : HeaderSearchOpts.SystemHeaderPrefixes)
Mapper.mapInPlace(Prefix.Prefix);
Mapper.mapInPlace(HeaderSearchOpts.ResourceDir);
Mapper.mapInPlace(HeaderSearchOpts.ModuleCachePath);
Mapper.mapInPlace(HeaderSearchOpts.ModuleUserBuildPath);
for (auto I = HeaderSearchOpts.PrebuiltModuleFiles.begin(),
E = HeaderSearchOpts.PrebuiltModuleFiles.end();
I != E;) {
auto Current = I++;
Mapper.mapInPlace(Current->second);
}
mapInPlaceAll(HeaderSearchOpts.PrebuiltModulePaths);
mapInPlaceAll(HeaderSearchOpts.VFSOverlayFiles);

// Preprocessor options.
auto &PPOpts = Invocation.getPreprocessorOpts();
mapInPlaceAll(PPOpts.MacroIncludes);
mapInPlaceAll(PPOpts.Includes);
Mapper.mapInPlace(PPOpts.ImplicitPCHInclude);

// Frontend options.
for (FrontendInputFile &Input : FrontendOpts.Inputs) {
if (Input.isBuffer())
continue; // FIXME: Can this happen when parsing command-line?

SmallString<256> RemappedFile;
Mapper.map(Input.getFile(), RemappedFile);
if (RemappedFile != Input.getFile())
Input =
FrontendInputFile(RemappedFile, Input.getKind(), Input.isSystem());
}

// Skip the output file. That's not the input CAS filesystem.
// Mapper.mapInPlace(OutputFile); <-- this doesn't make sense.

Mapper.mapInPlace(FrontendOpts.CodeCompletionAt.FileName);

// Don't remap plugins (for now), since we don't know how to remap their
// arguments. Maybe they should be loaded outside of the CAS filesystem?
// Note: We don't remap plugins for now, since we don't know how to remap
// their arguments. Maybe they should be loaded outside of the CAS filesystem?
// Maybe we should error?
//
// Mapper.mapInPlaceOrFilterOut(FrontendOpts.Plugins);

mapInPlaceAll(FrontendOpts.ModuleMapFiles);
mapInPlaceAll(FrontendOpts.ModuleFiles);
mapInPlaceAll(FrontendOpts.ModulesEmbedFiles);
mapInPlaceAll(FrontendOpts.ASTMergeFiles);
Mapper.mapInPlace(FrontendOpts.OverrideRecordLayoutsFile);
Mapper.mapInPlace(FrontendOpts.StatsFile);

// Filesystem options.
Mapper.mapInPlace(FileSystemOpts.WorkingDir);

// Code generation options.
auto &CodeGenOpts = Invocation.getCodeGenOpts();
Mapper.mapInPlace(CodeGenOpts.DebugCompilationDir);
Mapper.mapInPlace(CodeGenOpts.CoverageCompilationDir);

// Sanitizer options.
mapInPlaceAll(Invocation.getLangOpts().NoSanitizeFiles);

// Handle coverage mappings.
Mapper.mapInPlace(CodeGenOpts.ProfileInstrumentUsePath);
Mapper.mapInPlace(CodeGenOpts.SampleProfileFile);
Mapper.mapInPlace(CodeGenOpts.ProfileRemappingFile);

// Dependency output options.
// Note: these are not in the cache key, but they are in the module context
// hash, which indirectly impacts the cache key when importing a module.
// In the future we may change how -fmodule-file-cache-key works when
// remapping to avoid needing this.
for (auto &ExtraDep : Invocation.getDependencyOutputOpts().ExtraDeps)
Mapper.mapInPlace(ExtraDep.first);
// Note: DependencyOutputOptions::ExtraDeps are not in the cache key, but they
// are in the module context hash, which indirectly impacts the cache key when
// importing a module. In the future we may change how -fmodule-file-cache-key
// works when remapping to avoid needing this.
Invocation.visitPaths([&Mapper](std::string &Path) {
Mapper.mapInPlace(Path);
return false;
});
}

void DepscanPrefixMapping::configurePrefixMapper(const CompilerInvocation &CI,
Expand Down