2016-04-20 20:43:43 +08:00
|
|
|
//===-- ClangIncludeFixer.cpp - Standalone include fixer ------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "InMemoryXrefsDB.h"
|
|
|
|
#include "IncludeFixer.h"
|
2016-05-04 16:22:35 +08:00
|
|
|
#include "XrefsDBManager.h"
|
2016-04-29 17:23:38 +08:00
|
|
|
#include "YamlXrefsDB.h"
|
2016-04-20 20:43:43 +08:00
|
|
|
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
|
|
|
#include "clang/Rewrite/Core/Rewriter.h"
|
|
|
|
#include "clang/Tooling/CommonOptionsParser.h"
|
|
|
|
#include "clang/Tooling/Tooling.h"
|
|
|
|
#include "llvm/Support/CommandLine.h"
|
2016-04-29 17:23:38 +08:00
|
|
|
|
2016-04-20 20:43:43 +08:00
|
|
|
using namespace clang;
|
2016-04-27 22:24:32 +08:00
|
|
|
using namespace llvm;
|
2016-04-20 20:43:43 +08:00
|
|
|
|
2016-04-27 22:24:32 +08:00
|
|
|
namespace {
|
|
|
|
cl::OptionCategory IncludeFixerCategory("Tool options");
|
|
|
|
|
|
|
|
enum DatabaseFormatTy {
|
2016-04-28 04:43:32 +08:00
|
|
|
fixed, ///< Hard-coded mapping.
|
2016-04-29 17:23:38 +08:00
|
|
|
yaml, ///< Yaml database created by find-all-symbols.
|
2016-04-27 22:24:32 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
cl::opt<DatabaseFormatTy> DatabaseFormat(
|
|
|
|
"db", cl::desc("Specify input format"),
|
2016-04-29 17:23:38 +08:00
|
|
|
cl::values(clEnumVal(fixed, "Hard-coded mapping"),
|
|
|
|
clEnumVal(yaml, "Yaml database created by find-all-symbols"),
|
|
|
|
clEnumValEnd),
|
2016-04-27 22:24:32 +08:00
|
|
|
cl::init(fixed), cl::cat(IncludeFixerCategory));
|
|
|
|
|
|
|
|
cl::opt<std::string> Input("input",
|
|
|
|
cl::desc("String to initialize the database"),
|
|
|
|
cl::cat(IncludeFixerCategory));
|
2016-04-28 19:21:29 +08:00
|
|
|
|
|
|
|
cl::opt<bool>
|
|
|
|
MinimizeIncludePaths("minimize-paths",
|
|
|
|
cl::desc("Whether to minimize added include paths"),
|
|
|
|
cl::init(true), cl::cat(IncludeFixerCategory));
|
2016-04-20 20:43:43 +08:00
|
|
|
|
2016-05-03 16:38:35 +08:00
|
|
|
int includeFixerMain(int argc, const char **argv) {
|
2016-04-27 22:24:32 +08:00
|
|
|
tooling::CommonOptionsParser options(argc, argv, IncludeFixerCategory);
|
|
|
|
tooling::ClangTool tool(options.getCompilations(),
|
|
|
|
options.getSourcePathList());
|
|
|
|
|
2016-05-04 16:22:35 +08:00
|
|
|
// Set up data source.
|
|
|
|
auto XrefsDBMgr = llvm::make_unique<include_fixer::XrefsDBManager>();
|
2016-04-27 22:24:32 +08:00
|
|
|
switch (DatabaseFormat) {
|
|
|
|
case fixed: {
|
|
|
|
// Parse input and fill the database with it.
|
|
|
|
// <symbol>=<header><, header...>
|
|
|
|
// Multiple symbols can be given, separated by semicolons.
|
|
|
|
std::map<std::string, std::vector<std::string>> XrefsMap;
|
|
|
|
SmallVector<StringRef, 4> SemicolonSplits;
|
|
|
|
StringRef(Input).split(SemicolonSplits, ";");
|
|
|
|
for (StringRef Pair : SemicolonSplits) {
|
|
|
|
auto Split = Pair.split('=');
|
|
|
|
std::vector<std::string> Headers;
|
|
|
|
SmallVector<StringRef, 4> CommaSplits;
|
|
|
|
Split.second.split(CommaSplits, ",");
|
|
|
|
for (StringRef Header : CommaSplits)
|
|
|
|
Headers.push_back(Header.trim());
|
|
|
|
XrefsMap[Split.first.trim()] = std::move(Headers);
|
|
|
|
}
|
2016-05-04 16:22:35 +08:00
|
|
|
XrefsDBMgr->addXrefsDB(
|
|
|
|
llvm::make_unique<include_fixer::InMemoryXrefsDB>(std::move(XrefsMap)));
|
2016-04-27 22:24:32 +08:00
|
|
|
break;
|
|
|
|
}
|
2016-04-29 17:23:38 +08:00
|
|
|
case yaml: {
|
2016-05-04 16:22:35 +08:00
|
|
|
XrefsDBMgr->addXrefsDB(
|
|
|
|
llvm::make_unique<include_fixer::YamlXrefsDB>(Input));
|
2016-04-29 17:23:38 +08:00
|
|
|
break;
|
|
|
|
}
|
2016-04-27 22:24:32 +08:00
|
|
|
}
|
2016-04-20 20:43:43 +08:00
|
|
|
|
|
|
|
// Now run our tool.
|
2016-04-27 22:24:32 +08:00
|
|
|
std::vector<tooling::Replacement> Replacements;
|
2016-05-04 16:22:35 +08:00
|
|
|
include_fixer::IncludeFixerActionFactory Factory(*XrefsDBMgr, Replacements,
|
2016-04-28 19:21:29 +08:00
|
|
|
MinimizeIncludePaths);
|
2016-04-20 20:43:43 +08:00
|
|
|
|
|
|
|
tool.run(&Factory); // Always succeeds.
|
|
|
|
|
|
|
|
// Set up a new source manager for applying the resulting replacements.
|
2016-04-27 22:24:32 +08:00
|
|
|
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
|
|
|
|
DiagnosticsEngine Diagnostics(new DiagnosticIDs, &*DiagOpts);
|
|
|
|
TextDiagnosticPrinter DiagnosticPrinter(outs(), &*DiagOpts);
|
|
|
|
SourceManager SM(Diagnostics, tool.getFiles());
|
2016-04-20 20:43:43 +08:00
|
|
|
Diagnostics.setClient(&DiagnosticPrinter, false);
|
|
|
|
|
|
|
|
// Write replacements to disk.
|
2016-04-27 22:24:32 +08:00
|
|
|
Rewriter Rewrites(SM, LangOptions());
|
|
|
|
tooling::applyAllReplacements(Replacements, Rewrites);
|
2016-04-20 20:43:43 +08:00
|
|
|
return Rewrites.overwriteChangedFiles();
|
|
|
|
}
|
2016-05-03 16:38:35 +08:00
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
int main(int argc, const char **argv) {
|
|
|
|
return includeFixerMain(argc, argv);
|
|
|
|
}
|