1bf3c84cfSAlexander Shaposhnikov //===-- tools/extra/clang-reorder-fields/tool/ClangReorderFields.cpp -*- C++ -*-===//
2bf3c84cfSAlexander Shaposhnikov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bf3c84cfSAlexander Shaposhnikov //
7bf3c84cfSAlexander Shaposhnikov //===----------------------------------------------------------------------===//
8bf3c84cfSAlexander Shaposhnikov ///
9bf3c84cfSAlexander Shaposhnikov /// \file
10bf3c84cfSAlexander Shaposhnikov /// This file contains the implementation of clang-reorder-fields tool
11bf3c84cfSAlexander Shaposhnikov ///
12bf3c84cfSAlexander Shaposhnikov //===----------------------------------------------------------------------===//
13bf3c84cfSAlexander Shaposhnikov
14bf3c84cfSAlexander Shaposhnikov #include "../ReorderFieldsAction.h"
15bf3c84cfSAlexander Shaposhnikov #include "clang/Basic/Diagnostic.h"
16bf3c84cfSAlexander Shaposhnikov #include "clang/Basic/DiagnosticOptions.h"
17bf3c84cfSAlexander Shaposhnikov #include "clang/Basic/FileManager.h"
18bf3c84cfSAlexander Shaposhnikov #include "clang/Basic/LangOptions.h"
19bf3c84cfSAlexander Shaposhnikov #include "clang/Basic/SourceManager.h"
20bf3c84cfSAlexander Shaposhnikov #include "clang/Frontend/TextDiagnosticPrinter.h"
21bf3c84cfSAlexander Shaposhnikov #include "clang/Rewrite/Core/Rewriter.h"
22bf3c84cfSAlexander Shaposhnikov #include "clang/Tooling/CommonOptionsParser.h"
23bf3c84cfSAlexander Shaposhnikov #include "clang/Tooling/Refactoring.h"
24bf3c84cfSAlexander Shaposhnikov #include "clang/Tooling/Tooling.h"
25bf3c84cfSAlexander Shaposhnikov #include "llvm/ADT/IntrusiveRefCntPtr.h"
26bf3c84cfSAlexander Shaposhnikov #include "llvm/Support/CommandLine.h"
27bf3c84cfSAlexander Shaposhnikov #include "llvm/Support/FileSystem.h"
28bf3c84cfSAlexander Shaposhnikov #include <cstdlib>
29bf3c84cfSAlexander Shaposhnikov #include <string>
30bf3c84cfSAlexander Shaposhnikov #include <system_error>
31bf3c84cfSAlexander Shaposhnikov
32bf3c84cfSAlexander Shaposhnikov using namespace llvm;
33bf3c84cfSAlexander Shaposhnikov using namespace clang;
34bf3c84cfSAlexander Shaposhnikov
35bf3c84cfSAlexander Shaposhnikov cl::OptionCategory ClangReorderFieldsCategory("clang-reorder-fields options");
36bf3c84cfSAlexander Shaposhnikov
37bf3c84cfSAlexander Shaposhnikov static cl::opt<std::string>
38bf3c84cfSAlexander Shaposhnikov RecordName("record-name", cl::Required,
39bf3c84cfSAlexander Shaposhnikov cl::desc("The name of the struct/class."),
40bf3c84cfSAlexander Shaposhnikov cl::cat(ClangReorderFieldsCategory));
41bf3c84cfSAlexander Shaposhnikov
42bf3c84cfSAlexander Shaposhnikov static cl::list<std::string> FieldsOrder("fields-order", cl::CommaSeparated,
43bf3c84cfSAlexander Shaposhnikov cl::OneOrMore,
44bf3c84cfSAlexander Shaposhnikov cl::desc("The desired fields order."),
45bf3c84cfSAlexander Shaposhnikov cl::cat(ClangReorderFieldsCategory));
46bf3c84cfSAlexander Shaposhnikov
47bf3c84cfSAlexander Shaposhnikov static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited files."),
48bf3c84cfSAlexander Shaposhnikov cl::cat(ClangReorderFieldsCategory));
49bf3c84cfSAlexander Shaposhnikov
50bf3c84cfSAlexander Shaposhnikov const char Usage[] = "A tool to reorder fields in C/C++ structs/classes.\n";
51bf3c84cfSAlexander Shaposhnikov
main(int argc,const char ** argv)52bf3c84cfSAlexander Shaposhnikov int main(int argc, const char **argv) {
53d47ee525Sserge-sans-paille auto ExpectedParser = tooling::CommonOptionsParser::create(
54d47ee525Sserge-sans-paille argc, argv, ClangReorderFieldsCategory, cl::OneOrMore, Usage);
55d47ee525Sserge-sans-paille if (!ExpectedParser) {
56d47ee525Sserge-sans-paille llvm::errs() << ExpectedParser.takeError();
57d47ee525Sserge-sans-paille return 1;
58d47ee525Sserge-sans-paille }
59d47ee525Sserge-sans-paille
60d47ee525Sserge-sans-paille tooling::CommonOptionsParser &OP = ExpectedParser.get();
61bf3c84cfSAlexander Shaposhnikov
62bf3c84cfSAlexander Shaposhnikov auto Files = OP.getSourcePathList();
63bf3c84cfSAlexander Shaposhnikov tooling::RefactoringTool Tool(OP.getCompilations(), Files);
64bf3c84cfSAlexander Shaposhnikov
65bf3c84cfSAlexander Shaposhnikov reorder_fields::ReorderFieldsAction Action(RecordName, FieldsOrder,
66bf3c84cfSAlexander Shaposhnikov Tool.getReplacements());
67bf3c84cfSAlexander Shaposhnikov
68bf3c84cfSAlexander Shaposhnikov auto Factory = tooling::newFrontendActionFactory(&Action);
69bf3c84cfSAlexander Shaposhnikov
70bf3c84cfSAlexander Shaposhnikov if (Inplace)
71bf3c84cfSAlexander Shaposhnikov return Tool.runAndSave(Factory.get());
72bf3c84cfSAlexander Shaposhnikov
73bf3c84cfSAlexander Shaposhnikov int ExitCode = Tool.run(Factory.get());
74bf3c84cfSAlexander Shaposhnikov LangOptions DefaultLangOptions;
75bf3c84cfSAlexander Shaposhnikov IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions());
76bf3c84cfSAlexander Shaposhnikov TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
77bf3c84cfSAlexander Shaposhnikov DiagnosticsEngine Diagnostics(
78bf3c84cfSAlexander Shaposhnikov IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
79bf3c84cfSAlexander Shaposhnikov &DiagnosticPrinter, false);
80bf3c84cfSAlexander Shaposhnikov
81bf3c84cfSAlexander Shaposhnikov auto &FileMgr = Tool.getFiles();
82bf3c84cfSAlexander Shaposhnikov SourceManager Sources(Diagnostics, FileMgr);
83bf3c84cfSAlexander Shaposhnikov Rewriter Rewrite(Sources, DefaultLangOptions);
84bf3c84cfSAlexander Shaposhnikov Tool.applyAllReplacements(Rewrite);
85bf3c84cfSAlexander Shaposhnikov
86bf3c84cfSAlexander Shaposhnikov for (const auto &File : Files) {
87*27254ae5SJan Svoboda auto Entry = llvm::cantFail(FileMgr.getFileRef(File));
88*27254ae5SJan Svoboda const auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User);
89e4920c6fSAlexander Shaposhnikov Rewrite.getEditBuffer(ID).write(outs());
90bf3c84cfSAlexander Shaposhnikov }
91bf3c84cfSAlexander Shaposhnikov
92bf3c84cfSAlexander Shaposhnikov return ExitCode;
93bf3c84cfSAlexander Shaposhnikov }
94