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