Author: alexfh Date: Mon Jan 13 04:50:51 2014 New Revision: 199094 URL: http://llvm.org/viewvc/llvm-project?rev=199094&view=rev Log: Add the check name to the clang-tidy diagnostic output.
Summary: Pass check names all the way from ClangTidyModule through ClangTidyCheck and ClangTidyContext to ClangTidyError, and output it in handleErrors. This allows to find mis-behaving check and disable it easily. Reviewers: djasper, klimek Reviewed By: djasper CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2534 Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp clang-tools-extra/trunk/clang-tidy/ClangTidy.h clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp clang-tools-extra/trunk/clang-tidy/llvm/LLVMTidyModule.cpp clang-tools-extra/trunk/test/clang-tidy/basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Mon Jan 13 04:50:51 2014 @@ -174,11 +174,20 @@ bool ChecksFilter::IsCheckEnabled(String return EnableChecks.match(Name) && !DisableChecks.match(Name); } +DiagnosticBuilder ClangTidyCheck::diag(SourceLocation Loc, StringRef Message) { + return Context->diag(CheckName, Loc, Message); +} + void ClangTidyCheck::run(const ast_matchers::MatchFinder::MatchResult &Result) { Context->setSourceManager(Result.SourceManager); check(Result); } +void ClangTidyCheck::setName(StringRef Name) { + assert(CheckName.empty()); + CheckName = Name.str(); +} + std::vector<std::string> getCheckNames(StringRef EnableChecksRegex, StringRef DisableChecksRegex) { SmallVector<ClangTidyError, 8> Errors; @@ -231,7 +240,8 @@ void runClangTidy(StringRef EnableChecks static void reportDiagnostic(const ClangTidyMessage &Message, SourceManager &SourceMgr, DiagnosticsEngine::Level Level, - DiagnosticsEngine &Diags) { + DiagnosticsEngine &Diags, + StringRef CheckName = "") { SourceLocation Loc; if (!Message.FilePath.empty()) { const FileEntry *File = @@ -240,7 +250,11 @@ static void reportDiagnostic(const Clang Loc = SourceMgr.getLocForStartOfFile(ID); Loc = Loc.getLocWithOffset(Message.FileOffset); } - Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message)); + if (CheckName.empty()) + Diags.Report(Loc, Diags.getCustomDiagID(Level, Message.Message)); + else + Diags.Report(Loc, Diags.getCustomDiagID(Level, (Message.Message + " [" + + CheckName + "]").str())); } void handleErrors(SmallVectorImpl<ClangTidyError> &Errors, bool Fix) { @@ -256,7 +270,8 @@ void handleErrors(SmallVectorImpl<ClangT for (SmallVectorImpl<ClangTidyError>::iterator I = Errors.begin(), E = Errors.end(); I != E; ++I) { - reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags); + reportDiagnostic(I->Message, SourceMgr, DiagnosticsEngine::Warning, Diags, + I->CheckName); for (unsigned i = 0, e = I->Notes.size(); i != e; ++i) { reportDiagnostic(I->Notes[i], SourceMgr, DiagnosticsEngine::Note, Diags); } Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Mon Jan 13 04:50:51 2014 @@ -75,11 +75,17 @@ public: /// \brief The infrastructure sets the context to \p Ctx with this function. void setContext(ClangTidyContext *Ctx) { Context = Ctx; } -protected: - ClangTidyContext *Context; + /// \brief Add a diagnostic with the check's name. + DiagnosticBuilder diag(SourceLocation Loc, StringRef Message); + + /// \brief Sets the check name. Intended to be used by the clang-tidy + /// framework. Can be called only once. + void setName(StringRef Name); private: virtual void run(const ast_matchers::MatchFinder::MatchResult &Result); + ClangTidyContext *Context; + std::string CheckName; }; /// \brief Filters checks by name. Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Mon Jan 13 04:50:51 2014 @@ -33,13 +33,18 @@ ClangTidyMessage::ClangTidyMessage(Strin FileOffset = Sources.getFileOffset(Loc); } -ClangTidyError::ClangTidyError(const ClangTidyMessage &Message) - : Message(Message) {} +ClangTidyError::ClangTidyError(StringRef CheckName, + const ClangTidyMessage &Message) + : CheckName(CheckName), Message(Message) {} -DiagnosticBuilder ClangTidyContext::Diag(SourceLocation Loc, +DiagnosticBuilder ClangTidyContext::diag(StringRef CheckName, + SourceLocation Loc, StringRef Message) { - return DiagEngine->Report( - Loc, DiagEngine->getCustomDiagID(DiagnosticsEngine::Warning, Message)); + unsigned ID = + DiagEngine->getCustomDiagID(DiagnosticsEngine::Warning, Message); + if (CheckNamesByDiagnosticID.count(ID) == 0) + CheckNamesByDiagnosticID.insert(std::make_pair(ID, CheckName.str())); + return DiagEngine->Report(Loc, ID); } void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) { @@ -55,6 +60,14 @@ void ClangTidyContext::storeError(const Errors->push_back(Error); } +StringRef ClangTidyContext::getCheckName(unsigned DiagnosticID) const { + llvm::DenseMap<unsigned, std::string>::const_iterator I = + CheckNamesByDiagnosticID.find(DiagnosticID); + if (I != CheckNamesByDiagnosticID.end()) + return I->second; + return ""; +} + ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx) : Context(Ctx) { IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); @@ -72,7 +85,8 @@ void ClangTidyDiagnosticConsumer::Handle if (Diags->getSourceManager().isInSystemHeader(Info.getLocation())) return; if (DiagLevel != DiagnosticsEngine::Note) { - Errors.push_back(ClangTidyError(getMessage(Info))); + Errors.push_back( + ClangTidyError(Context.getCheckName(Info.getID()), getMessage(Info))); } else { assert(!Errors.empty() && "A diagnostic note can only be appended to a message."); Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Mon Jan 13 04:50:51 2014 @@ -13,6 +13,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Refactoring.h" +#include "llvm/ADT/DenseMap.h" namespace clang { @@ -46,8 +47,9 @@ struct ClangTidyMessage { /// /// FIXME: Make Diagnostics flexible enough to support this directly. struct ClangTidyError { - ClangTidyError(const ClangTidyMessage &Message); + ClangTidyError(StringRef CheckName, const ClangTidyMessage &Message); + std::string CheckName; ClangTidyMessage Message; tooling::Replacements Fix; SmallVector<ClangTidyMessage, 1> Notes; @@ -72,7 +74,8 @@ public: /// 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(SourceLocation Loc, StringRef Message); + DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, + StringRef Message); /// \brief Sets the \c DiagnosticsEngine so that Diagnostics can be generated /// correctly. @@ -85,6 +88,10 @@ public: /// This is called from the \c ClangTidyCheck base class. void setSourceManager(SourceManager *SourceMgr); + /// \brief Returns the name of the clang-tidy check which produced this + /// diagnostic ID. + StringRef getCheckName(unsigned DiagnosticID) const; + private: friend class ClangTidyDiagnosticConsumer; // Calls storeError(). @@ -93,6 +100,7 @@ private: SmallVectorImpl<ClangTidyError> *Errors; DiagnosticsEngine *DiagEngine; + llvm::DenseMap<unsigned, std::string> CheckNamesByDiagnosticID; }; /// \brief A diagnostic consumer that turns each \c Diagnostic into a Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyModule.cpp Mon Jan 13 04:50:51 2014 @@ -32,8 +32,11 @@ void ClangTidyCheckFactories::createChec ChecksFilter &Filter, SmallVectorImpl<ClangTidyCheck *> &Checks) { for (FactoryMap::iterator I = Factories.begin(), E = Factories.end(); I != E; ++I) { - if (Filter.IsCheckEnabled(I->first)) - Checks.push_back(I->second->createCheck()); + if (Filter.IsCheckEnabled(I->first)) { + ClangTidyCheck *Check = I->second->createCheck(); + Check->setName(I->first); + Checks.push_back(Check); + } } } Modified: clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/google/GoogleTidyModule.cpp Mon Jan 13 04:50:51 2014 @@ -35,7 +35,7 @@ void ExplicitConstructorCheck::check(con if (!Ctor->isExplicit() && !Ctor->isImplicit() && Ctor->getNumParams() >= 1 && Ctor->getMinRequiredArguments() <= 1) { SourceLocation Loc = Ctor->getLocation(); - Context->Diag(Loc, "Single-argument constructors must be explicit") + diag(Loc, "Single-argument constructors must be explicit") << FixItHint::CreateInsertion(Loc, "explicit "); } } Modified: clang-tools-extra/trunk/clang-tidy/llvm/LLVMTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/llvm/LLVMTidyModule.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/llvm/LLVMTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/llvm/LLVMTidyModule.cpp Mon Jan 13 04:50:51 2014 @@ -40,14 +40,14 @@ void NamespaceCommentCheck::check(const // FIXME: Check that this namespace is "long". if (Tok.is(tok::comment)) { // FIXME: Check comment content. + // FIXME: Check comment placement on the same line. return; } std::string Fix = " // namespace"; if (!ND->isAnonymousNamespace()) Fix = Fix.append(" ").append(ND->getNameAsString()); - Context->Diag(ND->getLocation(), - "namespace not terminated with a closing comment") + diag(ND->getLocation(), "namespace not terminated with a closing comment") << FixItHint::CreateInsertion(ND->getRBraceLoc().getLocWithOffset(1), Fix); } @@ -55,8 +55,8 @@ void NamespaceCommentCheck::check(const namespace { class IncludeOrderPPCallbacks : public PPCallbacks { public: - explicit IncludeOrderPPCallbacks(ClangTidyContext &Context) - : Context(Context) {} + explicit IncludeOrderPPCallbacks(IncludeOrderCheck &Check) + : Check(Check) {} virtual void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, @@ -66,17 +66,17 @@ public: const Module *Imported) { // FIXME: This is a dummy implementation to show how to get at preprocessor // information. Implement a real include order check. - Context.Diag(HashLoc, "This is an include"); + Check.diag(HashLoc, "This is an include"); } private: - ClangTidyContext &Context; + IncludeOrderCheck &Check; }; } // namespace void IncludeOrderCheck::registerPPCallbacks(CompilerInstance &Compiler) { Compiler.getPreprocessor() - .addPPCallbacks(new IncludeOrderPPCallbacks(*Context)); + .addPPCallbacks(new IncludeOrderPPCallbacks(*this)); } class LLVMModule : public ClangTidyModule { Modified: clang-tools-extra/trunk/test/clang-tidy/basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/basic.cpp?rev=199094&r1=199093&r2=199094&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/basic.cpp Mon Jan 13 04:50:51 2014 @@ -4,4 +4,4 @@ namespace i { } -// CHECK: warning: namespace not terminated with a closing comment +// CHECK: warning: namespace not terminated with a closing comment [llvm-namespace-comment] _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
