carlosgalvezp updated this revision to Diff 387519.
carlosgalvezp marked 4 inline comments as done.
carlosgalvezp added a comment.
- Rebased.
- Addressed comments.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D113848/new/
https://reviews.llvm.org/D113848
Files:
clang-tools-extra/clang-tidy/CMakeLists.txt
clang-tools-extra/clang-tidy/ClangTidy.cpp
clang-tools-extra/clang-tidy/ClangTidyCheck.h
clang-tools-extra/clang-tidy/ClangTidyContext.cpp
clang-tools-extra/clang-tidy/ClangTidyContext.h
clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
clang-tools-extra/clang-tidy/ClangTidyError.cpp
clang-tools-extra/clang-tidy/ClangTidyError.h
clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
Index: clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
===================================================================
--- clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h
@@ -12,6 +12,7 @@
#include "ClangTidy.h"
#include "ClangTidyCheck.h"
#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyError.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
Index: clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
===================================================================
--- clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp
@@ -1,6 +1,7 @@
#include "ClangTidyOptions.h"
#include "ClangTidyCheck.h"
#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyError.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Testing/Support/Annotations.h"
Index: clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -16,6 +16,8 @@
#include "ClangTidyMain.h"
#include "../ClangTidy.h"
+#include "../ClangTidyContext.h"
+#include "../ClangTidyError.h"
#include "../ClangTidyForceLinker.h"
#include "../GlobList.h"
#include "clang/Tooling/CommonOptionsParser.h"
@@ -128,10 +130,10 @@
cl::init(false), cl::cat(ClangTidyCategory));
static cl::opt<bool> FixNotes("fix-notes", cl::desc(R"(
-If a warning has no fix, but a single fix can
-be found through an associated diagnostic note,
-apply the fix.
-Specifying this flag will implicitly enable the
+If a warning has no fix, but a single fix can
+be found through an associated diagnostic note,
+apply the fix.
+Specifying this flag will implicitly enable the
'--fix' flag.
)"),
cl::init(false), cl::cat(ClangTidyCategory));
Index: clang-tools-extra/clang-tidy/ClangTidyError.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/ClangTidyError.h
@@ -0,0 +1,38 @@
+//===--- ClangTidyError.h - clang-tidy --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYERROR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYERROR_H
+
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tidy {
+
+/// 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 : tooling::Diagnostic {
+ ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
+ bool IsWarningAsError);
+
+ bool IsWarningAsError;
+ std::vector<std::string> EnabledDiagnosticAliases;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
Index: clang-tools-extra/clang-tidy/ClangTidyError.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/ClangTidyError.cpp
@@ -0,0 +1,29 @@
+//===--- tools/extra/clang-tidy/ClangTidyError.cpp -----------------------=== //
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file implements the ClangTidyErrorDiagnosticConsumer class.
+///
+/// This tool uses the Clang Tooling infrastructure, see
+/// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+/// for details on setting it up with LLVM source tree.
+///
+//===----------------------------------------------------------------------===//
+
+#include "ClangTidyError.h"
+
+namespace clang {
+namespace tidy {
+
+ClangTidyError::ClangTidyError(StringRef CheckName,
+ ClangTidyError::Level DiagLevel,
+ StringRef BuildDirectory, bool IsWarningAsError)
+ : tooling::Diagnostic(CheckName, DiagLevel, BuildDirectory),
+ IsWarningAsError(IsWarningAsError) {}
+
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
+++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
@@ -9,11 +9,8 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYDIAGNOSTICCONSUMER_H
-#include "ClangTidyOptions.h"
-#include "ClangTidyProfiling.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Tooling/Core/Diagnostic.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Regex.h"
namespace clang {
@@ -29,185 +26,8 @@
} // namespace tooling
namespace tidy {
-
-/// 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 : tooling::Diagnostic {
- ClangTidyError(StringRef CheckName, Level DiagLevel, StringRef BuildDirectory,
- bool IsWarningAsError);
-
- bool IsWarningAsError;
- std::vector<std::string> EnabledDiagnosticAliases;
-};
-
-/// Contains displayed and ignored diagnostic counters for a ClangTidy run.
-struct ClangTidyStats {
- unsigned ErrorsDisplayed = 0;
- unsigned ErrorsIgnoredCheckFilter = 0;
- unsigned ErrorsIgnoredNOLINT = 0;
- unsigned ErrorsIgnoredNonUserCode = 0;
- unsigned ErrorsIgnoredLineFilter = 0;
-
- unsigned errorsIgnored() const {
- return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
- ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
- }
-};
-
-/// Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
-/// 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:
- /// Initializes \c ClangTidyContext instance.
- ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
- bool AllowEnablingAnalyzerAlphaCheckers = false);
- /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
- // FIXME: this is required initialization, and should be a constructor param.
- // Fix the context -> diag engine -> consumer -> context initialization cycle.
- void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
- this->DiagEngine = DiagEngine;
- }
-
- ~ClangTidyContext();
-
- /// 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.
- DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
- StringRef Message,
- DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
-
- DiagnosticBuilder diag(StringRef CheckName, StringRef Message,
- DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
-
- DiagnosticBuilder diag(const ClangTidyError &Error);
-
- /// Report any errors to do with reading the configuration using this method.
- DiagnosticBuilder
- configurationDiag(StringRef Message,
- DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
-
- /// Sets the \c SourceManager of the used \c DiagnosticsEngine.
- ///
- /// This is called from the \c ClangTidyCheck base class.
- void setSourceManager(SourceManager *SourceMgr);
-
- /// Should be called when starting to process new translation unit.
- void setCurrentFile(StringRef File);
-
- /// Returns the main file name of the current translation unit.
- StringRef getCurrentFile() const { return CurrentFile; }
-
- /// Sets ASTContext for the current translation unit.
- void setASTContext(ASTContext *Context);
-
- /// Gets the language options from the AST context.
- const LangOptions &getLangOpts() const { return LangOpts; }
-
- /// Returns the name of the clang-tidy check which produced this
- /// diagnostic ID.
- std::string getCheckName(unsigned DiagnosticID) const;
-
- /// Returns \c true if the check is enabled for the \c CurrentFile.
- ///
- /// The \c CurrentFile can be changed using \c setCurrentFile.
- bool isCheckEnabled(StringRef CheckName) const;
-
- /// Returns \c true if the check should be upgraded to error for the
- /// \c CurrentFile.
- bool treatAsError(StringRef CheckName) const;
-
- /// Returns global options.
- const ClangTidyGlobalOptions &getGlobalOptions() const;
-
- /// Returns options for \c CurrentFile.
- ///
- /// The \c CurrentFile can be changed using \c setCurrentFile.
- const ClangTidyOptions &getOptions() const;
-
- /// Returns options for \c File. Does not change or depend on
- /// \c CurrentFile.
- ClangTidyOptions getOptionsForFile(StringRef File) const;
-
- /// Returns \c ClangTidyStats containing issued and ignored diagnostic
- /// counters.
- const ClangTidyStats &getStats() const { return Stats; }
-
- /// Control profile collection in clang-tidy.
- void setEnableProfiling(bool Profile);
- bool getEnableProfiling() const { return Profile; }
-
- /// Control storage of profile date.
- void setProfileStoragePrefix(StringRef ProfilePrefix);
- llvm::Optional<ClangTidyProfiling::StorageParams>
- getProfileStorageParams() const;
-
- /// Should be called when starting to process new translation unit.
- void setCurrentBuildDirectory(StringRef BuildDirectory) {
- CurrentBuildDirectory = std::string(BuildDirectory);
- }
-
- /// Returns build directory of the current translation unit.
- const std::string &getCurrentBuildDirectory() const {
- return CurrentBuildDirectory;
- }
-
- /// If the experimental alpha checkers from the static analyzer can be
- /// enabled.
- bool canEnableAnalyzerAlphaCheckers() const {
- return AllowEnablingAnalyzerAlphaCheckers;
- }
-
- using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
- DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID,
- SourceLocation Loc) {
- return DiagLevelAndFormatString(
- static_cast<DiagnosticIDs::Level>(
- DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
- std::string(
- DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID)));
- }
-
-private:
- // Writes to Stats.
- friend class ClangTidyDiagnosticConsumer;
-
- DiagnosticsEngine *DiagEngine;
- std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
-
- std::string CurrentFile;
- ClangTidyOptions CurrentOptions;
- class CachedGlobList;
- std::unique_ptr<CachedGlobList> CheckFilter;
- std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
-
- LangOptions LangOpts;
-
- ClangTidyStats Stats;
-
- std::string CurrentBuildDirectory;
-
- llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
-
- bool Profile;
- std::string ProfilePrefix;
-
- bool AllowEnablingAnalyzerAlphaCheckers;
-};
+class ClangTidyContext;
+struct ClangTidyError;
/// Check whether a given diagnostic should be suppressed due to the presence
/// of a "NOLINT" suppression comment.
Index: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -6,8 +6,7 @@
//
//===----------------------------------------------------------------------===//
///
-/// \file This file implements ClangTidyDiagnosticConsumer, ClangTidyContext
-/// and ClangTidyError classes.
+/// \file This file implements the ClangTidyDiagnosticConsumer class.
///
/// This tool uses the Clang Tooling infrastructure, see
/// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
@@ -16,6 +15,8 @@
//===----------------------------------------------------------------------===//
#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyContext.h"
+#include "ClangTidyError.h"
#include "ClangTidyOptions.h"
#include "GlobList.h"
#include "clang/AST/ASTContext.h"
@@ -143,152 +144,6 @@
};
} // end anonymous namespace
-ClangTidyError::ClangTidyError(StringRef CheckName,
- ClangTidyError::Level DiagLevel,
- StringRef BuildDirectory, bool IsWarningAsError)
- : tooling::Diagnostic(CheckName, DiagLevel, BuildDirectory),
- IsWarningAsError(IsWarningAsError) {}
-
-class ClangTidyContext::CachedGlobList {
-public:
- CachedGlobList(StringRef Globs) : Globs(Globs) {}
-
- bool contains(StringRef S) {
- switch (auto &Result = Cache[S]) {
- case Yes:
- return true;
- case No:
- return false;
- case None:
- Result = Globs.contains(S) ? Yes : No;
- return Result == Yes;
- }
- llvm_unreachable("invalid enum");
- }
-
-private:
- GlobList Globs;
- enum Tristate { None, Yes, No };
- llvm::StringMap<Tristate> Cache;
-};
-
-ClangTidyContext::ClangTidyContext(
- std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
- bool AllowEnablingAnalyzerAlphaCheckers)
- : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)),
- Profile(false),
- AllowEnablingAnalyzerAlphaCheckers(AllowEnablingAnalyzerAlphaCheckers) {
- // Before the first translation unit we can get errors related to command-line
- // parsing, use empty string for the file name in this case.
- setCurrentFile("");
-}
-
-ClangTidyContext::~ClangTidyContext() = default;
-
-DiagnosticBuilder ClangTidyContext::diag(
- StringRef CheckName, SourceLocation Loc, StringRef Description,
- DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
- assert(Loc.isValid());
- unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
- Level, (Description + " [" + CheckName + "]").str());
- CheckNamesByDiagnosticID.try_emplace(ID, CheckName);
- return DiagEngine->Report(Loc, ID);
-}
-
-DiagnosticBuilder ClangTidyContext::diag(
- StringRef CheckName, StringRef Description,
- DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
- unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
- Level, (Description + " [" + CheckName + "]").str());
- CheckNamesByDiagnosticID.try_emplace(ID, CheckName);
- return DiagEngine->Report(ID);
-}
-
-DiagnosticBuilder ClangTidyContext::diag(const ClangTidyError &Error) {
- SourceManager &SM = DiagEngine->getSourceManager();
- llvm::ErrorOr<const FileEntry *> File =
- SM.getFileManager().getFile(Error.Message.FilePath);
- FileID ID = SM.getOrCreateFileID(*File, SrcMgr::C_User);
- SourceLocation FileStartLoc = SM.getLocForStartOfFile(ID);
- SourceLocation Loc = FileStartLoc.getLocWithOffset(Error.Message.FileOffset);
- return diag(Error.DiagnosticName, Loc, Error.Message.Message,
- static_cast<DiagnosticIDs::Level>(Error.DiagLevel));
-}
-
-DiagnosticBuilder ClangTidyContext::configurationDiag(
- StringRef Message,
- DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
- return diag("clang-tidy-config", Message, Level);
-}
-
-void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
- DiagEngine->setSourceManager(SourceMgr);
-}
-
-void ClangTidyContext::setCurrentFile(StringRef File) {
- CurrentFile = std::string(File);
- CurrentOptions = getOptionsForFile(CurrentFile);
- CheckFilter = std::make_unique<CachedGlobList>(*getOptions().Checks);
- WarningAsErrorFilter =
- std::make_unique<CachedGlobList>(*getOptions().WarningsAsErrors);
-}
-
-void ClangTidyContext::setASTContext(ASTContext *Context) {
- DiagEngine->SetArgToStringFn(&FormatASTNodeDiagnosticArgument, Context);
- LangOpts = Context->getLangOpts();
-}
-
-const ClangTidyGlobalOptions &ClangTidyContext::getGlobalOptions() const {
- return OptionsProvider->getGlobalOptions();
-}
-
-const ClangTidyOptions &ClangTidyContext::getOptions() const {
- return CurrentOptions;
-}
-
-ClangTidyOptions ClangTidyContext::getOptionsForFile(StringRef File) const {
- // Merge options on top of getDefaults() as a safeguard against options with
- // unset values.
- return ClangTidyOptions::getDefaults().merge(
- OptionsProvider->getOptions(File), 0);
-}
-
-void ClangTidyContext::setEnableProfiling(bool P) { Profile = P; }
-
-void ClangTidyContext::setProfileStoragePrefix(StringRef Prefix) {
- ProfilePrefix = std::string(Prefix);
-}
-
-llvm::Optional<ClangTidyProfiling::StorageParams>
-ClangTidyContext::getProfileStorageParams() const {
- if (ProfilePrefix.empty())
- return llvm::None;
-
- return ClangTidyProfiling::StorageParams(ProfilePrefix, CurrentFile);
-}
-
-bool ClangTidyContext::isCheckEnabled(StringRef CheckName) const {
- assert(CheckFilter != nullptr);
- return CheckFilter->contains(CheckName);
-}
-
-bool ClangTidyContext::treatAsError(StringRef CheckName) const {
- assert(WarningAsErrorFilter != nullptr);
- return WarningAsErrorFilter->contains(CheckName);
-}
-
-std::string ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
- std::string ClangWarningOption = std::string(
- DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(DiagnosticID));
- if (!ClangWarningOption.empty())
- return "clang-diagnostic-" + ClangWarningOption;
- llvm::DenseMap<unsigned, std::string>::const_iterator I =
- CheckNamesByDiagnosticID.find(DiagnosticID);
- if (I != CheckNamesByDiagnosticID.end())
- return I->second;
- return "";
-}
-
ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(
ClangTidyContext &Ctx, DiagnosticsEngine *ExternalDiagEngine,
bool RemoveIncompatibleErrors, bool GetFixesFromNotes)
Index: clang-tools-extra/clang-tidy/ClangTidyContext.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/ClangTidyContext.h
@@ -0,0 +1,194 @@
+//===--- ClangTidyContext.h - clang-tidy ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCONTEXT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCONTEXT_H
+
+#include "ClangTidyOptions.h"
+#include "ClangTidyProfiling.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Regex.h"
+
+namespace clang {
+
+class ASTContext;
+class SourceManager;
+
+namespace tidy {
+struct ClangTidyError;
+
+/// Contains displayed and ignored diagnostic counters for a ClangTidy run.
+struct ClangTidyStats {
+ unsigned ErrorsDisplayed = 0;
+ unsigned ErrorsIgnoredCheckFilter = 0;
+ unsigned ErrorsIgnoredNOLINT = 0;
+ unsigned ErrorsIgnoredNonUserCode = 0;
+ unsigned ErrorsIgnoredLineFilter = 0;
+
+ unsigned errorsIgnored() const {
+ return ErrorsIgnoredNOLINT + ErrorsIgnoredCheckFilter +
+ ErrorsIgnoredNonUserCode + ErrorsIgnoredLineFilter;
+ }
+};
+
+/// Every \c ClangTidyCheck reports errors through a \c DiagnosticsEngine
+/// 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:
+ /// Initializes \c ClangTidyContext instance.
+ ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
+ bool AllowEnablingAnalyzerAlphaCheckers = false);
+ /// Sets the DiagnosticsEngine that diag() will emit diagnostics to.
+ // FIXME: this is required initialization, and should be a constructor param.
+ // Fix the context -> diag engine -> consumer -> context initialization cycle.
+ void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) {
+ this->DiagEngine = DiagEngine;
+ }
+
+ ~ClangTidyContext();
+
+ /// 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.
+ DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc,
+ StringRef Message,
+ DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
+
+ DiagnosticBuilder diag(StringRef CheckName, StringRef Message,
+ DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
+
+ DiagnosticBuilder diag(const ClangTidyError &Error);
+
+ /// Report any errors to do with reading the configuration using this method.
+ DiagnosticBuilder
+ configurationDiag(StringRef Message,
+ DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
+
+ /// Sets the \c SourceManager of the used \c DiagnosticsEngine.
+ ///
+ /// This is called from the \c ClangTidyCheck base class.
+ void setSourceManager(SourceManager *SourceMgr);
+
+ /// Should be called when starting to process new translation unit.
+ void setCurrentFile(StringRef File);
+
+ /// Returns the main file name of the current translation unit.
+ StringRef getCurrentFile() const { return CurrentFile; }
+
+ /// Sets ASTContext for the current translation unit.
+ void setASTContext(ASTContext *Context);
+
+ /// Gets the language options from the AST context.
+ const LangOptions &getLangOpts() const { return LangOpts; }
+
+ /// Returns the name of the clang-tidy check which produced this
+ /// diagnostic ID.
+ std::string getCheckName(unsigned DiagnosticID) const;
+
+ /// Returns \c true if the check is enabled for the \c CurrentFile.
+ ///
+ /// The \c CurrentFile can be changed using \c setCurrentFile.
+ bool isCheckEnabled(StringRef CheckName) const;
+
+ /// Returns \c true if the check should be upgraded to error for the
+ /// \c CurrentFile.
+ bool treatAsError(StringRef CheckName) const;
+
+ /// Returns global options.
+ const ClangTidyGlobalOptions &getGlobalOptions() const;
+
+ /// Returns options for \c CurrentFile.
+ ///
+ /// The \c CurrentFile can be changed using \c setCurrentFile.
+ const ClangTidyOptions &getOptions() const;
+
+ /// Returns options for \c File. Does not change or depend on
+ /// \c CurrentFile.
+ ClangTidyOptions getOptionsForFile(StringRef File) const;
+
+ /// Returns \c ClangTidyStats containing issued and ignored diagnostic
+ /// counters.
+ const ClangTidyStats &getStats() const { return Stats; }
+
+ /// Control profile collection in clang-tidy.
+ void setEnableProfiling(bool Profile);
+ bool getEnableProfiling() const { return Profile; }
+
+ /// Control storage of profile date.
+ void setProfileStoragePrefix(StringRef ProfilePrefix);
+ llvm::Optional<ClangTidyProfiling::StorageParams>
+ getProfileStorageParams() const;
+
+ /// Should be called when starting to process new translation unit.
+ void setCurrentBuildDirectory(StringRef BuildDirectory) {
+ CurrentBuildDirectory = std::string(BuildDirectory);
+ }
+
+ /// Returns build directory of the current translation unit.
+ const std::string &getCurrentBuildDirectory() const {
+ return CurrentBuildDirectory;
+ }
+
+ /// If the experimental alpha checkers from the static analyzer can be
+ /// enabled.
+ bool canEnableAnalyzerAlphaCheckers() const {
+ return AllowEnablingAnalyzerAlphaCheckers;
+ }
+
+ using DiagLevelAndFormatString = std::pair<DiagnosticIDs::Level, std::string>;
+ DiagLevelAndFormatString getDiagLevelAndFormatString(unsigned DiagnosticID,
+ SourceLocation Loc) {
+ return DiagLevelAndFormatString(
+ static_cast<DiagnosticIDs::Level>(
+ DiagEngine->getDiagnosticLevel(DiagnosticID, Loc)),
+ std::string(
+ DiagEngine->getDiagnosticIDs()->getDescription(DiagnosticID)));
+ }
+
+private:
+ // Writes to Stats.
+ friend class ClangTidyDiagnosticConsumer;
+
+ DiagnosticsEngine *DiagEngine;
+ std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
+
+ std::string CurrentFile;
+ ClangTidyOptions CurrentOptions;
+ class CachedGlobList;
+ std::unique_ptr<CachedGlobList> CheckFilter;
+ std::unique_ptr<CachedGlobList> WarningAsErrorFilter;
+
+ LangOptions LangOpts;
+
+ ClangTidyStats Stats;
+
+ std::string CurrentBuildDirectory;
+
+ llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID;
+
+ bool Profile;
+ std::string ProfilePrefix;
+
+ bool AllowEnablingAnalyzerAlphaCheckers;
+};
+
+} // end namespace tidy
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCONTEXT_H
Index: clang-tools-extra/clang-tidy/ClangTidyContext.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/ClangTidyContext.cpp
@@ -0,0 +1,185 @@
+//===--- tools/extra/clang-tidy/ClangTidyContext.cpp ---------------------=== //
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file This file implements the ClangTidyContext class.
+///
+/// This tool uses the Clang Tooling infrastructure, see
+/// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+/// for details on setting it up with LLVM source tree.
+///
+//===----------------------------------------------------------------------===//
+
+#include "ClangTidyContext.h"
+#include "ClangTidyError.h"
+#include "ClangTidyOptions.h"
+#include "GlobList.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/Attr.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/DiagnosticRenderer.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Regex.h"
+#include <tuple>
+#include <utility>
+#include <vector>
+
+namespace clang {
+namespace tidy {
+
+class ClangTidyContext::CachedGlobList {
+public:
+ CachedGlobList(StringRef Globs) : Globs(Globs) {}
+
+ bool contains(StringRef S) {
+ switch (auto &Result = Cache[S]) {
+ case Yes:
+ return true;
+ case No:
+ return false;
+ case None:
+ Result = Globs.contains(S) ? Yes : No;
+ return Result == Yes;
+ }
+ llvm_unreachable("invalid enum");
+ }
+
+private:
+ GlobList Globs;
+ enum Tristate { None, Yes, No };
+ llvm::StringMap<Tristate> Cache;
+};
+
+ClangTidyContext::ClangTidyContext(
+ std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
+ bool AllowEnablingAnalyzerAlphaCheckers)
+ : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)),
+ Profile(false),
+ AllowEnablingAnalyzerAlphaCheckers(AllowEnablingAnalyzerAlphaCheckers) {
+ // Before the first translation unit we can get errors related to command-line
+ // parsing, use empty string for the file name in this case.
+ setCurrentFile("");
+}
+
+ClangTidyContext::~ClangTidyContext() = default;
+
+DiagnosticBuilder ClangTidyContext::diag(
+ StringRef CheckName, SourceLocation Loc, StringRef Description,
+ DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
+ assert(Loc.isValid());
+ unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
+ Level, (Description + " [" + CheckName + "]").str());
+ CheckNamesByDiagnosticID.try_emplace(ID, CheckName);
+ return DiagEngine->Report(Loc, ID);
+}
+
+DiagnosticBuilder ClangTidyContext::diag(
+ StringRef CheckName, StringRef Description,
+ DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
+ unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
+ Level, (Description + " [" + CheckName + "]").str());
+ CheckNamesByDiagnosticID.try_emplace(ID, CheckName);
+ return DiagEngine->Report(ID);
+}
+
+DiagnosticBuilder ClangTidyContext::diag(const ClangTidyError &Error) {
+ SourceManager &SM = DiagEngine->getSourceManager();
+ llvm::ErrorOr<const FileEntry *> File =
+ SM.getFileManager().getFile(Error.Message.FilePath);
+ FileID ID = SM.getOrCreateFileID(*File, SrcMgr::C_User);
+ SourceLocation FileStartLoc = SM.getLocForStartOfFile(ID);
+ SourceLocation Loc = FileStartLoc.getLocWithOffset(Error.Message.FileOffset);
+ return diag(Error.DiagnosticName, Loc, Error.Message.Message,
+ static_cast<DiagnosticIDs::Level>(Error.DiagLevel));
+}
+
+DiagnosticBuilder ClangTidyContext::configurationDiag(
+ StringRef Message,
+ DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
+ return diag("clang-tidy-config", Message, Level);
+}
+
+void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
+ DiagEngine->setSourceManager(SourceMgr);
+}
+
+void ClangTidyContext::setCurrentFile(StringRef File) {
+ CurrentFile = std::string(File);
+ CurrentOptions = getOptionsForFile(CurrentFile);
+ CheckFilter = std::make_unique<CachedGlobList>(*getOptions().Checks);
+ WarningAsErrorFilter =
+ std::make_unique<CachedGlobList>(*getOptions().WarningsAsErrors);
+}
+
+void ClangTidyContext::setASTContext(ASTContext *Context) {
+ DiagEngine->SetArgToStringFn(&FormatASTNodeDiagnosticArgument, Context);
+ LangOpts = Context->getLangOpts();
+}
+
+const ClangTidyGlobalOptions &ClangTidyContext::getGlobalOptions() const {
+ return OptionsProvider->getGlobalOptions();
+}
+
+const ClangTidyOptions &ClangTidyContext::getOptions() const {
+ return CurrentOptions;
+}
+
+ClangTidyOptions ClangTidyContext::getOptionsForFile(StringRef File) const {
+ // Merge options on top of getDefaults() as a safeguard against options with
+ // unset values.
+ return ClangTidyOptions::getDefaults().merge(
+ OptionsProvider->getOptions(File), 0);
+}
+
+void ClangTidyContext::setEnableProfiling(bool P) { Profile = P; }
+
+void ClangTidyContext::setProfileStoragePrefix(StringRef Prefix) {
+ ProfilePrefix = std::string(Prefix);
+}
+
+llvm::Optional<ClangTidyProfiling::StorageParams>
+ClangTidyContext::getProfileStorageParams() const {
+ if (ProfilePrefix.empty())
+ return llvm::None;
+
+ return ClangTidyProfiling::StorageParams(ProfilePrefix, CurrentFile);
+}
+
+bool ClangTidyContext::isCheckEnabled(StringRef CheckName) const {
+ assert(CheckFilter != nullptr);
+ return CheckFilter->contains(CheckName);
+}
+
+bool ClangTidyContext::treatAsError(StringRef CheckName) const {
+ assert(WarningAsErrorFilter != nullptr);
+ return WarningAsErrorFilter->contains(CheckName);
+}
+
+std::string ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
+ std::string ClangWarningOption = std::string(
+ DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(DiagnosticID));
+ if (!ClangWarningOption.empty())
+ return "clang-diagnostic-" + ClangWarningOption;
+ llvm::DenseMap<unsigned, std::string>::const_iterator I =
+ CheckNamesByDiagnosticID.find(DiagnosticID);
+ if (I != CheckNamesByDiagnosticID.end())
+ return I->second;
+ return "";
+}
+
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/ClangTidyCheck.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyCheck.h
+++ clang-tools-extra/clang-tidy/ClangTidyCheck.h
@@ -9,7 +9,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANGTIDYCHECK_H
-#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyContext.h"
#include "ClangTidyOptions.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/Diagnostic.h"
Index: clang-tools-extra/clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -17,6 +17,7 @@
#include "ClangTidy.h"
#include "ClangTidyCheck.h"
#include "ClangTidyDiagnosticConsumer.h"
+#include "ClangTidyError.h"
#include "ClangTidyModuleRegistry.h"
#include "ClangTidyProfiling.h"
#include "ExpandModularHeadersPPCallbacks.h"
Index: clang-tools-extra/clang-tidy/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/CMakeLists.txt
@@ -11,6 +11,8 @@
add_clang_library(clangTidy
ClangTidy.cpp
ClangTidyCheck.cpp
+ ClangTidyContext.cpp
+ ClangTidyError.cpp
ClangTidyModule.cpp
ClangTidyDiagnosticConsumer.cpp
ClangTidyOptions.cpp
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits