Skip to content

Commit 96ac594

Browse files
committed
Extract more generic visitor implementation
1 parent f84b9c7 commit 96ac594

File tree

4 files changed

+65
-46
lines changed

4 files changed

+65
-46
lines changed

clang/include/clang/Frontend/CompilerInvocation.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ class CompilerInvocationBase {
149149

150150
/// Visitation.
151151
/// @{
152-
bool anyPath(llvm::function_ref<bool(StringRef)> Predicate) const;
152+
/// Visits paths stored in the invocation. The callback may return true to
153+
/// short-circuit the visitation, or return false to continue visiting.
154+
void visitPaths(llvm::function_ref<bool(StringRef)> Callback) const;
153155
/// @}
154156

155157
/// Command line generation.
@@ -187,6 +189,11 @@ class CompilerInvocationBase {
187189
std::vector<std::string> getCC1CommandLine() const;
188190

189191
private:
192+
/// Visits paths stored in the invocation. This is generally unsafe to call
193+
/// directly, and each sub-class need to ensure calling this doesn't violate
194+
/// its invariants.
195+
void visitPathsImpl(llvm::function_ref<bool(std::string &)> Predicate);
196+
190197
/// Generate command line options from DiagnosticOptions.
191198
static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
192199
ArgumentConsumer Consumer,

clang/include/clang/Frontend/FrontendOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ class FrontendInputFile {
241241
/// Whether we're dealing with a 'system' input (vs. a 'user' input).
242242
bool IsSystem = false;
243243

244+
friend class CompilerInvocationBase;
245+
244246
public:
245247
FrontendInputFile() = default;
246248
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5280,78 +5280,84 @@ std::string CompilerInvocation::getModuleHash() const {
52805280
return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
52815281
}
52825282

5283-
bool CompilerInvocationBase::anyPath(
5284-
llvm::function_ref<bool(StringRef)> Predicate) const {
5285-
#define PROPAGATE_TRUE_IF(PATH) \
5283+
void CompilerInvocationBase::visitPathsImpl(
5284+
llvm::function_ref<bool(std::string &)> Predicate) {
5285+
#define RETURN_IF(PATH) \
52865286
do { \
52875287
if (Predicate(PATH)) \
5288-
return true; \
5288+
return; \
52895289
} while (0)
52905290

5291-
#define PROPAGATE_TRUE_IF_MANY(PATHS) \
5291+
#define RETURN_IF_MANY(PATHS) \
52925292
do { \
52935293
if (llvm::any_of(PATHS, Predicate)) \
5294-
return true; \
5294+
return; \
52955295
} while (0)
52965296

5297+
auto &HeaderSearchOpts = *this->HSOpts;
52975298
// Header search paths.
5298-
const auto &HeaderSearchOpts = getHeaderSearchOpts();
5299-
PROPAGATE_TRUE_IF(HeaderSearchOpts.Sysroot);
5299+
RETURN_IF(HeaderSearchOpts.Sysroot);
53005300
for (auto &Entry : HeaderSearchOpts.UserEntries)
53015301
if (Entry.IgnoreSysRoot)
5302-
PROPAGATE_TRUE_IF(Entry.Path);
5303-
PROPAGATE_TRUE_IF(HeaderSearchOpts.ResourceDir);
5304-
PROPAGATE_TRUE_IF(HeaderSearchOpts.ModuleCachePath);
5305-
PROPAGATE_TRUE_IF(HeaderSearchOpts.ModuleUserBuildPath);
5306-
for (const auto &[Name, File] : HeaderSearchOpts.PrebuiltModuleFiles)
5307-
PROPAGATE_TRUE_IF(File);
5308-
PROPAGATE_TRUE_IF_MANY(HeaderSearchOpts.PrebuiltModulePaths);
5309-
PROPAGATE_TRUE_IF_MANY(HeaderSearchOpts.VFSOverlayFiles);
5302+
RETURN_IF(Entry.Path);
5303+
RETURN_IF(HeaderSearchOpts.ResourceDir);
5304+
RETURN_IF(HeaderSearchOpts.ModuleCachePath);
5305+
RETURN_IF(HeaderSearchOpts.ModuleUserBuildPath);
5306+
for (auto &[Name, File] : HeaderSearchOpts.PrebuiltModuleFiles)
5307+
RETURN_IF(File);
5308+
RETURN_IF_MANY(HeaderSearchOpts.PrebuiltModulePaths);
5309+
RETURN_IF_MANY(HeaderSearchOpts.VFSOverlayFiles);
53105310

53115311
// Preprocessor options.
5312-
const auto &PPOpts = getPreprocessorOpts();
5313-
PROPAGATE_TRUE_IF_MANY(PPOpts.MacroIncludes);
5314-
PROPAGATE_TRUE_IF_MANY(PPOpts.Includes);
5315-
PROPAGATE_TRUE_IF(PPOpts.ImplicitPCHInclude);
5312+
auto &PPOpts = *this->PPOpts;
5313+
RETURN_IF_MANY(PPOpts.MacroIncludes);
5314+
RETURN_IF_MANY(PPOpts.Includes);
5315+
RETURN_IF(PPOpts.ImplicitPCHInclude);
53165316

53175317
// Frontend options.
5318-
const auto &FrontendOpts = getFrontendOpts();
5319-
for (const FrontendInputFile &Input : FrontendOpts.Inputs) {
5318+
auto &FrontendOpts = *this->FrontendOpts;
5319+
for (auto &Input : FrontendOpts.Inputs) {
53205320
if (Input.isBuffer())
5321-
continue; // FIXME: Can this happen when parsing command-line?
5321+
continue;
53225322

5323-
PROPAGATE_TRUE_IF(Input.getFile());
5323+
RETURN_IF(Input.File);
53245324
}
5325-
PROPAGATE_TRUE_IF(FrontendOpts.CodeCompletionAt.FileName);
5326-
PROPAGATE_TRUE_IF_MANY(FrontendOpts.ModuleMapFiles);
5327-
PROPAGATE_TRUE_IF_MANY(FrontendOpts.ModuleFiles);
5328-
PROPAGATE_TRUE_IF_MANY(FrontendOpts.ModulesEmbedFiles);
5329-
PROPAGATE_TRUE_IF_MANY(FrontendOpts.ASTMergeFiles);
5330-
PROPAGATE_TRUE_IF(FrontendOpts.OverrideRecordLayoutsFile);
5331-
PROPAGATE_TRUE_IF(FrontendOpts.StatsFile);
5325+
RETURN_IF(FrontendOpts.CodeCompletionAt.FileName);
5326+
RETURN_IF_MANY(FrontendOpts.ModuleMapFiles);
5327+
RETURN_IF_MANY(FrontendOpts.ModuleFiles);
5328+
RETURN_IF_MANY(FrontendOpts.ModulesEmbedFiles);
5329+
RETURN_IF_MANY(FrontendOpts.ASTMergeFiles);
5330+
RETURN_IF(FrontendOpts.OverrideRecordLayoutsFile);
5331+
RETURN_IF(FrontendOpts.StatsFile);
53325332

53335333
// Filesystem options.
5334-
const auto &FileSystemOpts = getFileSystemOpts();
5335-
PROPAGATE_TRUE_IF(FileSystemOpts.WorkingDir);
5334+
auto &FileSystemOpts = *this->FSOpts;
5335+
RETURN_IF(FileSystemOpts.WorkingDir);
53365336

53375337
// Codegen options.
5338-
const auto &CodeGenOpts = getCodeGenOpts();
5339-
PROPAGATE_TRUE_IF(CodeGenOpts.DebugCompilationDir);
5340-
PROPAGATE_TRUE_IF(CodeGenOpts.CoverageCompilationDir);
5338+
auto &CodeGenOpts = *this->CodeGenOpts;
5339+
RETURN_IF(CodeGenOpts.DebugCompilationDir);
5340+
RETURN_IF(CodeGenOpts.CoverageCompilationDir);
53415341

53425342
// Sanitizer options.
5343-
PROPAGATE_TRUE_IF_MANY(getLangOpts().NoSanitizeFiles);
5343+
RETURN_IF_MANY(LangOpts->NoSanitizeFiles);
53445344

53455345
// Coverage mappings.
5346-
PROPAGATE_TRUE_IF(CodeGenOpts.ProfileInstrumentUsePath);
5347-
PROPAGATE_TRUE_IF(CodeGenOpts.SampleProfileFile);
5348-
PROPAGATE_TRUE_IF(CodeGenOpts.ProfileRemappingFile);
5346+
RETURN_IF(CodeGenOpts.ProfileInstrumentUsePath);
5347+
RETURN_IF(CodeGenOpts.SampleProfileFile);
5348+
RETURN_IF(CodeGenOpts.ProfileRemappingFile);
53495349

53505350
// Dependency output options.
5351-
for (auto &ExtraDep : getDependencyOutputOpts().ExtraDeps)
5352-
PROPAGATE_TRUE_IF(ExtraDep.first);
5351+
for (auto &ExtraDep : DependencyOutputOpts->ExtraDeps)
5352+
RETURN_IF(ExtraDep.first);
5353+
}
53535354

5354-
return false;
5355+
void CompilerInvocationBase::visitPaths(
5356+
llvm::function_ref<bool(StringRef)> Callback) const {
5357+
// The const_cast here is OK, because visitPathsImpl() itself doesn't modify
5358+
// the invocation, and our callback takes immutable StringRefs.
5359+
return const_cast<CompilerInvocationBase *>(this)->visitPathsImpl(
5360+
[&Callback](std::string &Path) { return Callback(StringRef(Path)); });
53555361
}
53565362

53575363
void CompilerInvocationBase::generateCC1CommandLine(

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,13 @@ static bool isSafeToIgnoreCWD(const CowCompilerInvocation &CI) {
471471
// Check if the command line input uses relative paths.
472472
// It is not safe to ignore the current working directory if any of the
473473
// command line inputs use relative paths.
474-
return !CI.anyPath([](StringRef Path) {
475-
return !Path.empty() && !llvm::sys::path::is_absolute(Path);
474+
bool AnyRelative = false;
475+
CI.visitPaths([&](StringRef Path) {
476+
assert(!AnyRelative && "Continuing path visitation despite returning true");
477+
AnyRelative |= !Path.empty() && !llvm::sys::path::is_absolute(Path);
478+
return AnyRelative;
476479
});
480+
return !AnyRelative;
477481
}
478482

479483
static std::string getModuleContextHash(const ModuleDeps &MD,

0 commit comments

Comments
 (0)