clang-tools  3.9.0
ClangTidy.cpp
Go to the documentation of this file.
1 //===--- tools/extra/clang-tidy/ClangTidy.cpp - Clang tidy tool -----------===//
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 This file implements a clang-tidy tool.
11 ///
12 /// This tool uses the Clang Tooling infrastructure, see
13 /// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
14 /// for details on setting it up with LLVM source tree.
15 ///
16 //===----------------------------------------------------------------------===//
17 
18 #include "ClangTidy.h"
21 #include "clang/AST/ASTConsumer.h"
22 #include "clang/AST/ASTContext.h"
23 #include "clang/AST/Decl.h"
24 #include "clang/ASTMatchers/ASTMatchFinder.h"
25 #include "clang/Frontend/ASTConsumers.h"
26 #include "clang/Frontend/CompilerInstance.h"
27 #include "clang/Frontend/FrontendActions.h"
28 #include "clang/Frontend/FrontendDiagnostic.h"
29 #include "clang/Frontend/MultiplexConsumer.h"
30 #include "clang/Frontend/TextDiagnosticPrinter.h"
31 #include "clang/Lex/PPCallbacks.h"
32 #include "clang/Lex/Preprocessor.h"
33 #include "clang/Rewrite/Frontend/FixItRewriter.h"
34 #include "clang/Rewrite/Frontend/FrontendActions.h"
35 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
36 #include "clang/Tooling/Refactoring.h"
37 #include "clang/Tooling/ReplacementsYaml.h"
38 #include "clang/Tooling/Tooling.h"
39 #include "llvm/Support/Process.h"
40 #include "llvm/Support/Signals.h"
41 #include <algorithm>
42 #include <utility>
43 
44 using namespace clang::ast_matchers;
45 using namespace clang::driver;
46 using namespace clang::tooling;
47 using namespace llvm;
48 
49 template class llvm::Registry<clang::tidy::ClangTidyModule>;
50 
51 namespace clang {
52 namespace tidy {
53 
54 namespace {
55 static const char *AnalyzerCheckNamePrefix = "clang-analyzer-";
56 
57 static const StringRef StaticAnalyzerChecks[] = {
58 #define GET_CHECKERS
59 #define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN) \
60  FULLNAME,
61 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
62 #undef CHECKER
63 #undef GET_CHECKERS
64 };
65 
66 class AnalyzerDiagnosticConsumer : public ento::PathDiagnosticConsumer {
67 public:
68  AnalyzerDiagnosticConsumer(ClangTidyContext &Context) : Context(Context) {}
69 
70  void FlushDiagnosticsImpl(std::vector<const ento::PathDiagnostic *> &Diags,
71  FilesMade *filesMade) override {
72  for (const ento::PathDiagnostic *PD : Diags) {
73  SmallString<64> CheckName(AnalyzerCheckNamePrefix);
74  CheckName += PD->getCheckName();
75  Context.diag(CheckName, PD->getLocation().asLocation(),
76  PD->getShortDescription())
77  << PD->path.back()->getRanges();
78 
79  for (const auto &DiagPiece :
80  PD->path.flatten(/*ShouldFlattenMacros=*/true)) {
81  Context.diag(CheckName, DiagPiece->getLocation().asLocation(),
82  DiagPiece->getString(), DiagnosticIDs::Note)
83  << DiagPiece->getRanges();
84  }
85  }
86  }
87 
88  StringRef getName() const override { return "ClangTidyDiags"; }
89  bool supportsLogicalOpControlFlow() const override { return true; }
90  bool supportsCrossFileDiagnostics() const override { return true; }
91 
92 private:
93  ClangTidyContext &Context;
94 };
95 
96 class ErrorReporter {
97 public:
98  ErrorReporter(bool ApplyFixes)
99  : Files(FileSystemOptions()), DiagOpts(new DiagnosticOptions()),
100  DiagPrinter(new TextDiagnosticPrinter(llvm::outs(), &*DiagOpts)),
101  Diags(IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts,
102  DiagPrinter),
104  ApplyFixes(ApplyFixes), TotalFixes(0), AppliedFixes(0),
105  WarningsAsErrors(0) {
106  DiagOpts->ShowColors = llvm::sys::Process::StandardOutHasColors();
107  DiagPrinter->BeginSourceFile(LangOpts);
108  }
109 
110  SourceManager &getSourceManager() { return SourceMgr; }
111 
112  void reportDiagnostic(const ClangTidyError &Error) {
113  const ClangTidyMessage &Message = Error.Message;
114  SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
115  // Contains a pair for each attempted fix: location and whether the fix was
116  // applied successfully.
117  SmallVector<std::pair<SourceLocation, bool>, 4> FixLocations;
118  {
119  auto Level = static_cast<DiagnosticsEngine::Level>(Error.DiagLevel);
120  std::string Name = Error.CheckName;
121  if (Error.IsWarningAsError) {
122  Name += ",-warnings-as-errors";
123  Level = DiagnosticsEngine::Error;
125  }
126  auto Diag = Diags.Report(Loc, Diags.getCustomDiagID(Level, "%0 [%1]"))
127  << Message.Message << Name;
128  for (const tooling::Replacement &Fix : Error.Fix) {
129  // Retrieve the source range for applicable fixes. Macro definitions
130  // on the command line have locations in a virtual buffer and don't
131  // have valid file paths and are therefore not applicable.
132  SourceRange Range;
133  SourceLocation FixLoc;
134  if (Fix.isApplicable()) {
135  SmallString<128> FixAbsoluteFilePath = Fix.getFilePath();
136  Files.makeAbsolutePath(FixAbsoluteFilePath);
137  FixLoc = getLocation(FixAbsoluteFilePath, Fix.getOffset());
138  SourceLocation FixEndLoc = FixLoc.getLocWithOffset(Fix.getLength());
139  Range = SourceRange(FixLoc, FixEndLoc);
140  Diag << FixItHint::CreateReplacement(Range, Fix.getReplacementText());
141  }
142 
143  ++TotalFixes;
144  if (ApplyFixes) {
145  bool Success = Fix.isApplicable() && Fix.apply(Rewrite);
146  if (Success)
147  ++AppliedFixes;
148  FixLocations.push_back(std::make_pair(FixLoc, Success));
149  }
150  }
151  }
152  for (auto Fix : FixLocations) {
153  Diags.Report(Fix.first, Fix.second ? diag::note_fixit_applied
154  : diag::note_fixit_failed);
155  }
156  for (const ClangTidyMessage &Note : Error.Notes)
157  reportNote(Note);
158  }
159 
160  void Finish() {
161  // FIXME: Run clang-format on changes.
162  if (ApplyFixes && TotalFixes > 0) {
163  llvm::errs() << "clang-tidy applied " << AppliedFixes << " of "
164  << TotalFixes << " suggested fixes.\n";
165  Rewrite.overwriteChangedFiles();
166  }
167  }
168 
169  unsigned getWarningsAsErrorsCount() const { return WarningsAsErrors; }
170 
171 private:
172  SourceLocation getLocation(StringRef FilePath, unsigned Offset) {
173  if (FilePath.empty())
174  return SourceLocation();
175 
176  const FileEntry *File = SourceMgr.getFileManager().getFile(FilePath);
177  FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
178  return SourceMgr.getLocForStartOfFile(ID).getLocWithOffset(Offset);
179  }
180 
181  void reportNote(const ClangTidyMessage &Message) {
182  SourceLocation Loc = getLocation(Message.FilePath, Message.FileOffset);
183  DiagnosticBuilder Diag =
184  Diags.Report(Loc, Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
185  << Message.Message;
186  }
187 
188  FileManager Files;
189  LangOptions LangOpts; // FIXME: use langopts from each original file
190  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
192  DiagnosticsEngine Diags;
193  SourceManager SourceMgr;
194  Rewriter Rewrite;
196  unsigned TotalFixes;
197  unsigned AppliedFixes;
199 };
200 
201 class ClangTidyASTConsumer : public MultiplexConsumer {
202 public:
203  ClangTidyASTConsumer(std::vector<std::unique_ptr<ASTConsumer>> Consumers,
204  std::unique_ptr<ast_matchers::MatchFinder> Finder,
205  std::vector<std::unique_ptr<ClangTidyCheck>> Checks)
206  : MultiplexConsumer(std::move(Consumers)), Finder(std::move(Finder)),
207  Checks(std::move(Checks)) {}
208 
209 private:
210  std::unique_ptr<ast_matchers::MatchFinder> Finder;
211  std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
212 };
213 
214 } // namespace
215 
216 ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory(
218  : Context(Context), CheckFactories(new ClangTidyCheckFactories) {
219  for (ClangTidyModuleRegistry::iterator I = ClangTidyModuleRegistry::begin(),
220  E = ClangTidyModuleRegistry::end();
221  I != E; ++I) {
222  std::unique_ptr<ClangTidyModule> Module(I->instantiate());
223  Module->addCheckFactories(*CheckFactories);
224  }
225 }
226 
228  AnalyzerOptionsRef AnalyzerOptions) {
229  StringRef AnalyzerPrefix(AnalyzerCheckNamePrefix);
230  for (const auto &Opt : Opts.CheckOptions) {
231  StringRef OptName(Opt.first);
232  if (!OptName.startswith(AnalyzerPrefix))
233  continue;
234  AnalyzerOptions->Config[OptName.substr(AnalyzerPrefix.size())] = Opt.second;
235  }
236 }
237 
238 std::unique_ptr<clang::ASTConsumer>
240  clang::CompilerInstance &Compiler, StringRef File) {
241  // FIXME: Move this to a separate method, so that CreateASTConsumer doesn't
242  // modify Compiler.
243  Context.setSourceManager(&Compiler.getSourceManager());
244  Context.setCurrentFile(File);
245  Context.setASTContext(&Compiler.getASTContext());
246 
247  auto WorkingDir = Compiler.getSourceManager()
248  .getFileManager()
249  .getVirtualFileSystem()
250  ->getCurrentWorkingDirectory();
251  if (WorkingDir)
252  Context.setCurrentBuildDirectory(WorkingDir.get());
253 
254  std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
255  CheckFactories->createChecks(&Context, Checks);
256 
257  ast_matchers::MatchFinder::MatchFinderOptions FinderOptions;
258  if (auto *P = Context.getCheckProfileData())
259  FinderOptions.CheckProfiling.emplace(P->Records);
260 
261  std::unique_ptr<ast_matchers::MatchFinder> Finder(
262  new ast_matchers::MatchFinder(std::move(FinderOptions)));
263 
264  for (auto &Check : Checks) {
265  Check->registerMatchers(&*Finder);
266  Check->registerPPCallbacks(Compiler);
267  }
268 
269  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
270  if (!Checks.empty())
271  Consumers.push_back(Finder->newASTConsumer());
272 
273  AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
274  // FIXME: Remove this option once clang's cfg-temporary-dtors option defaults
275  // to true.
276  AnalyzerOptions->Config["cfg-temporary-dtors"] =
277  Context.getOptions().AnalyzeTemporaryDtors ? "true" : "false";
278 
279  GlobList &Filter = Context.getChecksFilter();
280  AnalyzerOptions->CheckersControlList = getCheckersControlList(Filter);
281  if (!AnalyzerOptions->CheckersControlList.empty()) {
282  setStaticAnalyzerCheckerOpts(Context.getOptions(), AnalyzerOptions);
283  AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
284  AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
285  AnalyzerOptions->AnalyzeNestedBlocks = true;
286  AnalyzerOptions->eagerlyAssumeBinOpBifurcation = true;
287  std::unique_ptr<ento::AnalysisASTConsumer> AnalysisConsumer =
288  ento::CreateAnalysisConsumer(Compiler);
289  AnalysisConsumer->AddDiagnosticConsumer(
290  new AnalyzerDiagnosticConsumer(Context));
291  Consumers.push_back(std::move(AnalysisConsumer));
292  }
293  return llvm::make_unique<ClangTidyASTConsumer>(
294  std::move(Consumers), std::move(Finder), std::move(Checks));
295 }
296 
297 std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
298  std::vector<std::string> CheckNames;
299  GlobList &Filter = Context.getChecksFilter();
300  for (const auto &CheckFactory : *CheckFactories) {
301  if (Filter.contains(CheckFactory.first))
302  CheckNames.push_back(CheckFactory.first);
303  }
304 
305  for (const auto &AnalyzerCheck : getCheckersControlList(Filter))
306  CheckNames.push_back(AnalyzerCheckNamePrefix + AnalyzerCheck.first);
307 
308  std::sort(CheckNames.begin(), CheckNames.end());
309  return CheckNames;
310 }
311 
314  std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
315  CheckFactories->createChecks(&Context, Checks);
316  for (const auto &Check : Checks)
317  Check->storeOptions(Options);
318  return Options;
319 }
320 
321 ClangTidyASTConsumerFactory::CheckersList
322 ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
323  CheckersList List;
324 
325  bool AnalyzerChecksEnabled = false;
326  for (StringRef CheckName : StaticAnalyzerChecks) {
327  std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
328  AnalyzerChecksEnabled =
329  AnalyzerChecksEnabled ||
330  (!CheckName.startswith("debug") && Filter.contains(Checker));
331  }
332 
333  if (AnalyzerChecksEnabled) {
334  // Run our regex against all possible static analyzer checkers. Note that
335  // debug checkers print values / run programs to visualize the CFG and are
336  // thus not applicable to clang-tidy in general.
337  //
338  // Always add all core checkers if any other static analyzer checks are
339  // enabled. This is currently necessary, as other path sensitive checks
340  // rely on the core checkers.
341  for (StringRef CheckName : StaticAnalyzerChecks) {
342  std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
343 
344  if (CheckName.startswith("core") ||
345  (!CheckName.startswith("debug") && Filter.contains(Checker)))
346  List.push_back(std::make_pair(CheckName, true));
347  }
348  }
349  return List;
350 }
351 
352 DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message,
353  DiagnosticIDs::Level Level) {
354  return Context->diag(CheckName, Loc, Message, Level);
355 }
356 
357 void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) {
358  Context->setSourceManager(Result.SourceManager);
359  check(Result);
360 }
361 
362 OptionsView::OptionsView(StringRef CheckName,
363  const ClangTidyOptions::OptionMap &CheckOptions)
364  : NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
365 
366 std::string OptionsView::get(StringRef LocalName, StringRef Default) const {
367  const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
368  if (Iter != CheckOptions.end())
369  return Iter->second;
370  return Default;
371 }
372 
373 std::string OptionsView::getLocalOrGlobal(StringRef LocalName,
374  StringRef Default) const {
375  auto Iter = CheckOptions.find(NamePrefix + LocalName.str());
376  if (Iter != CheckOptions.end())
377  return Iter->second;
378  // Fallback to global setting, if present.
379  Iter = CheckOptions.find(LocalName.str());
380  if (Iter != CheckOptions.end())
381  return Iter->second;
382  return Default;
383 }
384 
386  StringRef LocalName, StringRef Value) const {
387  Options[NamePrefix + LocalName.str()] = Value;
388 }
389 
391  StringRef LocalName, int64_t Value) const {
392  store(Options, LocalName, llvm::itostr(Value));
393 }
394 
395 std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
397  llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
398  Options));
399  ClangTidyASTConsumerFactory Factory(Context);
400  return Factory.getCheckNames();
401 }
402 
405  llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
406  Options));
407  ClangTidyASTConsumerFactory Factory(Context);
408  return Factory.getCheckOptions();
409 }
410 
411 ClangTidyStats
412 runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
413  const tooling::CompilationDatabase &Compilations,
414  ArrayRef<std::string> InputFiles,
415  std::vector<ClangTidyError> *Errors, ProfileData *Profile) {
416  ClangTool Tool(Compilations, InputFiles);
417  clang::tidy::ClangTidyContext Context(std::move(OptionsProvider));
418 
419  // Add extra arguments passed by the clang-tidy command-line.
420  ArgumentsAdjuster PerFileExtraArgumentsInserter =
421  [&Context](const CommandLineArguments &Args, StringRef Filename) {
423  CommandLineArguments AdjustedArgs;
424  if (Opts.ExtraArgsBefore)
425  AdjustedArgs = *Opts.ExtraArgsBefore;
426  AdjustedArgs.insert(AdjustedArgs.begin(), Args.begin(), Args.end());
427  if (Opts.ExtraArgs)
428  AdjustedArgs.insert(AdjustedArgs.end(), Opts.ExtraArgs->begin(),
429  Opts.ExtraArgs->end());
430  return AdjustedArgs;
431  };
432 
433  // Remove plugins arguments.
434  ArgumentsAdjuster PluginArgumentsRemover =
435  [&Context](const CommandLineArguments &Args, StringRef Filename) {
436  CommandLineArguments AdjustedArgs;
437  for (size_t I = 0, E = Args.size(); I < E; ++I) {
438  if (I + 4 < Args.size() && Args[I] == "-Xclang" &&
439  (Args[I + 1] == "-load" || Args[I + 1] == "-add-plugin" ||
440  StringRef(Args[I + 1]).startswith("-plugin-arg-")) &&
441  Args[I + 2] == "-Xclang") {
442  I += 3;
443  } else
444  AdjustedArgs.push_back(Args[I]);
445  }
446  return AdjustedArgs;
447  };
448 
449  Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter);
450  Tool.appendArgumentsAdjuster(PluginArgumentsRemover);
451  if (Profile)
452  Context.setCheckProfileData(Profile);
453 
454  ClangTidyDiagnosticConsumer DiagConsumer(Context);
455 
456  Tool.setDiagnosticConsumer(&DiagConsumer);
457 
458  class ActionFactory : public FrontendActionFactory {
459  public:
460  ActionFactory(ClangTidyContext &Context) : ConsumerFactory(Context) {}
461  FrontendAction *create() override { return new Action(&ConsumerFactory); }
462 
463  private:
464  class Action : public ASTFrontendAction {
465  public:
466  Action(ClangTidyASTConsumerFactory *Factory) : Factory(Factory) {}
467  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
468  StringRef File) override {
469  return Factory->CreateASTConsumer(Compiler, File);
470  }
471 
472  private:
474  };
475 
476  ClangTidyASTConsumerFactory ConsumerFactory;
477  };
478 
479  ActionFactory Factory(Context);
480  Tool.run(&Factory);
481  *Errors = Context.getErrors();
482  return Context.getStats();
483 }
484 
485 void handleErrors(const std::vector<ClangTidyError> &Errors, bool Fix,
486  unsigned &WarningsAsErrorsCount) {
487  ErrorReporter Reporter(Fix);
488  vfs::FileSystem &FileSystem =
489  *Reporter.getSourceManager().getFileManager().getVirtualFileSystem();
490  auto InitialWorkingDir = FileSystem.getCurrentWorkingDirectory();
491  if (!InitialWorkingDir)
492  llvm::report_fatal_error("Cannot get current working path.");
493 
494  for (const ClangTidyError &Error : Errors) {
495  if (!Error.BuildDirectory.empty()) {
496  // By default, the working directory of file system is the current
497  // clang-tidy running directory.
498  //
499  // Change the directory to the one used during the analysis.
500  FileSystem.setCurrentWorkingDirectory(Error.BuildDirectory);
501  }
502  Reporter.reportDiagnostic(Error);
503  // Return to the initial directory to correctly resolve next Error.
504  FileSystem.setCurrentWorkingDirectory(InitialWorkingDir.get());
505  }
506  Reporter.Finish();
507  WarningsAsErrorsCount += Reporter.getWarningsAsErrorsCount();
508 }
509 
510 void exportReplacements(const std::vector<ClangTidyError> &Errors,
511  raw_ostream &OS) {
512  tooling::TranslationUnitReplacements TUR;
513  for (const ClangTidyError &Error : Errors)
514  TUR.Replacements.insert(TUR.Replacements.end(), Error.Fix.begin(),
515  Error.Fix.end());
516 
517  yaml::Output YAML(OS);
518  YAML << TUR;
519 }
520 
521 } // namespace tidy
522 } // namespace clang
SourceLocation Loc
'#' location in the include directive
std::vector< std::string > getCheckNames()
Get the list of enabled checks.
Definition: ClangTidy.cpp:297
SetLongJmpCheck & Check
const std::string Name
Definition: USRFinder.cpp:140
llvm::Optional< ArgList > ExtraArgs
Add extra compilation arguments to the end of the list.
LangOptions LangOpts
Definition: ClangTidy.cpp:189
Read-only set of strings represented as a list of positive and negative globs.
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:210
ClangTidyOptions::OptionMap getCheckOptions()
Get the union of options from all checks.
Definition: ClangTidy.cpp:312
std::vector< std::unique_ptr< ClangTidyCheck > > Checks
Definition: ClangTidy.cpp:211
HeaderHandle File
bool contains(StringRef S)
Returns true if the pattern matches S.
Rewriter Rewrite
Definition: ClangTidy.cpp:194
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options)
Returns the effective check-specific options.
Definition: ClangTidy.cpp:403
Contains options for clang-tidy.
unsigned AppliedFixes
Definition: ClangTidy.cpp:197
A collection of ClangTidyCheckFactory instances.
const std::vector< ClangTidyError > & getErrors() const
Returns all collected errors.
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
SourceManager SourceMgr
Definition: ClangTidy.cpp:193
std::string get(StringRef LocalName, StringRef Default) const
Read a named option from the Context.
Definition: ClangTidy.cpp:366
llvm::Optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
ClangTidyOptions getOptionsForFile(StringRef File) const
Returns options for File.
void exportReplacements(const std::vector< ClangTidyError > &Errors, raw_ostream &OS)
Serializes replacements into YAML and writes them to the specified output stream. ...
Definition: ClangTidy.cpp:510
void setCurrentFile(StringRef File)
Should be called when starting to process new translation unit.
const ClangTidyOptions & getOptions() const
Returns options for CurrentFile.
std::string Filename
Filename as a string.
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, StringRef Message, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Report any errors detected using this method.
void setCheckProfileData(ProfileData *Profile)
Set the output struct for profile data.
std::string getLocalOrGlobal(StringRef LocalName, StringRef Default) const
Read a named option from the Context.
Definition: ClangTidy.cpp:373
void setASTContext(ASTContext *Context)
Sets ASTContext for the current translation unit.
A diagnostic consumer that turns each Diagnostic into a SourceManager-independent ClangTidyError...
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Definition: ClangTidy.cpp:385
std::map< std::string, std::string > OptionMap
std::vector< std::string > getCheckNames(const ClangTidyOptions &Options)
Fills the list of check names that are enabled when the provided filters are applied.
Definition: ClangTidy.cpp:395
ClangTidyStats runClangTidy(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider, const tooling::CompilationDatabase &Compilations, ArrayRef< std::string > InputFiles, std::vector< ClangTidyError > *Errors, ProfileData *Profile)
Run a set of clang-tidy checks on a set of files.
Definition: ClangTidy.cpp:412
static void setStaticAnalyzerCheckerOpts(const ClangTidyOptions &Opts, AnalyzerOptionsRef AnalyzerOptions)
Definition: ClangTidy.cpp:227
unsigned WarningsAsErrors
Definition: ClangTidy.cpp:198
void setSourceManager(SourceManager *SourceMgr)
Sets the SourceManager of the used DiagnosticsEngine.
OptionsView(StringRef CheckName, const ClangTidyOptions::OptionMap &CheckOptions)
Initializes the instance using CheckName + "." as a prefix.
Definition: ClangTidy.cpp:362
llvm::Optional< bool > AnalyzeTemporaryDtors
Turns on temporary destructor-based analysis.
const ClangTidyStats & getStats() const
Returns ClangTidyStats containing issued and ignored diagnostic counters.
CharSourceRange Range
SourceRange for the file name.
bool ApplyFixes
Definition: ClangTidy.cpp:195
A detected error complete with information to display diagnostic and automatic fix.
IntrusiveRefCntPtr< DiagnosticOptions > DiagOpts
Definition: ClangTidy.cpp:190
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
std::unique_ptr< clang::ASTConsumer > CreateASTConsumer(clang::CompilerInstance &Compiler, StringRef File)
Returns an ASTConsumer that runs the specified clang-tidy checks.
Definition: ClangTidy.cpp:239
FileManager Files
Definition: ClangTidy.cpp:188
void handleErrors(const std::vector< ClangTidyError > &Errors, bool Fix, unsigned &WarningsAsErrorsCount)
Displays the found Errors to the users.
Definition: ClangTidy.cpp:485
static cl::opt< bool > Fix("fix", cl::desc(R"( Apply suggested fixes. Without -fix-errors clang-tidy will bail out if any compilation errors were found. )"), cl::init(false), cl::cat(ClangTidyCategory))
void setCurrentBuildDirectory(StringRef BuildDirectory)
Should be called when starting to process new translation unit.
virtual void check(const ast_matchers::MatchFinder::MatchResult &Result)
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: ClangTidy.h:146
GlobList & getChecksFilter()
Returns check filter for the CurrentFile.
DiagnosticsEngine Diags
Definition: ClangTidy.cpp:192
unsigned TotalFixes
Definition: ClangTidy.cpp:196
Container for clang-tidy profiling data.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidy.cpp:352
const NamedDecl * Result
Definition: USRFinder.cpp:137
DiagnosticConsumer * DiagPrinter
Definition: ClangTidy.cpp:191