Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file implements the Diagnostic IDs-related interfaces.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/DiagnosticIDs.h"
14
#include "clang/Basic/AllDiagnostics.h"
15
#include "clang/Basic/DiagnosticCategories.h"
16
#include "clang/Basic/SourceManager.h"
17
#include "llvm/ADT/STLExtras.h"
18
#include "llvm/ADT/SmallVector.h"
19
#include "llvm/Support/ErrorHandling.h"
20
#include <map>
21
using namespace clang;
22
23
//===----------------------------------------------------------------------===//
24
// Builtin Diagnostic information
25
//===----------------------------------------------------------------------===//
26
27
namespace {
28
29
// Diagnostic classes.
30
enum {
31
  CLASS_NOTE       = 0x01,
32
  CLASS_REMARK     = 0x02,
33
  CLASS_WARNING    = 0x03,
34
  CLASS_EXTENSION  = 0x04,
35
  CLASS_ERROR      = 0x05
36
};
37
38
struct StaticDiagInfoRec {
39
  uint16_t DiagID;
40
  unsigned DefaultSeverity : 3;
41
  unsigned Class : 3;
42
  unsigned SFINAE : 2;
43
  unsigned WarnNoWerror : 1;
44
  unsigned WarnShowInSystemHeader : 1;
45
  unsigned Category : 6;
46
47
  uint16_t OptionGroupIndex;
48
49
  uint16_t DescriptionLen;
50
  const char *DescriptionStr;
51
52
18.6k
  unsigned getOptionGroupIndex() const {
53
18.6k
    return OptionGroupIndex;
54
18.6k
  }
55
56
238k
  StringRef getDescription() const {
57
238k
    return StringRef(DescriptionStr, DescriptionLen);
58
238k
  }
59
60
3.59M
  diag::Flavor getFlavor() const {
61
3.59M
    return Class == CLASS_REMARK ? 
diag::Flavor::Remark2.18k
62
3.59M
                                 : 
diag::Flavor::WarningOrError3.58M
;
63
3.59M
  }
64
65
0
  bool operator<(const StaticDiagInfoRec &RHS) const {
66
0
    return DiagID < RHS.DiagID;
67
0
  }
68
};
69
70
#define STRINGIFY_NAME(NAME) #NAME
71
#define VALIDATE_DIAG_SIZE(NAME)                                               \
72
  static_assert(                                                               \
73
      static_cast<unsigned>(diag::NUM_BUILTIN_##NAME##_DIAGNOSTICS) <          \
74
          static_cast<unsigned>(diag::DIAG_START_##NAME) +                     \
75
              static_cast<unsigned>(diag::DIAG_SIZE_##NAME),                   \
76
      STRINGIFY_NAME(                                                          \
77
          DIAG_SIZE_##NAME) " is insufficient to contain all "                 \
78
                            "diagnostics, it may need to be made larger in "   \
79
                            "DiagnosticIDs.h.");
80
VALIDATE_DIAG_SIZE(COMMON)
81
VALIDATE_DIAG_SIZE(DRIVER)
82
VALIDATE_DIAG_SIZE(FRONTEND)
83
VALIDATE_DIAG_SIZE(SERIALIZATION)
84
VALIDATE_DIAG_SIZE(LEX)
85
VALIDATE_DIAG_SIZE(PARSE)
86
VALIDATE_DIAG_SIZE(AST)
87
VALIDATE_DIAG_SIZE(COMMENT)
88
VALIDATE_DIAG_SIZE(SEMA)
89
VALIDATE_DIAG_SIZE(ANALYSIS)
90
VALIDATE_DIAG_SIZE(REFACTORING)
91
#undef VALIDATE_DIAG_SIZE
92
#undef STRINGIFY_NAME
93
94
} // namespace anonymous
95
96
static const StaticDiagInfoRec StaticDiagInfo[] = {
97
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR,     \
98
             SHOWINSYSHEADER, CATEGORY)                                        \
99
  {                                                                            \
100
    diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR,      \
101
        SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC       \
102
  }                                                                            \
103
  ,
104
#include "clang/Basic/DiagnosticCommonKinds.inc"
105
#include "clang/Basic/DiagnosticDriverKinds.inc"
106
#include "clang/Basic/DiagnosticFrontendKinds.inc"
107
#include "clang/Basic/DiagnosticSerializationKinds.inc"
108
#include "clang/Basic/DiagnosticLexKinds.inc"
109
#include "clang/Basic/DiagnosticParseKinds.inc"
110
#include "clang/Basic/DiagnosticASTKinds.inc"
111
#include "clang/Basic/DiagnosticCommentKinds.inc"
112
#include "clang/Basic/DiagnosticCrossTUKinds.inc"
113
#include "clang/Basic/DiagnosticSemaKinds.inc"
114
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
115
#include "clang/Basic/DiagnosticRefactoringKinds.inc"
116
#undef DIAG
117
};
118
119
static const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo);
120
121
/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
122
/// or null if the ID is invalid.
123
135M
static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
124
135M
  // Out of bounds diag. Can't be in the table.
125
135M
  using namespace diag;
126
135M
  if (DiagID >= DIAG_UPPER_LIMIT || 
DiagID <= DIAG_START_COMMON135M
)
127
14.7k
    return nullptr;
128
135M
129
135M
  // Compute the index of the requested diagnostic in the static table.
130
135M
  // 1. Add the number of diagnostics in each category preceding the
131
135M
  //    diagnostic and of the category the diagnostic is in. This gives us
132
135M
  //    the offset of the category in the table.
133
135M
  // 2. Subtract the number of IDs in each category from our ID. This gives us
134
135M
  //    the offset of the diagnostic in the category.
135
135M
  // This is cheaper than a binary search on the table as it doesn't touch
136
135M
  // memory at all.
137
135M
  unsigned Offset = 0;
138
135M
  unsigned ID = DiagID - DIAG_START_COMMON - 1;
139
135M
#define CATEGORY(NAME, PREV) \
140
1.48G
  if (DiagID > DIAG_START_##NAME) { \
141
1.04G
    Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
142
1.04G
    ID -= DIAG_START_##NAME - DIAG_START_##PREV; \
143
1.04G
  }
144
135M
CATEGORY(DRIVER, COMMON)
145
135M
CATEGORY(FRONTEND, DRIVER)
146
135M
CATEGORY(SERIALIZATION, FRONTEND)
147
135M
CATEGORY(LEX, SERIALIZATION)
148
135M
CATEGORY(PARSE, LEX)
149
135M
CATEGORY(AST, PARSE)
150
135M
CATEGORY(COMMENT, AST)
151
135M
CATEGORY(CROSSTU, COMMENT)
152
135M
CATEGORY(SEMA, CROSSTU)
153
135M
CATEGORY(ANALYSIS, SEMA)
154
135M
CATEGORY(REFACTORING, ANALYSIS)
155
135M
#undef CATEGORY
156
135M
157
135M
  // Avoid out of bounds reads.
158
135M
  if (ID + Offset >= StaticDiagInfoSize)
159
0
    return nullptr;
160
135M
161
135M
  assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize);
162
135M
163
135M
  const StaticDiagInfoRec *Found = &StaticDiagInfo[ID + Offset];
164
135M
  // If the diag id doesn't match we found a different diag, abort. This can
165
135M
  // happen when this function is called with an ID that points into a hole in
166
135M
  // the diagID space.
167
135M
  if (Found->DiagID != DiagID)
168
0
    return nullptr;
169
135M
  return Found;
170
135M
}
171
172
3.30M
static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
173
3.30M
  DiagnosticMapping Info = DiagnosticMapping::Make(
174
3.30M
      diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
175
3.30M
176
3.30M
  if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
177
3.30M
    Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
178
3.30M
179
3.30M
    if (StaticInfo->WarnNoWerror) {
180
69
      assert(Info.getSeverity() == diag::Severity::Warning &&
181
69
             "Unexpected mapping with no-Werror bit!");
182
69
      Info.setNoWarningAsError(true);
183
69
    }
184
3.30M
  }
185
3.30M
186
3.30M
  return Info;
187
3.30M
}
188
189
/// getCategoryNumberForDiag - Return the category number that a specified
190
/// DiagID belongs to, or 0 if no category.
191
231k
unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
192
231k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
193
231k
    return Info->Category;
194
0
  return 0;
195
0
}
196
197
namespace {
198
  // The diagnostic category names.
199
  struct StaticDiagCategoryRec {
200
    const char *NameStr;
201
    uint8_t NameLen;
202
203
229k
    StringRef getName() const {
204
229k
      return StringRef(NameStr, NameLen);
205
229k
    }
206
  };
207
}
208
209
// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
210
// particularly clean, but for now we just implement this method here so we can
211
// access GetDefaultDiagMapping.
212
DiagnosticMapping &
213
101M
DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
214
101M
  std::pair<iterator, bool> Result =
215
101M
      DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
216
101M
217
101M
  // Initialize the entry if we added it.
218
101M
  if (Result.second)
219
2.97M
    Result.first->second = GetDefaultDiagMapping(Diag);
220
101M
221
101M
  return Result.first->second;
222
101M
}
223
224
static const StaticDiagCategoryRec CategoryNameTable[] = {
225
#define GET_CATEGORY_TABLE
226
#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
227
#include "clang/Basic/DiagnosticGroups.inc"
228
#undef GET_CATEGORY_TABLE
229
  { nullptr, 0 }
230
};
231
232
/// getNumberOfCategories - Return the number of categories
233
229k
unsigned DiagnosticIDs::getNumberOfCategories() {
234
229k
  return llvm::array_lengthof(CategoryNameTable) - 1;
235
229k
}
236
237
/// getCategoryNameFromID - Given a category ID, return the name of the
238
/// category, an empty string if CategoryID is zero, or null if CategoryID is
239
/// invalid.
240
229k
StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
241
229k
  if (CategoryID >= getNumberOfCategories())
242
0
   return StringRef();
243
229k
  return CategoryNameTable[CategoryID].getName();
244
229k
}
245
246
247
248
DiagnosticIDs::SFINAEResponse
249
164k
DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
250
164k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
251
164k
    return static_cast<DiagnosticIDs::SFINAEResponse>(Info->SFINAE);
252
0
  return SFINAE_Report;
253
0
}
254
255
/// getBuiltinDiagClass - Return the class field of the diagnostic.
256
///
257
104M
static unsigned getBuiltinDiagClass(unsigned DiagID) {
258
104M
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
259
104M
    return Info->Class;
260
0
  return ~0U;
261
0
}
262
263
//===----------------------------------------------------------------------===//
264
// Custom Diagnostic information
265
//===----------------------------------------------------------------------===//
266
267
namespace clang {
268
  namespace diag {
269
    class CustomDiagInfo {
270
      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
271
      std::vector<DiagDesc> DiagInfo;
272
      std::map<DiagDesc, unsigned> DiagIDs;
273
    public:
274
275
      /// getDescription - Return the description of the specified custom
276
      /// diagnostic.
277
14.6k
      StringRef getDescription(unsigned DiagID) const {
278
14.6k
        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
279
14.6k
               "Invalid diagnostic ID");
280
14.6k
        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
281
14.6k
      }
282
283
      /// getLevel - Return the level of the specified custom diagnostic.
284
14.8k
      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
285
14.8k
        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
286
14.8k
               "Invalid diagnostic ID");
287
14.8k
        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
288
14.8k
      }
289
290
      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
291
2.69k
                                 DiagnosticIDs &Diags) {
292
2.69k
        DiagDesc D(L, Message);
293
2.69k
        // Check to see if it already exists.
294
2.69k
        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
295
2.69k
        if (I != DiagIDs.end() && 
I->first == D1.50k
)
296
345
          return I->second;
297
2.35k
298
2.35k
        // If not, assign a new ID.
299
2.35k
        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
300
2.35k
        DiagIDs.insert(std::make_pair(D, ID));
301
2.35k
        DiagInfo.push_back(D);
302
2.35k
        return ID;
303
2.35k
      }
304
    };
305
306
  } // end diag namespace
307
} // end clang namespace
308
309
310
//===----------------------------------------------------------------------===//
311
// Common Diagnostic implementation
312
//===----------------------------------------------------------------------===//
313
314
158k
DiagnosticIDs::DiagnosticIDs() {}
315
316
144k
DiagnosticIDs::~DiagnosticIDs() {}
317
318
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
319
/// and level.  If this is the first request for this diagnostic, it is
320
/// registered and created, otherwise the existing ID is returned.
321
///
322
/// \param FormatString A fixed diagnostic format string that will be hashed and
323
/// mapped to a unique DiagID.
324
2.69k
unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) {
325
2.69k
  if (!CustomDiagInfo)
326
1.19k
    CustomDiagInfo.reset(new diag::CustomDiagInfo());
327
2.69k
  return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this);
328
2.69k
}
329
330
331
/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
332
/// level of the specified diagnostic ID is a Warning or Extension.
333
/// This only works on builtin diagnostics, not custom ones, and is not legal to
334
/// call on NOTEs.
335
234k
bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
336
234k
  return DiagID < diag::DIAG_UPPER_LIMIT &&
337
234k
         
getBuiltinDiagClass(DiagID) != CLASS_ERROR234k
;
338
234k
}
339
340
/// Determine whether the given built-in diagnostic ID is a
341
/// Note.
342
235k
bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
343
235k
  return DiagID < diag::DIAG_UPPER_LIMIT &&
344
235k
    
getBuiltinDiagClass(DiagID) == CLASS_NOTE235k
;
345
235k
}
346
347
/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
348
/// ID is for an extension of some sort.  This also returns EnabledByDefault,
349
/// which is set to indicate whether the diagnostic is ignored by default (in
350
/// which case -pedantic enables it) or treated as a warning/error by default.
351
///
352
bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
353
99.6M
                                        bool &EnabledByDefault) {
354
99.6M
  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
355
99.6M
      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
356
99.4M
    return false;
357
208k
358
208k
  EnabledByDefault =
359
208k
      GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
360
208k
  return true;
361
208k
}
362
363
119k
bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
364
119k
  if (DiagID >= diag::DIAG_UPPER_LIMIT)
365
110
    return false;
366
119k
367
119k
  return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error;
368
119k
}
369
370
/// getDescription - Given a diagnostic ID, return a description of the
371
/// issue.
372
253k
StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
373
253k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
374
238k
    return Info->getDescription();
375
14.6k
  assert(CustomDiagInfo && "Invalid CustomDiagInfo");
376
14.6k
  return CustomDiagInfo->getDescription(DiagID);
377
14.6k
}
378
379
3.99M
static DiagnosticIDs::Level toLevel(diag::Severity SV) {
380
3.99M
  switch (SV) {
381
3.99M
  case diag::Severity::Ignored:
382
3.81M
    return DiagnosticIDs::Ignored;
383
3.99M
  case diag::Severity::Remark:
384
846
    return DiagnosticIDs::Remark;
385
3.99M
  case diag::Severity::Warning:
386
54.8k
    return DiagnosticIDs::Warning;
387
3.99M
  case diag::Severity::Error:
388
122k
    return DiagnosticIDs::Error;
389
3.99M
  case diag::Severity::Fatal:
390
229
    return DiagnosticIDs::Fatal;
391
0
  }
392
0
  llvm_unreachable("unexpected severity");
393
0
}
394
395
/// getDiagnosticLevel - Based on the way the client configured the
396
/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
397
/// by consumable the DiagnosticClient.
398
DiagnosticIDs::Level
399
DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
400
4.23M
                                  const DiagnosticsEngine &Diag) const {
401
4.23M
  // Handle custom diagnostics, which cannot be mapped.
402
4.23M
  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
403
14.6k
    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
404
14.6k
    return CustomDiagInfo->getLevel(DiagID);
405
14.6k
  }
406
4.21M
407
4.21M
  unsigned DiagClass = getBuiltinDiagClass(DiagID);
408
4.21M
  if (DiagClass == CLASS_NOTE) 
return DiagnosticIDs::Note221k
;
409
3.99M
  return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
410
3.99M
}
411
412
/// Based on the way the client configured the Diagnostic
413
/// object, classify the specified diagnostic ID into a Level, consumable by
414
/// the DiagnosticClient.
415
///
416
/// \param Loc The source location we are interested in finding out the
417
/// diagnostic state. Can be null in order to query the latest state.
418
diag::Severity
419
DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
420
99.6M
                                     const DiagnosticsEngine &Diag) const {
421
99.6M
  assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
422
99.6M
423
99.6M
  // Specific non-error diagnostics may be mapped to various levels from ignored
424
99.6M
  // to error.  Errors can only be mapped to fatal.
425
99.6M
  diag::Severity Result = diag::Severity::Fatal;
426
99.6M
427
99.6M
  // Get the mapping information, or compute it lazily.
428
99.6M
  DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc);
429
99.6M
  DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
430
99.6M
431
99.6M
  // TODO: Can a null severity really get here?
432
99.6M
  if (Mapping.getSeverity() != diag::Severity())
433
99.6M
    Result = Mapping.getSeverity();
434
99.6M
435
99.6M
  // Upgrade ignored diagnostics if -Weverything is enabled.
436
99.6M
  if (State->EnableAllWarnings && 
Result == diag::Severity::Ignored9.82k
&&
437
99.6M
      
!Mapping.isUser()9.10k
&&
getBuiltinDiagClass(DiagID) != CLASS_REMARK9.09k
)
438
9.09k
    Result = diag::Severity::Warning;
439
99.6M
440
99.6M
  // Ignore -pedantic diagnostics inside __extension__ blocks.
441
99.6M
  // (The diagnostics controlled by -pedantic are the extension diagnostics
442
99.6M
  // that are not enabled by default.)
443
99.6M
  bool EnabledByDefault = false;
444
99.6M
  bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
445
99.6M
  if (Diag.AllExtensionsSilenced && 
IsExtensionDiag334k
&&
!EnabledByDefault12.6k
)
446
12.6k
    return diag::Severity::Ignored;
447
99.6M
448
99.6M
  // For extension diagnostics that haven't been explicitly mapped, check if we
449
99.6M
  // should upgrade the diagnostic.
450
99.6M
  if (IsExtensionDiag && 
!Mapping.isUser()196k
)
451
185k
    Result = std::max(Result, State->ExtBehavior);
452
99.6M
453
99.6M
  // At this point, ignored errors can no longer be upgraded.
454
99.6M
  if (Result == diag::Severity::Ignored)
455
83.8M
    return Result;
456
15.7M
457
15.7M
  // Honor -w: this disables all messages which which are not Error/Fatal by
458
15.7M
  // default (disregarding attempts to upgrade severity from Warning to Error),
459
15.7M
  // as well as disabling all messages which are currently mapped to Warning
460
15.7M
  // (whether by default or downgraded from Error via e.g. -Wno-error or #pragma
461
15.7M
  // diagnostic.)
462
15.7M
  if (State->IgnoreAllWarnings) {
463
4.20M
    if (Result == diag::Severity::Warning ||
464
4.20M
        
(5.82k
Result >= diag::Severity::Error5.82k
&&
465
5.82k
         
!isDefaultMappingAsError((diag::kind)DiagID)5.81k
))
466
4.20M
      return diag::Severity::Ignored;
467
11.5M
  }
468
11.5M
469
11.5M
  // If -Werror is enabled, map warnings to errors unless explicitly disabled.
470
11.5M
  if (Result == diag::Severity::Warning) {
471
11.4M
    if (State->WarningsAsErrors && 
!Mapping.hasNoWarningAsError()1.35M
)
472
1.35M
      Result = diag::Severity::Error;
473
11.4M
  }
474
11.5M
475
11.5M
  // If -Wfatal-errors is enabled, map errors to fatal unless explicitly
476
11.5M
  // disabled.
477
11.5M
  if (Result == diag::Severity::Error) {
478
1.50M
    if (State->ErrorsAsFatal && 
!Mapping.hasNoErrorAsFatal()6
)
479
6
      Result = diag::Severity::Fatal;
480
1.50M
  }
481
11.5M
482
11.5M
  // If explicitly requested, map fatal errors to errors.
483
11.5M
  if (Result == diag::Severity::Fatal &&
484
11.5M
      
Diag.CurDiagID != diag::fatal_too_many_errors260
&&
Diag.FatalsAsError235
)
485
12
    Result = diag::Severity::Error;
486
11.5M
487
11.5M
  // Custom diagnostics always are emitted in system headers.
488
11.5M
  bool ShowInSystemHeader =
489
11.5M
      
!GetDiagInfo(DiagID)11.5M
|| GetDiagInfo(DiagID)->WarnShowInSystemHeader;
490
11.5M
491
11.5M
  // If we are in a system header, we ignore it. We look at the diagnostic class
492
11.5M
  // because we also want to ignore extensions and warnings in -Werror and
493
11.5M
  // -pedantic-errors modes, which *map* warnings/extensions to errors.
494
11.5M
  if (State->SuppressSystemWarnings && 
!ShowInSystemHeader11.5M
&&
Loc.isValid()11.4M
&&
495
11.5M
      Diag.getSourceManager().isInSystemHeader(
496
11.3M
          Diag.getSourceManager().getExpansionLoc(Loc)))
497
4.10M
    return diag::Severity::Ignored;
498
7.46M
499
7.46M
  return Result;
500
7.46M
}
501
502
#define GET_DIAG_ARRAYS
503
#include "clang/Basic/DiagnosticGroups.inc"
504
#undef GET_DIAG_ARRAYS
505
506
namespace {
507
  struct WarningOption {
508
    uint16_t NameOffset;
509
    uint16_t Members;
510
    uint16_t SubGroups;
511
512
    // String is stored with a pascal-style length byte.
513
2.00M
    StringRef getName() const {
514
2.00M
      return StringRef(DiagGroupNames + NameOffset + 1,
515
2.00M
                       DiagGroupNames[NameOffset]);
516
2.00M
    }
517
  };
518
}
519
520
// Second the table of options, sorted by name for fast binary lookup.
521
static const WarningOption OptionTable[] = {
522
#define GET_DIAG_TABLE
523
#include "clang/Basic/DiagnosticGroups.inc"
524
#undef GET_DIAG_TABLE
525
};
526
527
/// getWarningOptionForDiag - Return the lowest-level warning option that
528
/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
529
/// the diagnostic, this returns null.
530
18.7k
StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
531
18.7k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
532
18.6k
    return OptionTable[Info->getOptionGroupIndex()].getName();
533
98
  return StringRef();
534
98
}
535
536
12
std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() {
537
12
  std::vector<std::string> Res;
538
9.26k
  for (size_t I = 1; DiagGroupNames[I] != '\0';) {
539
9.25k
    std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]);
540
9.25k
    I += DiagGroupNames[I] + 1;
541
9.25k
    Res.push_back("-W" + Diag);
542
9.25k
    Res.push_back("-Wno-" + Diag);
543
9.25k
  }
544
12
545
12
  return Res;
546
12
}
547
548
/// Return \c true if any diagnostics were found in this group, even if they
549
/// were filtered out due to having the wrong flavor.
550
static bool getDiagnosticsInGroup(diag::Flavor Flavor,
551
                                  const WarningOption *Group,
552
1.69M
                                  SmallVectorImpl<diag::kind> &Diags) {
553
1.69M
  // An empty group is considered to be a warning group: we have empty groups
554
1.69M
  // for GCC compatibility, and GCC does not have remarks.
555
1.69M
  if (!Group->Members && 
!Group->SubGroups163k
)
556
52.5k
    return Flavor == diag::Flavor::Remark;
557
1.64M
558
1.64M
  bool NotFound = true;
559
1.64M
560
1.64M
  // Add the members of the option diagnostic set.
561
1.64M
  const int16_t *Member = DiagArrays + Group->Members;
562
5.01M
  for (; *Member != -1; 
++Member3.36M
) {
563
3.36M
    if (GetDiagInfo(*Member)->getFlavor() == Flavor) {
564
3.36M
      NotFound = false;
565
3.36M
      Diags.push_back(*Member);
566
3.36M
    }
567
3.36M
  }
568
1.64M
569
1.64M
  // Add the members of the subgroups.
570
1.64M
  const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
571
3.15M
  for (; *SubGroups != (int16_t)-1; 
++SubGroups1.50M
)
572
1.50M
    NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups],
573
1.50M
                                      Diags);
574
1.64M
575
1.64M
  return NotFound;
576
1.64M
}
577
578
bool
579
DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
580
183k
                                     SmallVectorImpl<diag::kind> &Diags) const {
581
183k
  auto Found = llvm::partition_point(
582
1.79M
      OptionTable, [=](const WarningOption &O) { return O.getName() < Group; });
583
183k
  if (
Found == std::end(OptionTable)183k
|| Found->getName() != Group)
584
58
    return true; // Option not found.
585
183k
586
183k
  return ::getDiagnosticsInGroup(Flavor, Found, Diags);
587
183k
}
588
589
void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
590
44
                                      std::vector<diag::kind> &Diags) {
591
221k
  for (unsigned i = 0; i != StaticDiagInfoSize; 
++i221k
)
592
221k
    if (StaticDiagInfo[i].getFlavor() == Flavor)
593
176k
      Diags.push_back(StaticDiagInfo[i].DiagID);
594
44
}
595
596
StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
597
16
                                          StringRef Group) {
598
16
  StringRef Best;
599
16
  unsigned BestDistance = Group.size() + 1; // Sanity threshold.
600
12.3k
  for (const WarningOption &O : OptionTable) {
601
12.3k
    // Don't suggest ignored warning flags.
602
12.3k
    if (!O.Members && 
!O.SubGroups1.60k
)
603
624
      continue;
604
11.7k
605
11.7k
    unsigned Distance = O.getName().edit_distance(Group, true, BestDistance);
606
11.7k
    if (Distance > BestDistance)
607
10.7k
      continue;
608
929
609
929
    // Don't suggest groups that are not of this kind.
610
929
    llvm::SmallVector<diag::kind, 8> Diags;
611
929
    if (::getDiagnosticsInGroup(Flavor, &O, Diags) || 
Diags.empty()175
)
612
754
      continue;
613
175
614
175
    if (Distance == BestDistance) {
615
94
      // Two matches with the same distance, don't prefer one over the other.
616
94
      Best = "";
617
94
    } else 
if (81
Distance < BestDistance81
) {
618
81
      // This is a better match.
619
81
      Best = O.getName();
620
81
      BestDistance = Distance;
621
81
    }
622
175
  }
623
16
624
16
  return Best;
625
16
}
626
627
/// ProcessDiag - This is the method used to report a diagnostic that is
628
/// finally fully formed.
629
4.18M
bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
630
4.18M
  Diagnostic Info(&Diag);
631
4.18M
632
4.18M
  assert(Diag.getClient() && "DiagnosticClient not set!");
633
4.18M
634
4.18M
  // Figure out the diagnostic level of this message.
635
4.18M
  unsigned DiagID = Info.getID();
636
4.18M
  DiagnosticIDs::Level DiagLevel
637
4.18M
    = getDiagnosticLevel(DiagID, Info.getLocation(), Diag);
638
4.18M
639
4.18M
  // Update counts for DiagnosticErrorTrap even if a fatal error occurred
640
4.18M
  // or diagnostics are suppressed.
641
4.18M
  if (DiagLevel >= DiagnosticIDs::Error) {
642
118k
    ++Diag.TrapNumErrorsOccurred;
643
118k
    if (isUnrecoverable(DiagID))
644
115k
      ++Diag.TrapNumUnrecoverableErrorsOccurred;
645
118k
  }
646
4.18M
647
4.18M
  if (Diag.SuppressAllDiagnostics)
648
5.36k
    return false;
649
4.17M
650
4.17M
  if (DiagLevel != DiagnosticIDs::Note) {
651
3.95M
    // Record that a fatal error occurred only when we see a second
652
3.95M
    // non-note diagnostic. This allows notes to be attached to the
653
3.95M
    // fatal error, but suppresses any diagnostics that follow those
654
3.95M
    // notes.
655
3.95M
    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
656
112
      Diag.FatalErrorOccurred = true;
657
3.95M
658
3.95M
    Diag.LastDiagLevel = DiagLevel;
659
3.95M
  }
660
4.17M
661
4.17M
  // If a fatal error has already been emitted, silence all subsequent
662
4.17M
  // diagnostics.
663
4.17M
  if (Diag.FatalErrorOccurred) {
664
7.66k
    if (DiagLevel >= DiagnosticIDs::Error &&
665
7.66k
        
Diag.Client->IncludeInDiagnosticCounts()2.31k
) {
666
2.31k
      ++Diag.NumErrors;
667
2.31k
    }
668
7.66k
669
7.66k
    return false;
670
7.66k
  }
671
4.16M
672
4.16M
  // If the client doesn't care about this message, don't issue it.  If this is
673
4.16M
  // a note and the last real diagnostic was ignored, ignore it too.
674
4.16M
  if (DiagLevel == DiagnosticIDs::Ignored ||
675
4.16M
      
(389k
DiagLevel == DiagnosticIDs::Note389k
&&
676
389k
       
Diag.LastDiagLevel == DiagnosticIDs::Ignored220k
))
677
3.91M
    return false;
678
253k
679
253k
  if (DiagLevel >= DiagnosticIDs::Error) {
680
113k
    if (isUnrecoverable(DiagID))
681
110k
      Diag.UnrecoverableErrorOccurred = true;
682
113k
683
113k
    // Warnings which have been upgraded to errors do not prevent compilation.
684
113k
    if (isDefaultMappingAsError(DiagID))
685
112k
      Diag.UncompilableErrorOccurred = true;
686
113k
687
113k
    Diag.ErrorOccurred = true;
688
113k
    if (Diag.Client->IncludeInDiagnosticCounts()) {
689
113k
      ++Diag.NumErrors;
690
113k
    }
691
113k
692
113k
    // If we've emitted a lot of errors, emit a fatal error instead of it to
693
113k
    // stop a flood of bogus errors.
694
113k
    if (Diag.ErrorLimit && 
Diag.NumErrors > Diag.ErrorLimit26.4k
&&
695
113k
        
DiagLevel == DiagnosticIDs::Error50
) {
696
25
      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
697
25
      return false;
698
25
    }
699
253k
  }
700
253k
701
253k
  // Make sure we set FatalErrorOccurred to ensure that the notes from the
702
253k
  // diagnostic that caused `fatal_too_many_errors` won't be emitted.
703
253k
  if (Diag.CurDiagID == diag::fatal_too_many_errors)
704
25
    Diag.FatalErrorOccurred = true;
705
253k
  // Finally, report it.
706
253k
  EmitDiag(Diag, DiagLevel);
707
253k
  return true;
708
253k
}
709
710
253k
void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const {
711
253k
  Diagnostic Info(&Diag);
712
253k
  assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!");
713
253k
714
253k
  Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
715
253k
  if (Diag.Client->IncludeInDiagnosticCounts()) {
716
253k
    if (DiagLevel == DiagnosticIDs::Warning)
717
55.6k
      ++Diag.NumWarnings;
718
253k
  }
719
253k
720
253k
  Diag.CurDiagID = ~0U;
721
253k
}
722
723
232k
bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
724
232k
  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
725
220
    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
726
220
    // Custom diagnostics.
727
220
    return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
728
220
  }
729
232k
730
232k
  // Only errors may be unrecoverable.
731
232k
  if (getBuiltinDiagClass(DiagID) < CLASS_ERROR)
732
2.85k
    return false;
733
229k
734
229k
  if (DiagID == diag::err_unavailable ||
735
229k
      
DiagID == diag::err_unavailable_message229k
)
736
716
    return false;
737
228k
738
228k
  // Currently we consider all ARC errors as recoverable.
739
228k
  if (isARCDiagnostic(DiagID))
740
2.13k
    return false;
741
226k
742
226k
  return true;
743
226k
}
744
745
229k
bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
746
229k
  unsigned cat = getCategoryNumberForDiag(DiagID);
747
229k
  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
748
229k
}