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