DiagnosticIDs.cpp revision f3dee206ffa571b4541b8e777ee31dc8476d66da
1//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
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//  This file implements the Diagnostic IDs-related interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTDiagnostic.h"
15#include "clang/Analysis/AnalysisDiagnostic.h"
16#include "clang/Basic/DiagnosticIDs.h"
17#include "clang/Basic/DiagnosticCategories.h"
18#include "clang/Basic/SourceManager.h"
19#include "clang/Driver/DriverDiagnostic.h"
20#include "clang/Frontend/FrontendDiagnostic.h"
21#include "clang/Lex/LexDiagnostic.h"
22#include "clang/Parse/ParseDiagnostic.h"
23#include "clang/Sema/SemaDiagnostic.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Support/ErrorHandling.h"
26
27#include <map>
28using namespace clang;
29
30//===----------------------------------------------------------------------===//
31// Builtin Diagnostic information
32//===----------------------------------------------------------------------===//
33
34namespace {
35
36// Diagnostic classes.
37enum {
38  CLASS_NOTE       = 0x01,
39  CLASS_WARNING    = 0x02,
40  CLASS_EXTENSION  = 0x03,
41  CLASS_ERROR      = 0x04
42};
43
44struct StaticDiagInfoRec {
45  unsigned short DiagID;
46  unsigned Mapping : 3;
47  unsigned Class : 3;
48  unsigned SFINAE : 1;
49  unsigned AccessControl : 1;
50  unsigned WarnNoWerror : 1;
51  unsigned WarnShowInSystemHeader : 1;
52  unsigned Category : 5;
53
54  uint8_t  NameLen;
55  uint8_t  OptionGroupLen;
56
57  uint16_t DescriptionLen;
58  uint16_t BriefExplanationLen;
59  uint16_t FullExplanationLen;
60
61  const char *NameStr;
62  const char *OptionGroupStr;
63
64  const char *DescriptionStr;
65  const char *BriefExplanationStr;
66  const char *FullExplanationStr;
67
68  StringRef getName() const {
69    return StringRef(NameStr, NameLen);
70  }
71  StringRef getOptionGroup() const {
72    return StringRef(OptionGroupStr, OptionGroupLen);
73  }
74
75  StringRef getDescription() const {
76    return StringRef(DescriptionStr, DescriptionLen);
77  }
78  StringRef getBriefExplanation() const {
79    return StringRef(BriefExplanationStr, BriefExplanationLen);
80  }
81  StringRef getFullExplanation() const {
82    return StringRef(FullExplanationStr, FullExplanationLen);
83  }
84
85  bool operator<(const StaticDiagInfoRec &RHS) const {
86    return DiagID < RHS.DiagID;
87  }
88};
89
90struct StaticDiagNameIndexRec {
91  const char *NameStr;
92  unsigned short DiagID;
93  uint8_t NameLen;
94
95  StringRef getName() const {
96    return StringRef(NameStr, NameLen);
97  }
98
99  bool operator<(const StaticDiagNameIndexRec &RHS) const {
100    return getName() < RHS.getName();
101  }
102
103  bool operator==(const StaticDiagNameIndexRec &RHS) const {
104    return getName() == RHS.getName();
105  }
106};
107
108template <size_t SizeOfStr, typename FieldType>
109class StringSizerHelper {
110  char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
111public:
112  enum { Size = SizeOfStr };
113};
114
115} // namespace anonymous
116
117#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size
118
119static const StaticDiagInfoRec StaticDiagInfo[] = {
120#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,               \
121             SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER,              \
122             CATEGORY,BRIEF,FULL)                                 \
123  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS,           \
124    NOWERROR, SHOWINSYSHEADER, CATEGORY,                          \
125    STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t),           \
126    STR_SIZE(DESC, uint16_t), STR_SIZE(BRIEF, uint16_t),          \
127    STR_SIZE(FULL, uint16_t),                                     \
128    #ENUM, GROUP, DESC, BRIEF, FULL },
129#include "clang/Basic/DiagnosticCommonKinds.inc"
130#include "clang/Basic/DiagnosticDriverKinds.inc"
131#include "clang/Basic/DiagnosticFrontendKinds.inc"
132#include "clang/Basic/DiagnosticLexKinds.inc"
133#include "clang/Basic/DiagnosticParseKinds.inc"
134#include "clang/Basic/DiagnosticASTKinds.inc"
135#include "clang/Basic/DiagnosticSemaKinds.inc"
136#include "clang/Basic/DiagnosticAnalysisKinds.inc"
137#undef DIAG
138  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
139};
140
141static const unsigned StaticDiagInfoSize =
142  sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
143
144/// To be sorted before first use (since it's splitted among multiple files)
145static const StaticDiagNameIndexRec StaticDiagNameIndex[] = {
146#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
147#include "clang/Basic/DiagnosticIndexName.inc"
148#undef DIAG_NAME_INDEX
149  { 0, 0, 0 }
150};
151
152static const unsigned StaticDiagNameIndexSize =
153  sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1;
154
155/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
156/// or null if the ID is invalid.
157static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
158  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
159#ifndef NDEBUG
160  static bool IsFirst = true;
161  if (IsFirst) {
162    for (unsigned i = 1; i != StaticDiagInfoSize; ++i) {
163      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
164             "Diag ID conflict, the enums at the start of clang::diag (in "
165             "DiagnosticIDs.h) probably need to be increased");
166
167      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
168             "Improperly sorted diag info");
169    }
170    IsFirst = false;
171  }
172#endif
173
174  // Search the diagnostic table with a binary search.
175  StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID),
176                             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
177
178  const StaticDiagInfoRec *Found =
179    std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
180  if (Found == StaticDiagInfo + StaticDiagInfoSize ||
181      Found->DiagID != DiagID)
182    return 0;
183
184  return Found;
185}
186
187static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
188  DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
189    diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
190
191  if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
192    Info.setMapping((diag::Mapping) StaticInfo->Mapping);
193
194    if (StaticInfo->WarnNoWerror) {
195      assert(Info.getMapping() == diag::MAP_WARNING &&
196             "Unexpected mapping with no-Werror bit!");
197      Info.setNoWarningAsError(true);
198    }
199
200    if (StaticInfo->WarnShowInSystemHeader) {
201      assert(Info.getMapping() == diag::MAP_WARNING &&
202             "Unexpected mapping with show-in-system-header bit!");
203      Info.setShowInSystemHeader(true);
204    }
205  }
206
207  return Info;
208}
209
210/// getWarningOptionForDiag - Return the lowest-level warning option that
211/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
212/// the diagnostic, this returns null.
213StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
214  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
215    return Info->getOptionGroup();
216  return StringRef();
217}
218
219/// getCategoryNumberForDiag - Return the category number that a specified
220/// DiagID belongs to, or 0 if no category.
221unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
222  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
223    return Info->Category;
224  return 0;
225}
226
227namespace {
228  // The diagnostic category names.
229  struct StaticDiagCategoryRec {
230    const char *NameStr;
231    uint8_t NameLen;
232
233    StringRef getName() const {
234      return StringRef(NameStr, NameLen);
235    }
236  };
237}
238
239// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
240// particularly clean, but for now we just implement this method here so we can
241// access GetDefaultDiagMapping.
242DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo(
243  diag::kind Diag)
244{
245  std::pair<iterator, bool> Result = DiagMap.insert(
246    std::make_pair(Diag, DiagnosticMappingInfo()));
247
248  // Initialize the entry if we added it.
249  if (Result.second)
250    Result.first->second = GetDefaultDiagMappingInfo(Diag);
251
252  return Result.first->second;
253}
254
255static const StaticDiagCategoryRec CategoryNameTable[] = {
256#define GET_CATEGORY_TABLE
257#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
258#include "clang/Basic/DiagnosticGroups.inc"
259#undef GET_CATEGORY_TABLE
260  { 0, 0 }
261};
262
263/// getNumberOfCategories - Return the number of categories
264unsigned DiagnosticIDs::getNumberOfCategories() {
265  return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
266}
267
268/// getCategoryNameFromID - Given a category ID, return the name of the
269/// category, an empty string if CategoryID is zero, or null if CategoryID is
270/// invalid.
271StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
272  if (CategoryID >= getNumberOfCategories())
273   return StringRef();
274  return CategoryNameTable[CategoryID].getName();
275}
276
277
278
279DiagnosticIDs::SFINAEResponse
280DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
281  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
282    if (Info->AccessControl)
283      return SFINAE_AccessControl;
284
285    if (!Info->SFINAE)
286      return SFINAE_Report;
287
288    if (Info->Class == CLASS_ERROR)
289      return SFINAE_SubstitutionFailure;
290
291    // Suppress notes, warnings, and extensions;
292    return SFINAE_Suppress;
293  }
294
295  return SFINAE_Report;
296}
297
298/// getName - Given a diagnostic ID, return its name
299StringRef DiagnosticIDs::getName(unsigned DiagID) {
300  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
301    return Info->getName();
302  return StringRef();
303}
304
305/// getIdFromName - Given a diagnostic name, return its ID, or 0
306unsigned DiagnosticIDs::getIdFromName(StringRef Name) {
307  const StaticDiagNameIndexRec *StaticDiagNameIndexEnd =
308    StaticDiagNameIndex + StaticDiagNameIndexSize;
309
310  if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; }
311
312  assert(Name.size() == static_cast<uint8_t>(Name.size()) &&
313         "Name is too long");
314  StaticDiagNameIndexRec Find = { Name.data(), 0,
315                                  static_cast<uint8_t>(Name.size()) };
316
317  const StaticDiagNameIndexRec *Found =
318    std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find);
319  if (Found == StaticDiagNameIndexEnd ||
320      Found->getName() != Name)
321    return diag::DIAG_UPPER_LIMIT;
322
323  return Found->DiagID;
324}
325
326/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
327/// of the issue
328StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
329  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
330    return Info->getBriefExplanation();
331  return StringRef();
332}
333
334/// getFullExplanation - Given a diagnostic ID, return a full explanation
335/// of the issue
336StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) {
337  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
338    return Info->getFullExplanation();
339  return StringRef();
340}
341
342/// getBuiltinDiagClass - Return the class field of the diagnostic.
343///
344static unsigned getBuiltinDiagClass(unsigned DiagID) {
345  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
346    return Info->Class;
347  return ~0U;
348}
349
350//===----------------------------------------------------------------------===//
351// diag_iterator
352//===----------------------------------------------------------------------===//
353
354llvm::StringRef DiagnosticIDs::diag_iterator::getDiagName() const {
355  return static_cast<const StaticDiagNameIndexRec*>(impl)->getName();
356}
357
358unsigned DiagnosticIDs::diag_iterator::getDiagID() const {
359  return static_cast<const StaticDiagNameIndexRec*>(impl)->DiagID;
360}
361
362DiagnosticIDs::diag_iterator &DiagnosticIDs::diag_iterator::operator++() {
363  const StaticDiagNameIndexRec* ptr =
364    static_cast<const StaticDiagNameIndexRec*>(impl);;
365  ++ptr;
366  impl = ptr;
367  return *this;
368}
369
370DiagnosticIDs::diag_iterator DiagnosticIDs::diags_begin() {
371  return DiagnosticIDs::diag_iterator(StaticDiagNameIndex);
372}
373
374DiagnosticIDs::diag_iterator DiagnosticIDs::diags_end() {
375  return DiagnosticIDs::diag_iterator(StaticDiagNameIndex +
376                                      StaticDiagNameIndexSize);
377}
378
379//===----------------------------------------------------------------------===//
380// Custom Diagnostic information
381//===----------------------------------------------------------------------===//
382
383namespace clang {
384  namespace diag {
385    class CustomDiagInfo {
386      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
387      std::vector<DiagDesc> DiagInfo;
388      std::map<DiagDesc, unsigned> DiagIDs;
389    public:
390
391      /// getDescription - Return the description of the specified custom
392      /// diagnostic.
393      StringRef getDescription(unsigned DiagID) const {
394        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
395               "Invalid diagnosic ID");
396        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
397      }
398
399      /// getLevel - Return the level of the specified custom diagnostic.
400      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
401        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
402               "Invalid diagnosic ID");
403        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
404      }
405
406      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
407                                 DiagnosticIDs &Diags) {
408        DiagDesc D(L, Message);
409        // Check to see if it already exists.
410        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
411        if (I != DiagIDs.end() && I->first == D)
412          return I->second;
413
414        // If not, assign a new ID.
415        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
416        DiagIDs.insert(std::make_pair(D, ID));
417        DiagInfo.push_back(D);
418        return ID;
419      }
420    };
421
422  } // end diag namespace
423} // end clang namespace
424
425
426//===----------------------------------------------------------------------===//
427// Common Diagnostic implementation
428//===----------------------------------------------------------------------===//
429
430DiagnosticIDs::DiagnosticIDs() {
431  CustomDiagInfo = 0;
432}
433
434DiagnosticIDs::~DiagnosticIDs() {
435  delete CustomDiagInfo;
436}
437
438/// getCustomDiagID - Return an ID for a diagnostic with the specified message
439/// and level.  If this is the first request for this diagnosic, it is
440/// registered and created, otherwise the existing ID is returned.
441unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) {
442  if (CustomDiagInfo == 0)
443    CustomDiagInfo = new diag::CustomDiagInfo();
444  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
445}
446
447
448/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
449/// level of the specified diagnostic ID is a Warning or Extension.
450/// This only works on builtin diagnostics, not custom ones, and is not legal to
451/// call on NOTEs.
452bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
453  return DiagID < diag::DIAG_UPPER_LIMIT &&
454         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
455}
456
457/// \brief Determine whether the given built-in diagnostic ID is a
458/// Note.
459bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
460  return DiagID < diag::DIAG_UPPER_LIMIT &&
461    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
462}
463
464/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
465/// ID is for an extension of some sort.  This also returns EnabledByDefault,
466/// which is set to indicate whether the diagnostic is ignored by default (in
467/// which case -pedantic enables it) or treated as a warning/error by default.
468///
469bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
470                                        bool &EnabledByDefault) {
471  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
472      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
473    return false;
474
475  EnabledByDefault =
476    GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
477  return true;
478}
479
480bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
481  if (DiagID >= diag::DIAG_UPPER_LIMIT)
482    return false;
483
484  return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
485}
486
487/// getDescription - Given a diagnostic ID, return a description of the
488/// issue.
489StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
490  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
491    return Info->getDescription();
492  return CustomDiagInfo->getDescription(DiagID);
493}
494
495/// getDiagnosticLevel - Based on the way the client configured the
496/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
497/// by consumable the DiagnosticClient.
498DiagnosticIDs::Level
499DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
500                                  const DiagnosticsEngine &Diag) const {
501  // Handle custom diagnostics, which cannot be mapped.
502  if (DiagID >= diag::DIAG_UPPER_LIMIT)
503    return CustomDiagInfo->getLevel(DiagID);
504
505  unsigned DiagClass = getBuiltinDiagClass(DiagID);
506  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
507  return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
508}
509
510/// \brief Based on the way the client configured the Diagnostic
511/// object, classify the specified diagnostic ID into a Level, consumable by
512/// the DiagnosticClient.
513///
514/// \param Loc The source location we are interested in finding out the
515/// diagnostic state. Can be null in order to query the latest state.
516DiagnosticIDs::Level
517DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
518                                  SourceLocation Loc,
519                                  const DiagnosticsEngine &Diag) const {
520  // Specific non-error diagnostics may be mapped to various levels from ignored
521  // to error.  Errors can only be mapped to fatal.
522  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
523
524  DiagnosticsEngine::DiagStatePointsTy::iterator
525    Pos = Diag.GetDiagStatePointForLoc(Loc);
526  DiagnosticsEngine::DiagState *State = Pos->State;
527
528  // Get the mapping information, or compute it lazily.
529  DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
530    (diag::kind)DiagID);
531
532  switch (MappingInfo.getMapping()) {
533  default: llvm_unreachable("Unknown mapping!");
534  case diag::MAP_IGNORE:
535    Result = DiagnosticIDs::Ignored;
536    break;
537  case diag::MAP_WARNING:
538    Result = DiagnosticIDs::Warning;
539    break;
540  case diag::MAP_ERROR:
541    Result = DiagnosticIDs::Error;
542    break;
543  case diag::MAP_FATAL:
544    Result = DiagnosticIDs::Fatal;
545    break;
546  }
547
548  // Upgrade ignored diagnostics if -Weverything is enabled.
549  if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
550      !MappingInfo.isUser())
551    Result = DiagnosticIDs::Warning;
552
553  // Ignore -pedantic diagnostics inside __extension__ blocks.
554  // (The diagnostics controlled by -pedantic are the extension diagnostics
555  // that are not enabled by default.)
556  bool EnabledByDefault = false;
557  bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
558  if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
559    return DiagnosticIDs::Ignored;
560
561  // For extension diagnostics that haven't been explicitly mapped, check if we
562  // should upgrade the diagnostic.
563  if (IsExtensionDiag && !MappingInfo.isUser()) {
564    switch (Diag.ExtBehavior) {
565    case DiagnosticsEngine::Ext_Ignore:
566      break;
567    case DiagnosticsEngine::Ext_Warn:
568      // Upgrade ignored diagnostics to warnings.
569      if (Result == DiagnosticIDs::Ignored)
570        Result = DiagnosticIDs::Warning;
571      break;
572    case DiagnosticsEngine::Ext_Error:
573      // Upgrade ignored or warning diagnostics to errors.
574      if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
575        Result = DiagnosticIDs::Error;
576      break;
577    }
578  }
579
580  // At this point, ignored errors can no longer be upgraded.
581  if (Result == DiagnosticIDs::Ignored)
582    return Result;
583
584  // Honor -w, which is lower in priority than pedantic-errors, but higher than
585  // -Werror.
586  if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
587    return DiagnosticIDs::Ignored;
588
589  // If -Werror is enabled, map warnings to errors unless explicitly disabled.
590  if (Result == DiagnosticIDs::Warning) {
591    if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
592      Result = DiagnosticIDs::Error;
593  }
594
595  // If -Wfatal-errors is enabled, map errors to fatal unless explicity
596  // disabled.
597  if (Result == DiagnosticIDs::Error) {
598    if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
599      Result = DiagnosticIDs::Fatal;
600  }
601
602  // If we are in a system header, we ignore it. We look at the diagnostic class
603  // because we also want to ignore extensions and warnings in -Werror and
604  // -pedantic-errors modes, which *map* warnings/extensions to errors.
605  if (Result >= DiagnosticIDs::Warning &&
606      DiagClass != CLASS_ERROR &&
607      // Custom diagnostics always are emitted in system headers.
608      DiagID < diag::DIAG_UPPER_LIMIT &&
609      !MappingInfo.hasShowInSystemHeader() &&
610      Diag.SuppressSystemWarnings &&
611      Loc.isValid() &&
612      Diag.getSourceManager().isInSystemHeader(
613          Diag.getSourceManager().getExpansionLoc(Loc)))
614    return DiagnosticIDs::Ignored;
615
616  return Result;
617}
618
619struct clang::WarningOption {
620  // Be safe with the size of 'NameLen' because we don't statically check if
621  // the size will fit in the field; the struct size won't decrease with a
622  // shorter type anyway.
623  size_t NameLen;
624  const char *NameStr;
625  const short *Members;
626  const short *SubGroups;
627
628  StringRef getName() const {
629    return StringRef(NameStr, NameLen);
630  }
631};
632
633#define GET_DIAG_ARRAYS
634#include "clang/Basic/DiagnosticGroups.inc"
635#undef GET_DIAG_ARRAYS
636
637// Second the table of options, sorted by name for fast binary lookup.
638static const WarningOption OptionTable[] = {
639#define GET_DIAG_TABLE
640#include "clang/Basic/DiagnosticGroups.inc"
641#undef GET_DIAG_TABLE
642};
643static const size_t OptionTableSize =
644sizeof(OptionTable) / sizeof(OptionTable[0]);
645
646static bool WarningOptionCompare(const WarningOption &LHS,
647                                 const WarningOption &RHS) {
648  return LHS.getName() < RHS.getName();
649}
650
651void DiagnosticIDs::getDiagnosticsInGroup(
652  const WarningOption *Group,
653  llvm::SmallVectorImpl<diag::kind> &Diags) const
654{
655  // Add the members of the option diagnostic set.
656  if (const short *Member = Group->Members) {
657    for (; *Member != -1; ++Member)
658      Diags.push_back(*Member);
659  }
660
661  // Add the members of the subgroups.
662  if (const short *SubGroups = Group->SubGroups) {
663    for (; *SubGroups != (short)-1; ++SubGroups)
664      getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
665  }
666}
667
668bool DiagnosticIDs::getDiagnosticsInGroup(
669  StringRef Group,
670  llvm::SmallVectorImpl<diag::kind> &Diags) const
671{
672  WarningOption Key = { Group.size(), Group.data(), 0, 0 };
673  const WarningOption *Found =
674  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
675                   WarningOptionCompare);
676  if (Found == OptionTable + OptionTableSize ||
677      Found->getName() != Group)
678    return true; // Option not found.
679
680  getDiagnosticsInGroup(Found, Diags);
681  return false;
682}
683
684StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
685  StringRef Best;
686  unsigned BestDistance = Group.size() + 1; // Sanity threshold.
687  for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
688       i != e; ++i) {
689    // Don't suggest ignored warning flags.
690    if (!i->Members && !i->SubGroups)
691      continue;
692
693    unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
694    if (Distance == BestDistance) {
695      // Two matches with the same distance, don't prefer one over the other.
696      Best = "";
697    } else if (Distance < BestDistance) {
698      // This is a better match.
699      Best = i->getName();
700      BestDistance = Distance;
701    }
702  }
703
704  return Best;
705}
706
707/// ProcessDiag - This is the method used to report a diagnostic that is
708/// finally fully formed.
709bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
710  Diagnostic Info(&Diag);
711
712  if (Diag.SuppressAllDiagnostics)
713    return false;
714
715  assert(Diag.getClient() && "DiagnosticClient not set!");
716
717  // Figure out the diagnostic level of this message.
718  DiagnosticIDs::Level DiagLevel;
719  unsigned DiagID = Info.getID();
720
721  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
722    // Handle custom diagnostics, which cannot be mapped.
723    DiagLevel = CustomDiagInfo->getLevel(DiagID);
724  } else {
725    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
726    // the diagnostic level was for the previous diagnostic so that it is
727    // filtered the same as the previous diagnostic.
728    unsigned DiagClass = getBuiltinDiagClass(DiagID);
729    if (DiagClass == CLASS_NOTE) {
730      DiagLevel = DiagnosticIDs::Note;
731    } else {
732      DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(),
733                                     Diag);
734    }
735  }
736
737  if (DiagLevel != DiagnosticIDs::Note) {
738    // Record that a fatal error occurred only when we see a second
739    // non-note diagnostic. This allows notes to be attached to the
740    // fatal error, but suppresses any diagnostics that follow those
741    // notes.
742    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
743      Diag.FatalErrorOccurred = true;
744
745    Diag.LastDiagLevel = DiagLevel;
746  }
747
748  // Update counts for DiagnosticErrorTrap even if a fatal error occurred.
749  if (DiagLevel >= DiagnosticIDs::Error) {
750    ++Diag.TrapNumErrorsOccurred;
751    if (isUnrecoverable(DiagID))
752      ++Diag.TrapNumUnrecoverableErrorsOccurred;
753  }
754
755  // If a fatal error has already been emitted, silence all subsequent
756  // diagnostics.
757  if (Diag.FatalErrorOccurred) {
758    if (DiagLevel >= DiagnosticIDs::Error &&
759        Diag.Client->IncludeInDiagnosticCounts()) {
760      ++Diag.NumErrors;
761      ++Diag.NumErrorsSuppressed;
762    }
763
764    return false;
765  }
766
767  // If the client doesn't care about this message, don't issue it.  If this is
768  // a note and the last real diagnostic was ignored, ignore it too.
769  if (DiagLevel == DiagnosticIDs::Ignored ||
770      (DiagLevel == DiagnosticIDs::Note &&
771       Diag.LastDiagLevel == DiagnosticIDs::Ignored))
772    return false;
773
774  if (DiagLevel >= DiagnosticIDs::Error) {
775    if (isUnrecoverable(DiagID))
776      Diag.UnrecoverableErrorOccurred = true;
777
778    if (Diag.Client->IncludeInDiagnosticCounts()) {
779      Diag.ErrorOccurred = true;
780      ++Diag.NumErrors;
781    }
782
783    // If we've emitted a lot of errors, emit a fatal error instead of it to
784    // stop a flood of bogus errors.
785    if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit &&
786        DiagLevel == DiagnosticIDs::Error) {
787      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
788      return false;
789    }
790  }
791
792  // If we have any Fix-Its, make sure that all of the Fix-Its point into
793  // source locations that aren't macro expansions. If any point into macro
794  // expansions, remove all of the Fix-Its.
795  for (unsigned I = 0, N = Diag.NumFixItHints; I != N; ++I) {
796    const FixItHint &FixIt = Diag.FixItHints[I];
797    if (FixIt.RemoveRange.isInvalid() ||
798        FixIt.RemoveRange.getBegin().isMacroID() ||
799        FixIt.RemoveRange.getEnd().isMacroID()) {
800      Diag.NumFixItHints = 0;
801      break;
802    }
803  }
804
805  // Finally, report it.
806  Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
807  if (Diag.Client->IncludeInDiagnosticCounts()) {
808    if (DiagLevel == DiagnosticIDs::Warning)
809      ++Diag.NumWarnings;
810  }
811
812  Diag.CurDiagID = ~0U;
813
814  return true;
815}
816
817bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
818  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
819    // Custom diagnostics.
820    return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
821  }
822
823  // Only errors may be unrecoverable.
824  if (getBuiltinDiagClass(DiagID) < CLASS_ERROR)
825    return false;
826
827  if (DiagID == diag::err_unavailable ||
828      DiagID == diag::err_unavailable_message)
829    return false;
830
831  // Currently we consider all ARC errors as recoverable.
832  if (isARCDiagnostic(DiagID))
833    return false;
834
835  return true;
836}
837
838bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
839  unsigned cat = getCategoryNumberForDiag(DiagID);
840  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
841}
842
843