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