[clang][Tooling] Filter flags that generate output in SyntaxOnlyAdjuster

Summary:
Flags that generate output could result in failures when creating
syntax only actions. This patch introduces initial logic for filtering out
those. The first such flag is "save-temps", which saves intermediate
files(bitcode, assembly, etc.) into a specified directory.

Fixes https://github.com/clangd/clangd/issues/191

Reviewers: hokein

Subscribers: ilya-biryukov, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D70173
This commit is contained in:
Kadir Cetinkaya 2019-11-13 13:44:40 +01:00
parent 33e882d5ad
commit 16bdcc809c
No known key found for this signature in database
GPG Key ID: E39E36B8D2057ED6
2 changed files with 48 additions and 2 deletions

View File

@ -13,20 +13,32 @@
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <cstddef>
#include <vector>
namespace clang {
namespace tooling {
/// Add -fsyntax-only option to the command line arguments.
/// Add -fsyntax-only option and drop options that triggers output generation.
ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
return [](const CommandLineArguments &Args, StringRef /*unused*/) {
CommandLineArguments AdjustedArgs;
bool HasSyntaxOnly = false;
const std::vector<llvm::StringRef> OutputCommands = {
// FIXME: Add other options that generate output.
"-save-temps",
"--save-temps",
};
for (size_t i = 0, e = Args.size(); i < e; ++i) {
StringRef Arg = Args[i];
// FIXME: Remove options that generate output.
// Skip output commands.
if (llvm::any_of(OutputCommands, [&Arg](llvm::StringRef OutputCommand) {
return Arg.startswith(OutputCommand);
}))
continue;
if (!Arg.startswith("-fcolor-diagnostics") &&
!Arg.startswith("-fdiagnostics-color"))
AdjustedArgs.push_back(Args[i]);

View File

@ -13,15 +13,18 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>
#include <vector>
namespace clang {
namespace tooling {
@ -429,6 +432,37 @@ TEST(ClangToolTest, NoDoubleSyntaxOnly) {
EXPECT_EQ(SyntaxOnlyCount, 1U);
}
TEST(ClangToolTest, NoOutputCommands) {
FixedCompilationDatabase Compilations("/", {"-save-temps", "-save-temps=cwd",
"--save-temps",
"--save-temps=somedir"});
ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
Tool.mapVirtualFile("/a.cc", "void a() {}");
std::unique_ptr<FrontendActionFactory> Action(
newFrontendActionFactory<SyntaxOnlyAction>());
const std::vector<llvm::StringRef> OutputCommands = {"-save-temps"};
bool Ran = false;
ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
[&OutputCommands, &Ran](const CommandLineArguments &Args,
StringRef /*unused*/) {
for (llvm::StringRef Arg : Args) {
for (llvm::StringRef OutputCommand : OutputCommands)
EXPECT_FALSE(Arg.contains(OutputCommand));
}
Ran = true;
return Args;
};
Tool.clearArgumentsAdjusters();
Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
Tool.run(Action.get());
EXPECT_TRUE(Ran);
}
TEST(ClangToolTest, BaseVirtualFileSystemUsage) {
FixedCompilationDatabase Compilations("/", std::vector<std::string>());
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(