clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

ClangTidyDiagnosticConsumer.cpp
Go to the documentation of this file.
1 //===--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp ----------=== //
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file This file implements ClangTidyDiagnosticConsumer, ClangTidyMessage,
11 /// ClangTidyContext and ClangTidyError classes.
12 ///
13 /// This tool uses the Clang Tooling infrastructure, see
14 /// http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
15 /// for details on setting it up with LLVM source tree.
16 ///
17 //===----------------------------------------------------------------------===//
18
19 #include "ClangTidyDiagnosticConsumer.h"
20 #include "ClangTidyOptions.h"
21 #include "clang/AST/ASTDiagnostic.h"
22 #include "clang/Basic/DiagnosticOptions.h"
23 #include "clang/Frontend/DiagnosticRenderer.h"
24 #include "llvm/ADT/SmallString.h"
25 #include <tuple>
26 #include <vector>
27 using namespace clang;
28 using namespace tidy;
29
30 namespace {
31 class ClangTidyDiagnosticRenderer : public DiagnosticRenderer {
32 public:
33 ClangTidyDiagnosticRenderer(const LangOptions &LangOpts,
34 DiagnosticOptions *DiagOpts,
35 ClangTidyError &Error)
36 : DiagnosticRenderer(LangOpts, DiagOpts), Error(Error) {}
37
38 protected:
39 void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
40 DiagnosticsEngine::Level Level, StringRef Message,
41 ArrayRef<CharSourceRange> Ranges,
42 const SourceManager *SM,
43 DiagOrStoredDiag Info) override {
44 // Remove check name from the message.
45 // FIXME: Remove this once there's a better way to pass check names than
46 // appending the check name to the message in ClangTidyContext::diag and
47 // using getCustomDiagID.
48 std::string CheckNameInMessage = " [" + Error.CheckName + "]";
49 if (Message.endswith(CheckNameInMessage))
50 Message = Message.substr(0, Message.size() - CheckNameInMessage.size());
51
52 ClangTidyMessage TidyMessage = Loc.isValid()
53 ? ClangTidyMessage(Message, *SM, Loc)
54 : ClangTidyMessage(Message);
55 if (Level == DiagnosticsEngine::Note) {
56 Error.Notes.push_back(TidyMessage);
57 return;
58 }
59 assert(Error.Message.Message.empty() && "Overwriting a diagnostic message");
60 Error.Message = TidyMessage;
61 }
62
63 void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
64 DiagnosticsEngine::Level Level,
65 ArrayRef<CharSourceRange> Ranges,
66 const SourceManager &SM) override {}
67
68 void emitCodeContext(SourceLocation Loc, DiagnosticsEngine::Level Level,
69 SmallVectorImpl<CharSourceRange> &Ranges,
70 ArrayRef<FixItHint> Hints,
71 const SourceManager &SM) override {
72 assert(Loc.isValid());
73 for (const auto &FixIt : Hints) {
74 CharSourceRange Range = FixIt.RemoveRange;
75 assert(Range.getBegin().isValid() && Range.getEnd().isValid() &&
76 "Invalid range in the fix-it hint.");
77 assert(Range.getBegin().isFileID() && Range.getEnd().isFileID() &&
78 "Only file locations supported in fix-it hints.");
79
80 Error.Fix.insert(tooling::Replacement(SM, Range, FixIt.CodeToInsert));
81 }
82 }
83
84 void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
85 const SourceManager &SM) override {}
86
87 void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
88 StringRef ModuleName,
89 const SourceManager &SM) override {}
90
91 void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
92 StringRef ModuleName,
93 const SourceManager &SM) override {}
94
95 void endDiagnostic(DiagOrStoredDiag D,
96 DiagnosticsEngine::Level Level) override {
97 assert(!Error.Message.Message.empty() && "Message has not been set");
98 }
99
100 private:
101 ClangTidyError &Error;
102 };
103 } // end anonymous namespace
104
105 ClangTidyMessage::ClangTidyMessage(StringRef Message)
106 : Message(Message), FileOffset(0) {}
107
108 ClangTidyMessage::ClangTidyMessage(StringRef Message,
109 const SourceManager &Sources,
110 SourceLocation Loc)
111 : Message(Message) {
112 assert(Loc.isValid() && Loc.isFileID());
113 FilePath = Sources.getFilename(Loc);
114 FileOffset = Sources.getFileOffset(Loc);
115 }
116
117 ClangTidyError::ClangTidyError(StringRef CheckName,
118 ClangTidyError::Level DiagLevel)
119 : CheckName(CheckName), DiagLevel(DiagLevel) {}
120
121 // Returns true if GlobList starts with the negative indicator ('-'), removes it
122 // from the GlobList.
123 static bool ConsumeNegativeIndicator(StringRef &GlobList) {
124 if (GlobList.startswith("-")) {
125 GlobList = GlobList.substr(1);
126 return true;
127 }
128 return false;
129 }
130 // Converts first glob from the comma-separated list of globs to Regex and
131 // removes it and the trailing comma from the GlobList.
132 static llvm::Regex ConsumeGlob(StringRef &GlobList) {
133 StringRef Glob = GlobList.substr(0, GlobList.find(',')).trim();
134 GlobList = GlobList.substr(Glob.size() + 1);
135 SmallString<128> RegexText("^");
136 StringRef MetaChars("()^$|*+?.[]\\{}");
137 for (char C : Glob) {
138 if (C == '*')
139 RegexText.push_back('.');
140 else if (MetaChars.find(C) != StringRef::npos)
141 RegexText.push_back('\\');
142 RegexText.push_back(C);
143 }
144 RegexText.push_back('$');
145 return llvm::Regex(RegexText);
146 }
147
148 GlobList::GlobList(StringRef Globs)
149 : Positive(!ConsumeNegativeIndicator(Globs)), Regex(ConsumeGlob(Globs)),
150 NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {}
151
152 bool GlobList::contains(StringRef S, bool Contains) {
153 if (Regex.match(S))
154 Contains = Positive;
155
156 if (NextGlob)
157 Contains = NextGlob->contains(S, Contains);
158 return Contains;
159 }
160
161 ClangTidyContext::ClangTidyContext(
162 std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider)
163 : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)),
164 Profile(nullptr) {
165 // Before the first translation unit we can get errors related to command-line
166 // parsing, use empty string for the file name in this case.
167 setCurrentFile("");
168 }
169
170 DiagnosticBuilder ClangTidyContext::diag(
171 StringRef CheckName, SourceLocation Loc, StringRef Description,
172 DiagnosticIDs::Level Level /* = DiagnosticIDs::Warning*/) {
173 assert(Loc.isValid());
174 bool Invalid;
175 const char *CharacterData =
176 DiagEngine->getSourceManager().getCharacterData(Loc, &Invalid);
177 if (!Invalid) {
178 const char *P = CharacterData;
179 while (*P != '\0' && *P != '\r' && *P != '\n')
180 ++P;
181 StringRef RestOfLine(CharacterData, P - CharacterData + 1);
182 // FIXME: Handle /\bNOLINT\b(\([^)]*\))?/ as cpplint.py does.
183 if (RestOfLine.find("NOLINT") != StringRef::npos) {
184 Level = DiagnosticIDs::Ignored;
185 ++Stats.ErrorsIgnoredNOLINT;
186 }
187 }
188 unsigned ID = DiagEngine->getDiagnosticIDs()->getCustomDiagID(
189 Level, (Description + " [" + CheckName + "]").str());
190 if (CheckNamesByDiagnosticID.count(ID) == 0)
191 CheckNamesByDiagnosticID.insert(std::make_pair(ID, CheckName.str()));
192 return DiagEngine->Report(Loc, ID);
193 }
194
195 void ClangTidyContext::setDiagnosticsEngine(DiagnosticsEngine *Engine) {
196 DiagEngine = Engine;
197 }
198
199 void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) {
200 DiagEngine->setSourceManager(SourceMgr);
201 }
202
203 void ClangTidyContext::setCurrentFile(StringRef File) {
204 CurrentFile = File;
205 CurrentOptions = getOptionsForFile(CurrentFile);
206 CheckFilter.reset(new GlobList(*getOptions().Checks));
207 }
208
209 void ClangTidyContext::setASTContext(ASTContext *Context) {
210 DiagEngine->SetArgToStringFn(&FormatASTNodeDiagnosticArgument, Context);
211 LangOpts = Context->getLangOpts();
212 }
213
214 const ClangTidyGlobalOptions &ClangTidyContext::getGlobalOptions() const {
215 return OptionsProvider->getGlobalOptions();
216 }
217
218 const ClangTidyOptions &ClangTidyContext::getOptions() const {
219 return CurrentOptions;
220 }
221
222 ClangTidyOptions ClangTidyContext::getOptionsForFile(StringRef File) const {
223 // Merge options on top of getDefaults() as a safeguard against options with
224 // unset values.
225 return ClangTidyOptions::getDefaults().mergeWith(
226 OptionsProvider->getOptions(CurrentFile));
227 }
228
229 void ClangTidyContext::setCheckProfileData(ProfileData *P) { Profile = P; }
230
231 GlobList &ClangTidyContext::getChecksFilter() {
232 assert(CheckFilter != nullptr);
233 return *CheckFilter;
234 }
235
236 bool ClangTidyContext::isCheckEnabled(StringRef CheckName) const {
237 return CheckFilter->contains(CheckName);
238 }
239
240 /// \brief Store a \c ClangTidyError.
241 void ClangTidyContext::storeError(const ClangTidyError &Error) {
242 Errors.push_back(Error);
243 }
244
245 StringRef ClangTidyContext::getCheckName(unsigned DiagnosticID) const {
246 llvm::DenseMap<unsigned, std::string>::const_iterator I =
247 CheckNamesByDiagnosticID.find(DiagnosticID);
248 if (I != CheckNamesByDiagnosticID.end())
249 return I->second;
250 return "";
251 }
252
253 ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx)
254 : Context(Ctx), LastErrorRelatesToUserCode(false),
255 LastErrorPassesLineFilter(false) {
256 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
257 Diags.reset(new DiagnosticsEngine(
258 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts, this,
259 /*ShouldOwnClient=*/false));
260 Context.setDiagnosticsEngine(Diags.get());
261 }
262
263 void ClangTidyDiagnosticConsumer::finalizeLastError() {
264 if (!Errors.empty()) {
265 ClangTidyError &Error = Errors.back();
266 if (!Context.getChecksFilter().contains(Error.CheckName) &&
267 Error.DiagLevel != ClangTidyError::Error) {
268 ++Context.Stats.ErrorsIgnoredCheckFilter;
269 Errors.pop_back();
270 } else if (!LastErrorRelatesToUserCode) {
271 ++Context.Stats.ErrorsIgnoredNonUserCode;
272 Errors.pop_back();
273 } else if (!LastErrorPassesLineFilter) {
274 ++Context.Stats.ErrorsIgnoredLineFilter;
275 Errors.pop_back();
276 } else {
277 ++Context.Stats.ErrorsDisplayed;
278 }
279 }
280 LastErrorRelatesToUserCode = false;
281 LastErrorPassesLineFilter = false;
282 }
283
284 void ClangTidyDiagnosticConsumer::HandleDiagnostic(
285 DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
286 // Count warnings/errors.
287 DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
288
289 if (DiagLevel == DiagnosticsEngine::Note) {
290 assert(!Errors.empty() &&
291 "A diagnostic note can only be appended to a message.");
292 } else {
293 finalizeLastError();
294 StringRef WarningOption =
295 Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(
296 Info.getID());
297 std::string CheckName = !WarningOption.empty()
298 ? ("clang-diagnostic-" + WarningOption).str()
299 : Context.getCheckName(Info.getID()).str();
300
301 if (CheckName.empty()) {
302 // This is a compiler diagnostic without a warning option. Assign check
303 // name based on its level.
304 switch (DiagLevel) {
305 case DiagnosticsEngine::Error:
306 case DiagnosticsEngine::Fatal:
307 CheckName = "clang-diagnostic-error";
308 break;
309 case DiagnosticsEngine::Warning:
310 CheckName = "clang-diagnostic-warning";
311 break;
312 default:
313 CheckName = "clang-diagnostic-unknown";
314 break;
315 }
316 }
317
318 ClangTidyError::Level Level = ClangTidyError::Warning;
319 if (DiagLevel == DiagnosticsEngine::Error ||
320 DiagLevel == DiagnosticsEngine::Fatal) {
321 // Force reporting of Clang errors regardless of filters and non-user
322 // code.
323 Level = ClangTidyError::Error;
324 LastErrorRelatesToUserCode = true;
325 LastErrorPassesLineFilter = true;
326 }
327 Errors.push_back(ClangTidyError(CheckName, Level));
328 }
329
330 // FIXME: Provide correct LangOptions for each file.
331 LangOptions LangOpts;
332 ClangTidyDiagnosticRenderer Converter(
333 LangOpts, &Context.DiagEngine->getDiagnosticOptions(), Errors.back());
334 SmallString<100> Message;
335 Info.FormatDiagnostic(Message);
336 SourceManager *Sources = nullptr;
337 if (Info.hasSourceManager())
338 Sources = &Info.getSourceManager();
339 Converter.emitDiagnostic(Info.getLocation(), DiagLevel, Message,
340 Info.getRanges(), Info.getFixItHints(), Sources);
341
342 checkFilters(Info.getLocation());
343 }
344
345 bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName,
346 unsigned LineNumber) const {
347 if (Context.getGlobalOptions().LineFilter.empty())
348 return true;
349 for (const FileFilter &Filter : Context.getGlobalOptions().LineFilter) {
350 if (FileName.endswith(Filter.Name)) {
351 if (Filter.LineRanges.empty())
352 return true;
353 for (const FileFilter::LineRange &Range : Filter.LineRanges) {
354 if (Range.first <= LineNumber && LineNumber <= Range.second)
355 return true;
356 }
357 return false;
358 }
359 }
360 return false;
361 }
362
363 void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location) {
364 // Invalid location may mean a diagnostic in a command line, don't skip these.
365 if (!Location.isValid()) {
366 LastErrorRelatesToUserCode = true;
367 LastErrorPassesLineFilter = true;
368 return;
369 }
370
371 const SourceManager &Sources = Diags->getSourceManager();
372 if (!*Context.getOptions().SystemHeaders &&
373 Sources.isInSystemHeader(Location))
374 return;
375
376 // FIXME: We start with a conservative approach here, but the actual type of
377 // location needed depends on the check (in particular, where this check wants
378 // to apply fixes).
379 FileID FID = Sources.getDecomposedExpansionLoc(Location).first;
380 const FileEntry *File = Sources.getFileEntryForID(FID);
381
382 // -DMACRO definitions on the command line have locations in a virtual buffer
383 // that doesn't have a FileEntry. Don't skip these as well.
384 if (!File) {
385 LastErrorRelatesToUserCode = true;
386 LastErrorPassesLineFilter = true;
387 return;
388 }
389
390 StringRef FileName(File->getName());
391 LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
392 Sources.isInMainFile(Location) ||
393 getHeaderFilter()->match(FileName);
394
395 unsigned LineNumber = Sources.getExpansionLineNumber(Location);
396 LastErrorPassesLineFilter =
397 LastErrorPassesLineFilter || passesLineFilter(FileName, LineNumber);
398 }
399
400 llvm::Regex *ClangTidyDiagnosticConsumer::getHeaderFilter() {
401 if (!HeaderFilter)
402 HeaderFilter.reset(
403 new llvm::Regex(*Context.getOptions().HeaderFilterRegex));
404 return HeaderFilter.get();
405 }
406
407 void ClangTidyDiagnosticConsumer::removeIncompatibleErrors(
408 SmallVectorImpl<ClangTidyError> &Errors) const {
409 // Each error is modelled as the set of intervals in which it applies
410 // replacements. To detect overlapping replacements, we use a sweep line
411 // algorithm over these sets of intervals.
412 // An event here consists of the opening or closing of an interval. During the
413 // proccess, we maintain a counter with the amount of open intervals. If we
414 // find an endpoint of an interval and this counter is different from 0, it
415 // means that this interval overlaps with another one, so we set it as
416 // inapplicable.
417 struct Event {
418 // An event can be either the begin or the end of an interval.
419 enum EventType {
420 ET_Begin = 1,
421 ET_End = -1,
422 };
423
424 Event(unsigned Begin, unsigned End, EventType Type, unsigned ErrorId,
425 unsigned ErrorSize)
426 : Type(Type), ErrorId(ErrorId) {
427 // The events are going to be sorted by their position. In case of draw:
428 //
429 // * If an interval ends at the same position at which other interval
430 // begins, this is not an overlapping, so we want to remove the ending
431 // interval before adding the starting one: end events have higher
432 // priority than begin events.
433 //
434 // * If we have several begin points at the same position, we will mark as
435 // inapplicable the ones that we proccess later, so the first one has to
436 // be the one with the latest end point, because this one will contain
437 // all the other intervals. For the same reason, if we have several end
438 // points in the same position, the last one has to be the one with the
439 // earliest begin point. In both cases, we sort non-increasingly by the
440 // position of the complementary.
441 //
442 // * In case of two equal intervals, the one whose error is bigger can
443 // potentially contain the other one, so we want to proccess its begin
444 // points before and its end points later.
445 //
446 // * Finally, if we have two equal intervals whose errors have the same
447 // size, none of them will be strictly contained inside the other.
448 // Sorting by ErrorId will guarantee that the begin point of the first
449 // one will be proccessed before, disallowing the second one, and the
450 // end point of the first one will also be proccessed before,
451 // disallowing the first one.
452 if (Type == ET_Begin)
453 Priority = std::make_tuple(Begin, Type, -End, -ErrorSize, ErrorId);
454 else
455 Priority = std::make_tuple(End, Type, -Begin, ErrorSize, ErrorId);
456 }
457
458 bool operator<(const Event &Other) const {
459 return Priority < Other.Priority;
460 }
461
462 // Determines if this event is the begin or the end of an interval.
463 EventType Type;
464 // The index of the error to which the interval that generated this event
465 // belongs.
466 unsigned ErrorId;
467 // The events will be sorted based on this field.
468 std::tuple<unsigned, EventType, int, int, unsigned> Priority;
469 };
470
471 // Compute error sizes.
472 std::vector<int> Sizes;
473 for (const auto &Error : Errors) {
474 int Size = 0;
475 for (const auto &Replace : Error.Fix)
476 Size += Replace.getLength();
477 Sizes.push_back(Size);
478 }
479
480 // Build events from error intervals.
481 std::map<std::string, std::vector<Event>> FileEvents;
482 for (unsigned I = 0; I < Errors.size(); ++I) {
483 for (const auto &Replace : Errors[I].Fix) {
484 unsigned Begin = Replace.getOffset();
485 unsigned End = Begin + Replace.getLength();
486 const std::string &FilePath = Replace.getFilePath();
487 // FIXME: Handle empty intervals, such as those from insertions.
488 if (Begin == End)
489 continue;
490 FileEvents[FilePath].push_back(
491 Event(Begin, End, Event::ET_Begin, I, Sizes[I]));
492 FileEvents[FilePath].push_back(
493 Event(Begin, End, Event::ET_End, I, Sizes[I]));
494 }
495 }
496
497 std::vector<bool> Apply(Errors.size(), true);
498 for (auto &FileAndEvents : FileEvents) {
499 std::vector<Event> &Events = FileAndEvents.second;
500 // Sweep.
501 std::sort(Events.begin(), Events.end());
502 int OpenIntervals = 0;
503 for (const auto &Event : Events) {
504 if (Event.Type == Event::ET_End)
505 --OpenIntervals;
506 // This has to be checked after removing the interval from the count if it
507 // is an end event, or before adding it if it is a begin event.
508 if (OpenIntervals != 0)
509 Apply[Event.ErrorId] = false;
510 if (Event.Type == Event::ET_Begin)
511 ++OpenIntervals;
512 }
513 assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
514 }
515
516 for (unsigned I = 0; I < Errors.size(); ++I) {
517 if (!Apply[I]) {
518 Errors[I].Fix.clear();
519 Errors[I].Notes.push_back(
520 ClangTidyMessage("this fix will not be applied because"
521 " it overlaps with another fix"));
522 }
523 }
524 }
525
526 namespace {
527 struct LessClangTidyError {
528 bool operator()(const ClangTidyError &LHS, const ClangTidyError &RHS) const {
529 const ClangTidyMessage &M1 = LHS.Message;
530 const ClangTidyMessage &M2 = RHS.Message;
531
532 return std::tie(M1.FilePath, M1.FileOffset, M1.Message) <
533 std::tie(M2.FilePath, M2.FileOffset, M2.Message);
534 }
535 };
536 struct EqualClangTidyError {
537 bool operator()(const ClangTidyError &LHS, const ClangTidyError &RHS) const {
538 LessClangTidyError Less;
539 return !Less(LHS, RHS) && !Less(RHS, LHS);
540 }
541 };
542 } // end anonymous namespace
543
544 // Flushes the internal diagnostics buffer to the ClangTidyContext.
545 void ClangTidyDiagnosticConsumer::finish() {
546 finalizeLastError();
547
548 std::sort(Errors.begin(), Errors.end(), LessClangTidyError());
549 Errors.erase(std::unique(Errors.begin(), Errors.end(), EqualClangTidyError()),
550 Errors.end());
551 removeIncompatibleErrors(Errors);
552
553 for (const ClangTidyError &Error : Errors)
554 Context.storeError(Error);
555 Errors.clear();
556 }
Loc
SourceLocation Loc
'#' location in the include directive
Definition: IncludeOrderCheck.cpp:34
clang::tidy::ClangTidyMessage::Message
std::string Message
Definition: ClangTidyDiagnosticConsumer.h:42
LangOpts
LangOptions LangOpts
Definition: ClangTidy.cpp:168
clang::tidy::GlobList
Read-only set of strings represented as a list of positive and negative globs.
Definition: ClangTidyDiagnosticConsumer.h:73
clang::tidy::GlobList::GlobList
GlobList(StringRef Globs)
GlobList is a comma-separated list of globs (only '*' metacharacter is supported) with optional '-' p...
Definition: ClangTidyDiagnosticConsumer.cpp:148
Checks
std::vector< std::unique_ptr< ClangTidyCheck > > Checks
Definition: ClangTidy.cpp:189
File
HeaderHandle File
Definition: PreprocessorTracker.cpp:526
clang::tidy::ClangTidyDiagnosticConsumer::finish
void finish() override
Flushes the internal diagnostics buffer to the ClangTidyContext.
Definition: ClangTidyDiagnosticConsumer.cpp:545
clang::tidy::GlobList::contains
bool contains(StringRef S)
Returns true if the pattern matches S.
Definition: ClangTidyDiagnosticConsumer.h:81
clang::tidy::ClangTidyMessage
A message from a clang-tidy check.
Definition: ClangTidyDiagnosticConsumer.h:38
clang::tidy::ClangTidyError::CheckName
std::string CheckName
Definition: ClangTidyDiagnosticConsumer.h:62
clang::tidy::ClangTidyOptions::HeaderFilterRegex
llvm::Optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
Definition: ClangTidyOptions.h:67
clang::tidy::ClangTidyMessage::ClangTidyMessage
ClangTidyMessage(StringRef Message="")
Definition: ClangTidyDiagnosticConsumer.cpp:105
clang::tidy::ClangTidyOptions
Contains options for clang-tidy.
Definition: ClangTidyOptions.h:49
clang::tidy::ClangTidyStats::ErrorsIgnoredCheckFilter
unsigned ErrorsIgnoredCheckFilter
Definition: ClangTidyDiagnosticConsumer.h:99
clang::tidy::ClangTidyDiagnosticConsumer::ClangTidyDiagnosticConsumer
ClangTidyDiagnosticConsumer(ClangTidyContext &Ctx)
Definition: ClangTidyDiagnosticConsumer.cpp:253
clang::tidy::ClangTidyGlobalOptions
Global options.
Definition: ClangTidyOptions.h:41
ConsumeNegativeIndicator
static bool ConsumeNegativeIndicator(StringRef &GlobList)
Definition: ClangTidyDiagnosticConsumer.cpp:123
clang::tidy::ClangTidyStats::ErrorsIgnoredNOLINT
unsigned ErrorsIgnoredNOLINT
Definition: ClangTidyDiagnosticConsumer.h:100
clang::tidy::ClangTidyOptions::SystemHeaders
llvm::Optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
Definition: ClangTidyOptions.h:70
ClangTidyOptions.h
SourceMgr
SourceManager SourceMgr
Definition: ClangTidy.cpp:172
clang::tidy::ClangTidyContext::getOptionsForFile
ClangTidyOptions getOptionsForFile(StringRef File) const
Returns options for File.
Definition: ClangTidyDiagnosticConsumer.cpp:222
SM
SourceManager & SM
Definition: IncludeOrderCheck.cpp:44
clang::tidy::ClangTidyError::Message
ClangTidyMessage Message
Definition: ClangTidyDiagnosticConsumer.h:63
clang::tidy::FileFilter::LineRange
std::pair< unsigned, unsigned > LineRange
LineRange is a pair<start, end> (inclusive).
Definition: ClangTidyOptions.h:33
clang::tidy::ClangTidyContext::setCurrentFile
void setCurrentFile(StringRef File)
Should be called when starting to process new translation unit.
Definition: ClangTidyDiagnosticConsumer.cpp:203
clang::tidy::ClangTidyContext::getOptions
const ClangTidyOptions & getOptions() const
Returns options for CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:218
clang::tidy::ClangTidyError::Level
Level
Definition: ClangTidyDiagnosticConsumer.h:55
ConsumeGlob
static llvm::Regex ConsumeGlob(StringRef &GlobList)
Definition: ClangTidyDiagnosticConsumer.cpp:132
clang::tidy::ClangTidyContext::diag
DiagnosticBuilder diag(StringRef CheckName, SourceLocation Loc, StringRef Message, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Report any errors detected using this method.
Definition: ClangTidyDiagnosticConsumer.cpp:170
clang::tidy::ClangTidyStats::ErrorsIgnoredNonUserCode
unsigned ErrorsIgnoredNonUserCode
Definition: ClangTidyDiagnosticConsumer.h:101
ClangTidyDiagnosticConsumer.h
clang::tidy::ClangTidyContext::setCheckProfileData
void setCheckProfileData(ProfileData *Profile)
Set the output struct for profile data.
Definition: ClangTidyDiagnosticConsumer.cpp:229
clang::tidy::ClangTidyContext::ClangTidyContext
ClangTidyContext(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider)
Initializes ClangTidyContext instance.
Definition: ClangTidyDiagnosticConsumer.cpp:161
clang::tidy::ClangTidyContext::setASTContext
void setASTContext(ASTContext *Context)
Sets ASTContext for the current translation unit.
Definition: ClangTidyDiagnosticConsumer.cpp:209
clang::tidy::ClangTidyError::DiagLevel
Level DiagLevel
Definition: ClangTidyDiagnosticConsumer.h:67
clang::tidy::ClangTidyGlobalOptions::LineFilter
std::vector< FileFilter > LineFilter
Output warnings from certain line ranges of certain files only.
Definition: ClangTidyOptions.h:44
clang::tidy::ClangTidyOptions::mergeWith
ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const
Creates a new ClangTidyOptions instance combined from all fields of this instance overridden by the f...
Definition: ClangTidyOptions.cpp:118
clang::tidy::ClangTidyStats::ErrorsIgnoredLineFilter
unsigned ErrorsIgnoredLineFilter
Definition: ClangTidyDiagnosticConsumer.h:102
clang::tidy::ClangTidyError::ClangTidyError
ClangTidyError(StringRef CheckName, Level DiagLevel)
Definition: ClangTidyDiagnosticConsumer.cpp:117
clang::tidy::ClangTidyContext::getGlobalOptions
const ClangTidyGlobalOptions & getGlobalOptions() const
Returns global options.
Definition: ClangTidyDiagnosticConsumer.cpp:214
clang::tidy::ClangTidyContext::setSourceManager
void setSourceManager(SourceManager *SourceMgr)
Sets the SourceManager of the used DiagnosticsEngine.
Definition: ClangTidyDiagnosticConsumer.cpp:199
clang::tidy::FileFilter
Contains a list of line ranges in a single file.
Definition: ClangTidyOptions.h:28
clang::tidy::ClangTidyError::Error
Definition: ClangTidyDiagnosticConsumer.h:57
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:35
clang::tidy::ClangTidyContext::getCheckName
StringRef getCheckName(unsigned DiagnosticID) const
Returns the name of the clang-tidy check which produced this diagnostic ID.
Definition: ClangTidyDiagnosticConsumer.cpp:245
clang::tidy::ClangTidyError
A detected error complete with information to display diagnostic and automatic fix.
Definition: ClangTidyDiagnosticConsumer.h:54
DiagOpts
IntrusiveRefCntPtr< DiagnosticOptions > DiagOpts
Definition: ClangTidy.cpp:169
Context
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
clang::tidy::ClangTidyStats::ErrorsDisplayed
unsigned ErrorsDisplayed
Definition: ClangTidyDiagnosticConsumer.h:98
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:124
clang::tidy::ClangTidyError::Warning
Definition: ClangTidyDiagnosticConsumer.h:56
clang::tidy::ClangTidyOptions::getDefaults
static ClangTidyOptions getDefaults()
These options are used for all settings that haven't been overridden by the OptionsProvider.
Definition: ClangTidyOptions.cpp:103
clang::tidy::ClangTidyError::Fix
tooling::Replacements Fix
Definition: ClangTidyDiagnosticConsumer.h:64
Fix
static cl::opt< bool > Fix("fix", cl::desc("Apply suggested fixes. Without -fix-errors\n""clang-tidy will bail out if any compilation\n""errors were found."), cl::init(false), cl::cat(ClangTidyCategory))
clang::tidy::ClangTidyDiagnosticConsumer::HandleDiagnostic
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override
Definition: ClangTidyDiagnosticConsumer.cpp:284
clang::tidy::ClangTidyContext::isCheckEnabled
bool isCheckEnabled(StringRef CheckName) const
Returns true if the check name is enabled for the CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:236
clang::tidy::ClangTidyContext::getChecksFilter
GlobList & getChecksFilter()
Returns check filter for the CurrentFile.
Definition: ClangTidyDiagnosticConsumer.cpp:231
clang::tidy::ProfileData
Container for clang-tidy profiling data.
Definition: ClangTidyDiagnosticConsumer.h:111
clang::tidy::ClangTidyMessage::FileOffset
unsigned FileOffset
Definition: ClangTidyDiagnosticConsumer.h:44
clang::tidy::ClangTidyMessage::FilePath
std::string FilePath
Definition: ClangTidyDiagnosticConsumer.h:43
Location
Definition: Modularize.cpp:386