[clang-tools-extra] r203457 - Use DiagnosticRenderer to convert clang diagnostics to clang-tidy ones.
Alexander Kornienko
alexfh at google.com
Mon Mar 10 06:11:18 PDT 2014
Author: alexfh
Date: Mon Mar 10 08:11:17 2014
New Revision: 203457
URL: http://llvm.org/viewvc/llvm-project?rev=203457&view=rev
Log:
Use DiagnosticRenderer to convert clang diagnostics to clang-tidy ones.
Summary:
This is immediately useful for generating macro expansion notes, and
may be useful for other things later on.
Reviewers: klimek, djasper
Reviewed By: klimek
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D2950
Added:
clang-tools-extra/trunk/test/clang-tidy/macros.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
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=203457&r1=203456&r2=203457&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Mon Mar 10 08:11:17 2014
@@ -17,6 +17,8 @@
//===----------------------------------------------------------------------===//
#include "ClangTidyDiagnosticConsumer.h"
+
+#include "clang/Frontend/DiagnosticRenderer.h"
#include "llvm/ADT/SmallString.h"
#include <set>
@@ -25,19 +27,91 @@
namespace clang {
namespace tidy {
+class ClangTidyDiagnosticRenderer : public DiagnosticRenderer {
+public:
+ ClangTidyDiagnosticRenderer(const LangOptions &LangOpts,
+ DiagnosticOptions *DiagOpts,
+ ClangTidyError &Error)
+ : DiagnosticRenderer(LangOpts, DiagOpts), Error(Error) {}
+
+protected:
+ void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level, StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager *SM,
+ DiagOrStoredDiag Info) override {
+ if (Level == DiagnosticsEngine::Ignored)
+ return;
+ ClangTidyMessage TidyMessage = Loc.isValid()
+ ? ClangTidyMessage(Message, *SM, Loc)
+ : ClangTidyMessage(Message);
+ if (Level == DiagnosticsEngine::Note) {
+ Error.Notes.push_back(TidyMessage);
+ return;
+ }
+ assert(Error.Message.Message.empty() &&
+ "Overwriting a diagnostic message");
+ Error.Message = TidyMessage;
+ }
+
+ void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager &SM) override {}
+
+ void emitBasicNote(StringRef Message) override {
+ Error.Notes.push_back(ClangTidyMessage(Message));
+ }
+
+ void emitCodeContext(SourceLocation Loc, DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange> &Ranges,
+ ArrayRef<FixItHint> Hints,
+ const SourceManager &SM) override {
+ assert(Loc.isValid());
+ for (const auto &FixIt : Hints) {
+ CharSourceRange Range = FixIt.RemoveRange;
+ assert(Range.getBegin().isValid() && Range.getEnd().isValid() &&
+ "Invalid range in the fix-it hint.");
+ assert(Range.getBegin().isFileID() && Range.getEnd().isFileID() &&
+ "Only file locations supported in fix-it hints.");
+
+ Error.Fix.insert(tooling::Replacement(SM, Range, FixIt.CodeToInsert));
+ }
+ }
+
+ void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+ const SourceManager &SM) override {}
+
+ void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) override {}
+
+ void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
+ StringRef ModuleName,
+ const SourceManager &SM) override {}
+
+ void endDiagnostic(DiagOrStoredDiag D,
+ DiagnosticsEngine::Level Level) override {
+ assert(!Error.Message.Message.empty() && "Message has not been set");
+ }
+
+private:
+ ClangTidyError &Error;
+};
+
ClangTidyMessage::ClangTidyMessage(StringRef Message) : Message(Message) {}
ClangTidyMessage::ClangTidyMessage(StringRef Message,
const SourceManager &Sources,
SourceLocation Loc)
: Message(Message) {
+ assert(Loc.isValid() && Loc.isFileID());
FilePath = Sources.getFilename(Loc);
FileOffset = Sources.getFileOffset(Loc);
}
-ClangTidyError::ClangTidyError(StringRef CheckName,
- const ClangTidyMessage &Message)
- : CheckName(CheckName), Message(Message) {}
+ClangTidyError::ClangTidyError(StringRef CheckName)
+ : CheckName(CheckName) {}
DiagnosticBuilder ClangTidyContext::diag(
StringRef CheckName, SourceLocation Loc, StringRef Description,
@@ -100,17 +174,27 @@ void ClangTidyDiagnosticConsumer::finali
void ClangTidyDiagnosticConsumer::HandleDiagnostic(
DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
- // FIXME: Deduplicate diagnostics.
if (DiagLevel == DiagnosticsEngine::Note) {
assert(!Errors.empty() &&
"A diagnostic note can only be appended to a message.");
- Errors.back().Notes.push_back(getMessage(Info));
} else {
finalizeLastError();
- Errors.push_back(
- ClangTidyError(Context.getCheckName(Info.getID()), getMessage(Info)));
+ Errors.push_back(ClangTidyError(Context.getCheckName(Info.getID())));
}
- addFixes(Info, Errors.back());
+
+ // FIXME: Provide correct LangOptions for each file.
+ LangOptions LangOpts;
+ ClangTidyDiagnosticRenderer Converter(
+ LangOpts, &Context.DiagEngine->getDiagnosticOptions(), Errors.back());
+ SmallString<100> Message;
+ Info.FormatDiagnostic(Message);
+ SourceManager *Sources = nullptr;
+ if (Info.hasSourceManager())
+ Sources = &Info.getSourceManager();
+ Converter.emitDiagnostic(
+ Info.getLocation(), DiagLevel, Message, Info.getRanges(),
+ llvm::makeArrayRef(Info.getFixItHints(), Info.getNumFixItHints()),
+ Sources);
// Let argument parsing-related warnings through.
if (!Info.getLocation().isValid() ||
@@ -140,33 +224,5 @@ void ClangTidyDiagnosticConsumer::finish
Errors.clear();
}
-void ClangTidyDiagnosticConsumer::addFixes(const Diagnostic &Info,
- ClangTidyError &Error) {
- if (!Info.hasSourceManager())
- return;
- SourceManager &Sources = Info.getSourceManager();
- tooling::Replacements Replacements;
- for (unsigned i = 0, e = Info.getNumFixItHints(); i != e; ++i) {
- CharSourceRange Range = Info.getFixItHint(i).RemoveRange;
- assert(Range.getBegin().isValid() && Range.getEnd().isValid() &&
- "Invalid range in the fix-it hint.");
- assert(Range.getBegin().isFileID() && Range.getEnd().isFileID() &&
- "Only file locations supported in fix-it hints.");
- std::string Text = Info.getFixItHint(i).CodeToInsert;
- Error.Fix.insert(tooling::Replacement(Sources, Range, Text));
- }
-}
-
-ClangTidyMessage
-ClangTidyDiagnosticConsumer::getMessage(const Diagnostic &Info) const {
- SmallString<100> Buf;
- Info.FormatDiagnostic(Buf);
- if (!Info.hasSourceManager()) {
- return ClangTidyMessage(Buf.str());
- }
- return ClangTidyMessage(Buf.str(), Info.getSourceManager(),
- Info.getLocation());
-}
-
} // namespace tidy
} // namespace clang
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=203457&r1=203456&r2=203457&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Mon Mar 10 08:11:17 2014
@@ -47,7 +47,7 @@ struct ClangTidyMessage {
///
/// FIXME: Make Diagnostics flexible enough to support this directly.
struct ClangTidyError {
- ClangTidyError(StringRef CheckName, const ClangTidyMessage &Message);
+ ClangTidyError(StringRef CheckName);
std::string CheckName;
ClangTidyMessage Message;
@@ -123,8 +123,6 @@ public:
void finish() override;
private:
- void addFixes(const Diagnostic &Info, ClangTidyError &Error);
- ClangTidyMessage getMessage(const Diagnostic &Info) const;
void finalizeLastError();
ClangTidyContext &Context;
Added: clang-tools-extra/trunk/test/clang-tidy/macros.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/macros.cpp?rev=203457&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/macros.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/macros.cpp Mon Mar 10 08:11:17 2014
@@ -0,0 +1,7 @@
+// RUN: clang-tidy -checks=google-explicit-constructor %s -- | FileCheck %s
+
+#define Q(name) class name { name(int i); }
+
+Q(A);
+// CHECK: :[[@LINE-1]]:3: warning: Single-argument constructors must be explicit [google-explicit-constructor]
+// CHECK: :3:30: note: expanded from macro 'Q'
More information about the cfe-commits
mailing list