DiagnosticIDs.cpp revision ef8225444452a1486bd721f3285301fe84643b00
133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//
333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//
533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//
833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//
1033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//  This file implements the Diagnostic IDs-related interfaces.
1133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//
1233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
1433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticIDs.h"
156c44886ed05d7804bfd7b80857b81fd3477079f6David Blaikie#include "clang/Basic/AllDiagnostics.h"
16923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall#include "clang/Basic/DiagnosticCategories.h"
1733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h"
18cfaa5525b8eea6c5f7767010e04e323f76bed1abDavid Majnemer#include "llvm/ADT/STLExtras.h"
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "llvm/ADT/SmallVector.h"
209fe8c74a93ac8e92512615c5f83e7a328b3b0544David Blaikie#include "llvm/Support/ErrorHandling.h"
2133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include <map>
2233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisusing namespace clang;
2333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Builtin Diagnostic information
2633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisnamespace {
2933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Diagnostic classes.
3133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisenum {
3233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CLASS_NOTE       = 0x01,
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CLASS_REMARK     = 0x02,
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CLASS_WARNING    = 0x03,
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CLASS_EXTENSION  = 0x04,
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CLASS_ERROR      = 0x05
3733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
3833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstruct StaticDiagInfoRec {
408bfffa51d773d2411cf7b8ac513ef1f50e1a4773Craig Topper  uint16_t DiagID;
41ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  unsigned DefaultSeverity : 3;
4233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned Class : 3;
433347b497157d36cf280d1d9f52956faa6e702f34Richard Smith  unsigned SFINAE : 2;
444213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar  unsigned WarnNoWerror : 1;
454213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar  unsigned WarnShowInSystemHeader : 1;
4633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned Category : 5;
4733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
48d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer  uint16_t OptionGroupIndex;
49477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
50477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  uint16_t DescriptionLen;
51477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  const char *DescriptionStr;
52477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
53d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer  unsigned getOptionGroupIndex() const {
54d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer    return OptionGroupIndex;
55477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  }
56477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef getDescription() const {
585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    return StringRef(DescriptionStr, DescriptionLen);
59477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  }
607d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
6133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  bool operator<(const StaticDiagInfoRec &RHS) const {
6233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return DiagID < RHS.DiagID;
6333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
6433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
6533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
66477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis} // namespace anonymous
67477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
6833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const StaticDiagInfoRec StaticDiagInfo[] = {
69ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR,     \
70ef8225444452a1486bd721f3285301fe84643b00Stephen Hines             SHOWINSYSHEADER, CATEGORY)                                        \
71ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  {                                                                            \
72ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR,      \
73ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC       \
74ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }                                                                            \
75ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ,
7633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticCommonKinds.inc"
7733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticDriverKinds.inc"
7833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticFrontendKinds.inc"
79a2398d7da920b896001f385587e7f7d3366e5b17Chandler Carruth#include "clang/Basic/DiagnosticSerializationKinds.inc"
8033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticLexKinds.inc"
8133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticParseKinds.inc"
8233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticASTKinds.inc"
83a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko#include "clang/Basic/DiagnosticCommentKinds.inc"
8433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticSemaKinds.inc"
8533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticAnalysisKinds.inc"
8633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef DIAG
877d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor};
887d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
89cfaa5525b8eea6c5f7767010e04e323f76bed1abDavid Majnemerstatic const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo);
907d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
9133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
9233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// or null if the ID is invalid.
9333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
9433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
9533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#ifndef NDEBUG
96cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper  static bool IsFirst = true; // So the check is only performed on first call.
97cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper  if (IsFirst) {
98cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper    for (unsigned i = 1; i != StaticDiagInfoSize; ++i) {
99cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
100cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper             "Diag ID conflict, the enums at the start of clang::diag (in "
101cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper             "DiagnosticIDs.h) probably need to be increased");
102cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper
103cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
104cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper             "Improperly sorted diag info");
105cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper    }
106cbfb8d7ca40975acfa3382f5f62c40965fe316c4Craig Topper    IsFirst = false;
10733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
10833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#endif
10933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
110a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // Out of bounds diag. Can't be in the table.
111a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  using namespace diag;
112cfaa5525b8eea6c5f7767010e04e323f76bed1abDavid Majnemer  if (DiagID >= DIAG_UPPER_LIMIT || DiagID <= DIAG_START_COMMON)
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
11433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
115a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // Compute the index of the requested diagnostic in the static table.
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // 1. Add the number of diagnostics in each category preceding the
117a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  //    diagnostic and of the category the diagnostic is in. This gives us
118a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  //    the offset of the category in the table.
119a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // 2. Subtract the number of IDs in each category from our ID. This gives us
120a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  //    the offset of the diagnostic in the category.
121a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // This is cheaper than a binary search on the table as it doesn't touch
122a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // memory at all.
123a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  unsigned Offset = 0;
124cfaa5525b8eea6c5f7767010e04e323f76bed1abDavid Majnemer  unsigned ID = DiagID - DIAG_START_COMMON - 1;
125a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer#define CATEGORY(NAME, PREV) \
126a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  if (DiagID > DIAG_START_##NAME) { \
12735abfcd3285ad82fa269b8f2468dee01a4dceb52Argyrios Kyrtzidis    Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
12835abfcd3285ad82fa269b8f2468dee01a4dceb52Argyrios Kyrtzidis    ID -= DIAG_START_##NAME - DIAG_START_##PREV; \
129a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  }
130a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(DRIVER, COMMON)
131a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(FRONTEND, DRIVER)
132a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(SERIALIZATION, FRONTEND)
133a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(LEX, SERIALIZATION)
134a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(PARSE, LEX)
135a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(AST, PARSE)
136a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(COMMENT, AST)
137a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(SEMA, COMMENT)
138a07b59e5e9b55033239c80552094421a01b75c8aBenjamin KramerCATEGORY(ANALYSIS, SEMA)
139a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer#undef CATEGORY
140a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer
141a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // Avoid out of bounds reads.
142a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  if (ID + Offset >= StaticDiagInfoSize)
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
144a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer
14535abfcd3285ad82fa269b8f2468dee01a4dceb52Argyrios Kyrtzidis  assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize);
14635abfcd3285ad82fa269b8f2468dee01a4dceb52Argyrios Kyrtzidis
147a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  const StaticDiagInfoRec *Found = &StaticDiagInfo[ID + Offset];
148a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // If the diag id doesn't match we found a different diag, abort. This can
149a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // happen when this function is called with an ID that points into a hole in
150a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  // the diagID space.
151a07b59e5e9b55033239c80552094421a01b75c8aBenjamin Kramer  if (Found->DiagID != DiagID)
1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
15333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return Found;
15433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
15533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
156ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstatic DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
157ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  DiagnosticMapping Info = DiagnosticMapping::Make(
158ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
159a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar
160a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar  if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
161ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
1624213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar
163a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar    if (StaticInfo->WarnNoWerror) {
164ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      assert(Info.getSeverity() == diag::Severity::Warning &&
1654213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar             "Unexpected mapping with no-Werror bit!");
166a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar      Info.setNoWarningAsError(true);
1674213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar    }
1684213df3b5da21ce25a4541ca5c447eeb28b515a3Daniel Dunbar  }
169a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar
170a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar  return Info;
17133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
17233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
1737d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getCategoryNumberForDiag - Return the category number that a specified
17433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// DiagID belongs to, or 0 if no category.
17533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisunsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
17633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
17733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Category;
17833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return 0;
17933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
18033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
181dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramernamespace {
182dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer  // The diagnostic category names.
183dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer  struct StaticDiagCategoryRec {
184dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer    const char *NameStr;
185dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer    uint8_t NameLen;
186477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
1875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef getName() const {
1885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      return StringRef(NameStr, NameLen);
189dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer    }
190dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer  };
191dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramer}
192477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
193ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
194ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar// particularly clean, but for now we just implement this method here so we can
195ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar// access GetDefaultDiagMapping.
196ef8225444452a1486bd721f3285301fe84643b00Stephen HinesDiagnosticMapping &
197ef8225444452a1486bd721f3285301fe84643b00Stephen HinesDiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
198ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  std::pair<iterator, bool> Result =
199ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
200ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar
201ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar  // Initialize the entry if we added it.
202aeacae523a1c6e5bb99d12754415bbbc3ccb86c9Daniel Dunbar  if (Result.second)
203ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Result.first->second = GetDefaultDiagMapping(Diag);
204ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar
205ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar  return Result.first->second;
206ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar}
207ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar
208dbda513550aaea9f4106455a3fc6b584bacc77f2Benjamin Kramerstatic const StaticDiagCategoryRec CategoryNameTable[] = {
20933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define GET_CATEGORY_TABLE
210923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
21133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticGroups.inc"
21233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef GET_CATEGORY_TABLE
2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  { nullptr, 0 }
214477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis};
215477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
216477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis/// getNumberOfCategories - Return the number of categories
217477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidisunsigned DiagnosticIDs::getNumberOfCategories() {
218b960232518a1cd79c5f64ab5ef54c88e34660191Craig Topper  return llvm::array_lengthof(CategoryNameTable) - 1;
219477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis}
220477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis
221477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis/// getCategoryNameFromID - Given a category ID, return the name of the
222477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis/// category, an empty string if CategoryID is zero, or null if CategoryID is
223477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis/// invalid.
2245f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
225477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  if (CategoryID >= getNumberOfCategories())
2265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner   return StringRef();
227477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis  return CategoryNameTable[CategoryID].getName();
22833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
22933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
23033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
23133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2323347b497157d36cf280d1d9f52956faa6e702f34Richard SmithDiagnosticIDs::SFINAEResponse
23333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
2343347b497157d36cf280d1d9f52956faa6e702f34Richard Smith  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
2353347b497157d36cf280d1d9f52956faa6e702f34Richard Smith    return static_cast<DiagnosticIDs::SFINAEResponse>(Info->SFINAE);
23633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return SFINAE_Report;
23733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
23833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2397d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getBuiltinDiagClass - Return the class field of the diagnostic.
24033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis///
24133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic unsigned getBuiltinDiagClass(unsigned DiagID) {
24233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
24333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Class;
24433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return ~0U;
24533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
24633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
24733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
24833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Custom Diagnostic information
24933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
25033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
25133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisnamespace clang {
25233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  namespace diag {
25333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    class CustomDiagInfo {
25433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
25533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      std::vector<DiagDesc> DiagInfo;
25633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      std::map<DiagDesc, unsigned> DiagIDs;
25733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    public:
25833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
25933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// getDescription - Return the description of the specified custom
26033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// diagnostic.
2615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      StringRef getDescription(unsigned DiagID) const {
26233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
263fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit               "Invalid diagnostic ID");
264477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
26533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
26633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
26733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// getLevel - Return the level of the specified custom diagnostic.
26833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
26933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
270fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit               "Invalid diagnostic ID");
27133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
27233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
27333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
27533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                 DiagnosticIDs &Diags) {
27633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagDesc D(L, Message);
27733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        // Check to see if it already exists.
27833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
27933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        if (I != DiagIDs.end() && I->first == D)
28033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis          return I->second;
28133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
28233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        // If not, assign a new ID.
28333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
28433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagIDs.insert(std::make_pair(D, ID));
28533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagInfo.push_back(D);
28633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        return ID;
28733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
28833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    };
28933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
29033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  } // end diag namespace
29133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis} // end clang namespace
29233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
29333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
29433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
29533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Common Diagnostic implementation
29633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
29733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesDiagnosticIDs::DiagnosticIDs() { CustomDiagInfo = nullptr; }
29933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
30033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::~DiagnosticIDs() {
30133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  delete CustomDiagInfo;
30233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
30333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
30433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getCustomDiagID - Return an ID for a diagnostic with the specified message
305fc09336a5965040736f9bc63a70416003972364eStefanus Du Toit/// and level.  If this is the first request for this diagnostic, it is
30633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// registered and created, otherwise the existing ID is returned.
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines///
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \param FormatString A fixed diagnostic format string that will be hashed and
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// mapped to a unique DiagID.
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) {
3116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!CustomDiagInfo)
31233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    CustomDiagInfo = new diag::CustomDiagInfo();
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this);
31433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
31533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
31633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
31733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
31833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// level of the specified diagnostic ID is a Warning or Extension.
31933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// This only works on builtin diagnostics, not custom ones, and is not legal to
32033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// call on NOTEs.
32133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
32233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return DiagID < diag::DIAG_UPPER_LIMIT &&
32333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
32433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
32533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
32633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// \brief Determine whether the given built-in diagnostic ID is a
32733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// Note.
32833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
32933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return DiagID < diag::DIAG_UPPER_LIMIT &&
33033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
33133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
33233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
33333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
33433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// ID is for an extension of some sort.  This also returns EnabledByDefault,
33533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// which is set to indicate whether the diagnostic is ignored by default (in
33633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// which case -pedantic enables it) or treated as a warning/error by default.
33733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis///
33833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
33933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                        bool &EnabledByDefault) {
34033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
34133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
34233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
343ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
344a5e41333b06fdf036d58495490eb14d6a0a3fcf7Daniel Dunbar  EnabledByDefault =
345ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
34633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return true;
34733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
34833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
34976101cfe52d1b56974bf0e316247b3201f87c463Daniel Dunbarbool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
35076101cfe52d1b56974bf0e316247b3201f87c463Daniel Dunbar  if (DiagID >= diag::DIAG_UPPER_LIMIT)
35176101cfe52d1b56974bf0e316247b3201f87c463Daniel Dunbar    return false;
35276101cfe52d1b56974bf0e316247b3201f87c463Daniel Dunbar
353ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return GetDefaultDiagMapping(DiagID).getSeverity() == diag::Severity::Error;
3546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
3556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
35633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getDescription - Given a diagnostic ID, return a description of the
35733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// issue.
3585f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
35933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
360477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis    return Info->getDescription();
36133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return CustomDiagInfo->getDescription(DiagID);
36233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
36333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
364ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesstatic DiagnosticIDs::Level toLevel(diag::Severity SV) {
365ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  switch (SV) {
366ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case diag::Severity::Ignored:
367ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DiagnosticIDs::Ignored;
368ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case diag::Severity::Remark:
369ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DiagnosticIDs::Remark;
370ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case diag::Severity::Warning:
371ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DiagnosticIDs::Warning;
372ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case diag::Severity::Error:
373ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DiagnosticIDs::Error;
374ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  case diag::Severity::Fatal:
375ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return DiagnosticIDs::Fatal;
376ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
377ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  llvm_unreachable("unexpected severity");
378ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
379ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
380d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie/// getDiagnosticLevel - Based on the way the client configured the
381d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
382d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie/// by consumable the DiagnosticClient.
3830827408865e32789e0ec4b8113a302ccdc531423Argyrios KyrtzidisDiagnosticIDs::Level
3840827408865e32789e0ec4b8113a302ccdc531423Argyrios KyrtzidisDiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
3851656aaec223949245fdbebf306b719cba0b687caDaniel Dunbar                                  const DiagnosticsEngine &Diag) const {
38633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Handle custom diagnostics, which cannot be mapped.
38733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagID >= diag::DIAG_UPPER_LIMIT)
38833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return CustomDiagInfo->getLevel(DiagID);
38933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
39033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned DiagClass = getBuiltinDiagClass(DiagID);
391c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note;
392ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
39333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
39433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3950827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// \brief Based on the way the client configured the Diagnostic
39633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// object, classify the specified diagnostic ID into a Level, consumable by
39733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// the DiagnosticClient.
3980827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis///
3990827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// \param Loc The source location we are interested in finding out the
4000827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// diagnostic state. Can be null in order to query the latest state.
401ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesdiag::Severity
402ef8225444452a1486bd721f3285301fe84643b00Stephen HinesDiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
403ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                     const DiagnosticsEngine &Diag) const {
404ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
405ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
40633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Specific non-error diagnostics may be mapped to various levels from ignored
40733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // to error.  Errors can only be mapped to fatal.
408ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  diag::Severity Result = diag::Severity::Fatal;
40933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
410d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine::DiagStatePointsTy::iterator
4110827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    Pos = Diag.GetDiagStatePointForLoc(Loc);
412d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine::DiagState *State = Pos->State;
4130827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis
414ba494c64365d78b1cdb6baea4d1e79263389fda9Daniel Dunbar  // Get the mapping information, or compute it lazily.
415ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
416ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
417ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // TODO: Can a null severity really get here?
418ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Mapping.getSeverity() != diag::Severity())
419ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Result = Mapping.getSeverity();
42033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
421be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // Upgrade ignored diagnostics if -Weverything is enabled.
422ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Diag.EnableAllWarnings && Result == diag::Severity::Ignored &&
423ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !Mapping.isUser())
424ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Result = diag::Severity::Warning;
42533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Diagnostics of class REMARK are either printed as remarks or in case they
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // have been added to -Werror they are printed as errors.
428ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // FIXME: Disregarding user-requested remark mappings like this is bogus.
429ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Result == diag::Severity::Warning &&
430ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      getBuiltinDiagClass(DiagID) == CLASS_REMARK)
431ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Result = diag::Severity::Remark;
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
43318c407fcb25ea88a52ad48fcc4397c3616dd185dBob Wilson  // Ignore -pedantic diagnostics inside __extension__ blocks.
43418c407fcb25ea88a52ad48fcc4397c3616dd185dBob Wilson  // (The diagnostics controlled by -pedantic are the extension diagnostics
43518c407fcb25ea88a52ad48fcc4397c3616dd185dBob Wilson  // that are not enabled by default.)
436f3dee206ffa571b4541b8e777ee31dc8476d66daDaniel Dunbar  bool EnabledByDefault = false;
43718c407fcb25ea88a52ad48fcc4397c3616dd185dBob Wilson  bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
43818c407fcb25ea88a52ad48fcc4397c3616dd185dBob Wilson  if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
439ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return diag::Severity::Ignored;
44033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
441be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // For extension diagnostics that haven't been explicitly mapped, check if we
442be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // should upgrade the diagnostic.
443ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (IsExtensionDiag && !Mapping.isUser())
444ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Result = std::max(Result, Diag.ExtBehavior);
44533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
446be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // At this point, ignored errors can no longer be upgraded.
447ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Result == diag::Severity::Ignored)
448be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar    return Result;
44933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
450be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // Honor -w, which is lower in priority than pedantic-errors, but higher than
451be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // -Werror.
452ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Result == diag::Severity::Warning && Diag.IgnoreAllWarnings)
453ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return diag::Severity::Ignored;
45433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
455be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // If -Werror is enabled, map warnings to errors unless explicitly disabled.
456ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Result == diag::Severity::Warning) {
457ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (Diag.WarningsAsErrors && !Mapping.hasNoWarningAsError())
458ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Result = diag::Severity::Error;
45933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
46033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
461be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // If -Wfatal-errors is enabled, map errors to fatal unless explicity
462be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  // disabled.
463ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Result == diag::Severity::Error) {
464ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (Diag.ErrorsAsFatal && !Mapping.hasNoErrorAsFatal())
465ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      Result = diag::Severity::Fatal;
466be1aa410274b28fc143c47c814f07c989f4534d6Daniel Dunbar  }
46733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
468ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  // Custom diagnostics always are emitted in system headers.
469ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool ShowInSystemHeader =
470ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
471ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
472aeacae523a1c6e5bb99d12754415bbbc3ccb86c9Daniel Dunbar  // If we are in a system header, we ignore it. We look at the diagnostic class
473aeacae523a1c6e5bb99d12754415bbbc3ccb86c9Daniel Dunbar  // because we also want to ignore extensions and warnings in -Werror and
474cfdadfe547015b916bd59aec892caa972ff76cf0Argyrios Kyrtzidis  // -pedantic-errors modes, which *map* warnings/extensions to errors.
475ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  if (Diag.SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
476cfdadfe547015b916bd59aec892caa972ff76cf0Argyrios Kyrtzidis      Diag.getSourceManager().isInSystemHeader(
477402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth          Diag.getSourceManager().getExpansionLoc(Loc)))
478ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return diag::Severity::Ignored;
479cfdadfe547015b916bd59aec892caa972ff76cf0Argyrios Kyrtzidis
48033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return Result;
48133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
48233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
483354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper#define GET_DIAG_ARRAYS
484354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper#include "clang/Basic/DiagnosticGroups.inc"
485354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper#undef GET_DIAG_ARRAYS
486354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper
48746c8fca7b32a7613f9b37b46c381dd064b773b30Craig Toppernamespace {
48846c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper  struct WarningOption {
48946c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    uint16_t NameOffset;
49046c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    uint16_t Members;
49146c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    uint16_t SubGroups;
49246c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper
49346c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    // String is stored with a pascal-style length byte.
49446c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    StringRef getName() const {
49546c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper      return StringRef(DiagGroupNames + NameOffset + 1,
49646c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper                       DiagGroupNames[NameOffset]);
49746c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper    }
49846c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper  };
49946c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper}
50033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
50133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Second the table of options, sorted by name for fast binary lookup.
50233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const WarningOption OptionTable[] = {
50333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define GET_DIAG_TABLE
50433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticGroups.inc"
50533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef GET_DIAG_TABLE
50633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
507b960232518a1cd79c5f64ab5ef54c88e34660191Craig Topperstatic const size_t OptionTableSize = llvm::array_lengthof(OptionTable);
50833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
509354f20a8720732aa1745d1ff9595382cee324ee2Craig Topperstatic bool WarningOptionCompare(const WarningOption &LHS, StringRef RHS) {
510354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper  return LHS.getName() < RHS;
51133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
51233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
513d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer/// getWarningOptionForDiag - Return the lowest-level warning option that
514d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
515d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer/// the diagnostic, this returns null.
516d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin KramerStringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
517d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
518d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer    return OptionTable[Info->getOptionGroupIndex()].getName();
519d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer  return StringRef();
520d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer}
521d49cb20288b2dbc222aaf5673c1a4738c151b7bfBenjamin Kramer
52246c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topperstatic void getDiagnosticsInGroup(const WarningOption *Group,
52346c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper                                  SmallVectorImpl<diag::kind> &Diags) {
5243f8394669673451061f57ced81f0a2cae087f119Daniel Dunbar  // Add the members of the option diagnostic set.
525b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper  const int16_t *Member = DiagArrays + Group->Members;
526b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper  for (; *Member != -1; ++Member)
527b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper    Diags.push_back(*Member);
52833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
5293f8394669673451061f57ced81f0a2cae087f119Daniel Dunbar  // Add the members of the subgroups.
530b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper  const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
531b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper  for (; *SubGroups != (int16_t)-1; ++SubGroups)
532b1aa16a18563ebb6824fbe7267420942c802a8caCraig Topper    getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
53333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
53433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
5353f8394669673451061f57ced81f0a2cae087f119Daniel Dunbarbool DiagnosticIDs::getDiagnosticsInGroup(
536cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    StringRef Group,
537cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    SmallVectorImpl<diag::kind> &Diags) const {
53833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const WarningOption *Found =
539354f20a8720732aa1745d1ff9595382cee324ee2Craig Topper  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Group,
54033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                   WarningOptionCompare);
54133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Found == OptionTable + OptionTableSize ||
542477aab6782795e7472055a54108d2df270ce1a89Argyrios Kyrtzidis      Found->getName() != Group)
5433f8394669673451061f57ced81f0a2cae087f119Daniel Dunbar    return true; // Option not found.
54433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
54546c8fca7b32a7613f9b37b46c381dd064b773b30Craig Topper  ::getDiagnosticsInGroup(Found, Diags);
54633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return false;
54733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
54833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
54911583c757bac6ce5c342f2eb572055dd2619a657Argyrios Kyrtzidisvoid DiagnosticIDs::getAllDiagnostics(
550cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                               SmallVectorImpl<diag::kind> &Diags) const {
55111583c757bac6ce5c342f2eb572055dd2619a657Argyrios Kyrtzidis  for (unsigned i = 0; i != StaticDiagInfoSize; ++i)
55211583c757bac6ce5c342f2eb572055dd2619a657Argyrios Kyrtzidis    Diags.push_back(StaticDiagInfo[i].DiagID);
55311583c757bac6ce5c342f2eb572055dd2619a657Argyrios Kyrtzidis}
55411583c757bac6ce5c342f2eb572055dd2619a657Argyrios Kyrtzidis
555a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin KramerStringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
556a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer  StringRef Best;
557dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer  unsigned BestDistance = Group.size() + 1; // Sanity threshold.
558a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer  for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
559a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer       i != e; ++i) {
560a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer    // Don't suggest ignored warning flags.
561a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer    if (!i->Members && !i->SubGroups)
562a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer      continue;
563a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer
564a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer    unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
565dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer    if (Distance == BestDistance) {
566dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer      // Two matches with the same distance, don't prefer one over the other.
567dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer      Best = "";
568dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer    } else if (Distance < BestDistance) {
569dce6327160a6e333137b34cce77e2dfc2cd5aab6Benjamin Kramer      // This is a better match.
570a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer      Best = i->getName();
571a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer      BestDistance = Distance;
572a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer    }
573a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer  }
574a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer
575a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer  return Best;
576a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer}
577a70cb9db9dd79ca9fc1febbb2f331004297664e0Benjamin Kramer
57833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// ProcessDiag - This is the method used to report a diagnostic that is
57933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// finally fully formed.
580d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikiebool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
58140847cfb58acc3cac7d68727df9455ac45f2e118David Blaikie  Diagnostic Info(&Diag);
58233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
58333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.SuppressAllDiagnostics)
58433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
58533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
58633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  assert(Diag.getClient() && "DiagnosticClient not set!");
58733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
58833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Figure out the diagnostic level of this message.
58933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned DiagID = Info.getID();
590c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  DiagnosticIDs::Level DiagLevel
591c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose    = getDiagnosticLevel(DiagID, Info.getLocation(), Diag);
59233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
59333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel != DiagnosticIDs::Note) {
59433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Record that a fatal error occurred only when we see a second
59533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // non-note diagnostic. This allows notes to be attached to the
59633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // fatal error, but suppresses any diagnostics that follow those
59733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // notes.
59833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
59933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.FatalErrorOccurred = true;
60033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
60133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Diag.LastDiagLevel = DiagLevel;
60233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
60333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
604c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis  // Update counts for DiagnosticErrorTrap even if a fatal error occurred.
605c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis  if (DiagLevel >= DiagnosticIDs::Error) {
606c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis    ++Diag.TrapNumErrorsOccurred;
607c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis    if (isUnrecoverable(DiagID))
608c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis      ++Diag.TrapNumUnrecoverableErrorsOccurred;
609c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis  }
610c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis
61133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If a fatal error has already been emitted, silence all subsequent
61233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // diagnostics.
61333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.FatalErrorOccurred) {
61433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (DiagLevel >= DiagnosticIDs::Error &&
61533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        Diag.Client->IncludeInDiagnosticCounts()) {
61633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrors;
61733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrorsSuppressed;
61833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
61933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
62033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
62133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
62233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
62333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If the client doesn't care about this message, don't issue it.  If this is
62433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // a note and the last real diagnostic was ignored, ignore it too.
62533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel == DiagnosticIDs::Ignored ||
62633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      (DiagLevel == DiagnosticIDs::Note &&
62733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis       Diag.LastDiagLevel == DiagnosticIDs::Ignored))
62833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
62933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
63033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel >= DiagnosticIDs::Error) {
631c0a575f9b791a25c94b1c3c832dd73ec564646bbArgyrios Kyrtzidis    if (isUnrecoverable(DiagID))
63285bea9777d444ccbcc086d98f075fe666c2e865dDouglas Gregor      Diag.UnrecoverableErrorOccurred = true;
6331c84c68b6d7a92416493ab6c36f630de48c65d08Daniel Jasper
63412f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins    // Warnings which have been upgraded to errors do not prevent compilation.
63512f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins    if (isDefaultMappingAsError(DiagID))
63612f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins      Diag.UncompilableErrorOccurred = true;
63712f37e411462b8388eb1309357bd62257debacacDeLesley Hutchins
6381c84c68b6d7a92416493ab6c36f630de48c65d08Daniel Jasper    Diag.ErrorOccurred = true;
63933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.Client->IncludeInDiagnosticCounts()) {
64033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrors;
64133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
64233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
643f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor    // If we've emitted a lot of errors, emit a fatal error instead of it to
644f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor    // stop a flood of bogus errors.
645f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor    if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit &&
646f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor        DiagLevel == DiagnosticIDs::Error) {
64733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
648f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor      return false;
649f1d594864b4aefc1fe21535cb43e8a81038f3f15Douglas Gregor    }
65033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
65133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
65233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Finally, report it.
653c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  EmitDiag(Diag, DiagLevel);
654c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  return true;
655c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose}
656c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose
657c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rosevoid DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const {
658c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  Diagnostic Info(&Diag);
659c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose  assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!");
660c6d64a26c28bbeee50e06c94c4f4c08e610327b7Jordan Rose
661d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
66233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.Client->IncludeInDiagnosticCounts()) {
66333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (DiagLevel == DiagnosticIDs::Warning)
66433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumWarnings;
66533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
66633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
66733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  Diag.CurDiagID = ~0U;
66833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
669923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall
670923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCallbool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
671923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
672923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall    // Custom diagnostics.
673923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall    return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
674923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall  }
675923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall
676923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall  // Only errors may be unrecoverable.
67785bea9777d444ccbcc086d98f075fe666c2e865dDouglas Gregor  if (getBuiltinDiagClass(DiagID) < CLASS_ERROR)
678923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall    return false;
679923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall
680923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall  if (DiagID == diag::err_unavailable ||
681923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall      DiagID == diag::err_unavailable_message)
682923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall    return false;
683923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall
684f85e193739c953358c865005855253af4f68a497John McCall  // Currently we consider all ARC errors as recoverable.
685afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenek  if (isARCDiagnostic(DiagID))
686f85e193739c953358c865005855253af4f68a497John McCall    return false;
687f85e193739c953358c865005855253af4f68a497John McCall
688923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall  return true;
689923cd5744a724d9302ea12baa5476ad1c37f474dJohn McCall}
690afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenek
691afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenekbool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
692afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenek  unsigned cat = getCategoryNumberForDiag(DiagID);
693afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenek  return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
694afdc21ad774eff6ed6c464e3f2dff9e26ed3d0b0Ted Kremenek}
695