Coverage Report

Created: 2021-01-23 06:44

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