Allow CompilerInvocations to generate .d files.

Summary:
Most clang tools should ignore the -M
family of options because one wouldn't want them
to generate a new dependency (.d) file. However,
some tools may want this dependency file. This
patch creates a mechanism for them to do this.

This implementation just plumbs a boolean down
several layers of calls. Each of the modified calls
has several call sites, and so a single member
variable or new API entry point won't work.

An alternative would be to write a function to filter
the -M family of arguments out of CC1Args, and have
each caller call that function by hand before calling
newInvocation, Invocation::run, or buildAstFromCodeWithArgs.
This is a more complicated and error-prone solution.
Why burden all the callers to remember to use
this function?

But I could rewrite this patch to use that method if
that is deemed more appropriate.

Reviewers: klimek

Reviewed By: klimek

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D34304

llvm-svn: 307315
This commit is contained in:
Sterling Augustine 2017-07-06 21:02:52 +00:00
parent 9aa45f047f
commit 1cda1d76b1
4 changed files with 35 additions and 7 deletions

View File

@ -44,6 +44,10 @@ ArgumentsAdjuster getClangSyntaxOnlyAdjuster();
/// arguments.
ArgumentsAdjuster getClangStripOutputAdjuster();
/// \brief Gets an argument adjuster which removes dependency-file
/// related command line arguments.
ArgumentsAdjuster getClangStripDependencyFileAdjuster();
enum class ArgumentInsertPosition { BEGIN, END };
/// \brief Gets an argument adjuster which inserts \p Extra arguments in the

View File

@ -202,12 +202,15 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
/// \param PCHContainerOps The PCHContainerOperations for loading and creating
/// clang modules.
///
/// \param Adjuster A function to filter the command line arguments as specified.
///
/// \return The resulting AST or null if an error occurred.
std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
const Twine &Code, const std::vector<std::string> &Args,
const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
std::make_shared<PCHContainerOperations>(),
ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster());
/// \brief Utility to run a FrontendAction in a single clang invocation.
class ToolInvocation {

View File

@ -42,7 +42,7 @@ ArgumentsAdjuster getClangStripOutputAdjuster() {
AdjustedArgs.push_back(Args[i]);
if (Arg == "-o") {
// Output is specified as -o foo. Skip the next argument also.
// Output is specified as -o foo. Skip the next argument too.
++i;
}
// Else, the output is specified as -ofoo. Just do nothing.
@ -51,6 +51,26 @@ ArgumentsAdjuster getClangStripOutputAdjuster() {
};
}
ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
return [](const CommandLineArguments &Args, StringRef /*unused*/) {
CommandLineArguments AdjustedArgs;
for (size_t i = 0, e = Args.size(); i < e; ++i) {
StringRef Arg = Args[i];
// All dependency-file options begin with -M. These include -MM,
// -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
if (!Arg.startswith("-M"))
AdjustedArgs.push_back(Args[i]);
if ((Arg == "-MF") || (Arg == "-MT") || (Arg == "-MQ") ||
(Arg == "-MD") || (Arg == "-MMD")) {
// Output is specified as -MX foo. Skip the next argument also.
++i;
}
}
return AdjustedArgs;
};
}
ArgumentsAdjuster getInsertArgumentAdjuster(const CommandLineArguments &Extra,
ArgumentInsertPosition Pos) {
return [Extra, Pos](const CommandLineArguments &Args, StringRef /*unused*/) {
@ -83,4 +103,3 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
} // end namespace tooling
} // end namespace clang

View File

@ -100,7 +100,6 @@ clang::CompilerInvocation *newInvocation(
*Diagnostics);
Invocation->getFrontendOpts().DisableFree = false;
Invocation->getCodeGenOpts().DisableFree = false;
Invocation->getDependencyOutputOpts() = DependencyOutputOptions();
return Invocation;
}
@ -510,7 +509,8 @@ buildASTFromCode(const Twine &Code, const Twine &FileName,
std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
const Twine &Code, const std::vector<std::string> &Args,
const Twine &FileName, const Twine &ToolName,
std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
ArgumentsAdjuster Adjuster) {
SmallString<16> FileNameStorage;
StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
@ -523,8 +523,10 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
OverlayFileSystem->pushOverlay(InMemoryFileSystem);
llvm::IntrusiveRefCntPtr<FileManager> Files(
new FileManager(FileSystemOptions(), OverlayFileSystem));
ToolInvocation Invocation(getSyntaxOnlyToolArgs(ToolName, Args, FileNameRef),
&Action, Files.get(), std::move(PCHContainerOps));
ToolInvocation Invocation(
getSyntaxOnlyToolArgs(ToolName, Adjuster(Args, FileNameRef), FileNameRef),
&Action, Files.get(), std::move(PCHContainerOps));
SmallString<1024> CodeStorage;
InMemoryFileSystem->addFile(FileNameRef, 0,