diff options
author | Manuel Klimek <klimek@google.com> | 2013-06-04 14:44:44 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-06-04 14:44:44 +0000 |
commit | d91ac930874389fa2e906d8bcd2456136defd0be (patch) | |
tree | 4c318cc29af5727e10075ce695a88ef9014e60c6 | |
parent | a5e536ab0e785dc6fcff76420b65fa592d29b7e0 (diff) | |
download | bcm5719-llvm-d91ac930874389fa2e906d8bcd2456136defd0be.tar.gz bcm5719-llvm-d91ac930874389fa2e906d8bcd2456136defd0be.zip |
Enables chaining of argument adjusters in clang tools.
This enables changing clang-check to get extra arguments.
Patch by Pavel Labath.
llvm-svn: 183227
-rw-r--r-- | clang/include/clang/Tooling/Tooling.h | 20 | ||||
-rw-r--r-- | clang/lib/Tooling/Tooling.cpp | 20 | ||||
-rw-r--r-- | clang/unittests/Tooling/ToolingTest.cpp | 41 |
3 files changed, 73 insertions, 8 deletions
diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index 7de0a1fe2a5..dc8163e553f 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -175,8 +175,8 @@ class ToolInvocation { /// This class is written to be usable for command line utilities. /// By default the class uses ClangSyntaxOnlyAdjuster to modify /// command line arguments before the arguments are used to run -/// a frontend action. One could install another command line -/// arguments adjuster by call setArgumentsAdjuster() method. +/// a frontend action. One could install an additional command line +/// arguments adjuster by calling the appendArgumentsAdjuster() method. class ClangTool { public: /// \brief Constructs a clang tool to run over a list of files. @@ -188,7 +188,7 @@ class ClangTool { ClangTool(const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths); - virtual ~ClangTool() {} + virtual ~ClangTool() { clearArgumentsAdjusters(); } /// \brief Map a virtual file to be used while running the tool. /// @@ -199,8 +199,20 @@ class ClangTool { /// \brief Install command line arguments adjuster. /// /// \param Adjuster Command line arguments adjuster. + // + /// FIXME: Function is deprecated. Use (clear/append)ArgumentsAdjuster instead. + /// Remove it once all callers are gone. void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); + /// \brief Append a command line arguments adjuster to the adjuster chain. + /// + /// \param Adjuster An argument adjuster, which will be run on the output of + /// previous argument adjusters. + void appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster); + + /// \brief Clear the command line arguments adjuster chain. + void clearArgumentsAdjusters(); + /// Runs a frontend action over all files specified in the command line. /// /// \param ActionFactory Factory generating the frontend actions. The function @@ -221,7 +233,7 @@ class ClangTool { // Contains a list of pairs (<file name>, <file content>). std::vector< std::pair<StringRef, StringRef> > MappedFileContents; - OwningPtr<ArgumentsAdjuster> ArgsAdjuster; + SmallVector<ArgumentsAdjuster *, 1> ArgsAdjusters; }; template <typename T> diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index 52855f657f6..cdb9bc71ee2 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -237,7 +237,7 @@ void ToolInvocation::addFileMappingsTo(SourceManager &Sources) { ClangTool::ClangTool(const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths) : Files((FileSystemOptions())), - ArgsAdjuster(new ClangSyntaxOnlyAdjuster()) { + ArgsAdjusters(1, new ClangSyntaxOnlyAdjuster()) { for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) { SmallString<1024> File(getAbsolutePath(SourcePaths[I])); @@ -264,7 +264,18 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) { } void ClangTool::setArgumentsAdjuster(ArgumentsAdjuster *Adjuster) { - ArgsAdjuster.reset(Adjuster); + clearArgumentsAdjusters(); + appendArgumentsAdjuster(Adjuster); +} + +void ClangTool::appendArgumentsAdjuster(ArgumentsAdjuster *Adjuster) { + ArgsAdjusters.push_back(Adjuster); +} + +void ClangTool::clearArgumentsAdjusters() { + for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I) + delete ArgsAdjusters[I]; + ArgsAdjusters.clear(); } int ClangTool::run(FrontendActionFactory *ActionFactory) { @@ -292,8 +303,9 @@ int ClangTool::run(FrontendActionFactory *ActionFactory) { if (chdir(CompileCommands[I].second.Directory.c_str())) llvm::report_fatal_error("Cannot chdir into \"" + CompileCommands[I].second.Directory + "\n!"); - std::vector<std::string> CommandLine = - ArgsAdjuster->Adjust(CompileCommands[I].second.CommandLine); + std::vector<std::string> CommandLine = CompileCommands[I].second.CommandLine; + for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I) + CommandLine = ArgsAdjusters[I]->Adjust(CommandLine); assert(!CommandLine.empty()); CommandLine[0] = MainExecutable; // FIXME: We need a callback mechanism for the tool writer to output a diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp index d96366dcd58..e435ea92e23 100644 --- a/clang/unittests/Tooling/ToolingTest.cpp +++ b/clang/unittests/Tooling/ToolingTest.cpp @@ -193,5 +193,46 @@ TEST(runToolOnCode, TestSkipFunctionBody) { "int skipMeNot() { an_error_here }")); } +struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster { + bool &Found; + bool &Ran; + + CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { } + + virtual CommandLineArguments + Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE { + Ran = true; + for (unsigned I = 0, E = Args.size(); I != E; ++I) { + if (Args[I] == "-fsyntax-only") { + Found = true; + break; + } + } + return Args; + } +}; + +TEST(ClangToolTest, ArgumentAdjusters) { + FixedCompilationDatabase Compilations("/", std::vector<std::string>()); + + ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc")); + Tool.mapVirtualFile("/a.cc", "void a() {}"); + + bool Found = false; + bool Ran = false; + Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); + Tool.run(newFrontendActionFactory<SyntaxOnlyAction>()); + EXPECT_TRUE(Ran); + EXPECT_TRUE(Found); + + Ran = Found = false; + Tool.clearArgumentsAdjusters(); + Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); + Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster()); + Tool.run(newFrontendActionFactory<SyntaxOnlyAction>()); + EXPECT_TRUE(Ran); + EXPECT_FALSE(Found); +} + } // end namespace tooling } // end namespace clang |