[Tooling] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 327573
This commit is contained in:
Eugene Zelenko 2018-03-14 21:05:51 +00:00
parent adf72e8549
commit 6366efeddc
14 changed files with 346 additions and 231 deletions

View File

@ -1,4 +1,4 @@
//===--- ArgumentsAdjusters.h - Command line arguments adjuster -*- C++ -*-===//
//===- ArgumentsAdjusters.h - Command line arguments adjuster ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
// This file declares typedef ArgumentsAdjuster and functions to create several
// This file declares type ArgumentsAdjuster and functions to create several
// useful argument adjusters.
// ArgumentsAdjusters modify command line arguments obtained from a compilation
// database before they are used to run a frontend action.
@ -27,14 +27,14 @@ namespace clang {
namespace tooling {
/// \brief A sequence of command line arguments.
typedef std::vector<std::string> CommandLineArguments;
using CommandLineArguments = std::vector<std::string>;
/// \brief A prototype of a command line adjuster.
///
/// Command line argument adjuster is responsible for command line arguments
/// modification before the arguments are used to run a frontend action.
typedef std::function<CommandLineArguments(
const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster;
using ArgumentsAdjuster = std::function<CommandLineArguments(
const CommandLineArguments &, StringRef Filename)>;
/// \brief Gets an argument adjuster that converts input command line arguments
/// to the "syntax check only" variant.
@ -70,4 +70,3 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
} // namespace clang
#endif // LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H

View File

@ -1,4 +1,4 @@
//===--- CompilationDatabase.h - --------------------------------*- C++ -*-===//
//===- CompilationDatabase.h ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -34,6 +34,7 @@
#include "llvm/ADT/Twine.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace clang {
@ -41,13 +42,11 @@ namespace tooling {
/// \brief Specifies the working directory and command of a compilation.
struct CompileCommand {
CompileCommand() {}
CompileCommand() = default;
CompileCommand(Twine Directory, Twine Filename,
std::vector<std::string> CommandLine, Twine Output)
: Directory(Directory.str()),
Filename(Filename.str()),
CommandLine(std::move(CommandLine)),
Output(Output.str()){}
: Directory(Directory.str()), Filename(Filename.str()),
CommandLine(std::move(CommandLine)), Output(Output.str()){}
/// \brief The working directory the command was executed from.
std::string Directory;
@ -214,7 +213,7 @@ private:
std::vector<CompileCommand> CompileCommands;
};
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
#endif
#endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H

View File

@ -1,4 +1,4 @@
//===--- CompilationDatabasePluginRegistry.h - ------------------*- C++ -*-===//
//===- CompilationDatabasePluginRegistry.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -16,12 +16,10 @@
namespace clang {
namespace tooling {
class CompilationDatabasePlugin;
using CompilationDatabasePluginRegistry =
llvm::Registry<CompilationDatabasePlugin>;
typedef llvm::Registry<CompilationDatabasePlugin>
CompilationDatabasePluginRegistry;
} // namespace tooling
} // namespace clang
} // end namespace tooling
} // end namespace clang
#endif
#endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASEPLUGINREGISTRY_H

View File

@ -1,4 +1,4 @@
//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
//===- Replacement.h - Framework for clang refactoring tools ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -19,29 +19,32 @@
#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <set>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
namespace clang {
class FileManager;
class Rewriter;
class SourceManager;
namespace tooling {
/// \brief A source range independent of the \c SourceManager.
class Range {
public:
Range() : Offset(0), Length(0) {}
Range() = default;
Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
/// \brief Accessors.
@ -70,8 +73,8 @@ public:
/// @}
private:
unsigned Offset;
unsigned Length;
unsigned Offset = 0;
unsigned Length = 0;
};
/// \brief A text replacement.
@ -186,9 +189,11 @@ private:
}
replacement_error Err;
// A new replacement, which is to expected be added into a set of
// replacements, that is causing problem.
llvm::Optional<Replacement> NewReplacement;
// An existing replacement in a replacements set that is causing problem.
llvm::Optional<Replacement> ExistingReplacement;
};
@ -203,12 +208,12 @@ bool operator==(const Replacement &LHS, const Replacement &RHS);
/// Two replacements are considered conflicts if they overlap or have the same
/// offset (i.e. order-dependent).
class Replacements {
private:
typedef std::set<Replacement> ReplacementsImpl;
private:
using ReplacementsImpl = std::set<Replacement>;
public:
typedef ReplacementsImpl::const_iterator const_iterator;
typedef ReplacementsImpl::const_reverse_iterator const_reverse_iterator;
public:
using const_iterator = ReplacementsImpl::const_iterator;
using const_reverse_iterator = ReplacementsImpl::const_reverse_iterator;
Replacements() = default;
@ -283,7 +288,6 @@ class Replacements {
return Replaces == RHS.Replaces;
}
private:
Replacements(const_iterator Begin, const_iterator End)
: Replaces(Begin, End) {}
@ -329,6 +333,7 @@ llvm::Expected<std::string> applyAllReplacements(StringRef Code,
struct TranslationUnitReplacements {
/// Name of the main source for the translation unit.
std::string MainSourceFile;
std::vector<Replacement> Replacements;
};
@ -360,7 +365,8 @@ Replacement::Replacement(const SourceManager &Sources,
setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
}
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H

View File

@ -1,4 +1,4 @@
//===--- FileMatchTrie.h - --------------------------------------*- C++ -*-===//
//===- FileMatchTrie.h ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -16,20 +16,19 @@
#define LLVM_CLANG_TOOLING_FILEMATCHTRIE_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
namespace llvm {
class StringRef;
}
namespace clang {
namespace tooling {
class FileMatchTrieNode;
struct PathComparator {
virtual ~PathComparator() {}
virtual ~PathComparator() = default;
virtual bool equivalent(StringRef FileA, StringRef FileB) const = 0;
};
class FileMatchTrieNode;
/// \brief A trie to efficiently match against the entries of the compilation
/// database in order of matching suffix length.
@ -78,13 +77,13 @@ public:
/// written to 'Error'.
StringRef findEquivalent(StringRef FileName,
raw_ostream &Error) const;
private:
FileMatchTrieNode *Root;
std::unique_ptr<PathComparator> Comparator;
};
} // namespace tooling
} // namespace clang
} // end namespace tooling
} // end namespace clang
#endif
#endif // LLVM_CLANG_TOOLING_FILEMATCHTRIE_H

View File

@ -1,4 +1,4 @@
//===--- JSONCompilationDatabase.h - ----------------------------*- C++ -*-===//
//===- JSONCompilationDatabase.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/FileMatchTrie.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
@ -25,6 +26,8 @@
#include "llvm/Support/YAMLParser.h"
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
namespace clang {
@ -110,10 +113,10 @@ private:
// Otherwise, each entry in the command line vector is a literal
// argument to the compiler.
// The output field may be a nullptr.
typedef std::tuple<llvm::yaml::ScalarNode *,
llvm::yaml::ScalarNode *,
using CompileCommandRef =
std::tuple<llvm::yaml::ScalarNode *, llvm::yaml::ScalarNode *,
std::vector<llvm::yaml::ScalarNode *>,
llvm::yaml::ScalarNode *> CompileCommandRef;
llvm::yaml::ScalarNode *>;
/// \brief Converts the given array of CompileCommandRefs to CompileCommands.
void getCommands(ArrayRef<CompileCommandRef> CommandsRef,
@ -134,7 +137,7 @@ private:
llvm::yaml::Stream YAMLStream;
};
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
#endif
#endif // LLVM_CLANG_TOOLING_JSONCOMPILATIONDATABASE_H

View File

@ -1,4 +1,4 @@
//===--- ToolExecutorPluginRegistry.h - -------------------------*- C++ -*-===//
//===- ToolExecutorPluginRegistry.h -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -16,9 +16,9 @@
namespace clang {
namespace tooling {
typedef llvm::Registry<ToolExecutorPlugin> ToolExecutorPluginRegistry;
using ToolExecutorPluginRegistry = llvm::Registry<ToolExecutorPlugin>;
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
#endif // LLVM_CLANG_TOOLING_TOOLEXECUTORPLUGINREGISTRY_H

View File

@ -1,4 +1,4 @@
//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===//
//===- Tooling.h - Framework for standalone Clang tools ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -31,34 +31,42 @@
#define LLVM_CLANG_TOOLING_TOOLING_H
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Util.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Option.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace clang {
namespace driver {
class Compilation;
} // end namespace driver
class CompilerInstance;
class CompilerInvocation;
class DiagnosticConsumer;
class DiagnosticsEngine;
class SourceManager;
class FrontendAction;
namespace driver {
class Compilation;
} // namespace driver
namespace tooling {
class CompilationDatabase;
/// \brief Interface to process a clang::CompilerInvocation.
///
/// If your tool is based on FrontendAction, you should be deriving from
@ -69,7 +77,7 @@ public:
/// \brief Perform an action for an invocation.
virtual bool
runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *Files,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagConsumer) = 0;
@ -86,7 +94,7 @@ public:
~FrontendActionFactory() override;
/// \brief Invokes the compiler with a FrontendAction created by create().
bool runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
FileManager *Files,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagConsumer) override;
@ -94,7 +102,7 @@ public:
/// \brief Returns a new clang::FrontendAction.
///
/// The caller takes ownership of the returned action.
virtual clang::FrontendAction *create() = 0;
virtual FrontendAction *create() = 0;
};
/// \brief Returns a new FrontendActionFactory for a given type.
@ -112,7 +120,7 @@ std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
/// newFrontendActionFactory.
class SourceFileCallbacks {
public:
virtual ~SourceFileCallbacks() {}
virtual ~SourceFileCallbacks() = default;
/// \brief Called before a source file is processed by a FrontEndAction.
/// \see clang::FrontendAction::BeginSourceFileAction
@ -149,14 +157,14 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
/// clang modules.
///
/// \return - True if 'ToolAction' was successfully executed.
bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
bool runToolOnCode(FrontendAction *ToolAction, const Twine &Code,
const Twine &FileName = "input.cc",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>());
/// The first part of the pair is the filename, the second part the
/// file-content.
typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
/// with additional other flags.
@ -172,7 +180,7 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings;
///
/// \return - True if 'ToolAction' was successfully executed.
bool runToolOnCodeWithArgs(
clang::FrontendAction *ToolAction, const Twine &Code,
FrontendAction *ToolAction, const Twine &Code,
const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
const Twine &ToolName = "clang-tool",
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
@ -265,8 +273,8 @@ public:
void addFileMappingsTo(SourceManager &SourceManager);
bool runInvocation(const char *BinaryName,
clang::driver::Compilation *Compilation,
std::shared_ptr<clang::CompilerInvocation> Invocation,
driver::Compilation *Compilation,
std::shared_ptr<CompilerInvocation> Invocation,
std::shared_ptr<PCHContainerOperations> PCHContainerOps);
std::vector<std::string> CommandLine;
@ -276,7 +284,7 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
// Maps <file name> -> <file content>.
llvm::StringMap<StringRef> MappedFileContents;
DiagnosticConsumer *DiagConsumer;
DiagnosticConsumer *DiagConsumer = nullptr;
};
/// \brief Utility to run a FrontendAction over a set of files.
@ -287,7 +295,7 @@ public:
/// a frontend action. One could install an additional command line
/// arguments adjuster by calling the appendArgumentsAdjuster() method.
class ClangTool {
public:
public:
/// \brief Constructs a clang tool to run over a list of files.
///
/// \param Compilations The CompilationDatabase which contains the compile
@ -354,20 +362,22 @@ private:
llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem;
llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem;
llvm::IntrusiveRefCntPtr<FileManager> Files;
// Contains a list of pairs (<file name>, <file content>).
std::vector< std::pair<StringRef, StringRef> > MappedFileContents;
std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
llvm::StringSet<> SeenWorkingDirectories;
ArgumentsAdjuster ArgsAdjuster;
DiagnosticConsumer *DiagConsumer;
DiagnosticConsumer *DiagConsumer = nullptr;
};
template <typename T>
std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
class SimpleFrontendActionFactory : public FrontendActionFactory {
public:
clang::FrontendAction *create() override { return new T; }
FrontendAction *create() override { return new T; }
};
return std::unique_ptr<FrontendActionFactory>(
@ -383,34 +393,35 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
SourceFileCallbacks *Callbacks)
: ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
clang::FrontendAction *create() override {
FrontendAction *create() override {
return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
}
private:
class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
class ConsumerFactoryAdaptor : public ASTFrontendAction {
public:
ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
SourceFileCallbacks *Callbacks)
: ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &, StringRef) override {
std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance &, StringRef) override {
return ConsumerFactory->newASTConsumer();
}
protected:
bool BeginSourceFileAction(CompilerInstance &CI) override {
if (!clang::ASTFrontendAction::BeginSourceFileAction(CI))
if (!ASTFrontendAction::BeginSourceFileAction(CI))
return false;
if (Callbacks)
return Callbacks->handleBeginSource(CI);
return true;
}
void EndSourceFileAction() override {
if (Callbacks)
Callbacks->handleEndSource();
clang::ASTFrontendAction::EndSourceFileAction();
ASTFrontendAction::EndSourceFileAction();
}
private:
@ -463,11 +474,11 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
StringRef InvokedAs);
/// \brief Creates a \c CompilerInvocation.
clang::CompilerInvocation *newInvocation(
clang::DiagnosticsEngine *Diagnostics,
CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
const llvm::opt::ArgStringList &CC1Args);
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
#endif // LLVM_CLANG_TOOLING_TOOLING_H

View File

@ -1,4 +1,4 @@
//===--- ArgumentsAdjusters.cpp - Command line arguments adjuster ---------===//
//===- ArgumentsAdjusters.cpp - Command line arguments adjuster -----------===//
//
// The LLVM Compiler Infrastructure
//
@ -13,6 +13,9 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include <cstddef>
namespace clang {
namespace tooling {
@ -21,7 +24,7 @@ namespace tooling {
ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
return [](const CommandLineArguments &Args, StringRef /*unused*/) {
CommandLineArguments AdjustedArgs;
for (size_t i = 0, e = Args.size(); i != e; ++i) {
for (size_t i = 0, e = Args.size(); i < e; ++i) {
StringRef Arg = Args[i];
// FIXME: Remove options that generate output.
if (!Arg.startswith("-fcolor-diagnostics") &&

View File

@ -1,4 +1,4 @@
//===--- CompilationDatabase.cpp - ----------------------------------------===//
//===- CompilationDatabase.cpp --------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -17,7 +17,9 @@
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
@ -26,20 +28,38 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Arg.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
using namespace clang;
using namespace tooling;
LLVM_INSTANTIATE_REGISTRY(CompilationDatabasePluginRegistry)
CompilationDatabase::~CompilationDatabase() {}
CompilationDatabase::~CompilationDatabase() = default;
std::unique_ptr<CompilationDatabase>
CompilationDatabase::loadFromDirectory(StringRef BuildDirectory,
@ -121,20 +141,20 @@ std::vector<CompileCommand> CompilationDatabase::getAllCompileCommands() const {
return Result;
}
CompilationDatabasePlugin::~CompilationDatabasePlugin() {}
CompilationDatabasePlugin::~CompilationDatabasePlugin() = default;
namespace {
// Helper for recursively searching through a chain of actions and collecting
// all inputs, direct and indirect, of compile jobs.
struct CompileJobAnalyzer {
SmallVector<std::string, 2> Inputs;
void run(const driver::Action *A) {
runImpl(A, false);
}
SmallVector<std::string, 2> Inputs;
private:
void runImpl(const driver::Action *A, bool Collect) {
bool CollectChildren = Collect;
switch (A->getKind()) {
@ -142,16 +162,16 @@ private:
CollectChildren = true;
break;
case driver::Action::InputClass: {
case driver::Action::InputClass:
if (Collect) {
const driver::InputAction *IA = cast<driver::InputAction>(A);
const auto *IA = cast<driver::InputAction>(A);
Inputs.push_back(IA->getInputArg().getSpelling());
}
} break;
break;
default:
// Don't care about others
;
break;
}
for (const driver::Action *AI : A->inputs())
@ -168,7 +188,7 @@ public:
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override {
if (Info.getID() == clang::diag::warn_drv_input_file_unused) {
if (Info.getID() == diag::warn_drv_input_file_unused) {
// Arg 1 for this diagnostic is the option that didn't get used.
UnusedInputs.push_back(Info.getArgStdStr(0));
} else if (DiagLevel >= DiagnosticsEngine::Error) {
@ -186,15 +206,18 @@ public:
// S2 in Arr where S1 == S2?"
struct MatchesAny {
MatchesAny(ArrayRef<std::string> Arr) : Arr(Arr) {}
bool operator() (StringRef S) {
for (const std::string *I = Arr.begin(), *E = Arr.end(); I != E; ++I)
if (*I == S)
return true;
return false;
}
private:
ArrayRef<std::string> Arr;
};
} // namespace
/// \brief Strips any positional args and possible argv[0] from a command-line
@ -224,7 +247,7 @@ static bool stripPositionalArgs(std::vector<const char *> Args,
TextDiagnosticPrinter DiagnosticPrinter(Output, &*DiagOpts);
UnusedInputDiagConsumer DiagClient(DiagnosticPrinter);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
&*DiagOpts, &DiagClient, false);
// The clang executable path isn't required since the jobs the driver builds
@ -362,11 +385,11 @@ class FixedCompilationDatabasePlugin : public CompilationDatabasePlugin {
}
};
} // namespace
static CompilationDatabasePluginRegistry::Add<FixedCompilationDatabasePlugin>
X("fixed-compilation-database", "Reads plain-text flags file");
} // namespace
namespace clang {
namespace tooling {
@ -375,5 +398,5 @@ namespace tooling {
extern volatile int JSONAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED JSONAnchorDest = JSONAnchorSource;
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang

View File

@ -1,4 +1,4 @@
//===--- Replacement.cpp - Framework for clang refactoring tools ----------===//
//===- Replacement.cpp - Framework for clang refactoring tools ------------===//
//
// The LLVM Compiler Infrastructure
//
@ -12,21 +12,34 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <limits>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace clang {
namespace tooling {
using namespace clang;
using namespace tooling;
static const char * const InvalidLocation = "";
@ -80,6 +93,9 @@ std::string Replacement::toString() const {
return Stream.str();
}
namespace clang {
namespace tooling {
bool operator<(const Replacement &LHS, const Replacement &RHS) {
if (LHS.getOffset() != RHS.getOffset())
return LHS.getOffset() < RHS.getOffset();
@ -99,6 +115,9 @@ bool operator==(const Replacement &LHS, const Replacement &RHS) {
LHS.getReplacementText() == RHS.getReplacementText();
}
} // namespace tooling
} // namespace clang
void Replacement::setFromSourceLocation(const SourceManager &Sources,
SourceLocation Start, unsigned Length,
StringRef ReplacementText) {
@ -231,7 +250,7 @@ llvm::Error Replacements::add(const Replacement &R) {
replacement_error::wrong_file_path, R, *Replaces.begin());
// Special-case header insertions.
if (R.getOffset() == UINT_MAX) {
if (R.getOffset() == std::numeric_limits<unsigned>::max()) {
Replaces.insert(R);
return llvm::Error::success();
}
@ -396,6 +415,7 @@ public:
// Returns 'true' if an element from the second set should be merged next.
bool mergeSecond() const { return MergeSecond; }
int deltaFirst() const { return DeltaFirst; }
Replacement asReplacement() const { return {FilePath, Offset, Length, Text}; }
@ -485,6 +505,9 @@ static std::vector<Range> combineAndSortRanges(std::vector<Range> Ranges) {
return Result;
}
namespace clang {
namespace tooling {
std::vector<Range>
calculateRangesAfterReplacements(const Replacements &Replaces,
const std::vector<Range> &Ranges) {
@ -508,10 +531,13 @@ calculateRangesAfterReplacements(const Replacements &Replaces,
return FakeReplaces.merge(Replaces).getAffectedRanges();
}
} // namespace tooling
} // namespace clang
std::vector<Range> Replacements::getAffectedRanges() const {
std::vector<Range> ChangedRanges;
int Shift = 0;
for (const Replacement &R : Replaces) {
for (const auto &R : Replaces) {
unsigned Offset = R.getOffset() + Shift;
unsigned Length = R.getReplacementText().size();
Shift += Length - R.getLength();
@ -522,7 +548,7 @@ std::vector<Range> Replacements::getAffectedRanges() const {
unsigned Replacements::getShiftedCodePosition(unsigned Position) const {
unsigned Offset = 0;
for (const auto& R : Replaces) {
for (const auto &R : Replaces) {
if (R.getOffset() + R.getLength() <= Position) {
Offset += R.getReplacementText().size() - R.getLength();
continue;
@ -530,7 +556,7 @@ unsigned Replacements::getShiftedCodePosition(unsigned Position) const {
if (R.getOffset() < Position &&
R.getOffset() + R.getReplacementText().size() <= Position) {
Position = R.getOffset() + R.getReplacementText().size();
if (R.getReplacementText().size() > 0)
if (!R.getReplacementText().empty())
Position--;
}
break;
@ -538,6 +564,9 @@ unsigned Replacements::getShiftedCodePosition(unsigned Position) const {
return Position + Offset;
}
namespace clang {
namespace tooling {
bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite) {
bool Result = true;
for (auto I = Replaces.rbegin(), E = Replaces.rend(); I != E; ++I) {
@ -596,5 +625,5 @@ std::map<std::string, Replacements> groupReplacementsByFile(
return Result;
}
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang

View File

@ -1,4 +1,4 @@
//===--- FileMatchTrie.cpp - ----------------------------------------------===//
//===- FileMatchTrie.cpp --------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -13,24 +13,30 @@
#include "clang/Tooling/FileMatchTrie.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <sstream>
#include <string>
#include <vector>
using namespace clang;
using namespace tooling;
namespace {
/// \brief Default \c PathComparator using \c llvm::sys::fs::equivalent().
struct DefaultPathComparator : public PathComparator {
bool equivalent(StringRef FileA, StringRef FileB) const override {
return FileA == FileB || llvm::sys::fs::equivalent(FileA, FileB);
}
};
}
} // namespace
namespace clang {
namespace tooling {
/// \brief A node of the \c FileMatchTrie.
///
/// Each node has storage for up to one path and a map mapping a path segment to
@ -103,7 +109,7 @@ public:
if (Children.empty()) {
if (Comparator.equivalent(StringRef(Path), FileName))
return StringRef(Path);
return StringRef();
return {};
}
StringRef Element(llvm::sys::path::filename(FileName.drop_back(
ConsumedLength)));
@ -119,13 +125,13 @@ public:
std::vector<StringRef> AllChildren;
getAll(AllChildren, MatchingChild);
StringRef Result;
for (unsigned i = 0; i < AllChildren.size(); i++) {
if (Comparator.equivalent(AllChildren[i], FileName)) {
for (const auto &Child : AllChildren) {
if (Comparator.equivalent(Child, FileName)) {
if (Result.empty()) {
Result = AllChildren[i];
Result = Child;
} else {
IsAmbiguous = true;
return StringRef();
return {};
}
}
}
@ -158,8 +164,9 @@ private:
// The children of this node stored in a map based on the next path segment.
llvm::StringMap<FileMatchTrieNode> Children;
};
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang
FileMatchTrie::FileMatchTrie()
: Root(new FileMatchTrieNode), Comparator(new DefaultPathComparator()) {}
@ -179,7 +186,7 @@ StringRef FileMatchTrie::findEquivalent(StringRef FileName,
raw_ostream &Error) const {
if (llvm::sys::path::is_relative(FileName)) {
Error << "Cannot resolve relative paths";
return StringRef();
return {};
}
bool IsAmbiguous = false;
StringRef Result = Root->findEquivalent(*Comparator, FileName, IsAmbiguous);

View File

@ -1,4 +1,4 @@
//===--- JSONCompilationDatabase.cpp - ------------------------------------===//
//===- JSONCompilationDatabase.cpp ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -12,18 +12,34 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/JSONCompilationDatabase.h"
#include "clang/Basic/LLVM.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <memory>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>
namespace clang {
namespace tooling {
using namespace clang;
using namespace tooling;
namespace {
@ -151,17 +167,23 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
}
};
} // end namespace
} // namespace
// Register the JSONCompilationDatabasePlugin with the
// CompilationDatabasePluginRegistry using this statically initialized variable.
static CompilationDatabasePluginRegistry::Add<JSONCompilationDatabasePlugin>
X("json-compilation-database", "Reads JSON formatted compilation databases");
namespace clang {
namespace tooling {
// This anchor is used to force the linker to link in the generated object file
// and thus register the JSONCompilationDatabasePlugin.
volatile int JSONAnchorSource = 0;
} // namespace tooling
} // namespace clang
std::unique_ptr<JSONCompilationDatabase>
JSONCompilationDatabase::loadFromFile(StringRef FilePath,
std::string &ErrorMessage,
@ -201,11 +223,10 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
llvm::raw_string_ostream ES(Error);
StringRef Match = MatchTrie.findEquivalent(NativeFilePath, ES);
if (Match.empty())
return std::vector<CompileCommand>();
llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
CommandsRefI = IndexByFile.find(Match);
return {};
const auto CommandsRefI = IndexByFile.find(Match);
if (CommandsRefI == IndexByFile.end())
return std::vector<CompileCommand>();
return {};
std::vector<CompileCommand> Commands;
getCommands(CommandsRefI->getValue(), Commands);
return Commands;
@ -214,15 +235,8 @@ JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
std::vector<std::string>
JSONCompilationDatabase::getAllFiles() const {
std::vector<std::string> Result;
llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
CommandsRefI = IndexByFile.begin();
const llvm::StringMap< std::vector<CompileCommandRef> >::const_iterator
CommandsRefEnd = IndexByFile.end();
for (; CommandsRefI != CommandsRefEnd; ++CommandsRefI) {
Result.push_back(CommandsRefI->first().str());
}
for (const auto &CommandRef : IndexByFile)
Result.push_back(CommandRef.first().str());
return Result;
}
@ -237,28 +251,26 @@ static std::vector<std::string>
nodeToCommandLine(JSONCommandLineSyntax Syntax,
const std::vector<llvm::yaml::ScalarNode *> &Nodes) {
SmallString<1024> Storage;
if (Nodes.size() == 1) {
if (Nodes.size() == 1)
return unescapeCommandLine(Syntax, Nodes[0]->getValue(Storage));
}
std::vector<std::string> Arguments;
for (auto *Node : Nodes) {
for (const auto *Node : Nodes)
Arguments.push_back(Node->getValue(Storage));
}
return Arguments;
}
void JSONCompilationDatabase::getCommands(
ArrayRef<CompileCommandRef> CommandsRef,
std::vector<CompileCommand> &Commands) const {
for (int I = 0, E = CommandsRef.size(); I != E; ++I) {
for (const auto &CommandRef : CommandsRef) {
SmallString<8> DirectoryStorage;
SmallString<32> FilenameStorage;
SmallString<32> OutputStorage;
auto Output = std::get<3>(CommandsRef[I]);
auto Output = std::get<3>(CommandRef);
Commands.emplace_back(
std::get<0>(CommandsRef[I])->getValue(DirectoryStorage),
std::get<1>(CommandsRef[I])->getValue(FilenameStorage),
nodeToCommandLine(Syntax, std::get<2>(CommandsRef[I])),
std::get<0>(CommandRef)->getValue(DirectoryStorage),
std::get<1>(CommandRef)->getValue(FilenameStorage),
nodeToCommandLine(Syntax, std::get<2>(CommandRef)),
Output ? Output->getValue(OutputStorage) : "");
}
}
@ -274,13 +286,13 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
ErrorMessage = "Error while parsing YAML.";
return false;
}
llvm::yaml::SequenceNode *Array = dyn_cast<llvm::yaml::SequenceNode>(Root);
auto *Array = dyn_cast<llvm::yaml::SequenceNode>(Root);
if (!Array) {
ErrorMessage = "Expected array.";
return false;
}
for (auto& NextObject : *Array) {
llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&NextObject);
for (auto &NextObject : *Array) {
auto *Object = dyn_cast<llvm::yaml::MappingNode>(&NextObject);
if (!Object) {
ErrorMessage = "Expected object.";
return false;
@ -290,8 +302,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
llvm::yaml::ScalarNode *File = nullptr;
llvm::yaml::ScalarNode *Output = nullptr;
for (auto& NextKeyValue : *Object) {
llvm::yaml::ScalarNode *KeyString =
dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
auto *KeyString = dyn_cast<llvm::yaml::ScalarNode>(NextKeyValue.getKey());
if (!KeyString) {
ErrorMessage = "Expected strings as key.";
return false;
@ -303,10 +314,8 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
ErrorMessage = "Expected value.";
return false;
}
llvm::yaml::ScalarNode *ValueString =
dyn_cast<llvm::yaml::ScalarNode>(Value);
llvm::yaml::SequenceNode *SequenceString =
dyn_cast<llvm::yaml::SequenceNode>(Value);
auto *ValueString = dyn_cast<llvm::yaml::ScalarNode>(Value);
auto *SequenceString = dyn_cast<llvm::yaml::SequenceNode>(Value);
if (KeyValue == "arguments" && !SequenceString) {
ErrorMessage = "Expected sequence as value.";
return false;
@ -319,7 +328,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
} else if (KeyValue == "arguments") {
Command = std::vector<llvm::yaml::ScalarNode *>();
for (auto &Argument : *SequenceString) {
auto Scalar = dyn_cast<llvm::yaml::ScalarNode>(&Argument);
auto *Scalar = dyn_cast<llvm::yaml::ScalarNode>(&Argument);
if (!Scalar) {
ErrorMessage = "Only strings are allowed in 'arguments'.";
return false;
@ -370,6 +379,3 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
}
return true;
}
} // end namespace tooling
} // end namespace clang

View File

@ -1,4 +1,4 @@
//===--- Tooling.cpp - Running clang standalone tools ---------------------===//
//===- Tooling.cpp - Running clang standalone tools -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@ -13,49 +13,73 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/Tooling.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstring>
#include <memory>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
#define DEBUG_TYPE "clang-tooling"
namespace clang {
namespace tooling {
using namespace clang;
using namespace tooling;
ToolAction::~ToolAction() {}
ToolAction::~ToolAction() = default;
FrontendActionFactory::~FrontendActionFactory() {}
FrontendActionFactory::~FrontendActionFactory() = default;
// FIXME: This file contains structural duplication with other parts of the
// code that sets up a compiler to run tools on it, and we should refactor
// it to be based on the same framework.
/// \brief Builds a clang driver initialized for running clang tools.
static clang::driver::Driver *newDriver(
clang::DiagnosticsEngine *Diagnostics, const char *BinaryName,
static driver::Driver *newDriver(
DiagnosticsEngine *Diagnostics, const char *BinaryName,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
clang::driver::Driver *CompilerDriver =
new clang::driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
driver::Driver *CompilerDriver =
new driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(),
*Diagnostics, std::move(VFS));
CompilerDriver->setTitle("clang_based_tool");
return CompilerDriver;
@ -63,40 +87,40 @@ static clang::driver::Driver *newDriver(
/// \brief Retrieves the clang CC1 specific flags out of the compilation's jobs.
///
/// Returns NULL on error.
/// Returns nullptr on error.
static const llvm::opt::ArgStringList *getCC1Arguments(
clang::DiagnosticsEngine *Diagnostics,
clang::driver::Compilation *Compilation) {
DiagnosticsEngine *Diagnostics, driver::Compilation *Compilation) {
// We expect to get back exactly one Command job, if we didn't something
// failed. Extract that job from the Compilation.
const clang::driver::JobList &Jobs = Compilation->getJobs();
if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
const driver::JobList &Jobs = Compilation->getJobs();
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
SmallString<256> error_msg;
llvm::raw_svector_ostream error_stream(error_msg);
Jobs.Print(error_stream, "; ", true);
Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
Diagnostics->Report(diag::err_fe_expected_compiler_job)
<< error_stream.str();
return nullptr;
}
// The one job we find should be to invoke clang again.
const clang::driver::Command &Cmd =
cast<clang::driver::Command>(*Jobs.begin());
const auto &Cmd = cast<driver::Command>(*Jobs.begin());
if (StringRef(Cmd.getCreator().getName()) != "clang") {
Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
Diagnostics->Report(diag::err_fe_expected_clang_command);
return nullptr;
}
return &Cmd.getArguments();
}
namespace clang {
namespace tooling {
/// \brief Returns a clang build invocation initialized from the CC1 flags.
clang::CompilerInvocation *newInvocation(
clang::DiagnosticsEngine *Diagnostics,
const llvm::opt::ArgStringList &CC1Args) {
CompilerInvocation *newInvocation(
DiagnosticsEngine *Diagnostics, const llvm::opt::ArgStringList &CC1Args) {
assert(!CC1Args.empty() && "Must at least contain the program name!");
clang::CompilerInvocation *Invocation = new clang::CompilerInvocation;
clang::CompilerInvocation::CreateFromArgs(
CompilerInvocation *Invocation = new CompilerInvocation;
CompilerInvocation::CreateFromArgs(
*Invocation, CC1Args.data() + 1, CC1Args.data() + CC1Args.size(),
*Diagnostics);
Invocation->getFrontendOpts().DisableFree = false;
@ -104,7 +128,7 @@ clang::CompilerInvocation *newInvocation(
return Invocation;
}
bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
bool runToolOnCode(FrontendAction *ToolAction, const Twine &Code,
const Twine &FileName,
std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
return runToolOnCodeWithArgs(ToolAction, Code, std::vector<std::string>(),
@ -112,6 +136,9 @@ bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
std::move(PCHContainerOps));
}
} // namespace tooling
} // namespace clang
static std::vector<std::string>
getSyntaxOnlyToolArgs(const Twine &ToolName,
const std::vector<std::string> &ExtraArgs,
@ -124,13 +151,15 @@ getSyntaxOnlyToolArgs(const Twine &ToolName,
return Args;
}
namespace clang {
namespace tooling {
bool runToolOnCodeWithArgs(
clang::FrontendAction *ToolAction, const Twine &Code,
FrontendAction *ToolAction, const Twine &Code,
const std::vector<std::string> &Args, const Twine &FileName,
const Twine &ToolName,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
const FileContentMappings &VirtualMappedFiles) {
SmallString<16> FileNameStorage;
StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem(
@ -190,7 +219,7 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
TokenRef.startswith("--driver-mode="));
}
auto TargetMode =
clang::driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs);
driver::ToolChain::getTargetAndModeFromProgramName(InvokedAs);
if (!AlreadyHasMode && TargetMode.DriverMode) {
CommandLine.insert(++CommandLine.begin(), TargetMode.DriverMode);
}
@ -201,6 +230,9 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
}
}
} // namespace tooling
} // namespace clang
namespace {
class SingleFrontendActionFactory : public FrontendActionFactory {
@ -212,22 +244,20 @@ public:
FrontendAction *create() override { return Action; }
};
}
} // namespace
ToolInvocation::ToolInvocation(
std::vector<std::string> CommandLine, ToolAction *Action,
FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
: CommandLine(std::move(CommandLine)), Action(Action), OwnsAction(false),
Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
DiagConsumer(nullptr) {}
Files(Files), PCHContainerOps(std::move(PCHContainerOps)) {}
ToolInvocation::ToolInvocation(
std::vector<std::string> CommandLine, FrontendAction *FAction,
FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
: CommandLine(std::move(CommandLine)),
Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),
Files(Files), PCHContainerOps(std::move(PCHContainerOps)),
DiagConsumer(nullptr) {}
Files(Files), PCHContainerOps(std::move(PCHContainerOps)) {}
ToolInvocation::~ToolInvocation() {
if (OwnsAction)
@ -254,23 +284,22 @@ bool ToolInvocation::run() {
TextDiagnosticPrinter DiagnosticPrinter(
llvm::errs(), &*DiagOpts);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
const std::unique_ptr<clang::driver::Driver> Driver(
const std::unique_ptr<driver::Driver> Driver(
newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
// Since the input might only be virtual, don't check whether it exists.
Driver->setCheckInputsExist(false);
const std::unique_ptr<clang::driver::Compilation> Compilation(
const std::unique_ptr<driver::Compilation> Compilation(
Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
if (!Compilation)
return false;
const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
&Diagnostics, Compilation.get());
if (!CC1Args) {
if (!CC1Args)
return false;
}
std::unique_ptr<clang::CompilerInvocation> Invocation(
std::unique_ptr<CompilerInvocation> Invocation(
newInvocation(&Diagnostics, *CC1Args));
// FIXME: remove this when all users have migrated!
for (const auto &It : MappedFileContents) {
@ -285,8 +314,8 @@ bool ToolInvocation::run() {
}
bool ToolInvocation::runInvocation(
const char *BinaryName, clang::driver::Compilation *Compilation,
std::shared_ptr<clang::CompilerInvocation> Invocation,
const char *BinaryName, driver::Compilation *Compilation,
std::shared_ptr<CompilerInvocation> Invocation,
std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
// Show the invocation, with -v.
if (Invocation->getHeaderSearchOpts().Verbose) {
@ -304,7 +333,7 @@ bool FrontendActionFactory::runInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagConsumer) {
// Create a compiler instance to handle the actual work.
clang::CompilerInstance Compiler(std::move(PCHContainerOps));
CompilerInstance Compiler(std::move(PCHContainerOps));
Compiler.setInvocation(std::move(Invocation));
Compiler.setFileManager(Files);
@ -334,15 +363,14 @@ ClangTool::ClangTool(const CompilationDatabase &Compilations,
PCHContainerOps(std::move(PCHContainerOps)),
OverlayFileSystem(new vfs::OverlayFileSystem(BaseFS)),
InMemoryFileSystem(new vfs::InMemoryFileSystem),
Files(new FileManager(FileSystemOptions(), OverlayFileSystem)),
DiagConsumer(nullptr) {
Files(new FileManager(FileSystemOptions(), OverlayFileSystem)) {
OverlayFileSystem->pushOverlay(InMemoryFileSystem);
appendArgumentsAdjuster(getClangStripOutputAdjuster());
appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
appendArgumentsAdjuster(getClangStripDependencyFileAdjuster());
}
ClangTool::~ClangTool() {}
ClangTool::~ClangTool() = default;
void ClangTool::mapVirtualFile(StringRef FilePath, StringRef Content) {
MappedFileContents.push_back(std::make_pair(FilePath, Content));
@ -491,13 +519,17 @@ public:
return true;
}
};
}
} // namespace
int ClangTool::buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs) {
ASTBuilderAction Action(ASTs);
return run(&Action);
}
namespace clang {
namespace tooling {
std::unique_ptr<ASTUnit>
buildASTFromCode(const Twine &Code, const Twine &FileName,
std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
@ -538,5 +570,5 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
return std::move(ASTs[0]);
}
} // end namespace tooling
} // end namespace clang
} // namespace tooling
} // namespace clang