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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
|
|
|
|
|
2014-05-05 22:54:47 +08:00
|
|
|
#include "ClangTidyOptions.h"
|
2013-07-29 16:19:24 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
|
|
|
#include "clang/Tooling/Refactoring.h"
|
2014-01-13 18:50:51 +08:00
|
|
|
#include "llvm/ADT/DenseMap.h"
|
2014-03-20 17:38:22 +08:00
|
|
|
#include "llvm/Support/Regex.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 message from a clang-tidy check.
|
|
|
|
///
|
|
|
|
/// Note that this is independent of a \c SourceManager.
|
|
|
|
struct ClangTidyMessage {
|
|
|
|
ClangTidyMessage(StringRef Message = "");
|
|
|
|
ClangTidyMessage(StringRef Message, const SourceManager &Sources,
|
|
|
|
SourceLocation Loc);
|
|
|
|
std::string Message;
|
|
|
|
std::string FilePath;
|
|
|
|
unsigned FileOffset;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \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.
|
|
|
|
struct ClangTidyError {
|
2014-06-03 04:44:32 +08:00
|
|
|
enum Level {
|
|
|
|
Warning = DiagnosticsEngine::Warning,
|
|
|
|
Error = DiagnosticsEngine::Error
|
|
|
|
};
|
|
|
|
|
|
|
|
ClangTidyError(StringRef CheckName, Level DiagLevel);
|
2013-11-14 23:49:44 +08:00
|
|
|
|
2014-01-13 18:50:51 +08:00
|
|
|
std::string CheckName;
|
2013-11-14 23:49:44 +08:00
|
|
|
ClangTidyMessage Message;
|
|
|
|
tooling::Replacements Fix;
|
|
|
|
SmallVector<ClangTidyMessage, 1> Notes;
|
2014-06-03 04:44:32 +08:00
|
|
|
|
|
|
|
Level DiagLevel;
|
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
|
|
|
};
|
|
|
|
|
2013-11-14 23:49:44 +08:00
|
|
|
/// \brief Every \c ClangTidyCheck reports errors through a \c DiagnosticEngine
|
|
|
|
/// 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.
|
|
|
|
///
|
|
|
|
/// Takes ownership of the \c OptionsProvider.
|
|
|
|
ClangTidyContext(ClangTidyOptionsProvider *OptionsProvider);
|
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);
|
|
|
|
|
2014-07-14 22:10:03 +08:00
|
|
|
/// \brief Sets ASTContext for the current translation unit.
|
|
|
|
void setASTContext(ASTContext *Context);
|
|
|
|
|
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;
|
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Returns check filter for the \c CurrentFile.
|
2014-08-06 19:49:10 +08:00
|
|
|
GlobList &getChecksFilter();
|
2014-06-05 21:31:45 +08:00
|
|
|
|
|
|
|
/// \brief Returns global options.
|
|
|
|
const ClangTidyGlobalOptions &getGlobalOptions() const;
|
|
|
|
|
|
|
|
/// \brief Returns options for \c CurrentFile.
|
|
|
|
const ClangTidyOptions &getOptions() const;
|
|
|
|
|
|
|
|
/// \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
|
|
|
|
|
|
|
/// \brief Returns all collected errors.
|
2014-05-09 20:24:09 +08:00
|
|
|
const std::vector<ClangTidyError> &getErrors() const { return Errors; }
|
2014-06-05 21:31:45 +08:00
|
|
|
|
|
|
|
/// \brief Clears collected errors.
|
2014-05-09 23:50:15 +08:00
|
|
|
void clearErrors() { Errors.clear(); }
|
2014-03-20 17:38:22 +08:00
|
|
|
|
2013-11-14 23:49:44 +08:00
|
|
|
private:
|
2014-06-05 21:31:45 +08:00
|
|
|
// Calls setDiagnosticsEngine() and storeError().
|
|
|
|
friend class ClangTidyDiagnosticConsumer;
|
2013-11-14 23:49:44 +08:00
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated
|
|
|
|
/// correctly.
|
|
|
|
void setDiagnosticsEngine(DiagnosticsEngine *Engine);
|
|
|
|
|
|
|
|
/// \brief Store an \p Error.
|
2013-11-14 23:49:44 +08:00
|
|
|
void storeError(const ClangTidyError &Error);
|
|
|
|
|
2014-05-09 20:24:09 +08:00
|
|
|
std::vector<ClangTidyError> Errors;
|
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-08-06 19:49:10 +08:00
|
|
|
std::unique_ptr<GlobList> CheckFilter;
|
2014-06-05 21:31:45 +08:00
|
|
|
|
2014-05-07 17:06:53 +08:00
|
|
|
ClangTidyStats Stats;
|
2014-03-20 17:38:22 +08:00
|
|
|
|
2014-01-13 18:50:51 +08:00
|
|
|
llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
|
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:
|
2014-01-10 00:31:25 +08:00
|
|
|
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx);
|
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
|
|
|
|
2014-06-05 21:31:45 +08:00
|
|
|
/// \brief Sets \c HeaderFilter to the value configured for this file.
|
|
|
|
void BeginSourceFile(const LangOptions &LangOpts,
|
|
|
|
const Preprocessor *PP) override;
|
|
|
|
|
|
|
|
/// \brief Flushes the internal diagnostics buffer to the ClangTidyContext.
|
2014-03-02 18:20:11 +08:00
|
|
|
void finish() override;
|
2013-11-14 23:49:44 +08:00
|
|
|
|
|
|
|
private:
|
2014-02-06 22:50:10 +08:00
|
|
|
void finalizeLastError();
|
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;
|
2014-03-09 17:24:40 +08:00
|
|
|
std::unique_ptr<DiagnosticsEngine> Diags;
|
2013-11-14 23:49:44 +08:00
|
|
|
SmallVector<ClangTidyError, 8> 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;
|
2013-07-29 16:19:24 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace tidy
|
|
|
|
} // end namespace clang
|
|
|
|
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_DIAGNOSTIC_CONSUMER_H
|