Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/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
15.8k
  unsigned getOptionGroupIndex() const {
53
15.8k
    return OptionGroupIndex;
54
15.8k
  }
55
56
296k
  StringRef getDescription() const {
57
296k
    return StringRef(DescriptionStr, DescriptionLen);
58
296k
  }
59
60
1.12M
  diag::Flavor getFlavor() const {
61
1.12M
    return Class == CLASS_REMARK ? 
diag::Flavor::Remark2.11k
62
1.12M
                                 : 
diag::Flavor::WarningOrError1.12M
;
63
1.12M
  }
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
267M
static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
124
267M
  // Out of bounds diag. Can't be in the table.
125
267M
  using namespace diag;
126
267M
  if (DiagID >= DIAG_UPPER_LIMIT || 
DiagID <= DIAG_START_COMMON267M
)
127
17.4k
    return nullptr;
128
267M
129
267M
  // Compute the index of the requested diagnostic in the static table.
130
267M
  // 1. Add the number of diagnostics in each category preceding the
131
267M
  //    diagnostic and of the category the diagnostic is in. This gives us
132
267M
  //    the offset of the category in the table.
133
267M
  // 2. Subtract the number of IDs in each category from our ID. This gives us
134
267M
  //    the offset of the diagnostic in the category.
135
267M
  // This is cheaper than a binary search on the table as it doesn't touch
136
267M
  // memory at all.
137
267M
  unsigned Offset = 0;
138
267M
  unsigned ID = DiagID - DIAG_START_COMMON - 1;
139
267M
#define CATEGORY(NAME, PREV) \
140
2.93G
  if (DiagID > DIAG_START_##NAME) { \
141
1.87G
    Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
142
1.87G
    ID -= DIAG_START_##NAME - DIAG_START_##PREV; \
143
1.87G
  }
144
267M
CATEGORY(DRIVER, COMMON)
145
267M
CATEGORY(FRONTEND, DRIVER)
146
267M
CATEGORY(SERIALIZATION, FRONTEND)
147
267M
CATEGORY(LEX, SERIALIZATION)
148
267M
CATEGORY(PARSE, LEX)
149
267M
CATEGORY(AST, PARSE)
150
267M
CATEGORY(COMMENT, AST)
151
267M
CATEGORY(CROSSTU, COMMENT)
152
267M
CATEGORY(SEMA, CROSSTU)
153
267M
CATEGORY(ANALYSIS, SEMA)
154
267M
CATEGORY(REFACTORING, ANALYSIS)
155
267M
#undef CATEGORY
156
267M
157
267M
  // Avoid out of bounds reads.
158
267M
  if (ID + Offset >= StaticDiagInfoSize)
159
0
    return nullptr;
160
267M
161
267M
  assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize);
162
267M
163
267M
  const StaticDiagInfoRec *Found = &StaticDiagInfo[ID + Offset];
164
267M
  // If the diag id doesn't match we found a different diag, abort. This can
165
267M
  // happen when this function is called with an ID that points into a hole in
166
267M
  // the diagID space.
167
267M
  if (Found->DiagID != DiagID)
168
0
    return nullptr;
169
267M
  return Found;
170
267M
}
171
172
3.38M
static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
173
3.38M
  DiagnosticMapping Info = DiagnosticMapping::Make(
174
3.38M
      diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
175
3.38M
176
3.38M
  if (const StaticDiagInfoRec *
StaticInfo3.38M
= GetDiagInfo(DiagID)) {
177
3.38M
    Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
178
3.38M
179
3.38M
    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.38M
  }
185
3.38M
186
3.38M
  return Info;
187
3.38M
}
188
189
/// getCategoryNumberForDiag - Return the category number that a specified
190
/// DiagID belongs to, or 0 if no category.
191
302k
unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
192
302k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
193
302k
    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
300k
    StringRef getName() const {
204
300k
      return StringRef(NameStr, NameLen);
205
300k
    }
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
116M
DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
214
116M
  std::pair<iterator, bool> Result =
215
116M
      DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
216
116M
217
116M
  // Initialize the entry if we added it.
218
116M
  if (Result.second)
219
1.98M
    Result.first->second = GetDefaultDiagMapping(Diag);
220
116M
221
116M
  return Result.first->second;
222
116M
}
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
300k
unsigned DiagnosticIDs::getNumberOfCategories() {
234
300k
  return llvm::array_lengthof(CategoryNameTable) - 1;
235
300k
}
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
300k
StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
241
300k
  if (CategoryID >= getNumberOfCategories())
242
0
   return StringRef();
243
300k
  return CategoryNameTable[CategoryID].getName();
244
300k
}
245
246
247
248
DiagnosticIDs::SFINAEResponse
249
142k
DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
250
142k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
251
142k
    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
239M
static unsigned getBuiltinDiagClass(unsigned DiagID) {
258
239M
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
259
239M
    return Info->Class;
260
18.4E
  return ~0U;
261
18.4E
}
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
17.3k
      StringRef getDescription(unsigned DiagID) const {
278
17.3k
        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
279
17.3k
               "Invalid diagnostic ID");
280
17.3k
        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
281
17.3k
      }
282
283
      /// getLevel - Return the level of the specified custom diagnostic.
284
17.7k
      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
285
17.7k
        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
286
17.7k
               "Invalid diagnostic ID");
287
17.7k
        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
288
17.7k
      }
289
290
      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
291
4.71k
                                 DiagnosticIDs &Diags) {
292
4.71k
        DiagDesc D(L, std::string(Message));
293
4.71k
        // Check to see if it already exists.
294
4.71k
        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
295
4.71k
        if (I != DiagIDs.end() && 
I->first == D3.11k
)
296
370
          return I->second;
297
4.34k
298
4.34k
        // If not, assign a new ID.
299
4.34k
        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
300
4.34k
        DiagIDs.insert(std::make_pair(D, ID));
301
4.34k
        DiagInfo.push_back(D);
302
4.34k
        return ID;
303
4.34k
      }
304
    };
305
306
  } // end diag namespace
307
} // end clang namespace
308
309
310
//===----------------------------------------------------------------------===//
311
// Common Diagnostic implementation
312
//===----------------------------------------------------------------------===//
313
314
193k
DiagnosticIDs::DiagnosticIDs() {}
315
316
185k
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
4.71k
unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) {
325
4.71k
  if (!CustomDiagInfo)
326
1.59k
    CustomDiagInfo.reset(new diag::CustomDiagInfo());
327
4.71k
  return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this);
328
4.71k
}
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
1.02M
bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
336
1.02M
  return DiagID < diag::DIAG_UPPER_LIMIT &&
337
1.02M
         
getBuiltinDiagClass(DiagID) != CLASS_ERROR1.02M
;
338
1.02M
}
339
340
/// Determine whether the given built-in diagnostic ID is a
341
/// Note.
342
280k
bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
343
280k
  return DiagID < diag::DIAG_UPPER_LIMIT &&
344
280k
    
getBuiltinDiagClass(DiagID) == CLASS_NOTE280k
;
345
280k
}
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
116M
                                        bool &EnabledByDefault) {
354
116M
  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
355
116M
      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
356
114M
    return false;
357
1.25M
358
1.25M
  EnabledByDefault =
359
1.25M
      GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
360
1.25M
  return true;
361
1.25M
}
362
363
152k
bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
364
152k
  if (DiagID >= diag::DIAG_UPPER_LIMIT)
365
182
    return false;
366
151k
367
151k
  return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error;
368
151k
}
369
370
/// getDescription - Given a diagnostic ID, return a description of the
371
/// issue.
372
313k
StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
373
313k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
374
296k
    return Info->getDescription();
375
17.3k
  assert(CustomDiagInfo && "Invalid CustomDiagInfo");
376
17.3k
  return CustomDiagInfo->getDescription(DiagID);
377
17.3k
}
378
379
5.58M
static DiagnosticIDs::Level toLevel(diag::Severity SV) {
380
5.58M
  switch (SV) {
381
5.36M
  case diag::Severity::Ignored:
382
5.36M
    return DiagnosticIDs::Ignored;
383
727
  case diag::Severity::Remark:
384
727
    return DiagnosticIDs::Remark;
385
58.2k
  case diag::Severity::Warning:
386
58.2k
    return DiagnosticIDs::Warning;
387
158k
  case diag::Severity::Error:
388
158k
    return DiagnosticIDs::Error;
389
241
  case diag::Severity::Fatal:
390
241
    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
6.20M
                                  const DiagnosticsEngine &Diag) const {
401
6.20M
  // Handle custom diagnostics, which cannot be mapped.
402
6.20M
  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
403
17.3k
    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
404
17.3k
    return CustomDiagInfo->getLevel(DiagID);
405
17.3k
  }
406
6.18M
407
6.18M
  unsigned DiagClass = getBuiltinDiagClass(DiagID);
408
6.18M
  if (DiagClass == CLASS_NOTE) 
return DiagnosticIDs::Note599k
;
409
5.58M
  return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
410
5.58M
}
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
116M
                                     const DiagnosticsEngine &Diag) const {
421
116M
  assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
422
116M
423
116M
  // Specific non-error diagnostics may be mapped to various levels from ignored
424
116M
  // to error.  Errors can only be mapped to fatal.
425
116M
  diag::Severity Result = diag::Severity::Fatal;
426
116M
427
116M
  // Get the mapping information, or compute it lazily.
428
116M
  DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc);
429
116M
  DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
430
116M
431
116M
  // TODO: Can a null severity really get here?
432
116M
  if (Mapping.getSeverity() != diag::Severity())
433
116M
    Result = Mapping.getSeverity();
434
116M
435
116M
  // Upgrade ignored diagnostics if -Weverything is enabled.
436
116M
  if (State->EnableAllWarnings && 
Result == diag::Severity::Ignored10.8k
&&
437
116M
      
!Mapping.isUser()9.90k
&&
getBuiltinDiagClass(DiagID) != CLASS_REMARK9.89k
)
438
9.89k
    Result = diag::Severity::Warning;
439
116M
440
116M
  // Ignore -pedantic diagnostics inside __extension__ blocks.
441
116M
  // (The diagnostics controlled by -pedantic are the extension diagnostics
442
116M
  // that are not enabled by default.)
443
116M
  bool EnabledByDefault = false;
444
116M
  bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
445
116M
  if (Diag.AllExtensionsSilenced && 
IsExtensionDiag321k
&&
!EnabledByDefault13.2k
)
446
13.2k
    return diag::Severity::Ignored;
447
116M
448
116M
  // For extension diagnostics that haven't been explicitly mapped, check if we
449
116M
  // should upgrade the diagnostic.
450
116M
  if (IsExtensionDiag && 
!Mapping.isUser()1.23M
)
451
1.23M
    Result = std::max(Result, State->ExtBehavior);
452
116M
453
116M
  // At this point, ignored errors can no longer be upgraded.
454
116M
  if (Result == diag::Severity::Ignored)
455
103M
    return Result;
456
12.0M
457
12.0M
  // Honor -w: this disables all messages which which are not Error/Fatal by
458
12.0M
  // default (disregarding attempts to upgrade severity from Warning to Error),
459
12.0M
  // as well as disabling all messages which are currently mapped to Warning
460
12.0M
  // (whether by default or downgraded from Error via e.g. -Wno-error or #pragma
461
12.0M
  // diagnostic.)
462
12.0M
  if (State->IgnoreAllWarnings) {
463
999k
    if (Result == diag::Severity::Warning ||
464
999k
        
(1.94k
Result >= diag::Severity::Error1.94k
&&
465
1.94k
         
!isDefaultMappingAsError((diag::kind)DiagID)1.94k
))
466
997k
      return diag::Severity::Ignored;
467
11.0M
  }
468
11.0M
469
11.0M
  // If -Werror is enabled, map warnings to errors unless explicitly disabled.
470
11.0M
  if (Result == diag::Severity::Warning) {
471
10.8M
    if (State->WarningsAsErrors && 
!Mapping.hasNoWarningAsError()2.25M
)
472
2.25M
      Result = diag::Severity::Error;
473
10.8M
  }
474
11.0M
475
11.0M
  // If -Wfatal-errors is enabled, map errors to fatal unless explicitly
476
11.0M
  // disabled.
477
11.0M
  if (Result == diag::Severity::Error) {
478
2.44M
    if (State->ErrorsAsFatal && 
!Mapping.hasNoErrorAsFatal()6
)
479
6
      Result = diag::Severity::Fatal;
480
2.44M
  }
481
11.0M
482
11.0M
  // If explicitly requested, map fatal errors to errors.
483
11.0M
  if (Result == diag::Severity::Fatal &&
484
11.0M
      
Diag.CurDiagID != diag::fatal_too_many_errors278
&&
Diag.FatalsAsError272
)
485
12
    Result = diag::Severity::Error;
486
11.0M
487
11.0M
  // Custom diagnostics always are emitted in system headers.
488
11.0M
  bool ShowInSystemHeader =
489
11.0M
      
!GetDiagInfo(DiagID)11.0M
|| GetDiagInfo(DiagID)->WarnShowInSystemHeader;
490
11.0M
491
11.0M
  // If we are in a system header, we ignore it. We look at the diagnostic class
492
11.0M
  // because we also want to ignore extensions and warnings in -Werror and
493
11.0M
  // -pedantic-errors modes, which *map* warnings/extensions to errors.
494
11.0M
  if (State->SuppressSystemWarnings && 
!ShowInSystemHeader11.0M
&&
Loc.isValid()10.8M
&&
495
11.0M
      Diag.getSourceManager().isInSystemHeader(
496
7.70M
          Diag.getSourceManager().getExpansionLoc(Loc)))
497
3.94M
    return diag::Severity::Ignored;
498
7.11M
499
7.11M
  return Result;
500
7.11M
}
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
1.47M
    StringRef getName() const {
514
1.47M
      return StringRef(DiagGroupNames + NameOffset + 1,
515
1.47M
                       DiagGroupNames[NameOffset]);
516
1.47M
    }
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
15.9k
StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
531
15.9k
  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
532
15.8k
    return OptionTable[Info->getOptionGroupIndex()].getName();
533
112
  return StringRef();
534
112
}
535
536
12
std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() {
537
12
  std::vector<std::string> Res;
538
9.92k
  for (size_t I = 1; DiagGroupNames[I] != '\0';) {
539
9.91k
    std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]);
540
9.91k
    I += DiagGroupNames[I] + 1;
541
9.91k
    Res.push_back("-W" + Diag);
542
9.91k
    Res.push_back("-Wno-" + Diag);
543
9.91k
  }
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
310k
                                  SmallVectorImpl<diag::kind> &Diags) {
553
310k
  // An empty group is considered to be a warning group: we have empty groups
554
310k
  // for GCC compatibility, and GCC does not have remarks.
555
310k
  if (!Group->Members && 
!Group->SubGroups11.6k
)
556
4.40k
    return Flavor == diag::Flavor::Remark;
557
305k
558
305k
  bool NotFound = true;
559
305k
560
305k
  // Add the members of the option diagnostic set.
561
305k
  const int16_t *Member = DiagArrays + Group->Members;
562
1.19M
  for (; *Member != -1; 
++Member890k
) {
563
890k
    if (GetDiagInfo(*Member)->getFlavor() == Flavor) {
564
884k
      NotFound = false;
565
884k
      Diags.push_back(*Member);
566
884k
    }
567
890k
  }
568
305k
569
305k
  // Add the members of the subgroups.
570
305k
  const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
571
474k
  for (; *SubGroups != (int16_t)-1; 
++SubGroups168k
)
572
168k
    NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups],
573
168k
                                      Diags);
574
305k
575
305k
  return NotFound;
576
305k
}
577
578
bool
579
DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
580
140k
                                     SmallVectorImpl<diag::kind> &Diags) const {
581
140k
  auto Found = llvm::partition_point(
582
1.31M
      OptionTable, [=](const WarningOption &O) { return O.getName() < Group; });
583
140k
  if (Found == std::end(OptionTable) || 
Found->getName() != Group140k
)
584
58
    return true; // Option not found.
585
140k
586
140k
  return ::getDiagnosticsInGroup(Flavor, Found, Diags);
587
140k
}
588
589
void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
590
44
                                      std::vector<diag::kind> &Diags) {
591
235k
  for (unsigned i = 0; i != StaticDiagInfoSize; 
++i235k
)
592
235k
    if (StaticDiagInfo[i].getFlavor() == Flavor)
593
187k
      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
13.2k
  for (const WarningOption &O : OptionTable) {
601
13.2k
    // Don't suggest ignored warning flags.
602
13.2k
    if (!O.Members && 
!O.SubGroups1.64k
)
603
608
      continue;
604
12.6k
605
12.6k
    unsigned Distance = O.getName().edit_distance(Group, true, BestDistance);
606
12.6k
    if (Distance > BestDistance)
607
11.6k
      continue;
608
991
609
991
    // Don't suggest groups that are not of this kind.
610
991
    llvm::SmallVector<diag::kind, 8> Diags;
611
991
    if (::getDiagnosticsInGroup(Flavor, &O, Diags) || 
Diags.empty()181
)
612
810
      continue;
613
181
614
181
    if (Distance == BestDistance) {
615
97
      // Two matches with the same distance, don't prefer one over the other.
616
97
      Best = "";
617
97
    } else 
if (84
Distance < BestDistance84
) {
618
84
      // This is a better match.
619
84
      Best = O.getName();
620
84
      BestDistance = Distance;
621
84
    }
622
181
  }
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
6.14M
bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
630
6.14M
  Diagnostic Info(&Diag);
631
6.14M
632
6.14M
  assert(Diag.getClient() && "DiagnosticClient not set!");
633
6.14M
634
6.14M
  // Figure out the diagnostic level of this message.
635
6.14M
  unsigned DiagID = Info.getID();
636
6.14M
  DiagnosticIDs::Level DiagLevel
637
6.14M
    = getDiagnosticLevel(DiagID, Info.getLocation(), Diag);
638
6.14M
639
6.14M
  // Update counts for DiagnosticErrorTrap even if a fatal error occurred
640
6.14M
  // or diagnostics are suppressed.
641
6.14M
  if (DiagLevel >= DiagnosticIDs::Error) {
642
153k
    ++Diag.TrapNumErrorsOccurred;
643
153k
    if (isUnrecoverable(DiagID))
644
150k
      ++Diag.TrapNumUnrecoverableErrorsOccurred;
645
153k
  }
646
6.14M
647
6.14M
  if (Diag.SuppressAllDiagnostics)
648
4.48k
    return false;
649
6.14M
650
6.14M
  if (DiagLevel != DiagnosticIDs::Note) {
651
5.54M
    // Record that a fatal error occurred only when we see a second
652
5.54M
    // non-note diagnostic. This allows notes to be attached to the
653
5.54M
    // fatal error, but suppresses any diagnostics that follow those
654
5.54M
    // notes.
655
5.54M
    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
656
111
      Diag.FatalErrorOccurred = true;
657
5.54M
658
5.54M
    Diag.LastDiagLevel = DiagLevel;
659
5.54M
  }
660
6.14M
661
6.14M
  // If a fatal error has already been emitted, silence all subsequent
662
6.14M
  // diagnostics.
663
6.14M
  if (Diag.FatalErrorOccurred) {
664
3.52k
    if (DiagLevel >= DiagnosticIDs::Error &&
665
3.52k
        
Diag.Client->IncludeInDiagnosticCounts()1.84k
) {
666
1.84k
      ++Diag.NumErrors;
667
1.84k
    }
668
3.52k
669
3.52k
    return false;
670
3.52k
  }
671
6.14M
672
6.14M
  // If the client doesn't care about this message, don't issue it.  If this is
673
6.14M
  // a note and the last real diagnostic was ignored, ignore it too.
674
6.14M
  if (DiagLevel == DiagnosticIDs::Ignored ||
675
6.14M
      
(809k
DiagLevel == DiagnosticIDs::Note809k
&&
676
809k
       
Diag.LastDiagLevel == DiagnosticIDs::Ignored598k
))
677
5.82M
    return false;
678
312k
679
312k
  if (DiagLevel >= DiagnosticIDs::Error) {
680
150k
    if (isUnrecoverable(DiagID))
681
147k
      Diag.UnrecoverableErrorOccurred = true;
682
150k
683
150k
    // Warnings which have been upgraded to errors do not prevent compilation.
684
150k
    if (isDefaultMappingAsError(DiagID))
685
148k
      Diag.UncompilableErrorOccurred = true;
686
150k
687
150k
    Diag.ErrorOccurred = true;
688
150k
    if (Diag.Client->IncludeInDiagnosticCounts()) {
689
150k
      ++Diag.NumErrors;
690
150k
    }
691
150k
692
150k
    // If we've emitted a lot of errors, emit a fatal error instead of it to
693
150k
    // stop a flood of bogus errors.
694
150k
    if (Diag.ErrorLimit && 
Diag.NumErrors > Diag.ErrorLimit33.0k
&&
695
150k
        
DiagLevel == DiagnosticIDs::Error12
) {
696
6
      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
697
6
      return false;
698
6
    }
699
312k
  }
700
312k
701
312k
  // Make sure we set FatalErrorOccurred to ensure that the notes from the
702
312k
  // diagnostic that caused `fatal_too_many_errors` won't be emitted.
703
312k
  if (Diag.CurDiagID == diag::fatal_too_many_errors)
704
6
    Diag.FatalErrorOccurred = true;
705
312k
  // Finally, report it.
706
312k
  EmitDiag(Diag, DiagLevel);
707
312k
  return true;
708
312k
}
709
710
312k
void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const {
711
312k
  Diagnostic Info(&Diag);
712
312k
  assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!");
713
312k
714
312k
  Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
715
312k
  if (Diag.Client->IncludeInDiagnosticCounts()) {
716
312k
    if (DiagLevel == DiagnosticIDs::Warning)
717
60.3k
      ++Diag.NumWarnings;
718
312k
  }
719
312k
720
312k
  Diag.CurDiagID = ~0U;
721
312k
}
722
723
303k
bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
724
303k
  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
725
364
    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
726
364
    // Custom diagnostics.
727
364
    return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
728
364
  }
729
303k
730
303k
  // Only errors may be unrecoverable.
731
303k
  if (getBuiltinDiagClass(DiagID) < CLASS_ERROR)
732
3.11k
    return false;
733
300k
734
300k
  if (DiagID == diag::err_unavailable ||
735
300k
      
DiagID == diag::err_unavailable_message299k
)
736
716
    return false;
737
299k
738
299k
  // Currently we consider all ARC errors as recoverable.
739
299k
  if (isARCDiagnostic(DiagID))
740
2.14k
    return false;
741
297k
742
297k
  return true;
743
297k
}
744
745
300k
bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
746
300k
  unsigned cat = getCategoryNumberForDiag(DiagID);
747
300k
  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
748
300k
}