diff --git a/clang/include/clang/Tooling/ArgumentsAdjusters.h b/clang/include/clang/Tooling/ArgumentsAdjusters.h new file mode 100644 index 000000000000..28d2a38a4c1a --- /dev/null +++ b/clang/include/clang/Tooling/ArgumentsAdjusters.h @@ -0,0 +1,56 @@ +//===--- ArgumentsAdjusters.h - Command line arguments adjuster -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares base abstract class ArgumentsAdjuster and its descendants. +// These classes are intended to modify command line arguments obtained from +// a compilation database before they are used to run a frontend action. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H +#define LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H + +#include +#include + +namespace clang { + +namespace tooling { + +/// \brief A sequence of command line arguments. +typedef std::vector CommandLineArguments; + +/// \brief Abstract interface for a command line adjusters. +/// +/// This abstract interface describes a command line argument adjuster, +/// which is responsible for command line arguments modification before +/// the arguments are used to run a frontend action. +class ArgumentsAdjuster { +public: + /// \brief Returns adjusted command line arguments. + /// + /// \param Args Input sequence of command line arguments. + /// + /// \returns Modified sequence of command line arguments. + virtual CommandLineArguments Adjust(const CommandLineArguments &Args) = 0; +}; + +/// \brief Syntax check only command line adjuster. +/// +/// This class implements ArgumentsAdjuster interface and converts input +/// command line arguments to the "syntax check only" variant. +class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster { + virtual CommandLineArguments Adjust(const CommandLineArguments &Args); +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H + diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index ff66616dfc44..ecf14181de2b 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -35,6 +35,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "clang/Driver/Util.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CompilationDatabase.h" #include #include @@ -138,6 +139,10 @@ class ToolInvocation { /// \brief Utility to run a FrontendAction over a set of files. /// /// 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. class ClangTool { public: /// \brief Constructs a clang tool to run over a list of files. @@ -155,6 +160,11 @@ class ClangTool { /// \param Content A null terminated buffer of the file's content. void mapVirtualFile(StringRef FilePath, StringRef Content); + /// \brief Install command line arguments adjuster. + /// + /// \param Adjuster Command line arguments adjuster. + void setArgumentsAdjuster(ArgumentsAdjuster *Adjuster); + /// Runs a frontend action over all files specified in the command line. /// /// \param ActionFactory Factory generating the frontend actions. The function @@ -174,6 +184,8 @@ class ClangTool { FileManager Files; // Contains a list of pairs (, ). std::vector< std::pair > MappedFileContents; + + llvm::OwningPtr ArgsAdjuster; }; template diff --git a/clang/lib/Tooling/ArgumentsAdjusters.cpp b/clang/lib/Tooling/ArgumentsAdjusters.cpp new file mode 100644 index 000000000000..73ad39816bf8 --- /dev/null +++ b/clang/lib/Tooling/ArgumentsAdjusters.cpp @@ -0,0 +1,31 @@ +//===--- ArgumentsAdjusters.cpp - Command line arguments adjuster ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains definitions of classes which implement ArgumentsAdjuster +// interface. +// +//===----------------------------------------------------------------------===// + +#include "clang/Tooling/ArgumentsAdjusters.h" + +namespace clang { +namespace tooling { + +/// Add -fsyntax-only option to the commnand line arguments. +CommandLineArguments +ClangSyntaxOnlyAdjuster::Adjust(const CommandLineArguments &Args) { + CommandLineArguments AdjustedArgs = Args; + // FIXME: Remove options that generate output. + AdjustedArgs.push_back("-fsyntax-only"); + return AdjustedArgs; +} + +} // end namespace tooling +} // end namespace clang + diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index b84b21194190..66045515e5e7 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -4,4 +4,5 @@ SET(LLVM_USED_LIBS clangBasic clangFrontend clangAST) add_clang_library(clangTooling CompilationDatabase.cpp Tooling.cpp + ArgumentsAdjusters.cpp ) diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index 9b4d4e2e239a..abd670380e9d 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/Tooling.h" #include "clang/Tooling/CompilationDatabase.h" #include "clang/Driver/Compilation.h" @@ -253,7 +254,8 @@ void ToolInvocation::addFileMappingsTo(SourceManager &Sources) { ClangTool::ClangTool(const CompilationDatabase &Compilations, ArrayRef SourcePaths) - : Files((FileSystemOptions())) { + : Files((FileSystemOptions())), + ArgsAdjuster(new ClangSyntaxOnlyAdjuster()) { llvm::SmallString<1024> BaseDirectory; if (const char *PWD = ::getenv("PWD")) BaseDirectory = PWD; @@ -285,6 +287,10 @@ void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) { MappedFileContents.push_back(std::make_pair(FilePath, Content)); } +void ClangTool::setArgumentsAdjuster(ArgumentsAdjuster *Adjuster) { + ArgsAdjuster.reset(Adjuster); +} + int ClangTool::run(FrontendActionFactory *ActionFactory) { bool ProcessingFailed = false; for (unsigned I = 0; I < CompileCommands.size(); ++I) { @@ -299,8 +305,8 @@ 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 &CommandLine = - CompileCommands[I].second.CommandLine; + std::vector CommandLine = + ArgsAdjuster->Adjust(CompileCommands[I].second.CommandLine); llvm::outs() << "Processing: " << File << ".\n"; ToolInvocation Invocation(CommandLine, ActionFactory->create(), &Files); for (int I = 0, E = MappedFileContents.size(); I != E; ++I) { diff --git a/clang/test/Tooling/multi-jobs.cpp b/clang/test/Tooling/multi-jobs.cpp new file mode 100644 index 000000000000..e330d18b9c4e --- /dev/null +++ b/clang/test/Tooling/multi-jobs.cpp @@ -0,0 +1,8 @@ +// RUN: clang-check . "%s" -- -no-integrated-as -c 2>&1 | FileCheck %s + +// CHECK: C++ requires +invalid; + +// FIXME: clang-check doesn't like gcc driver on cygming. +// XFAIL: cygwin,mingw32,win32 +