1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | #include "clang/AST/ASTConsumer.h" |
19 | #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" |
20 | #include "clang/Driver/Options.h" |
21 | #include "clang/Frontend/ASTConsumers.h" |
22 | #include "clang/Frontend/CompilerInstance.h" |
23 | #include "clang/Rewrite/Frontend/FixItRewriter.h" |
24 | #include "clang/Rewrite/Frontend/FrontendActions.h" |
25 | #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" |
26 | #include "clang/Tooling/CommonOptionsParser.h" |
27 | #include "clang/Tooling/Tooling.h" |
28 | #include "llvm/ADT/STLExtras.h" |
29 | #include "llvm/Option/OptTable.h" |
30 | #include "llvm/Support/Path.h" |
31 | #include "llvm/Support/Signals.h" |
32 | #include "llvm/Support/TargetSelect.h" |
33 | |
34 | using namespace clang::driver; |
35 | using namespace clang::tooling; |
36 | using namespace llvm; |
37 | |
38 | static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); |
39 | static cl::extrahelp MoreHelp( |
40 | "\tFor example, to run clang-check on all files in a subtree of the\n" |
41 | "\tsource tree, use:\n" |
42 | "\n" |
43 | "\t find path/in/subtree -name '*.cpp'|xargs clang-check\n" |
44 | "\n" |
45 | "\tor using a specific build path:\n" |
46 | "\n" |
47 | "\t find path/in/subtree -name '*.cpp'|xargs clang-check -p build/path\n" |
48 | "\n" |
49 | "\tNote, that path/in/subtree and current directory should follow the\n" |
50 | "\trules described above.\n" |
51 | "\n" |
52 | ); |
53 | |
54 | static cl::OptionCategory ClangCheckCategory("clang-check options"); |
55 | static std::unique_ptr<opt::OptTable> Options(createDriverOptTable()); |
56 | static cl::opt<bool> |
57 | ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)), |
58 | cl::cat(ClangCheckCategory)); |
59 | static cl::opt<bool> |
60 | ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)), |
61 | cl::cat(ClangCheckCategory)); |
62 | static cl::opt<bool> |
63 | ASTPrint("ast-print", |
64 | cl::desc(Options->getOptionHelpText(options::OPT_ast_print)), |
65 | cl::cat(ClangCheckCategory)); |
66 | static cl::opt<std::string> ASTDumpFilter( |
67 | "ast-dump-filter", |
68 | cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)), |
69 | cl::cat(ClangCheckCategory)); |
70 | static cl::opt<bool> |
71 | Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)), |
72 | cl::cat(ClangCheckCategory)); |
73 | |
74 | static cl::opt<bool> |
75 | Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)), |
76 | cl::cat(ClangCheckCategory)); |
77 | static cl::opt<bool> FixWhatYouCan( |
78 | "fix-what-you-can", |
79 | cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)), |
80 | cl::cat(ClangCheckCategory)); |
81 | |
82 | namespace { |
83 | |
84 | |
85 | |
86 | class FixItOptions : public clang::FixItOptions { |
87 | public: |
88 | FixItOptions() { |
89 | FixWhatYouCan = ::FixWhatYouCan; |
90 | } |
91 | |
92 | std::string RewriteFilename(const std::string& filename, int &fd) override { |
93 | (0) . __assert_fail ("llvm..sys..path..is_absolute(filename) && \"clang-fixit expects absolute paths only.\"", "/home/seafit/code_projects/clang_source/clang/tools/clang-check/ClangCheck.cpp", 94, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(llvm::sys::path::is_absolute(filename) && |
94 | (0) . __assert_fail ("llvm..sys..path..is_absolute(filename) && \"clang-fixit expects absolute paths only.\"", "/home/seafit/code_projects/clang_source/clang/tools/clang-check/ClangCheck.cpp", 94, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "clang-fixit expects absolute paths only."); |
95 | |
96 | |
97 | |
98 | |
99 | fd = -1; |
100 | |
101 | return filename; |
102 | } |
103 | }; |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | class FixItRewriter : public clang::FixItRewriter { |
111 | public: |
112 | FixItRewriter(clang::DiagnosticsEngine& Diags, |
113 | clang::SourceManager& SourceMgr, |
114 | const clang::LangOptions& LangOpts, |
115 | clang::FixItOptions* FixItOpts) |
116 | : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) { |
117 | } |
118 | |
119 | bool IncludeInDiagnosticCounts() const override { return false; } |
120 | }; |
121 | |
122 | |
123 | |
124 | class ClangCheckFixItAction : public clang::FixItAction { |
125 | public: |
126 | bool BeginSourceFileAction(clang::CompilerInstance& CI) override { |
127 | FixItOpts.reset(new FixItOptions); |
128 | Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), |
129 | CI.getLangOpts(), FixItOpts.get())); |
130 | return true; |
131 | } |
132 | }; |
133 | |
134 | class ClangCheckActionFactory { |
135 | public: |
136 | std::unique_ptr<clang::ASTConsumer> newASTConsumer() { |
137 | if (ASTList) |
138 | return clang::CreateASTDeclNodeLister(); |
139 | if (ASTDump) |
140 | return clang::CreateASTDumper(nullptr , |
141 | ASTDumpFilter, |
142 | , |
143 | , |
144 | ); |
145 | if (ASTPrint) |
146 | return clang::CreateASTPrinter(nullptr, ASTDumpFilter); |
147 | return llvm::make_unique<clang::ASTConsumer>(); |
148 | } |
149 | }; |
150 | |
151 | } |
152 | |
153 | int main(int argc, const char **argv) { |
154 | llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); |
155 | |
156 | |
157 | llvm::InitializeAllTargets(); |
158 | llvm::InitializeAllTargetMCs(); |
159 | llvm::InitializeAllAsmPrinters(); |
160 | llvm::InitializeAllAsmParsers(); |
161 | |
162 | CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory); |
163 | ClangTool Tool(OptionsParser.getCompilations(), |
164 | OptionsParser.getSourcePathList()); |
165 | |
166 | |
167 | Tool.clearArgumentsAdjusters(); |
168 | Tool.appendArgumentsAdjuster(getClangStripOutputAdjuster()); |
169 | Tool.appendArgumentsAdjuster(getClangStripDependencyFileAdjuster()); |
170 | |
171 | |
172 | |
173 | Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster( |
174 | Analyze ? "--analyze" : "-fsyntax-only", ArgumentInsertPosition::BEGIN)); |
175 | |
176 | ClangCheckActionFactory CheckFactory; |
177 | std::unique_ptr<FrontendActionFactory> FrontendFactory; |
178 | |
179 | |
180 | if (Analyze) |
181 | FrontendFactory = newFrontendActionFactory<clang::ento::AnalysisAction>(); |
182 | else if (Fixit) |
183 | FrontendFactory = newFrontendActionFactory<ClangCheckFixItAction>(); |
184 | else |
185 | FrontendFactory = newFrontendActionFactory(&CheckFactory); |
186 | |
187 | return Tool.run(FrontendFactory.get()); |
188 | } |
189 | |