DiagnosticIDs.cpp revision 7d2b8c1fcc2b707be78b09930a7767477822462f
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/AST/ASTDiagnostic.h"
1533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Analysis/AnalysisDiagnostic.h"
1633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticIDs.h"
1733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h"
1833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Driver/DriverDiagnostic.h"
1933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Frontend/FrontendDiagnostic.h"
2033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Lex/LexDiagnostic.h"
2133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Parse/ParseDiagnostic.h"
2233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h"
2333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include <map>
2533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisusing namespace clang;
2633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Builtin Diagnostic information
2933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
3033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisnamespace {
3233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Diagnostic classes.
3433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisenum {
3533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CLASS_NOTE       = 0x01,
3633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CLASS_WARNING    = 0x02,
3733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CLASS_EXTENSION  = 0x03,
3833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CLASS_ERROR      = 0x04
3933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
4033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
4133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstruct StaticDiagInfoRec {
4233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned short DiagID;
4333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned Mapping : 3;
4433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned Class : 3;
45418df343bb50802586d20aae3b83e2eb44c6c828Douglas Gregor  unsigned SFINAE : 1;
46418df343bb50802586d20aae3b83e2eb44c6c828Douglas Gregor  unsigned AccessControl : 1;
4733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned Category : 5;
4833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
497d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  const char *Name;
507d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
5133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const char *Description;
5233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const char *OptionGroup;
5333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
547d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  const char *BriefExplanation;
557d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  const char *FullExplanation;
567d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
5733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  bool operator<(const StaticDiagInfoRec &RHS) const {
5833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return DiagID < RHS.DiagID;
5933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
6033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
6133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
627d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorstruct StaticDiagNameIndexRec {
637d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  const char *Name;
647d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  unsigned short DiagID;
657d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
667d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  bool operator<(const StaticDiagNameIndexRec &RHS) const {
677d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    assert(Name && RHS.Name && "Null Diagnostic Name");
687d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return strcmp(Name, RHS.Name) == -1;
697d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  }
707d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
717d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  bool operator==(const StaticDiagNameIndexRec &RHS) const {
727d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    assert(Name && RHS.Name && "Null Diagnostic Name");
737d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return strcmp(Name, RHS.Name) == 0;
747d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  }
757d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor};
767d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
7733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
7833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
7933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const StaticDiagInfoRec StaticDiagInfo[] = {
807d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,     \
817d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor             SFINAE,ACCESS,CATEGORY,BRIEF,FULL)         \
827d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE,         \
837d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor   ACCESS, CATEGORY, #ENUM, DESC, GROUP, BRIEF, FULL },
8433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticCommonKinds.inc"
8533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticDriverKinds.inc"
8633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticFrontendKinds.inc"
8733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticLexKinds.inc"
8833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticParseKinds.inc"
8933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticASTKinds.inc"
9033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticSemaKinds.inc"
9133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticAnalysisKinds.inc"
9233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef DIAG
937d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
947d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor};
957d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
967d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorstatic const unsigned StaticDiagInfoSize =
977d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
987d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
997d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// To be sorted before first use (since it's splitted among multiple files)
1007d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorstatic StaticDiagNameIndexRec StaticDiagNameIndex[] = {
1017d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM },
1027d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor#include "clang/Basic/DiagnosticIndexName.inc"
1037d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor#undef DIAG_NAME_INDEX
1047d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  { 0, 0 }
1057d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor};
1067d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
1077d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorstatic const unsigned StaticDiagNameIndexSize =
1087d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1;
10933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
11033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
11133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// or null if the ID is invalid.
11233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
11333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If assertions are enabled, verify that the StaticDiagInfo array is sorted.
11433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#ifndef NDEBUG
11533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  static bool IsFirst = true;
11633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (IsFirst) {
1177d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    for (unsigned i = 1; i != StaticDiagInfoSize; ++i) {
11833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
11933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis             "Diag ID conflict, the enums at the start of clang::diag (in "
120f84109ee6aeffb09366bd70c8593ce1b7818b1adFariborz Jahanian             "DiagnosticIDs.h) probably need to be increased");
12133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
12233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      assert(StaticDiagInfo[i-1] < StaticDiagInfo[i] &&
12333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis             "Improperly sorted diag info");
12433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
12533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    IsFirst = false;
12633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
12733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#endif
12833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
12933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Search the diagnostic table with a binary search.
1307d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
13133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
13233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const StaticDiagInfoRec *Found =
1337d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
1347d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (Found == StaticDiagInfo + StaticDiagInfoSize ||
13533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Found->DiagID != DiagID)
13633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return 0;
13733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
13833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return Found;
13933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
14033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
14133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic unsigned GetDefaultDiagMapping(unsigned DiagID) {
14233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
14333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Mapping;
14433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return diag::MAP_FATAL;
14533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
14633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
14733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getWarningOptionForDiag - Return the lowest-level warning option that
14833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// enables the specified diagnostic.  If there is no -Wfoo flag that controls
14933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// the diagnostic, this returns null.
15033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisconst char *DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
15133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
15233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->OptionGroup;
15333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return 0;
15433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
15533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
1567d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getCategoryNumberForDiag - Return the category number that a specified
15733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// DiagID belongs to, or 0 if no category.
15833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisunsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) {
15933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
16033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Category;
16133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return 0;
16233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
16333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
16433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getCategoryNameFromID - Given a category ID, return the name of the
16533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// category, an empty string if CategoryID is zero, or null if CategoryID is
16633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// invalid.
16733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisconst char *DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
16833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Second the table of options, sorted by name for fast binary lookup.
16933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  static const char *CategoryNameTable[] = {
17033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define GET_CATEGORY_TABLE
17133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define CATEGORY(X) X,
17233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticGroups.inc"
17333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef GET_CATEGORY_TABLE
17433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    "<<END>>"
17533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  };
17633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  static const size_t CategoryNameTableSize =
17733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
17833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
17933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (CategoryID >= CategoryNameTableSize) return 0;
18033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return CategoryNameTable[CategoryID];
18133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
18233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
18333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
18433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
18533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::SFINAEResponse
18633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
18733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
188418df343bb50802586d20aae3b83e2eb44c6c828Douglas Gregor    if (Info->AccessControl)
189418df343bb50802586d20aae3b83e2eb44c6c828Douglas Gregor      return SFINAE_AccessControl;
190418df343bb50802586d20aae3b83e2eb44c6c828Douglas Gregor
19133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (!Info->SFINAE)
19233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      return SFINAE_Report;
19333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
19433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Info->Class == CLASS_ERROR)
19533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      return SFINAE_SubstitutionFailure;
19633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
19733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Suppress notes, warnings, and extensions;
19833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return SFINAE_Suppress;
19933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
20033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
20133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return SFINAE_Report;
20233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
20333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
2047d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getName - Given a diagnostic ID, return its name
2057d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorconst char *DiagnosticIDs::getName(unsigned DiagID) {
2067d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
2077d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return Info->Name;
2087d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  return 0;
2097d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor}
2107d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2117d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getIdFromName - Given a diagnostic name, return its ID, or 0
2127d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorunsigned DiagnosticIDs::getIdFromName(char const *Name) {
2137d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  StaticDiagNameIndexRec *StaticDiagNameIndexEnd =
2147d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    StaticDiagNameIndex + StaticDiagNameIndexSize;
2157d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2167d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (Name == 0) { return diag::DIAG_UPPER_LIMIT; }
2177d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2187d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  StaticDiagNameIndexRec Find = { Name, 0 };
2197d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2207d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  const StaticDiagNameIndexRec *Found =
2217d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find);
2227d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (Found == StaticDiagNameIndexEnd ||
2237d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor      strcmp(Found->Name, Name) != 0)
2247d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return diag::DIAG_UPPER_LIMIT;
2257d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2267d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  return Found->DiagID;
2277d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor}
2287d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2297d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
2307d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// of the issue
2317d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorconst char *DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
2327d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
2337d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return Info->BriefExplanation;
2347d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  return 0;
2357d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor}
2367d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2377d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getFullExplanation - Given a diagnostic ID, return a full explanation
2387d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// of the issue
2397d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregorconst char *DiagnosticIDs::getFullExplanation(unsigned DiagID) {
2407d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
2417d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor    return Info->FullExplanation;
2427d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor  return 0;
2437d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor}
2447d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor
2457d2b8c1fcc2b707be78b09930a7767477822462fDouglas Gregor/// getBuiltinDiagClass - Return the class field of the diagnostic.
24633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis///
24733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic unsigned getBuiltinDiagClass(unsigned DiagID) {
24833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
24933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Class;
25033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return ~0U;
25133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
25233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
25333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
25433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Custom Diagnostic information
25533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
25633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
25733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisnamespace clang {
25833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  namespace diag {
25933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    class CustomDiagInfo {
26033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      typedef std::pair<DiagnosticIDs::Level, std::string> DiagDesc;
26133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      std::vector<DiagDesc> DiagInfo;
26233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      std::map<DiagDesc, unsigned> DiagIDs;
26333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    public:
26433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
26533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// getDescription - Return the description of the specified custom
26633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// diagnostic.
26733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      const char *getDescription(unsigned DiagID) const {
26833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
26933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis               "Invalid diagnosic ID");
27033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
27133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
27233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
27333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      /// getLevel - Return the level of the specified custom diagnostic.
27433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      DiagnosticIDs::Level getLevel(unsigned DiagID) const {
27533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
27633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis               "Invalid diagnosic ID");
27733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
27833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
27933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
28033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      unsigned getOrCreateDiagID(DiagnosticIDs::Level L, llvm::StringRef Message,
28133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                 DiagnosticIDs &Diags) {
28233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagDesc D(L, Message);
28333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        // Check to see if it already exists.
28433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D);
28533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        if (I != DiagIDs.end() && I->first == D)
28633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis          return I->second;
28733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
28833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        // If not, assign a new ID.
28933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
29033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagIDs.insert(std::make_pair(D, ID));
29133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagInfo.push_back(D);
29233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        return ID;
29333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      }
29433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    };
29533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
29633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  } // end diag namespace
29733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis} // end clang namespace
29833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
29933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
30033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
30133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Common Diagnostic implementation
30233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
30333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
30433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::DiagnosticIDs() {
30533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  CustomDiagInfo = 0;
30633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
30733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
30833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::~DiagnosticIDs() {
30933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  delete CustomDiagInfo;
31033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
31133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
31233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getCustomDiagID - Return an ID for a diagnostic with the specified message
31333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// and level.  If this is the first request for this diagnosic, it is
31433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// registered and created, otherwise the existing ID is returned.
31533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisunsigned DiagnosticIDs::getCustomDiagID(Level L, llvm::StringRef Message) {
31633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (CustomDiagInfo == 0)
31733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    CustomDiagInfo = new diag::CustomDiagInfo();
31833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
31933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
32033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
32133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
32233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic
32333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// level of the specified diagnostic ID is a Warning or Extension.
32433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// This only works on builtin diagnostics, not custom ones, and is not legal to
32533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// call on NOTEs.
32633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) {
32733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return DiagID < diag::DIAG_UPPER_LIMIT &&
32833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis         getBuiltinDiagClass(DiagID) != CLASS_ERROR;
32933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
33033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
33133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// \brief Determine whether the given built-in diagnostic ID is a
33233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// Note.
33333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinNote(unsigned DiagID) {
33433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return DiagID < diag::DIAG_UPPER_LIMIT &&
33533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    getBuiltinDiagClass(DiagID) == CLASS_NOTE;
33633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
33733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
33833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
33933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// ID is for an extension of some sort.  This also returns EnabledByDefault,
34033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// which is set to indicate whether the diagnostic is ignored by default (in
34133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// which case -pedantic enables it) or treated as a warning/error by default.
34233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis///
34333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
34433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                        bool &EnabledByDefault) {
34533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagID >= diag::DIAG_UPPER_LIMIT ||
34633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
34733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
34833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
34933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  EnabledByDefault = GetDefaultDiagMapping(DiagID) != diag::MAP_IGNORE;
35033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return true;
35133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
35233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
35333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getDescription - Given a diagnostic ID, return a description of the
35433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// issue.
35533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisconst char *DiagnosticIDs::getDescription(unsigned DiagID) const {
35633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
35733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return Info->Description;
35833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return CustomDiagInfo->getDescription(DiagID);
35933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
36033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
36133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
36233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// object, classify the specified diagnostic ID into a Level, consumable by
36333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// the DiagnosticClient.
3640827408865e32789e0ec4b8113a302ccdc531423Argyrios KyrtzidisDiagnosticIDs::Level
3650827408865e32789e0ec4b8113a302ccdc531423Argyrios KyrtzidisDiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
3667decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek                                  const Diagnostic &Diag,
3677decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek                                  diag::Mapping *mapping) const {
36833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Handle custom diagnostics, which cannot be mapped.
36933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagID >= diag::DIAG_UPPER_LIMIT)
37033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return CustomDiagInfo->getLevel(DiagID);
37133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
37233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned DiagClass = getBuiltinDiagClass(DiagID);
37333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
3747decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek  return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag, mapping);
37533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
37633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3770827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// \brief Based on the way the client configured the Diagnostic
37833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// object, classify the specified diagnostic ID into a Level, consumable by
37933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// the DiagnosticClient.
3800827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis///
3810827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// \param Loc The source location we are interested in finding out the
3820827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis/// diagnostic state. Can be null in order to query the latest state.
38333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::Level
38433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios KyrtzidisDiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
3850827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                  SourceLocation Loc,
3867decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek                                  const Diagnostic &Diag,
3877decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek                                  diag::Mapping *mapping) const {
38833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Specific non-error diagnostics may be mapped to various levels from ignored
38933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // to error.  Errors can only be mapped to fatal.
39033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
39133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
3920827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  Diagnostic::DiagStatePointsTy::iterator
3930827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis    Pos = Diag.GetDiagStatePointForLoc(Loc);
3940827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  Diagnostic::DiagState *State = Pos->State;
3950827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis
39633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Get the mapping information, if unset, compute it lazily.
3970827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  unsigned MappingInfo = Diag.getDiagnosticMappingInfo((diag::kind)DiagID,
3980827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                                       State);
39933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (MappingInfo == 0) {
40033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    MappingInfo = GetDefaultDiagMapping(DiagID);
4013efd52cf8f4e57c5571bd8cc3168264c3bc46a1eArgyrios Kyrtzidis    Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, State, false, false);
40233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
4037decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek
4047decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek  if (mapping)
4057decebfc7b9dc841f228c93cc2e41e3e62911ff8Ted Kremenek    *mapping = (diag::Mapping) (MappingInfo & 7);
40633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
40733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  switch (MappingInfo & 7) {
40833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  default: assert(0 && "Unknown mapping!");
40933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_IGNORE:
41033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Ignore this, unless this is an extension diagnostic and we're mapping
41133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // them onto warnings or errors.
41233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (!isBuiltinExtensionDiag(DiagID) ||  // Not an extension
41333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        Diag.ExtBehavior == Diagnostic::Ext_Ignore || // Ext ignored
41433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        (MappingInfo & 8) != 0)             // User explicitly mapped it.
41533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      return DiagnosticIDs::Ignored;
41633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Warning;
41733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.ExtBehavior == Diagnostic::Ext_Error) Result = DiagnosticIDs::Error;
41833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
41933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Result = DiagnosticIDs::Fatal;
42033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
42133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_ERROR:
42233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Error;
42333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.ErrorsAsFatal)
42433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Result = DiagnosticIDs::Fatal;
42533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
42633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_FATAL:
42733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Fatal;
42833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
42933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_WARNING:
43033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // If warnings are globally mapped to ignore or error, do it.
43133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.IgnoreAllWarnings)
43233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      return DiagnosticIDs::Ignored;
43333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
43433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Warning;
43533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
43633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // If this is an extension diagnostic and we're in -pedantic-error mode, and
43733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // if the user didn't explicitly map it, upgrade to an error.
43833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.ExtBehavior == Diagnostic::Ext_Error &&
43933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        (MappingInfo & 8) == 0 &&
44033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        isBuiltinExtensionDiag(DiagID))
44133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Result = DiagnosticIDs::Error;
44233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
44333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.WarningsAsErrors)
44433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Result = DiagnosticIDs::Error;
44533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
44633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Result = DiagnosticIDs::Fatal;
44733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
44833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
44933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_WARNING_NO_WERROR:
45033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Diagnostics specified with -Wno-error=foo should be set to warnings, but
45133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // not be adjusted by -Werror or -pedantic-errors.
45233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Warning;
45333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
45433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // If warnings are globally mapped to ignore or error, do it.
45533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.IgnoreAllWarnings)
45633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      return DiagnosticIDs::Ignored;
45733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
45833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
45933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
46033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  case diag::MAP_ERROR_NO_WFATAL:
46133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Diagnostics specified as -Wno-fatal-error=foo should be errors, but
46233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // unaffected by -Wfatal-errors.
46333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Result = DiagnosticIDs::Error;
46433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    break;
46533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
46633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
46733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Okay, we're about to return this as a "diagnostic to emit" one last check:
46833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // if this is any sort of extension warning, and if we're in an __extension__
46933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // block, silence it.
47033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
47133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return DiagnosticIDs::Ignored;
47233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
47333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return Result;
47433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
47533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
47633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstruct WarningOption {
47733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const char  *Name;
47833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const short *Members;
47933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const short *SubGroups;
48033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
48133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
48233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define GET_DIAG_ARRAYS
48333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticGroups.inc"
48433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef GET_DIAG_ARRAYS
48533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
48633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis// Second the table of options, sorted by name for fast binary lookup.
48733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const WarningOption OptionTable[] = {
48833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#define GET_DIAG_TABLE
48933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#include "clang/Basic/DiagnosticGroups.inc"
49033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis#undef GET_DIAG_TABLE
49133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis};
49233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic const size_t OptionTableSize =
49333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidissizeof(OptionTable) / sizeof(OptionTable[0]);
49433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
49533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic bool WarningOptionCompare(const WarningOption &LHS,
49633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                 const WarningOption &RHS) {
49733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return strcmp(LHS.Name, RHS.Name) < 0;
49833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
49933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
50033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisstatic void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
5010827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                            SourceLocation Loc, Diagnostic &Diag) {
50233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Option exists, poke all the members of its diagnostic set.
50333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const short *Member = Group->Members) {
50433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    for (; *Member != -1; ++Member)
5050827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      Diag.setDiagnosticMapping(*Member, Mapping, Loc);
50633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
50733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
50833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Enable/disable all subgroups along with this one.
50933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (const short *SubGroups = Group->SubGroups) {
51033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    for (; *SubGroups != (short)-1; ++SubGroups)
5110827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      MapGroupMembers(&OptionTable[(short)*SubGroups], Mapping, Loc, Diag);
51233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
51333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
51433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
51533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
51633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// "unknown-pragmas" to have the specified mapping.  This returns true and
51733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// ignores the request if "Group" was unknown, false otherwise.
51833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group,
51933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                           diag::Mapping Map,
5200827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                           SourceLocation Loc,
52133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                                           Diagnostic &Diag) const {
5220827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  assert((Loc.isValid() ||
5230827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis          Diag.DiagStatePoints.empty() ||
5240827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis          Diag.DiagStatePoints.back().Loc.isInvalid()) &&
5250827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis         "Loc should be invalid only when the mapping comes from command-line");
5260827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  assert((Loc.isInvalid() || Diag.DiagStatePoints.empty() ||
5270827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis          Diag.DiagStatePoints.back().Loc.isInvalid() ||
5280827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis          !Diag.SourceMgr->isBeforeInTranslationUnit(Loc,
5290827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                            Diag.DiagStatePoints.back().Loc)) &&
5300827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis         "Source location of new mapping is before the previous one!");
5310827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis
53233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  WarningOption Key = { Group, 0, 0 };
53333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  const WarningOption *Found =
53433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
53533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis                   WarningOptionCompare);
53633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Found == OptionTable + OptionTableSize ||
53733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      strcmp(Found->Name, Group) != 0)
53833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return true;  // Option not found.
53933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
5400827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis  MapGroupMembers(Found, Map, Loc, Diag);
54133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return false;
54233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
54333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
54433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// ProcessDiag - This is the method used to report a diagnostic that is
54533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis/// finally fully formed.
54633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidisbool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
54733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  DiagnosticInfo Info(&Diag);
54833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
54933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.SuppressAllDiagnostics)
55033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
55133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
55233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  assert(Diag.getClient() && "DiagnosticClient not set!");
55333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
55433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Figure out the diagnostic level of this message.
55533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  DiagnosticIDs::Level DiagLevel;
55633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  unsigned DiagID = Info.getID();
55733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
55833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // ShouldEmitInSystemHeader - True if this diagnostic should be produced even
55933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // in a system header.
56033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  bool ShouldEmitInSystemHeader;
56133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
56233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
56333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Handle custom diagnostics, which cannot be mapped.
56433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    DiagLevel = CustomDiagInfo->getLevel(DiagID);
56533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
56633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Custom diagnostics always are emitted in system headers.
56733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    ShouldEmitInSystemHeader = true;
56833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  } else {
56933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Get the class of the diagnostic.  If this is a NOTE, map it onto whatever
57033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // the diagnostic level was for the previous diagnostic so that it is
57133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // filtered the same as the previous diagnostic.
57233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    unsigned DiagClass = getBuiltinDiagClass(DiagID);
57333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (DiagClass == CLASS_NOTE) {
57433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      DiagLevel = DiagnosticIDs::Note;
57533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ShouldEmitInSystemHeader = false;  // extra consideration is needed
57633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    } else {
57733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      // If this is not an error and we are in a system header, we ignore it.
57833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      // Check the original Diag ID here, because we also want to ignore
57933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      // extensions and warnings in -Werror and -pedantic-errors modes, which
58033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      // *map* warnings/extensions to errors.
58133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ShouldEmitInSystemHeader = DiagClass == CLASS_ERROR;
58233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
5830827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis      DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(),
5840827408865e32789e0ec4b8113a302ccdc531423Argyrios Kyrtzidis                                     Diag);
58533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
58633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
58733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
58833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel != DiagnosticIDs::Note) {
58933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // Record that a fatal error occurred only when we see a second
59033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // non-note diagnostic. This allows notes to be attached to the
59133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // fatal error, but suppresses any diagnostics that follow those
59233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // notes.
59333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.LastDiagLevel == DiagnosticIDs::Fatal)
59433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.FatalErrorOccurred = true;
59533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
59633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Diag.LastDiagLevel = DiagLevel;
59733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
59833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
59933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If a fatal error has already been emitted, silence all subsequent
60033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // diagnostics.
60133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.FatalErrorOccurred) {
60233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (DiagLevel >= DiagnosticIDs::Error &&
60333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        Diag.Client->IncludeInDiagnosticCounts()) {
60433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrors;
60533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrorsSuppressed;
60633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
60733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
60833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
60933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
61033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
61133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If the client doesn't care about this message, don't issue it.  If this is
61233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // a note and the last real diagnostic was ignored, ignore it too.
61333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel == DiagnosticIDs::Ignored ||
61433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      (DiagLevel == DiagnosticIDs::Note &&
61533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis       Diag.LastDiagLevel == DiagnosticIDs::Ignored))
61633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
61733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
61833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // If this diagnostic is in a system header and is not a clang error, suppress
61933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // it.
62033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.SuppressSystemWarnings && !ShouldEmitInSystemHeader &&
62133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Info.getLocation().isValid() &&
62233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.getSourceManager().isInSystemHeader(
62333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis          Diag.getSourceManager().getInstantiationLoc(Info.getLocation())) &&
62433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      (DiagLevel != DiagnosticIDs::Note ||
62533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis       Diag.LastDiagLevel == DiagnosticIDs::Ignored)) {
62633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    Diag.LastDiagLevel = DiagnosticIDs::Ignored;
62733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    return false;
62833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
62933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
63033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (DiagLevel >= DiagnosticIDs::Error) {
63133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.Client->IncludeInDiagnosticCounts()) {
63233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.ErrorOccurred = true;
63333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumErrors;
63433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    }
63533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
63633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // If we've emitted a lot of errors, emit a fatal error after it to stop a
63733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    // flood of bogus errors.
63833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (Diag.ErrorLimit && Diag.NumErrors >= Diag.ErrorLimit &&
63933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis        DiagLevel == DiagnosticIDs::Error)
64033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
64133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
64233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
6434814fb560322daf009fda6226cffccb10bd44620Douglas Gregor  // If we have any Fix-Its, make sure that all of the Fix-Its point into
6444814fb560322daf009fda6226cffccb10bd44620Douglas Gregor  // source locations that aren't macro instantiations. If any point into
6454814fb560322daf009fda6226cffccb10bd44620Douglas Gregor  // macro instantiations, remove all of the Fix-Its.
6464814fb560322daf009fda6226cffccb10bd44620Douglas Gregor  for (unsigned I = 0, N = Diag.NumFixItHints; I != N; ++I) {
6474814fb560322daf009fda6226cffccb10bd44620Douglas Gregor    const FixItHint &FixIt = Diag.FixItHints[I];
6484814fb560322daf009fda6226cffccb10bd44620Douglas Gregor    if (FixIt.RemoveRange.isInvalid() ||
6494814fb560322daf009fda6226cffccb10bd44620Douglas Gregor        FixIt.RemoveRange.getBegin().isMacroID() ||
6504814fb560322daf009fda6226cffccb10bd44620Douglas Gregor        FixIt.RemoveRange.getEnd().isMacroID()) {
6514814fb560322daf009fda6226cffccb10bd44620Douglas Gregor      Diag.NumFixItHints = 0;
6524814fb560322daf009fda6226cffccb10bd44620Douglas Gregor      break;
6534814fb560322daf009fda6226cffccb10bd44620Douglas Gregor    }
6544814fb560322daf009fda6226cffccb10bd44620Douglas Gregor  }
6554814fb560322daf009fda6226cffccb10bd44620Douglas Gregor
65633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  // Finally, report it.
65733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  Diag.Client->HandleDiagnostic((Diagnostic::Level)DiagLevel, Info);
65833e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  if (Diag.Client->IncludeInDiagnosticCounts()) {
65933e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis    if (DiagLevel == DiagnosticIDs::Warning)
66033e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis      ++Diag.NumWarnings;
66133e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  }
66233e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
66333e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  Diag.CurDiagID = ~0U;
66433e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis
66533e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis  return true;
66633e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis}
667