1 //===-- tools/extra/clang-reorder-fields/tool/ClangReorderFields.cpp -*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains the implementation of clang-reorder-fields tool 11 /// 12 //===----------------------------------------------------------------------===// 13 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" 28 #include <cstdlib> 29 #include <string> 30 #include <system_error> 31 32 using namespace llvm; 33 using namespace clang; 34 35 cl::OptionCategory ClangReorderFieldsCategory("clang-reorder-fields options"); 36 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)); 41 42 static cl::list<std::string> FieldsOrder("fields-order", cl::CommaSeparated, 43 cl::OneOrMore, 44 cl::desc("The desired fields order."), 45 cl::cat(ClangReorderFieldsCategory)); 46 47 static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited files."), 48 cl::cat(ClangReorderFieldsCategory)); 49 50 const char Usage[] = "A tool to reorder fields in C/C++ structs/classes.\n"; 51 52 int main(int argc, const char **argv) { 53 tooling::CommonOptionsParser OP(argc, argv, ClangReorderFieldsCategory, 54 Usage); 55 56 auto Files = OP.getSourcePathList(); 57 tooling::RefactoringTool Tool(OP.getCompilations(), Files); 58 59 reorder_fields::ReorderFieldsAction Action(RecordName, FieldsOrder, 60 Tool.getReplacements()); 61 62 auto Factory = tooling::newFrontendActionFactory(&Action); 63 64 if (Inplace) 65 return Tool.runAndSave(Factory.get()); 66 67 int ExitCode = Tool.run(Factory.get()); 68 LangOptions DefaultLangOptions; 69 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions()); 70 TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts); 71 DiagnosticsEngine Diagnostics( 72 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts, 73 &DiagnosticPrinter, false); 74 75 auto &FileMgr = Tool.getFiles(); 76 SourceManager Sources(Diagnostics, FileMgr); 77 Rewriter Rewrite(Sources, DefaultLangOptions); 78 Tool.applyAllReplacements(Rewrite); 79 80 for (const auto &File : Files) { 81 const auto *Entry = FileMgr.getFile(File); 82 const auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User); 83 Rewrite.getEditBuffer(ID).write(outs()); 84 } 85 86 return ExitCode; 87 } 88