|
20 | 20 | #include "ClangTidyModuleRegistry.h"
|
21 | 21 | #include "ClangTidyProfiling.h"
|
22 | 22 | #include "ExpandModularHeadersPPCallbacks.h"
|
| 23 | +#ifndef CLANG_TIDY_CONFIG_H |
23 | 24 | #include "clang-tidy-config.h"
|
| 25 | +#endif |
24 | 26 | #include "utils/OptionsUtils.h"
|
25 | 27 | #include "clang/AST/ASTConsumer.h"
|
26 | 28 | #include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
49 | 51 | #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
|
50 | 52 | #endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER
|
51 | 53 |
|
52 |
| -#if CLANG_ENABLE_CIR |
53 |
| -#include "mlir/IR/BuiltinOps.h" |
54 |
| -#include "mlir/IR/MLIRContext.h" |
55 |
| -#include "mlir/Pass/Pass.h" |
56 |
| -#include "mlir/Pass/PassManager.h" |
57 |
| -#include "clang/AST/ASTContext.h" |
58 |
| -#include "clang/CIR/CIRGenerator.h" |
59 |
| -#include "clang/CIR/Dialect/Passes.h" |
60 |
| -#include <algorithm> |
61 |
| -#endif // CLANG_ENABLE_CIR |
62 |
| - |
63 | 54 | using namespace clang::ast_matchers;
|
64 | 55 | using namespace clang::driver;
|
65 | 56 | using namespace clang::tooling;
|
@@ -104,205 +95,6 @@ class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
|
104 | 95 | };
|
105 | 96 | #endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER
|
106 | 97 |
|
107 |
| -#if CLANG_ENABLE_CIR |
108 |
| -namespace cir { |
109 |
| - |
110 |
| -constexpr const char *LifetimeCheckName = "cir-lifetime-check"; |
111 |
| -struct CIROpts { |
112 |
| - std::vector<StringRef> RemarksList; |
113 |
| - std::vector<StringRef> HistoryList; |
114 |
| - unsigned HistLimit; |
115 |
| -}; |
116 |
| - |
117 |
| -static const char StringsDelimiter[] = ";"; |
118 |
| - |
119 |
| -// FIXME(cir): this function was extracted from clang::tidy::utils::options |
120 |
| -// given that ClangTidy.cpp cannot be linked with ClangTidyUtils. |
121 |
| -std::vector<StringRef> parseStringList(StringRef Option) { |
122 |
| - Option = Option.trim().trim(StringsDelimiter); |
123 |
| - if (Option.empty()) |
124 |
| - return {}; |
125 |
| - std::vector<StringRef> Result; |
126 |
| - Result.reserve(Option.count(StringsDelimiter) + 1); |
127 |
| - StringRef Cur; |
128 |
| - while (std::tie(Cur, Option) = Option.split(StringsDelimiter), |
129 |
| - !Option.empty()) { |
130 |
| - Cur = Cur.trim(); |
131 |
| - if (!Cur.empty()) |
132 |
| - Result.push_back(Cur); |
133 |
| - } |
134 |
| - Cur = Cur.trim(); |
135 |
| - if (!Cur.empty()) |
136 |
| - Result.push_back(Cur); |
137 |
| - return Result; |
138 |
| -} |
139 |
| - |
140 |
| -class CIRASTConsumer : public ASTConsumer { |
141 |
| -public: |
142 |
| - CIRASTConsumer(CompilerInstance &CI, StringRef inputFile, |
143 |
| - clang::tidy::ClangTidyContext &Context, CIROpts &cirOpts); |
144 |
| - |
145 |
| -private: |
146 |
| - void Initialize(ASTContext &Context) override; |
147 |
| - void HandleTranslationUnit(ASTContext &C) override; |
148 |
| - bool HandleTopLevelDecl(DeclGroupRef D) override; |
149 |
| - std::unique_ptr<::cir::CIRGenerator> Gen; |
150 |
| - ASTContext *AstContext{nullptr}; |
151 |
| - clang::tidy::ClangTidyContext &Context; |
152 |
| - CIROpts cirOpts; |
153 |
| -}; |
154 |
| - |
155 |
| -/// CIR AST Consumer |
156 |
| -CIRASTConsumer::CIRASTConsumer(CompilerInstance &CI, StringRef inputFile, |
157 |
| - clang::tidy::ClangTidyContext &Context, |
158 |
| - CIROpts &O) |
159 |
| - : Context(Context), cirOpts(O) { |
160 |
| - Gen = std::make_unique<::cir::CIRGenerator>(CI.getDiagnostics(), nullptr, |
161 |
| - CI.getCodeGenOpts()); |
162 |
| -} |
163 |
| - |
164 |
| -bool CIRASTConsumer::HandleTopLevelDecl(DeclGroupRef D) { |
165 |
| - PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), |
166 |
| - AstContext->getSourceManager(), |
167 |
| - "CIR generation of declaration"); |
168 |
| - Gen->HandleTopLevelDecl(D); |
169 |
| - return true; |
170 |
| -} |
171 |
| - |
172 |
| -void CIRASTConsumer::Initialize(ASTContext &Context) { |
173 |
| - AstContext = &Context; |
174 |
| - Gen->Initialize(Context); |
175 |
| -} |
176 |
| - |
177 |
| -void CIRASTConsumer::HandleTranslationUnit(ASTContext &C) { |
178 |
| - Gen->HandleTranslationUnit(C); |
179 |
| - Gen->verifyModule(); |
180 |
| - |
181 |
| - mlir::ModuleOp mlirMod = Gen->getModule(); |
182 |
| - std::unique_ptr<mlir::MLIRContext> mlirCtx = Gen->takeContext(); |
183 |
| - |
184 |
| - mlir::OpPrintingFlags flags; |
185 |
| - flags.enableDebugInfo(/*prettyForm=*/false); |
186 |
| - |
187 |
| - clang::SourceManager &clangSrcMgr = C.getSourceManager(); |
188 |
| - FileID MainFileID = clangSrcMgr.getMainFileID(); |
189 |
| - |
190 |
| - llvm::MemoryBufferRef MainFileBuf = clangSrcMgr.getBufferOrFake(MainFileID); |
191 |
| - std::unique_ptr<llvm::MemoryBuffer> FileBuf = |
192 |
| - llvm::MemoryBuffer::getMemBuffer(MainFileBuf); |
193 |
| - |
194 |
| - llvm::SourceMgr llvmSrcMgr; |
195 |
| - llvmSrcMgr.AddNewSourceBuffer(std::move(FileBuf), llvm::SMLoc()); |
196 |
| - |
197 |
| - class CIRTidyDiagnosticHandler : public mlir::SourceMgrDiagnosticHandler { |
198 |
| - clang::tidy::ClangTidyContext &tidyCtx; |
199 |
| - clang::SourceManager &clangSrcMgr; |
200 |
| - |
201 |
| - clang::SourceLocation getClangFromFileLineCol(mlir::FileLineColLoc loc) { |
202 |
| - clang::SourceLocation clangLoc; |
203 |
| - FileManager &fileMgr = clangSrcMgr.getFileManager(); |
204 |
| - assert(loc && "not a valid mlir::FileLineColLoc"); |
205 |
| - // The column and line may be zero to represent unknown column and/or |
206 |
| - // unknown line/column information. |
207 |
| - if (loc.getLine() == 0 || loc.getColumn() == 0) { |
208 |
| - llvm_unreachable("How should we workaround this?"); |
209 |
| - return clangLoc; |
210 |
| - } |
211 |
| - if (auto FE = fileMgr.getFile(loc.getFilename())) { |
212 |
| - return clangSrcMgr.translateFileLineCol(*FE, loc.getLine(), |
213 |
| - loc.getColumn()); |
214 |
| - } |
215 |
| - llvm_unreachable("location doesn't map to a file?"); |
216 |
| - } |
217 |
| - |
218 |
| - clang::SourceLocation getClangSrcLoc(mlir::Location loc) { |
219 |
| - // Direct maps into a clang::SourceLocation. |
220 |
| - if (auto fileLoc = loc.dyn_cast<mlir::FileLineColLoc>()) { |
221 |
| - return getClangFromFileLineCol(fileLoc); |
222 |
| - } |
223 |
| - |
224 |
| - // FusedLoc needs to be decomposed but the canonical one |
225 |
| - // is the first location, we handle source ranges somewhere |
226 |
| - // else. |
227 |
| - if (auto fileLoc = loc.dyn_cast<mlir::FusedLoc>()) { |
228 |
| - auto locArray = fileLoc.getLocations(); |
229 |
| - assert(locArray.size() > 0 && "expected multiple locs"); |
230 |
| - return getClangFromFileLineCol( |
231 |
| - locArray[0].dyn_cast<mlir::FileLineColLoc>()); |
232 |
| - } |
233 |
| - |
234 |
| - // Many loc styles are yet to be handled. |
235 |
| - if (auto fileLoc = loc.dyn_cast<mlir::UnknownLoc>()) { |
236 |
| - llvm_unreachable("mlir::UnknownLoc not implemented!"); |
237 |
| - } |
238 |
| - if (auto fileLoc = loc.dyn_cast<mlir::CallSiteLoc>()) { |
239 |
| - llvm_unreachable("mlir::CallSiteLoc not implemented!"); |
240 |
| - } |
241 |
| - llvm_unreachable("Unknown location style"); |
242 |
| - } |
243 |
| - |
244 |
| - clang::DiagnosticIDs::Level |
245 |
| - translateToClangDiagLevel(const mlir::DiagnosticSeverity &sev) { |
246 |
| - switch (sev) { |
247 |
| - case mlir::DiagnosticSeverity::Note: |
248 |
| - return clang::DiagnosticIDs::Level::Note; |
249 |
| - case mlir::DiagnosticSeverity::Warning: |
250 |
| - return clang::DiagnosticIDs::Level::Warning; |
251 |
| - case mlir::DiagnosticSeverity::Error: |
252 |
| - return clang::DiagnosticIDs::Level::Error; |
253 |
| - case mlir::DiagnosticSeverity::Remark: |
254 |
| - return clang::DiagnosticIDs::Level::Remark; |
255 |
| - } |
256 |
| - llvm_unreachable("should not get here!"); |
257 |
| - } |
258 |
| - |
259 |
| - public: |
260 |
| - void emitClangTidyDiagnostic(mlir::Diagnostic &diag) { |
261 |
| - auto clangBeginLoc = getClangSrcLoc(diag.getLocation()); |
262 |
| - tidyCtx.diag(LifetimeCheckName, clangBeginLoc, diag.str(), |
263 |
| - translateToClangDiagLevel(diag.getSeverity())); |
264 |
| - for (const auto ¬e : diag.getNotes()) { |
265 |
| - auto clangNoteBeginLoc = getClangSrcLoc(note.getLocation()); |
266 |
| - tidyCtx.diag(LifetimeCheckName, clangNoteBeginLoc, note.str(), |
267 |
| - translateToClangDiagLevel(note.getSeverity())); |
268 |
| - } |
269 |
| - } |
270 |
| - |
271 |
| - CIRTidyDiagnosticHandler(llvm::SourceMgr &mgr, mlir::MLIRContext *ctx, |
272 |
| - clang::tidy::ClangTidyContext &tidyContext, |
273 |
| - clang::SourceManager &clangMgr, |
274 |
| - ShouldShowLocFn &&shouldShowLocFn = {}) |
275 |
| - : SourceMgrDiagnosticHandler(mgr, ctx, llvm::errs(), |
276 |
| - std::move(shouldShowLocFn)), |
277 |
| - tidyCtx(tidyContext), clangSrcMgr(clangMgr) { |
278 |
| - setHandler( |
279 |
| - [this](mlir::Diagnostic &diag) { emitClangTidyDiagnostic(diag); }); |
280 |
| - } |
281 |
| - ~CIRTidyDiagnosticHandler() = default; |
282 |
| - }; |
283 |
| - |
284 |
| - // Use a custom diagnostic handler that can allow both regular printing to |
285 |
| - // stderr but also populates clang-tidy context with diagnostics (and allow |
286 |
| - // for instance, diagnostics to be later converted to YAML). |
287 |
| - CIRTidyDiagnosticHandler sourceMgrHandler(llvmSrcMgr, mlirCtx.get(), Context, |
288 |
| - clangSrcMgr); |
289 |
| - |
290 |
| - mlir::PassManager pm(mlirCtx.get()); |
291 |
| - pm.addPass(mlir::createMergeCleanupsPass()); |
292 |
| - |
293 |
| - if (Context.isCheckEnabled(LifetimeCheckName)) |
294 |
| - pm.addPass(mlir::createLifetimeCheckPass( |
295 |
| - cirOpts.RemarksList, cirOpts.HistoryList, cirOpts.HistLimit, &C)); |
296 |
| - |
297 |
| - bool Result = !mlir::failed(pm.run(mlirMod)); |
298 |
| - if (!Result) |
299 |
| - llvm::report_fatal_error( |
300 |
| - "The pass manager failed to run pass on the module!"); |
301 |
| -} |
302 |
| -} // namespace cir |
303 |
| - |
304 |
| -#endif |
305 |
| - |
306 | 98 | class ErrorReporter {
|
307 | 99 | public:
|
308 | 100 | ErrorReporter(ClangTidyContext &Context, FixBehaviour ApplyFixes,
|
@@ -661,27 +453,6 @@ ClangTidyASTConsumerFactory::createASTConsumer(
|
661 | 453 | }
|
662 | 454 | #endif // CLANG_TIDY_ENABLE_STATIC_ANALYZER
|
663 | 455 |
|
664 |
| -#if CLANG_ENABLE_CIR |
665 |
| - if (Context.isCheckEnabled(cir::LifetimeCheckName)) { |
666 |
| - auto OV = ClangTidyCheck::OptionsView( |
667 |
| - cir::LifetimeCheckName, Context.getOptions().CheckOptions, &Context); |
668 |
| - // Setup CIR codegen options via config specified information. |
669 |
| - Compiler.getCodeGenOpts().ClangIRBuildDeferredThreshold = |
670 |
| - OV.get("CodeGenBuildDeferredThreshold", 500U); |
671 |
| - Compiler.getCodeGenOpts().ClangIRSkipFunctionsFromSystemHeaders = |
672 |
| - OV.get("CodeGenSkipFunctionsFromSystemHeaders", false); |
673 |
| - |
674 |
| - cir::CIROpts opts; |
675 |
| - opts.RemarksList = cir::parseStringList(OV.get("RemarksList", "")); |
676 |
| - opts.HistoryList = cir::parseStringList(OV.get("HistoryList", "all")); |
677 |
| - opts.HistLimit = OV.get("HistLimit", 1U); |
678 |
| - |
679 |
| - std::unique_ptr<cir::CIRASTConsumer> CIRConsumer = |
680 |
| - std::make_unique<cir::CIRASTConsumer>(Compiler, File, Context, opts); |
681 |
| - Consumers.push_back(std::move(CIRConsumer)); |
682 |
| - } |
683 |
| -#endif // CLANG_ENABLE_CIR |
684 |
| - |
685 | 456 | return std::make_unique<ClangTidyASTConsumer>(
|
686 | 457 | std::move(Consumers), std::move(Profiling), std::move(Finder),
|
687 | 458 | std::move(Checks));
|
|
0 commit comments