2013-07-29 16:19:24 +08:00
|
|
|
//===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-03-10 00:52:33 +08:00
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
|
2013-07-29 16:19:24 +08:00
|
|
|
|
2014-05-05 22:54:47 +08:00
|
|
|
#include "ClangTidyOptions.h"
|
[clang-tidy] Store checks profiling info as JSON files
Summary:
Continuation of D46504.
Example output:
```
$ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp
$ # Note that there won't be timings table printed to the console.
$ cat *.json
{
"file": "/path/to/source.cpp",
"timestamp": "2018-05-16 16:13:18.717446360",
"profile": {
"time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
"time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
"time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
}
}
```
There are two arguments that control profile storage:
* `-store-check-profile=<prefix>`
By default reports are printed in tabulated format to stderr. When this option
is passed, these per-TU profiles are instead stored as JSON.
If the prefix is not an absolute path, it is considered to be relative to the
directory from where you have run :program:`clang-tidy`. All `.` and `..`
patterns in the path are collapsed, and symlinks are resolved.
Example:
Let's suppose you have a source file named `example.cpp`, located in
`/source` directory.
* If you specify `-store-check-profile=/tmp`, then the profile will be saved
to `/tmp/<timestamp>-example.cpp.json`
* If you run :program:`clang-tidy` from within `/foo` directory, and specify
`-store-check-profile=.`, then the profile will still be saved to
`/foo/<timestamp>-example.cpp.json`
Reviewers: alexfh, sbenza, george.karpenkov, NoQ, aaron.ballman
Reviewed By: alexfh, george.karpenkov, aaron.ballman
Subscribers: Quuxplusone, JonasToth, aaron.ballman, llvm-commits, rja, Eugene.Zelenko, xazax.hun, mgrang, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46602
llvm-svn: 334101
2018-06-06 23:07:51 +08:00
|
|
|
#include "ClangTidyProfiling.h"
|
2013-07-29 16:19:24 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
2017-01-03 22:36:13 +08:00
|
|
|
#include "clang/Tooling/Core/Diagnostic.h"
|
2013-07-29 16:19:24 +08:00
|
|
|
#include "clang/Tooling/Refactoring.h"
|
2014-01-13 18:50:51 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2014-10-24 01:23:20 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
2014-03-20 17:38:22 +08:00
|
|
|
#include "llvm/Support/Regex.h"
|
2014-10-24 01:23:20 +08:00
|
|
|
#include "llvm/Support/Timer.h"
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
|
2014-07-14 22:10:03 +08:00
|
|
|
class ASTContext;
|
2013-07-29 16:19:24 +08:00
|
|
|
class CompilerInstance;
|
|
|
|
namespace ast_matchers {
|
|
|
|
class MatchFinder;
|
|
|
|
}
|
|
|
|
namespace tooling {
|
|
|
|
class CompilationDatabase;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace tidy {
|
|
|
|
|
2013-11-14 23:49:44 +08:00
|
|
|
/// \brief A detected error complete with information to display diagnostic and
|
|
|
|
/// automatic fix.
|
|
|
|
///
|
|
|
|
/// This is used as an intermediate format to transport Diagnostics without a
|
|
|
|
/// dependency on a SourceManager.
|
|
|
|
///
|
|
|
|
/// FIXME: Make Diagnostics flexible enough to support this directly.
|
2017-01-03 22:36:13 +08:00
|
|
|
struct ClangTidyError : tooling::Diagnostic {
|
|
|
|
ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
|
|
|
|
bool IsWarningAsError);
|
2016-02-26 17:19:33 +08:00
|
|
|
|
2016-01-14 01:36:41 +08:00
|
|
|
bool IsWarningAsError;
|
2013-11-14 23:49:44 +08:00
|
|
|
};
|
|
|
|
|
2014-08-06 19:49:10 +08:00
|
|
|
/// \brief Read-only set of strings represented as a list of positive and
|
|
|
|
/// negative globs. Positive globs add all matched strings to the set, negative
|
|
|
|
/// globs remove them in the order of appearance in the list.
|
|
|
|
class GlobList {
|
2014-03-20 17:38:22 +08:00
|
|
|
public:
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief \p GlobList is a comma-separated list of globs (only '*'
|
|
|
|
/// metacharacter is supported) with optional '-' prefix to denote exclusion.
|
2014-08-06 19:49:10 +08:00
|
|
|
GlobList(StringRef Globs);
|
2014-06-05 21:31:45 +08:00
|
|
|
|
2014-08-06 19:49:10 +08:00
|
|
|
/// \brief Returns \c true if the pattern matches \p S. The result is the last
|
|
|
|
/// matching glob's Positive flag.
|
|
|
|
bool contains(StringRef S) { return contains(S, false); }
|
2014-03-20 17:38:22 +08:00
|
|
|
|
|
|
|
private:
|
2014-08-06 19:49:10 +08:00
|
|
|
bool contains(StringRef S, bool Contains);
|
Change the behavior of clang-tidy -checks=, remove -disable-checks.
Summary:
Make checks filtering more intuitive and easy to use. Remove
-disable-checks and change the format of -checks= to a comma-separated list of
globs with optional '-' prefix to denote exclusion. The -checks= option is now
cumulative, so it modifies defaults, not overrides them. Each glob adds or
removes to the current set of checks, so the filter can be refined or overriden
by adding globs.
Example:
The default value for -checks= is
'*,-clang-analyzer-alpha*,-llvm-include-order,-llvm-namespace-comment,-google-*',
which allows all checks except for the ones named clang-analyzer-alpha* and
others specified with the leading '-'. To allow all google-* checks one can
write:
clang-tidy -checks=google-* ...
If one needs only google-* checks, we first need to remove everything (-*):
clang-tidy -checks=-*,google-*
etc.
I'm not sure if we need to change something here, so I didn't touch the docs
yet.
Reviewers: klimek, alexfh
Reviewed By: alexfh
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D3770
llvm-svn: 208883
2014-05-15 22:27:36 +08:00
|
|
|
|
|
|
|
bool Positive;
|
|
|
|
llvm::Regex Regex;
|
2014-08-06 19:49:10 +08:00
|
|
|
std::unique_ptr<GlobList> NextGlob;
|
2014-03-20 17:38:22 +08:00
|
|
|
};
|
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Contains displayed and ignored diagnostic counters for a ClangTidy
|
|
|
|
/// run.
|
2014-05-07 17:06:53 +08:00
|
|
|
struct ClangTidyStats {
|
|
|
|
ClangTidyStats()
|
|
|
|
: ErrorsDisplayed(0), ErrorsIgnoredCheckFilter(0), ErrorsIgnoredNOLINT(0),
|
2014-05-23 00:07:11 +08:00
|
|
|
ErrorsIgnoredNonUserCode(0), ErrorsIgnoredLineFilter(0) {}
|
2014-05-07 17:06:53 +08:00
|
|
|
|
|
|
|
unsigned ErrorsDisplayed;
|
|
|
|
unsigned ErrorsIgnoredCheckFilter;
|
|
|
|
unsigned ErrorsIgnoredNOLINT;
|
|
|
|
unsigned ErrorsIgnoredNonUserCode;
|
2014-05-23 00:07:11 +08:00
|
|
|
unsigned ErrorsIgnoredLineFilter;
|
|
|
|
|
|
|
|
unsigned errorsIgnored() const {
|
|
|
|
return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
|
|
|
|
ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
|
|
|
|
}
|
2014-05-07 17:06:53 +08:00
|
|
|
};
|
|
|
|
|
2014-12-19 23:37:02 +08:00
|
|
|
/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
|
2013-11-14 23:49:44 +08:00
|
|
|
/// provided by this context.
|
|
|
|
///
|
|
|
|
/// A \c ClangTidyCheck always has access to the active context to report
|
|
|
|
/// warnings like:
|
|
|
|
/// \code
|
|
|
|
/// Context->Diag(Loc, "Single-argument constructors must be explicit")
|
|
|
|
/// << FixItHint::CreateInsertion(Loc, "explicit ");
|
|
|
|
/// \endcode
|
|
|
|
class ClangTidyContext {
|
|
|
|
public:
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Initializes \c ClangTidyContext instance.
|
[clang-tidy] Add a flag to enable alpha checkers
Summary: The alpha checkers can already be enabled using the clang driver, this allows them to be enabled using the clang-tidy as well. This can make it easier to test the alpha checkers with projects which already support the compile_commands.json. It will also allow more people to give feedback and patches about the alpha checkers since they can run it as part of clang tidy checks.
Reviewers: aaron.ballman, hokein, ilya-biryukov, alexfh, lebedev.ri, xbolva00
Reviewed By: aaron.ballman, alexfh, lebedev.ri, xbolva00
Subscribers: xbolva00, NoQ, dcoughlin, lebedev.ri, xazax.hun, cfe-commits
Patch by Paul Fultz II!
Differential Revision: https://reviews.llvm.org/D46159
llvm-svn: 332609
2018-05-17 22:04:27 +08:00
|
|
|
ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
|
|
|
|
bool AllowEnablingAnalyzerAlphaCheckers = false);
|
2013-11-14 23:49:44 +08:00
|
|
|
|
[clang-tidy] Optimize GlobList::contains
With large lists of checks and large number of warnings GlobList::contains
starts being ridiculously CPU hungry, since it runs regexp match per glob.
Caching results of glob matching in a StringMap significantly speeds up check
filtering even for small GlobLists.
/tmp/q.cc:
void f() {
int I;
{int I;}
{int I;}
{int I;}
... // 200k times
}
Before the patch:
GlobList with 2 entries:
$ time clang-tidy-old -checks=-*,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m3.826s
user 0m3.176s
sys 0m0.504s
GlobList with 28 entries:
$ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m5.000s
user 0m4.744s
sys 0m0.060s
GlobList with 158 entries:
$ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m13.920s
user 0m13.636s
sys 0m0.104s
With the patch runtime is practically independent from the length of the GlobList:
$ time clang-tidy-new -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m2.300s
user 0m2.104s
sys 0m0.044s
llvm-svn: 303321
2017-05-18 09:13:51 +08:00
|
|
|
~ClangTidyContext();
|
|
|
|
|
2013-11-14 23:49:44 +08:00
|
|
|
/// \brief Report any errors detected using this method.
|
|
|
|
///
|
|
|
|
/// This is still under heavy development and will likely change towards using
|
|
|
|
/// tablegen'd diagnostic IDs.
|
|
|
|
/// FIXME: Figure out a way to manage ID spaces.
|
2014-01-13 18:50:51 +08:00
|
|
|
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
|
2014-02-06 22:50:10 +08:00
|
|
|
StringRef Message,
|
|
|
|
DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
|
2013-11-14 23:49:44 +08:00
|
|
|
|
|
|
|
/// \brief Sets the \c SourceManager of the used \c DiagnosticsEngine.
|
|
|
|
///
|
|
|
|
/// This is called from the \c ClangTidyCheck base class.
|
|
|
|
void setSourceManager(SourceManager *SourceMgr);
|
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Should be called when starting to process new translation unit.
|
|
|
|
void setCurrentFile(StringRef File);
|
|
|
|
|
2015-05-21 22:08:56 +08:00
|
|
|
/// \brief Returns the main file name of the current translation unit.
|
|
|
|
StringRef getCurrentFile() const { return CurrentFile; }
|
|
|
|
|
2014-07-14 22:10:03 +08:00
|
|
|
/// \brief Sets ASTContext for the current translation unit.
|
|
|
|
void setASTContext(ASTContext *Context);
|
|
|
|
|
2015-11-10 00:28:11 +08:00
|
|
|
/// \brief Gets the language options from the AST context.
|
2016-02-26 07:57:23 +08:00
|
|
|
const LangOptions &getLangOpts() const { return LangOpts; }
|
2015-08-28 21:20:46 +08:00
|
|
|
|
2014-01-13 18:50:51 +08:00
|
|
|
/// \brief Returns the name of the clang-tidy check which produced this
|
|
|
|
/// diagnostic ID.
|
|
|
|
StringRef getCheckName(unsigned DiagnosticID) const;
|
|
|
|
|
2017-05-17 22:39:47 +08:00
|
|
|
/// \brief Returns \c true if the check is enabled for the \c CurrentFile.
|
2015-11-10 00:28:11 +08:00
|
|
|
///
|
|
|
|
/// The \c CurrentFile can be changed using \c setCurrentFile.
|
2017-05-17 22:39:47 +08:00
|
|
|
bool isCheckEnabled(StringRef CheckName) const;
|
2014-06-05 21:31:45 +08:00
|
|
|
|
2017-05-17 22:39:47 +08:00
|
|
|
/// \brief Returns \c true if the check should be upgraded to error for the
|
|
|
|
/// \c CurrentFile.
|
|
|
|
bool treatAsError(StringRef CheckName) const;
|
2016-01-14 01:36:41 +08:00
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Returns global options.
|
|
|
|
const ClangTidyGlobalOptions &getGlobalOptions() const;
|
|
|
|
|
|
|
|
/// \brief Returns options for \c CurrentFile.
|
2015-11-10 00:28:11 +08:00
|
|
|
///
|
|
|
|
/// The \c CurrentFile can be changed using \c setCurrentFile.
|
2014-06-05 21:31:45 +08:00
|
|
|
const ClangTidyOptions &getOptions() const;
|
|
|
|
|
2015-11-10 00:28:11 +08:00
|
|
|
/// \brief Returns options for \c File. Does not change or depend on
|
|
|
|
/// \c CurrentFile.
|
|
|
|
ClangTidyOptions getOptionsForFile(StringRef File) const;
|
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic
|
|
|
|
/// counters.
|
2014-05-07 17:06:53 +08:00
|
|
|
const ClangTidyStats &getStats() const { return Stats; }
|
2014-06-05 21:31:45 +08:00
|
|
|
|
[clang-tidy] Profile is a per-AST (per-TU) data.
Summary:
As discussed in D45931, currently, profiling output of clang-tidy is somewhat not great.
It outputs one profile at the end of the execution, and that profile contains the data
from the last TU that was processed. So if the tool run on multiple TU's, the data is
not accumulated, it is simply discarded.
It would be nice to improve this.
This differential is the first step - make this profiling info per-TU,
and output it after the tool has finished processing each TU.
In particular, when `ClangTidyASTConsumer` destructor runs.
Next step will be to add a CSV (JSON?) printer to store said profiles under user-specified directory prefix.
Reviewers: alexfh, sbenza
Reviewed By: alexfh
Subscribers: Eugene.Zelenko, mgorny, xazax.hun, mgrang, klimek, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46504
llvm-svn: 331763
2018-05-08 21:14:21 +08:00
|
|
|
/// \brief Control profile collection in clang-tidy.
|
|
|
|
void setEnableProfiling(bool Profile);
|
|
|
|
bool getEnableProfiling() const { return Profile; }
|
2014-10-24 01:23:20 +08:00
|
|
|
|
[clang-tidy] Store checks profiling info as JSON files
Summary:
Continuation of D46504.
Example output:
```
$ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp
$ # Note that there won't be timings table printed to the console.
$ cat *.json
{
"file": "/path/to/source.cpp",
"timestamp": "2018-05-16 16:13:18.717446360",
"profile": {
"time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
"time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
"time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
}
}
```
There are two arguments that control profile storage:
* `-store-check-profile=<prefix>`
By default reports are printed in tabulated format to stderr. When this option
is passed, these per-TU profiles are instead stored as JSON.
If the prefix is not an absolute path, it is considered to be relative to the
directory from where you have run :program:`clang-tidy`. All `.` and `..`
patterns in the path are collapsed, and symlinks are resolved.
Example:
Let's suppose you have a source file named `example.cpp`, located in
`/source` directory.
* If you specify `-store-check-profile=/tmp`, then the profile will be saved
to `/tmp/<timestamp>-example.cpp.json`
* If you run :program:`clang-tidy` from within `/foo` directory, and specify
`-store-check-profile=.`, then the profile will still be saved to
`/foo/<timestamp>-example.cpp.json`
Reviewers: alexfh, sbenza, george.karpenkov, NoQ, aaron.ballman
Reviewed By: alexfh, george.karpenkov, aaron.ballman
Subscribers: Quuxplusone, JonasToth, aaron.ballman, llvm-commits, rja, Eugene.Zelenko, xazax.hun, mgrang, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46602
llvm-svn: 334101
2018-06-06 23:07:51 +08:00
|
|
|
/// \brief Control storage of profile date.
|
|
|
|
void setProfileStoragePrefix(StringRef ProfilePrefix);
|
|
|
|
llvm::Optional<ClangTidyProfiling::StorageParams>
|
|
|
|
getProfileStorageParams() const;
|
|
|
|
|
2016-02-26 17:19:33 +08:00
|
|
|
/// \brief Should be called when starting to process new translation unit.
|
|
|
|
void setCurrentBuildDirectory(StringRef BuildDirectory) {
|
|
|
|
CurrentBuildDirectory = BuildDirectory;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns build directory of the current translation unit.
|
|
|
|
const std::string &getCurrentBuildDirectory() {
|
|
|
|
return CurrentBuildDirectory;
|
|
|
|
}
|
|
|
|
|
[clang-tidy] Add a flag to enable alpha checkers
Summary: The alpha checkers can already be enabled using the clang driver, this allows them to be enabled using the clang-tidy as well. This can make it easier to test the alpha checkers with projects which already support the compile_commands.json. It will also allow more people to give feedback and patches about the alpha checkers since they can run it as part of clang tidy checks.
Reviewers: aaron.ballman, hokein, ilya-biryukov, alexfh, lebedev.ri, xbolva00
Reviewed By: aaron.ballman, alexfh, lebedev.ri, xbolva00
Subscribers: xbolva00, NoQ, dcoughlin, lebedev.ri, xazax.hun, cfe-commits
Patch by Paul Fultz II!
Differential Revision: https://reviews.llvm.org/D46159
llvm-svn: 332609
2018-05-17 22:04:27 +08:00
|
|
|
/// \brief If the experimental alpha checkers from the static analyzer can be
|
|
|
|
/// enabled.
|
|
|
|
bool canEnableAnalyzerAlphaCheckers() const {
|
|
|
|
return AllowEnablingAnalyzerAlphaCheckers;
|
|
|
|
}
|
|
|
|
|
2013-11-14 23:49:44 +08:00
|
|
|
private:
|
2018-10-31 21:08:19 +08:00
|
|
|
// Sets DiagEngine and Errors.
|
2014-06-05 21:31:45 +08:00
|
|
|
friend class ClangTidyDiagnosticConsumer;
|
2016-03-03 16:58:12 +08:00
|
|
|
friend class ClangTidyPluginAction;
|
2013-11-14 23:49:44 +08:00
|
|
|
|
2014-03-20 18:53:03 +08:00
|
|
|
DiagnosticsEngine *DiagEngine;
|
2014-06-05 21:31:45 +08:00
|
|
|
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
|
|
|
|
|
|
|
|
std::string CurrentFile;
|
2014-09-04 22:23:36 +08:00
|
|
|
ClangTidyOptions CurrentOptions;
|
[clang-tidy] Optimize GlobList::contains
With large lists of checks and large number of warnings GlobList::contains
starts being ridiculously CPU hungry, since it runs regexp match per glob.
Caching results of glob matching in a StringMap significantly speeds up check
filtering even for small GlobLists.
/tmp/q.cc:
void f() {
int I;
{int I;}
{int I;}
{int I;}
... // 200k times
}
Before the patch:
GlobList with 2 entries:
$ time clang-tidy-old -checks=-*,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m3.826s
user 0m3.176s
sys 0m0.504s
GlobList with 28 entries:
$ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m5.000s
user 0m4.744s
sys 0m0.060s
GlobList with 158 entries:
$ time clang-tidy-old -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m13.920s
user 0m13.636s
sys 0m0.104s
With the patch runtime is practically independent from the length of the GlobList:
$ time clang-tidy-new -checks=-*,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,modernize-use-override /tmp/q.cc -- -Wshadow
200000 warnings generated.
Suppressed 200000 warnings (200000 with check filters).
real 0m2.300s
user 0m2.104s
sys 0m0.044s
llvm-svn: 303321
2017-05-18 09:13:51 +08:00
|
|
|
class CachedGlobList;
|
|
|
|
std::unique_ptr<CachedGlobList> CheckFilter;
|
|
|
|
std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
|
2014-06-05 21:31:45 +08:00
|
|
|
|
2015-08-28 21:20:46 +08:00
|
|
|
LangOptions LangOpts;
|
|
|
|
|
2014-05-07 17:06:53 +08:00
|
|
|
ClangTidyStats Stats;
|
2014-03-20 17:38:22 +08:00
|
|
|
|
2016-02-26 17:19:33 +08:00
|
|
|
std::string CurrentBuildDirectory;
|
|
|
|
|
2014-01-13 18:50:51 +08:00
|
|
|
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
|
2014-10-24 01:23:20 +08:00
|
|
|
|
[clang-tidy] Profile is a per-AST (per-TU) data.
Summary:
As discussed in D45931, currently, profiling output of clang-tidy is somewhat not great.
It outputs one profile at the end of the execution, and that profile contains the data
from the last TU that was processed. So if the tool run on multiple TU's, the data is
not accumulated, it is simply discarded.
It would be nice to improve this.
This differential is the first step - make this profiling info per-TU,
and output it after the tool has finished processing each TU.
In particular, when `ClangTidyASTConsumer` destructor runs.
Next step will be to add a CSV (JSON?) printer to store said profiles under user-specified directory prefix.
Reviewers: alexfh, sbenza
Reviewed By: alexfh
Subscribers: Eugene.Zelenko, mgorny, xazax.hun, mgrang, klimek, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46504
llvm-svn: 331763
2018-05-08 21:14:21 +08:00
|
|
|
bool Profile;
|
[clang-tidy] Store checks profiling info as JSON files
Summary:
Continuation of D46504.
Example output:
```
$ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp
$ # Note that there won't be timings table printed to the console.
$ cat *.json
{
"file": "/path/to/source.cpp",
"timestamp": "2018-05-16 16:13:18.717446360",
"profile": {
"time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00,
"time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01,
"time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01
}
}
```
There are two arguments that control profile storage:
* `-store-check-profile=<prefix>`
By default reports are printed in tabulated format to stderr. When this option
is passed, these per-TU profiles are instead stored as JSON.
If the prefix is not an absolute path, it is considered to be relative to the
directory from where you have run :program:`clang-tidy`. All `.` and `..`
patterns in the path are collapsed, and symlinks are resolved.
Example:
Let's suppose you have a source file named `example.cpp`, located in
`/source` directory.
* If you specify `-store-check-profile=/tmp`, then the profile will be saved
to `/tmp/<timestamp>-example.cpp.json`
* If you run :program:`clang-tidy` from within `/foo` directory, and specify
`-store-check-profile=.`, then the profile will still be saved to
`/foo/<timestamp>-example.cpp.json`
Reviewers: alexfh, sbenza, george.karpenkov, NoQ, aaron.ballman
Reviewed By: alexfh, george.karpenkov, aaron.ballman
Subscribers: Quuxplusone, JonasToth, aaron.ballman, llvm-commits, rja, Eugene.Zelenko, xazax.hun, mgrang, cfe-commits
Tags: #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D46602
llvm-svn: 334101
2018-06-06 23:07:51 +08:00
|
|
|
std::string ProfilePrefix;
|
[clang-tidy] Add a flag to enable alpha checkers
Summary: The alpha checkers can already be enabled using the clang driver, this allows them to be enabled using the clang-tidy as well. This can make it easier to test the alpha checkers with projects which already support the compile_commands.json. It will also allow more people to give feedback and patches about the alpha checkers since they can run it as part of clang tidy checks.
Reviewers: aaron.ballman, hokein, ilya-biryukov, alexfh, lebedev.ri, xbolva00
Reviewed By: aaron.ballman, alexfh, lebedev.ri, xbolva00
Subscribers: xbolva00, NoQ, dcoughlin, lebedev.ri, xazax.hun, cfe-commits
Patch by Paul Fultz II!
Differential Revision: https://reviews.llvm.org/D46159
llvm-svn: 332609
2018-05-17 22:04:27 +08:00
|
|
|
|
|
|
|
bool AllowEnablingAnalyzerAlphaCheckers;
|
2013-11-14 23:49:44 +08:00
|
|
|
};
|
|
|
|
|
2013-07-29 16:19:24 +08:00
|
|
|
/// \brief A diagnostic consumer that turns each \c Diagnostic into a
|
|
|
|
/// \c SourceManager-independent \c ClangTidyError.
|
|
|
|
//
|
|
|
|
// FIXME: If we move away from unit-tests, this can be moved to a private
|
|
|
|
// implementation file.
|
|
|
|
class ClangTidyDiagnosticConsumer : public DiagnosticConsumer {
|
|
|
|
public:
|
2017-05-09 23:10:26 +08:00
|
|
|
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx,
|
|
|
|
bool RemoveIncompatibleErrors = true);
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
// FIXME: The concept of converting between FixItHints and Replacements is
|
|
|
|
// more generic and should be pulled out into a more useful Diagnostics
|
|
|
|
// library.
|
2014-02-27 21:14:51 +08:00
|
|
|
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
|
2014-03-02 18:20:11 +08:00
|
|
|
const Diagnostic &Info) override;
|
2013-11-14 23:49:44 +08:00
|
|
|
|
[clang-tidy] Get ClangTidyContext out of the business of storing diagnostics. NFC
Summary:
Currently ClangTidyContext::diag() sends the diagnostics to a
DiagnosticsEngine, which probably delegates to a ClangTidyDiagnosticsConsumer,
which is supposed to go back and populate ClangTidyContext::Errors.
After this patch, the diagnostics are stored in the ClangTidyDiagnosticsConsumer
itself and can be retrieved from there.
Why?
- the round-trip from context -> engine -> consumer -> context is confusing
and makes it harder to establish layering between these things.
- context does too many things, and makes it hard to use clang-tidy as a library
- everyone who actually wants the diagnostics has access to the ClangTidyDiagnosticsConsumer
The most natural implementation (ClangTidyDiagnosticsConsumer::take()
finalizes diagnostics) causes a test failure: clang-tidy-run-with-database.cpp
asserts that clang-tidy exits successfully when trying to process a file
that doesn't exist.
In clang-tidy today, this happens because finish() is never called, so the
diagnostic is never flushed. This looks like a bug to me.
For now, this patch carefully preserves that behavior, but I'll ping the
authors to see whether it's deliberate and worth preserving.
Reviewers: hokein
Subscribers: xazax.hun, cfe-commits, alexfh
Differential Revision: https://reviews.llvm.org/D53953
llvm-svn: 345961
2018-11-02 18:01:59 +08:00
|
|
|
// Retrieve the diagnostics that were captured.
|
|
|
|
std::vector<ClangTidyError> take();
|
2013-11-14 23:49:44 +08:00
|
|
|
|
|
|
|
private:
|
2014-02-06 22:50:10 +08:00
|
|
|
void finalizeLastError();
|
[clang-tidy] Get ClangTidyContext out of the business of storing diagnostics. NFC
Summary:
Currently ClangTidyContext::diag() sends the diagnostics to a
DiagnosticsEngine, which probably delegates to a ClangTidyDiagnosticsConsumer,
which is supposed to go back and populate ClangTidyContext::Errors.
After this patch, the diagnostics are stored in the ClangTidyDiagnosticsConsumer
itself and can be retrieved from there.
Why?
- the round-trip from context -> engine -> consumer -> context is confusing
and makes it harder to establish layering between these things.
- context does too many things, and makes it hard to use clang-tidy as a library
- everyone who actually wants the diagnostics has access to the ClangTidyDiagnosticsConsumer
The most natural implementation (ClangTidyDiagnosticsConsumer::take()
finalizes diagnostics) causes a test failure: clang-tidy-run-with-database.cpp
asserts that clang-tidy exits successfully when trying to process a file
that doesn't exist.
In clang-tidy today, this happens because finish() is never called, so the
diagnostic is never flushed. This looks like a bug to me.
For now, this patch carefully preserves that behavior, but I'll ping the
authors to see whether it's deliberate and worth preserving.
Reviewers: hokein
Subscribers: xazax.hun, cfe-commits, alexfh
Differential Revision: https://reviews.llvm.org/D53953
llvm-svn: 345961
2018-11-02 18:01:59 +08:00
|
|
|
void removeIncompatibleErrors();
|
2015-10-16 19:43:49 +08:00
|
|
|
|
2015-08-12 21:16:41 +08:00
|
|
|
/// \brief Returns the \c HeaderFilter constructed for the options set in the
|
|
|
|
/// context.
|
2015-10-16 19:43:49 +08:00
|
|
|
llvm::Regex *getHeaderFilter();
|
2015-08-12 21:16:41 +08:00
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter
|
|
|
|
/// according to the diagnostic \p Location.
|
2014-05-23 00:07:11 +08:00
|
|
|
void checkFilters(SourceLocation Location);
|
|
|
|
bool passesLineFilter(StringRef FileName, unsigned LineNumber) const;
|
2013-07-29 16:19:24 +08:00
|
|
|
|
|
|
|
ClangTidyContext &Context;
|
2017-05-09 23:10:26 +08:00
|
|
|
bool RemoveIncompatibleErrors;
|
2014-03-09 17:24:40 +08:00
|
|
|
std::unique_ptr<DiagnosticsEngine> Diags;
|
[clang-tidy] Get ClangTidyContext out of the business of storing diagnostics. NFC
Summary:
Currently ClangTidyContext::diag() sends the diagnostics to a
DiagnosticsEngine, which probably delegates to a ClangTidyDiagnosticsConsumer,
which is supposed to go back and populate ClangTidyContext::Errors.
After this patch, the diagnostics are stored in the ClangTidyDiagnosticsConsumer
itself and can be retrieved from there.
Why?
- the round-trip from context -> engine -> consumer -> context is confusing
and makes it harder to establish layering between these things.
- context does too many things, and makes it hard to use clang-tidy as a library
- everyone who actually wants the diagnostics has access to the ClangTidyDiagnosticsConsumer
The most natural implementation (ClangTidyDiagnosticsConsumer::take()
finalizes diagnostics) causes a test failure: clang-tidy-run-with-database.cpp
asserts that clang-tidy exits successfully when trying to process a file
that doesn't exist.
In clang-tidy today, this happens because finish() is never called, so the
diagnostic is never flushed. This looks like a bug to me.
For now, this patch carefully preserves that behavior, but I'll ping the
authors to see whether it's deliberate and worth preserving.
Reviewers: hokein
Subscribers: xazax.hun, cfe-commits, alexfh
Differential Revision: https://reviews.llvm.org/D53953
llvm-svn: 345961
2018-11-02 18:01:59 +08:00
|
|
|
std::vector<ClangTidyError> Errors;
|
2014-06-05 21:31:45 +08:00
|
|
|
std::unique_ptr<llvm::Regex> HeaderFilter;
|
2014-02-06 22:50:10 +08:00
|
|
|
bool LastErrorRelatesToUserCode;
|
2014-05-23 00:07:11 +08:00
|
|
|
bool LastErrorPassesLineFilter;
|
2016-11-03 05:14:22 +08:00
|
|
|
bool LastErrorWasIgnored;
|
2013-07-29 16:19:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace tidy
|
|
|
|
} // end namespace clang
|
|
|
|
|
2015-03-10 00:52:33 +08:00
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
|