280 changes: 0 additions & 280 deletions clang/test/ClangScanDeps/P1689.cppm

This file was deleted.

219 changes: 15 additions & 204 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
Expand Down Expand Up @@ -134,15 +133,12 @@ static llvm::cl::opt<ScanningMode> ScanMode(

static llvm::cl::opt<ScanningOutputFormat> Format(
"format", llvm::cl::desc("The output format for the dependencies"),
llvm::cl::values(
clEnumValN(ScanningOutputFormat::Make, "make",
"Makefile compatible dep file"),
clEnumValN(ScanningOutputFormat::P1689, "p1689",
"Generate standard c++ modules dependency P1689 format"),
clEnumValN(ScanningOutputFormat::Full, "experimental-full",
"Full dependency graph suitable"
" for explicitly building modules. This format "
"is experimental and will change.")),
llvm::cl::values(clEnumValN(ScanningOutputFormat::Make, "make",
"Makefile compatible dep file"),
clEnumValN(ScanningOutputFormat::Full, "experimental-full",
"Full dependency graph suitable"
" for explicitly building modules. This format "
"is experimental and will change.")),
llvm::cl::init(ScanningOutputFormat::Make),
llvm::cl::cat(DependencyScannerCategory));

Expand Down Expand Up @@ -171,14 +167,9 @@ llvm::cl::opt<unsigned>

llvm::cl::opt<std::string>
CompilationDB("compilation-database",
llvm::cl::desc("Compilation database"), llvm::cl::Optional,
llvm::cl::desc("Compilation database"), llvm::cl::Required,
llvm::cl::cat(DependencyScannerCategory));

llvm::cl::opt<std::string> P1689TargettedCommand(
llvm::cl::Positional, llvm::cl::ZeroOrMore,
llvm::cl::desc("The command line flags for the target of which "
"the dependencies are to be computed."));

llvm::cl::opt<std::string> ModuleName(
"module-name", llvm::cl::Optional,
llvm::cl::desc("the module of which the dependencies are to be computed"),
Expand Down Expand Up @@ -472,88 +463,6 @@ static bool handleModuleResult(
return false;
}

class P1689Deps {
public:
void printDependencies(raw_ostream &OS) {
addSourcePathsToRequires();
// Sort the modules by name to get a deterministic order.
llvm::sort(Rules, [](const P1689Rule &A, const P1689Rule &B) {
return A.PrimaryOutput < B.PrimaryOutput;
});

using namespace llvm::json;
Array OutputRules;
for (const P1689Rule &R : Rules) {
Object O{{"primary-output", R.PrimaryOutput}};

if (R.Provides) {
Array Provides;
Object Provided{{"logical-name", R.Provides->ModuleName},
{"source-path", R.Provides->SourcePath},
{"is-interface", R.Provides->IsStdCXXModuleInterface}};
Provides.push_back(std::move(Provided));
O.insert({"provides", std::move(Provides)});
}

Array Requires;
for (const P1689ModuleInfo &Info : R.Requires) {
Object RequiredInfo{{"logical-name", Info.ModuleName}};
if (!Info.SourcePath.empty())
RequiredInfo.insert({"source-path", Info.SourcePath});
Requires.push_back(std::move(RequiredInfo));
}

if (!Requires.empty())
O.insert({"requires", std::move(Requires)});

OutputRules.push_back(std::move(O));
}

Object Output{
{"version", 1}, {"revision", 0}, {"rules", std::move(OutputRules)}};

OS << llvm::formatv("{0:2}\n", Value(std::move(Output)));
}

void addRules(P1689Rule &Rule) { Rules.push_back(Rule); }

private:
void addSourcePathsToRequires() {
llvm::DenseMap<StringRef, StringRef> ModuleSourceMapper;
for (const P1689Rule &R : Rules)
if (R.Provides && !R.Provides->SourcePath.empty())
ModuleSourceMapper[R.Provides->ModuleName] = R.Provides->SourcePath;

for (P1689Rule &R : Rules) {
for (P1689ModuleInfo &Info : R.Requires) {
auto Iter = ModuleSourceMapper.find(Info.ModuleName);
if (Iter != ModuleSourceMapper.end())
Info.SourcePath = Iter->second;
}
}
}

std::vector<P1689Rule> Rules;
};

static bool
handleP1689DependencyToolResult(const std::string &Input,
llvm::Expected<P1689Rule> &MaybeRule,
P1689Deps &PD, SharedStream &Errs) {
if (!MaybeRule) {
llvm::handleAllErrors(
MaybeRule.takeError(), [&Input, &Errs](llvm::StringError &Err) {
Errs.applyLocked([&](raw_ostream &OS) {
OS << "Error while scanning dependencies for " << Input << ":\n";
OS << Err.getMessage();
});
});
return true;
}
PD.addRules(*MaybeRule);
return false;
}

/// Construct a path for the explicitly built PCM.
static std::string constructPCMPath(ModuleID MID, StringRef OutputDir) {
SmallString<256> ExplicitPCMPath(OutputDir);
Expand Down Expand Up @@ -590,109 +499,19 @@ static std::string getModuleCachePath(ArrayRef<std::string> Args) {
return std::string(Path);
}

// getCompilationDataBase - If -compilation-database is set, load the
// compilation database from the specified file. Otherwise if the we're
// generating P1689 format, trying to generate the compilation database
// form specified command line after the positional parameter "--".
static std::unique_ptr<tooling::CompilationDatabase>
getCompilationDataBase(int argc, const char **argv, std::string &ErrorMessage) {
int main(int argc, const char **argv) {
llvm::InitLLVM X(argc, argv);
llvm::cl::HideUnrelatedOptions(DependencyScannerCategory);
if (!llvm::cl::ParseCommandLineOptions(argc, argv))
return nullptr;

if (!CompilationDB.empty())
return tooling::JSONCompilationDatabase::loadFromFile(
CompilationDB, ErrorMessage,
tooling::JSONCommandLineSyntax::AutoDetect);

if (Format != ScanningOutputFormat::P1689) {
llvm::errs() << "the --compilation-database option: must be specified at "
"least once!";
return nullptr;
}

// Trying to get the input file, the output file and the command line options
// from the positional parameter "--".
const char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
if (DoubleDash == argv + argc) {
llvm::errs() << "The command line arguments is required after '--' in "
"P1689 per file mode.";
return nullptr;
}
std::vector<const char *> CommandLine(DoubleDash + 1, argv + argc);

llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
CompilerInstance::createDiagnostics(new DiagnosticOptions);
driver::Driver TheDriver(CommandLine[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
std::unique_ptr<driver::Compilation> C(
TheDriver.BuildCompilation(CommandLine));
if (!C)
return nullptr;

auto Cmd = C->getJobs().begin();
auto CI = std::make_unique<CompilerInvocation>();
CompilerInvocation::CreateFromArgs(*CI, Cmd->getArguments(), *Diags,
CommandLine[0]);
if (!CI)
return nullptr;

FrontendOptions &FEOpts = CI->getFrontendOpts();
if (FEOpts.Inputs.size() != 1) {
llvm::errs() << "Only one input file is allowed in P1689 per file mode.";
return nullptr;
}

// There might be multiple jobs for a compilation. Extract the specified
// output filename from the last job.
auto LastCmd = C->getJobs().end();
LastCmd--;
if (LastCmd->getOutputFilenames().size() != 1) {
llvm::errs() << "The command line should provide exactly one output file "
"in P1689 per file mode.\n";
}
StringRef OutputFile = LastCmd->getOutputFilenames().front();

class InplaceCompilationDatabase : public tooling::CompilationDatabase {
public:
InplaceCompilationDatabase(StringRef InputFile, StringRef OutputFile,
ArrayRef<const char *> CommandLine)
: Command(".", InputFile, {}, OutputFile) {
for (auto *C : CommandLine)
Command.CommandLine.push_back(C);
}

std::vector<tooling::CompileCommand>
getCompileCommands(StringRef FilePath) const override {
if (FilePath != Command.Filename)
return {};
return {Command};
}

std::vector<std::string> getAllFiles() const override {
return {Command.Filename};
}

std::vector<tooling::CompileCommand>
getAllCompileCommands() const override {
return {Command};
}

private:
tooling::CompileCommand Command;
};

return std::make_unique<InplaceCompilationDatabase>(
FEOpts.Inputs[0].getFile(), OutputFile, CommandLine);
}
return 1;

int main(int argc, const char **argv) {
std::string ErrorMessage;
std::unique_ptr<tooling::CompilationDatabase> Compilations =
getCompilationDataBase(argc, argv, ErrorMessage);
std::unique_ptr<tooling::JSONCompilationDatabase> Compilations =
tooling::JSONCompilationDatabase::loadFromFile(
CompilationDB, ErrorMessage,
tooling::JSONCommandLineSyntax::AutoDetect);
if (!Compilations) {
llvm::errs() << ErrorMessage << "\n";
llvm::errs() << "error: " << ErrorMessage << "\n";
return 1;
}

Expand Down Expand Up @@ -779,7 +598,6 @@ int main(int argc, const char **argv) {

std::atomic<bool> HadErrors(false);
FullDeps FD;
P1689Deps PD;
std::mutex Lock;
size_t Index = 0;

Expand All @@ -788,7 +606,7 @@ int main(int argc, const char **argv) {
<< " files using " << Pool.getThreadCount() << " workers\n";
}
for (unsigned I = 0; I < Pool.getThreadCount(); ++I) {
Pool.async([I, &Lock, &Index, &Inputs, &HadErrors, &FD, &PD, &WorkerTools,
Pool.async([I, &Lock, &Index, &Inputs, &HadErrors, &FD, &WorkerTools,
&DependencyOS, &Errs]() {
llvm::StringSet<> AlreadySeenModules;
while (true) {
Expand Down Expand Up @@ -824,11 +642,6 @@ int main(int argc, const char **argv) {
if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS,
Errs))
HadErrors = true;
} else if (Format == ScanningOutputFormat::P1689) {
auto MaybeRule =
WorkerTools[I]->getP1689ModuleDependencyFile(*Input, CWD);
if (handleP1689DependencyToolResult(Filename, MaybeRule, PD, Errs))
HadErrors = true;
} else if (MaybeModuleName) {
auto MaybeModuleDepsGraph = WorkerTools[I]->getModuleDependencies(
*MaybeModuleName, Input->CommandLine, CWD, AlreadySeenModules,
Expand All @@ -854,8 +667,6 @@ int main(int argc, const char **argv) {

if (Format == ScanningOutputFormat::Full)
FD.printFullOutput(llvm::outs());
else if (Format == ScanningOutputFormat::P1689)
PD.printDependencies(llvm::outs());

return HadErrors;
}