Diagnostic.cpp revision 4ad4b3ebbe5769143389dccfcfadb666a4ba5940
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the Diagnostic-related interfaces. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/Diagnostic.h" 1543b628cd47ecdc3caf640d79b3ad7ecef0f2c285Chris Lattner#include "clang/Basic/IdentifierTable.h" 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/SourceLocation.h" 17f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner#include "llvm/ADT/SmallVector.h" 1830bc96544346bea42921cf6837e66cef80d664b4Chris Lattner#include "llvm/ADT/StringExtras.h" 19182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner#include <vector> 20182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner#include <map> 2187cf5ac1b046a1db874b77dcb6e35f9c4b88c386Chris Lattner#include <cstring> 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 24182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 25182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner// Builtin Diagnostic information 26182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 27182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Flag values for diagnostics. 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerenum { 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Diagnostic classes. 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NOTE = 0x01, 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer WARNING = 0x02, 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer EXTENSION = 0x03, 344489fe10fa073eb326e2c8906db170f009050911Daniel Dunbar EXTWARN = 0x04, 354489fe10fa073eb326e2c8906db170f009050911Daniel Dunbar ERROR = 0x05, 36da0cbc1ad4a553c4de111c1181ec7b42c5ddefceChris Lattner FATAL = 0x06, 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer class_mask = 0x07 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DiagnosticFlags - A set of flags, or'd together, that describe the 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// diagnostic. 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define DIAG(ENUM,FLAGS,DESC) FLAGS, 4320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsCommon[] = { 4420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticCommonKinds.def" 4520c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 4620c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 474ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbarstatic unsigned char DiagnosticFlagsDriver[] = { 484ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar#include "clang/Basic/DiagnosticDriverKinds.def" 494ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar 0 504ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar}; 5120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsLex[] = { 5220c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticLexKinds.def" 5320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 5420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 5520c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsParse[] = { 5620c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticParseKinds.def" 5720c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 5820c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 5920c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsAST[] = { 6020c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticASTKinds.def" 6120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 6220c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 6320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsSema[] = { 6420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticSemaKinds.def" 6520c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 6620c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 6720c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic unsigned char DiagnosticFlagsAnalysis[] = { 6820c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticAnalysisKinds.def" 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 0 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 7120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#undef DIAG 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getDiagClass - Return the class field of the diagnostic. 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 750750618b0beacdc9b0a9e210a661e4746823ced7Chris Lattnerstatic unsigned getBuiltinDiagClass(unsigned DiagID) { 7619e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner assert(DiagID < diag::DIAG_UPPER_LIMIT && 770750618b0beacdc9b0a9e210a661e4746823ced7Chris Lattner "Diagnostic ID out of range!"); 7820c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner unsigned res; 794ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar if (DiagID < diag::DIAG_START_DRIVER) 8020c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner res = DiagnosticFlagsCommon[DiagID]; 814ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar else if (DiagID < diag::DIAG_START_LEX) 824ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar res = DiagnosticFlagsDriver[DiagID - diag::DIAG_START_DRIVER - 1]; 8319e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner else if (DiagID < diag::DIAG_START_PARSE) 8419e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner res = DiagnosticFlagsLex[DiagID - diag::DIAG_START_LEX - 1]; 8519e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner else if (DiagID < diag::DIAG_START_AST) 8619e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner res = DiagnosticFlagsParse[DiagID - diag::DIAG_START_PARSE - 1]; 8719e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner else if (DiagID < diag::DIAG_START_SEMA) 8819e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner res = DiagnosticFlagsAST[DiagID - diag::DIAG_START_AST - 1]; 8919e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner else if (DiagID < diag::DIAG_START_ANALYSIS) 9019e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner res = DiagnosticFlagsSema[DiagID - diag::DIAG_START_SEMA - 1]; 9120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner else 9219e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner res = DiagnosticFlagsAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1]; 9320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner return res & class_mask; 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// DiagnosticText - An english message to print for the diagnostic. These 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// should be localized. 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define DIAG(ENUM,FLAGS,DESC) DESC, 9920c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextCommon[] = { 10020c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticCommonKinds.def" 10120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 10220c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 1034ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbarstatic const char * const DiagnosticTextDriver[] = { 1044ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar#include "clang/Basic/DiagnosticDriverKinds.def" 1054ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar 0 1064ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar}; 10720c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextLex[] = { 10820c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticLexKinds.def" 10920c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 11020c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 11120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextParse[] = { 11220c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticParseKinds.def" 11320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 11420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 11520c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextAST[] = { 11620c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticASTKinds.def" 11720c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 11820c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 11920c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextSema[] = { 12020c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticSemaKinds.def" 12120c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner 0 12220c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner}; 12320c6b3b85e186cd52d5d99489132d71d498159ebChris Lattnerstatic const char * const DiagnosticTextAnalysis[] = { 12420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#include "clang/Basic/DiagnosticAnalysisKinds.def" 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 0 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 12720c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner#undef DIAG 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 129182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 130182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner// Custom Diagnostic information 131182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 132182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 133182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattnernamespace clang { 134182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner namespace diag { 135182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner class CustomDiagInfo { 136182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner typedef std::pair<Diagnostic::Level, std::string> DiagDesc; 137182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner std::vector<DiagDesc> DiagInfo; 138182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner std::map<DiagDesc, unsigned> DiagIDs; 139182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner public: 140182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 141182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner /// getDescription - Return the description of the specified custom 142182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner /// diagnostic. 143182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner const char *getDescription(unsigned DiagID) const { 14488eccaf06f9d88191723e71bdf5ca68409393be6Chris Lattner assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && 145182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner "Invalid diagnosic ID"); 14688eccaf06f9d88191723e71bdf5ca68409393be6Chris Lattner return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str(); 147182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner } 148182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 149182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner /// getLevel - Return the level of the specified custom diagnostic. 150182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner Diagnostic::Level getLevel(unsigned DiagID) const { 15188eccaf06f9d88191723e71bdf5ca68409393be6Chris Lattner assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && 152182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner "Invalid diagnosic ID"); 15388eccaf06f9d88191723e71bdf5ca68409393be6Chris Lattner return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; 154182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner } 155182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 156a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner unsigned getOrCreateDiagID(Diagnostic::Level L, const char *Message, 157a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner Diagnostic &Diags) { 158182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner DiagDesc D(L, Message); 159182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner // Check to see if it already exists. 160182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner std::map<DiagDesc, unsigned>::iterator I = DiagIDs.lower_bound(D); 161182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner if (I != DiagIDs.end() && I->first == D) 162182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner return I->second; 163182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 164182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner // If not, assign a new ID. 16588eccaf06f9d88191723e71bdf5ca68409393be6Chris Lattner unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT; 166182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner DiagIDs.insert(std::make_pair(D, ID)); 167182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner DiagInfo.push_back(D); 168a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner 169a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner // If this is a warning, and all warnings are supposed to map to errors, 170a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner // insert the mapping now. 171a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner if (L == Diagnostic::Warning && Diags.getWarningsAsErrors()) 172a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner Diags.setDiagnosticMapping((diag::kind)ID, diag::MAP_ERROR); 173182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner return ID; 174182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner } 175182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner }; 176182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 177182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner } // end diag namespace 178182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner} // end clang namespace 179182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 180182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 181182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 182182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner// Common Diagnostic implementation 183182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner//===----------------------------------------------------------------------===// 184182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 1853fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattnerstatic void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT, 1863fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner const char *Modifier, unsigned ML, 1873fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner const char *Argument, unsigned ArgLen, 18892dd386e3f05d176b45a638199d51f536bd9d1c4Chris Lattner llvm::SmallVectorImpl<char> &Output, 18992dd386e3f05d176b45a638199d51f536bd9d1c4Chris Lattner void *Cookie) { 1903fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner const char *Str = "<can't format argument>"; 19122caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner Output.append(Str, Str+strlen(Str)); 19222caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner} 19322caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner 19422caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner 195b4398aa27da4d6919c3ae448d1ae66ba6cafc048Ted KremenekDiagnostic::Diagnostic(DiagnosticClient *client) : Client(client) { 1965b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner IgnoreAllWarnings = false; 1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer WarningsAsErrors = false; 1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer WarnOnExtensions = false; 1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ErrorOnExtensions = false; 2002fe0997427d92388e66e7573f4b043e7ba285ef0Daniel Dunbar SuppressSystemWarnings = false; 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Clear all mappings, setting them to MAP_DEFAULT. 2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memset(DiagMappings, 0, sizeof(DiagMappings)); 2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ErrorOccurred = false; 20515221422eda7bac679e38b07512feda49715ef66Chris Lattner FatalErrorOccurred = false; 2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumDiagnostics = 0; 2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumErrors = 0; 208182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner CustomDiagInfo = 0; 2093cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner CurDiagID = ~0U; 210f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner LastDiagLevel = Fatal; 21122caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner 2123fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner ArgToStringFn = DummyArgToStringFn; 21392dd386e3f05d176b45a638199d51f536bd9d1c4Chris Lattner ArgToStringCookie = 0; 214ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor 215ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor InPostDiagnosticHook = false; 216182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner} 217182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 218182745ae7892bca0842d9c023370ade5f8d1c6e8Chris LattnerDiagnostic::~Diagnostic() { 219182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner delete CustomDiagInfo; 220182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner} 221182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 222182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner/// getCustomDiagID - Return an ID for a diagnostic with the specified message 223182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner/// and level. If this is the first request for this diagnosic, it is 224182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner/// registered and created, otherwise the existing ID is returned. 225182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattnerunsigned Diagnostic::getCustomDiagID(Level L, const char *Message) { 226182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner if (CustomDiagInfo == 0) 227182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner CustomDiagInfo = new diag::CustomDiagInfo(); 228a1f23cc7f5dae8b71b8ee631994274609d35eb89Chris Lattner return CustomDiagInfo->getOrCreateDiagID(L, Message, *this); 2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 231182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner 232f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic 233f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// level of the specified diagnostic ID is a Warning or Extension. 234f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// This only works on builtin diagnostics, not custom ones, and is not legal to 235f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// call on NOTEs. 236f5d2328fc849288c3a62e43d065685f516d57091Chris Lattnerbool Diagnostic::isBuiltinWarningOrExtension(unsigned DiagID) { 23719e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner return DiagID < diag::DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) < ERROR; 2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 240ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor/// \brief Determine whether the given built-in diagnostic ID is a 241ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor/// Note. 242ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregorbool Diagnostic::isBuiltinNote(unsigned DiagID) { 243ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor return DiagID < diag::DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) == NOTE; 244ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor} 245ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor 2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getDescription - Given a diagnostic ID, return a description of the 2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// issue. 2490a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattnerconst char *Diagnostic::getDescription(unsigned DiagID) const { 2504ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar if (DiagID < diag::DIAG_START_DRIVER) 251f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextCommon[DiagID]; 2524ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar else if (DiagID < diag::DIAG_START_LEX) 2534ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar return DiagnosticTextDriver[DiagID - diag::DIAG_START_DRIVER - 1]; 254f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner else if (DiagID < diag::DIAG_START_PARSE) 255f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextLex[DiagID - diag::DIAG_START_LEX - 1]; 256f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner else if (DiagID < diag::DIAG_START_AST) 257f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextParse[DiagID - diag::DIAG_START_PARSE - 1]; 258f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner else if (DiagID < diag::DIAG_START_SEMA) 259f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextAST[DiagID - diag::DIAG_START_AST - 1]; 260f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner else if (DiagID < diag::DIAG_START_ANALYSIS) 261f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextSema[DiagID - diag::DIAG_START_SEMA - 1]; 262f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner else if (DiagID < diag::DIAG_UPPER_LIMIT) 263f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return DiagnosticTextAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1]; 26420c6b3b85e186cd52d5d99489132d71d498159ebChris Lattner return CustomDiagInfo->getDescription(DiagID); 2655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// getDiagnosticLevel - Based on the way the client configured the Diagnostic 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// object, classify the specified diagnostic ID into a Level, consumable by 2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the DiagnosticClient. 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerDiagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const { 271182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner // Handle custom diagnostics, which cannot be mapped. 27219e8e2cffc19606d0f44e7c2897cd126ffd3f9b0Chris Lattner if (DiagID >= diag::DIAG_UPPER_LIMIT) 273182745ae7892bca0842d9c023370ade5f8d1c6e8Chris Lattner return CustomDiagInfo->getLevel(DiagID); 2740750618b0beacdc9b0a9e210a661e4746823ced7Chris Lattner 2750750618b0beacdc9b0a9e210a661e4746823ced7Chris Lattner unsigned DiagClass = getBuiltinDiagClass(DiagID); 276f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner assert(DiagClass != NOTE && "Cannot get the diagnostic level of a note!"); 277f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner return getDiagnosticLevel(DiagID, DiagClass); 278f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner} 279f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 280f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// getDiagnosticLevel - Based on the way the client configured the Diagnostic 281f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// object, classify the specified diagnostic ID into a Level, consumable by 282f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner/// the DiagnosticClient. 283f5d2328fc849288c3a62e43d065685f516d57091Chris LattnerDiagnostic::Level 284f5d2328fc849288c3a62e43d065685f516d57091Chris LattnerDiagnostic::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const { 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Specific non-error diagnostics may be mapped to various levels from ignored 286f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // to error. Errors can only be mapped to fatal. 287f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner switch (getDiagnosticMapping((diag::kind)DiagID)) { 288f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner case diag::MAP_DEFAULT: break; 289f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner case diag::MAP_IGNORE: return Diagnostic::Ignored; 290f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner case diag::MAP_WARNING: DiagClass = WARNING; break; 291f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner case diag::MAP_ERROR: DiagClass = ERROR; break; 292f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner case diag::MAP_FATAL: DiagClass = FATAL; break; 2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Map diagnostic classes based on command line argument settings. 2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (DiagClass == EXTENSION) { 2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (ErrorOnExtensions) 2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DiagClass = ERROR; 2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer else if (WarnOnExtensions) 3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer DiagClass = WARNING; 3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer else 3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return Ignored; 3034489fe10fa073eb326e2c8906db170f009050911Daniel Dunbar } else if (DiagClass == EXTWARN) { 3044489fe10fa073eb326e2c8906db170f009050911Daniel Dunbar DiagClass = ErrorOnExtensions ? ERROR : WARNING; 3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3075b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner // If warnings are globally mapped to ignore or error, do it. 3085b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner if (DiagClass == WARNING) { 3095b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner if (IgnoreAllWarnings) 3105b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner return Diagnostic::Ignored; 3115b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner if (WarningsAsErrors) 3125b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner DiagClass = ERROR; 3135b4681c8ef65808ec4d72ab6081efd24d53d4969Chris Lattner } 3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer switch (DiagClass) { 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer default: assert(0 && "Unknown diagnostic class!"); 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case WARNING: return Diagnostic::Warning; 3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer case ERROR: return Diagnostic::Error; 319da0cbc1ad4a553c4de111c1181ec7b42c5ddefceChris Lattner case FATAL: return Diagnostic::Fatal; 3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 3230a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner/// ProcessDiag - This is the method used to report a diagnostic that is 3240a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner/// finally fully formed. 3253cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattnervoid Diagnostic::ProcessDiag() { 3263cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner DiagnosticInfo Info(this); 3273cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner 32815221422eda7bac679e38b07512feda49715ef66Chris Lattner // If a fatal error has already been emitted, silence all subsequent 32915221422eda7bac679e38b07512feda49715ef66Chris Lattner // diagnostics. 33015221422eda7bac679e38b07512feda49715ef66Chris Lattner if (FatalErrorOccurred) 33115221422eda7bac679e38b07512feda49715ef66Chris Lattner return; 33215221422eda7bac679e38b07512feda49715ef66Chris Lattner 3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Figure out the diagnostic level of this message. 334f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner Diagnostic::Level DiagLevel; 335f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner unsigned DiagID = Info.getID(); 336f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 337f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // ShouldEmitInSystemHeader - True if this diagnostic should be produced even 338f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // in a system header. 339f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner bool ShouldEmitInSystemHeader; 340f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 341f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner if (DiagID >= diag::DIAG_UPPER_LIMIT) { 342f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // Handle custom diagnostics, which cannot be mapped. 343f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner DiagLevel = CustomDiagInfo->getLevel(DiagID); 344f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 345f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // Custom diagnostics always are emitted in system headers. 346f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner ShouldEmitInSystemHeader = true; 347f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner } else { 348f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // Get the class of the diagnostic. If this is a NOTE, map it onto whatever 349f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // the diagnostic level was for the previous diagnostic so that it is 350f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // filtered the same as the previous diagnostic. 351f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner unsigned DiagClass = getBuiltinDiagClass(DiagID); 352f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner if (DiagClass == NOTE) { 353f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner DiagLevel = Diagnostic::Note; 354f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner ShouldEmitInSystemHeader = false; // extra consideration is needed 355f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner } else { 356f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // If this is not an error and we are in a system header, we ignore it. 357f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // Check the original Diag ID here, because we also want to ignore 358f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // extensions and warnings in -Werror and -pedantic-errors modes, which 359f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // *map* warnings/extensions to errors. 360f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner ShouldEmitInSystemHeader = DiagClass == ERROR; 361f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 362f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner DiagLevel = getDiagnosticLevel(DiagID, DiagClass); 363f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner } 364f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner } 365f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 366f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner if (DiagLevel != Diagnostic::Note) 367f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner LastDiagLevel = DiagLevel; 3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 369f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // If the client doesn't care about this message, don't issue it. If this is 370f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // a note and the last real diagnostic was ignored, ignore it too. 371f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner if (DiagLevel == Diagnostic::Ignored || 372f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner (DiagLevel == Diagnostic::Note && LastDiagLevel == Diagnostic::Ignored)) 3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return; 3747bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber 375f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // If this diagnostic is in a system header and is not a clang error, suppress 376f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner // it. 377f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner if (SuppressSystemWarnings && !ShouldEmitInSystemHeader && 3780a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner Info.getLocation().isValid() && 379f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner Info.getLocation().getSpellingLoc().isInSystemHeader() && 380336f26be05c30c0c65b8b518d68f04c29b43b3d2Chris Lattner (DiagLevel != Diagnostic::Note || LastDiagLevel == Diagnostic::Ignored)) { 381336f26be05c30c0c65b8b518d68f04c29b43b3d2Chris Lattner LastDiagLevel = Diagnostic::Ignored; 3827097d9167dc6b5d6ab5ebf149b296a43939d4b36Chris Lattner return; 383336f26be05c30c0c65b8b518d68f04c29b43b3d2Chris Lattner } 384f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (DiagLevel >= Diagnostic::Error) { 3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ErrorOccurred = true; 3870a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner ++NumErrors; 38815221422eda7bac679e38b07512feda49715ef66Chris Lattner 38915221422eda7bac679e38b07512feda49715ef66Chris Lattner if (DiagLevel == Diagnostic::Fatal) 39015221422eda7bac679e38b07512feda49715ef66Chris Lattner FatalErrorOccurred = true; 3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 392f5d2328fc849288c3a62e43d065685f516d57091Chris Lattner 3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Finally, report it. 3940a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner Client->HandleDiagnostic(DiagLevel, Info); 395cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek if (Client->IncludeInDiagnosticCounts()) ++NumDiagnostics; 396ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor 397ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor // Invoke any post-diagnostic hooks. 398ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor unsigned LastDiag = CurDiagID; 399ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor CurDiagID = ~0U; 400ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor 401ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor InPostDiagnosticHook = true; 402ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor for (unsigned Hook = 0; Hook < NumPostDiagnosticHooks; ++Hook) 403ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor PostDiagnosticHooks[Hook].Hook(LastDiag, 404ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor PostDiagnosticHooks[Hook].Cookie); 405ee1828a6b5ae1bc4ea300e48f3840ac1ec5be295Douglas Gregor InPostDiagnosticHook = false; 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4087bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber 4095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerDiagnosticClient::~DiagnosticClient() {} 4107bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber 411f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner 412af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// ModifierIs - Return true if the specified modifier matches specified string. 413af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattnertemplate <std::size_t StrLen> 414af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattnerstatic bool ModifierIs(const char *Modifier, unsigned ModifierLen, 415af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char (&Str)[StrLen]) { 416af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1); 417af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner} 418af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 419af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// HandleSelectModifier - Handle the integer 'select' modifier. This is used 420af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// like this: %select{foo|bar|baz}2. This means that the integer argument 421af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'. 422af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'. 423af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// This is very useful for certain classes of variant diagnostics. 424af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattnerstatic void HandleSelectModifier(unsigned ValNo, 425af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char *Argument, unsigned ArgumentLen, 426af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner llvm::SmallVectorImpl<char> &OutStr) { 427af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char *ArgumentEnd = Argument+ArgumentLen; 428af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 429af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // Skip over 'ValNo' |'s. 430af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner while (ValNo) { 431af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char *NextVal = std::find(Argument, ArgumentEnd, '|'); 432af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(NextVal != ArgumentEnd && "Value for integer select modifier was" 433af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner " larger than the number of options in the diagnostic string!"); 434af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner Argument = NextVal+1; // Skip this string. 435af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner --ValNo; 436af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 437af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 438af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // Get the end of the value. This is either the } or the |. 439af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char *EndPtr = std::find(Argument, ArgumentEnd, '|'); 440af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // Add the value to the output string. 441af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner OutStr.append(Argument, EndPtr); 442af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner} 443af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 444af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// HandleIntegerSModifier - Handle the integer 's' modifier. This adds the 445af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// letter 's' to the string if the value is not 1. This is used in cases like 446af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner/// this: "you idiot, you have %4 parameter%s4!". 447af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattnerstatic void HandleIntegerSModifier(unsigned ValNo, 448af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner llvm::SmallVectorImpl<char> &OutStr) { 449af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner if (ValNo != 1) 450af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner OutStr.push_back('s'); 451af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner} 452af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 453af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 454e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// PluralNumber - Parse an unsigned integer and advance Start. 455e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redlstatic unsigned PluralNumber(const char *&Start, const char *End) 456e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl{ 457e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl // Programming 101: Parse a decimal number :-) 458e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned Val = 0; 459e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl while (Start != End && *Start >= '0' && *Start <= '9') { 460e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl Val *= 10; 461e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl Val += *Start - '0'; 462e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 463e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 464e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return Val; 465e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl} 466e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 467e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// TestPluralRange - Test if Val is in the parsed range. Modifies Start. 468e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redlstatic bool TestPluralRange(unsigned Val, const char *&Start, const char *End) 469e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl{ 470e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (*Start != '[') { 471e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned Ref = PluralNumber(Start, End); 472e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return Ref == Val; 473e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 474e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 475e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 476e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned Low = PluralNumber(Start, End); 477e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl assert(*Start == ',' && "Bad plural expression syntax: expected ,"); 478e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 479e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned High = PluralNumber(Start, End); 480e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl assert(*Start == ']' && "Bad plural expression syntax: expected )"); 481e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 482e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return Low <= Val && Val <= High; 483e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl} 484e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 485e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// EvalPluralExpr - Actual expression evaluator for HandlePluralModifier. 486e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redlstatic bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) 487e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl{ 488e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl // Empty condition? 489e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (*Start == ':') 490e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return true; 491e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 492e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl while (1) { 493e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl char C = *Start; 494e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (C == '%') { 495e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl // Modulo expression 496e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 497e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned Arg = PluralNumber(Start, End); 498e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl assert(*Start == '=' && "Bad plural expression syntax: expected ="); 499e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 500e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl unsigned ValMod = ValNo % Arg; 501e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (TestPluralRange(ValMod, Start, End)) 502e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return true; 503e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } else { 504e20653219732b03294130999415fc3aa92d2336aSebastian Redl assert((C == '[' || (C >= '0' && C <= '9')) && 505e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl "Bad plural expression syntax: unexpected character"); 506e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl // Range expression 507e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (TestPluralRange(ValNo, Start, End)) 508e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return true; 509e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 510e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 511e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl // Scan for next or-expr part. 512e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl Start = std::find(Start, End, ','); 513e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if(Start == End) 514e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl break; 515e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++Start; 516e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 517e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return false; 518e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl} 519e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 520e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// HandlePluralModifier - Handle the integer 'plural' modifier. This is used 521e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// for complex plural forms, or in languages where all plurals are complex. 522e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// The syntax is: %plural{cond1:form1|cond2:form2|:form3}, where condn are 523e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// conditions that are tested in order, the form corresponding to the first 524e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// that applies being emitted. The empty condition is always true, making the 525e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// last form a default case. 526e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Conditions are simple boolean expressions, where n is the number argument. 527e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Here are the rules. 528e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// condition := expression | empty 529e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// empty := -> always true 530e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// expression := numeric [',' expression] -> logical or 531e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// numeric := range -> true if n in range 532e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// | '%' number '=' range -> true if n % number in range 533e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// range := number 534e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// | '[' number ',' number ']' -> ranges are inclusive both ends 535e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// 536e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Here are some examples from the GNU gettext manual written in this form: 537e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// English: 538e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {1:form0|:form1} 539e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Latvian: 540e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {0:form2|%100=11,%10=0,%10=[2,9]:form1|:form0} 541e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Gaeilge: 542e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {1:form0|2:form1|:form2} 543e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Romanian: 544e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {1:form0|0,%100=[1,19]:form1|:form2} 545e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Lithuanian: 546e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {%10=0,%100=[10,19]:form2|%10=1:form0|:form1} 547e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Russian (requires repeated form): 548e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {%100=[11,14]:form2|%10=1:form0|%10=[2,4]:form1|:form2} 549e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Slovak 550e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {1:form0|[2,4]:form1|:form2} 551e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// Polish (requires repeated form): 552e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2} 553e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redlstatic void HandlePluralModifier(unsigned ValNo, 554e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl const char *Argument, unsigned ArgumentLen, 555e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl llvm::SmallVectorImpl<char> &OutStr) 556e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl{ 557e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl const char *ArgumentEnd = Argument + ArgumentLen; 558e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl while (1) { 559e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl assert(Argument < ArgumentEnd && "Plural expression didn't match."); 560e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl const char *ExprEnd = Argument; 561e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl while (*ExprEnd != ':') { 562e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl assert(ExprEnd != ArgumentEnd && "Plural missing expression end"); 563e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ++ExprEnd; 564e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 565e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl if (EvalPluralExpr(ValNo, Argument, ExprEnd)) { 566e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl Argument = ExprEnd + 1; 567e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl ExprEnd = std::find(Argument, ArgumentEnd, '|'); 568e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl OutStr.append(Argument, ExprEnd); 569e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl return; 570e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 571e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl Argument = std::find(Argument, ArgumentEnd - 1, '|') + 1; 572e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } 573e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl} 574e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 575e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl 576f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner/// FormatDiagnostic - Format this diagnostic into a string, substituting the 577f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner/// formal arguments into the %0 slots. The result is appended onto the Str 578f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner/// array. 579f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattnervoid DiagnosticInfo:: 580f4c839657742b823cea1a95b18422f1ba74d3dddChris LattnerFormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const { 581f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner const char *DiagStr = getDiags()->getDescription(getID()); 582f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner const char *DiagEnd = DiagStr+strlen(DiagStr); 5837bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber 584f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner while (DiagStr != DiagEnd) { 585f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner if (DiagStr[0] != '%') { 586f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner // Append non-%0 substrings to Str if we have one. 587f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner const char *StrEnd = std::find(DiagStr, DiagEnd, '%'); 588f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner OutStr.append(DiagStr, StrEnd); 589f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner DiagStr = StrEnd; 590af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner continue; 591f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner } else if (DiagStr[1] == '%') { 592f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner OutStr.push_back('%'); // %% -> %. 593f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner DiagStr += 2; 594af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner continue; 595af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 596af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 597af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // Skip the %. 598af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ++DiagStr; 599af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 600af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // This must be a placeholder for a diagnostic argument. The format for a 601af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // placeholder is one of "%0", "%modifier0", or "%modifier{arguments}0". 602af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // The digit is a number from 0-9 indicating which argument this comes from. 603af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // The modifier is a string of digits from the set [-a-z]+, arguments is a 604af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // brace enclosed string. 605af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner const char *Modifier = 0, *Argument = 0; 606af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner unsigned ModifierLen = 0, ArgumentLen = 0; 607af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 608af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // Check to see if we have a modifier. If so eat it. 609af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner if (!isdigit(DiagStr[0])) { 610af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner Modifier = DiagStr; 611af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner while (DiagStr[0] == '-' || 612af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')) 613af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ++DiagStr; 614af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ModifierLen = DiagStr-Modifier; 615f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner 616af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner // If we have an argument, get it next. 617af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner if (DiagStr[0] == '{') { 618af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ++DiagStr; // Skip {. 619af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner Argument = DiagStr; 620af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 621af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner for (; DiagStr[0] != '}'; ++DiagStr) 622af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(DiagStr[0] && "Mismatched {}'s in diagnostic string!"); 623af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ArgumentLen = DiagStr-Argument; 624af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner ++DiagStr; // Skip }. 625f4c839657742b823cea1a95b18422f1ba74d3dddChris Lattner } 626af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 627af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 628af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic"); 62922caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner unsigned ArgNo = *DiagStr++ - '0'; 630af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 63122caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner switch (getArgKind(ArgNo)) { 63208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner // ---- STRINGS ---- 6333cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner case Diagnostic::ak_std_string: { 63422caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner const std::string &S = getArgStdStr(ArgNo); 635af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(ModifierLen == 0 && "No modifiers for strings yet"); 636af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner OutStr.append(S.begin(), S.end()); 637af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner break; 638af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 6393cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner case Diagnostic::ak_c_string: { 64022caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner const char *S = getArgCStr(ArgNo); 641af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(ModifierLen == 0 && "No modifiers for strings yet"); 642af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner OutStr.append(S, S + strlen(S)); 643af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner break; 644af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 64508631c5fa053867146b5ee8be658c229f6bf127cChris Lattner // ---- INTEGERS ---- 6463cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner case Diagnostic::ak_sint: { 64722caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner int Val = getArgSInt(ArgNo); 648af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 649af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner if (ModifierIs(Modifier, ModifierLen, "select")) { 650af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner HandleSelectModifier((unsigned)Val, Argument, ArgumentLen, OutStr); 651af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } else if (ModifierIs(Modifier, ModifierLen, "s")) { 652af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner HandleIntegerSModifier(Val, OutStr); 653e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 654e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl HandlePluralModifier((unsigned)Val, Argument, ArgumentLen, OutStr); 655af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } else { 656af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(ModifierLen == 0 && "Unknown integer modifier"); 65730bc96544346bea42921cf6837e66cef80d664b4Chris Lattner // FIXME: Optimize 658af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner std::string S = llvm::itostr(Val); 65930bc96544346bea42921cf6837e66cef80d664b4Chris Lattner OutStr.append(S.begin(), S.end()); 66030bc96544346bea42921cf6837e66cef80d664b4Chris Lattner } 661af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner break; 662af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 6633cbfe2c4159e0a219ae660d50625c013aa4afbd0Chris Lattner case Diagnostic::ak_uint: { 66422caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner unsigned Val = getArgUInt(ArgNo); 665af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 666af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner if (ModifierIs(Modifier, ModifierLen, "select")) { 667af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner HandleSelectModifier(Val, Argument, ArgumentLen, OutStr); 668af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } else if (ModifierIs(Modifier, ModifierLen, "s")) { 669af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner HandleIntegerSModifier(Val, OutStr); 670e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl } else if (ModifierIs(Modifier, ModifierLen, "plural")) { 671e4c452c4c7b9124fe94a96f559ff077d59cdf996Sebastian Redl HandlePluralModifier((unsigned)Val, Argument, ArgumentLen, OutStr); 672af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } else { 673af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner assert(ModifierLen == 0 && "Unknown integer modifier"); 674af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner 67530bc96544346bea42921cf6837e66cef80d664b4Chris Lattner // FIXME: Optimize 676af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner std::string S = llvm::utostr_32(Val); 67730bc96544346bea42921cf6837e66cef80d664b4Chris Lattner OutStr.append(S.begin(), S.end()); 67830bc96544346bea42921cf6837e66cef80d664b4Chris Lattner } 67922caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner break; 680af7ae4e8160fc5c23e471f2125b3fe5911e3532aChris Lattner } 68108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner // ---- NAMES and TYPES ---- 68208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner case Diagnostic::ak_identifierinfo: { 68308631c5fa053867146b5ee8be658c229f6bf127cChris Lattner const IdentifierInfo *II = getArgIdentifier(ArgNo); 68408631c5fa053867146b5ee8be658c229f6bf127cChris Lattner assert(ModifierLen == 0 && "No modifiers for strings yet"); 685d0344a4a6182ad704881cbbaa21cca14913d2296Chris Lattner OutStr.push_back('\''); 68608631c5fa053867146b5ee8be658c229f6bf127cChris Lattner OutStr.append(II->getName(), II->getName() + II->getLength()); 68708631c5fa053867146b5ee8be658c229f6bf127cChris Lattner OutStr.push_back('\''); 68808631c5fa053867146b5ee8be658c229f6bf127cChris Lattner break; 68908631c5fa053867146b5ee8be658c229f6bf127cChris Lattner } 69022caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner case Diagnostic::ak_qualtype: 691011bb4edf731d529da1cbf71c7c2696aaf5a054fChris Lattner case Diagnostic::ak_declarationname: 69247b9a1ca55e61e37f5a368740e29de190345acc6Douglas Gregor case Diagnostic::ak_nameddecl: 6933fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner getDiags()->ConvertArgToString(getArgKind(ArgNo), getRawArg(ArgNo), 6943fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner Modifier, ModifierLen, 6953fdf4b071dc79fae778fb5f376485480756c76a3Chris Lattner Argument, ArgumentLen, OutStr); 69622caddc91d2f6186739c6b20ec58ed38cd68e595Chris Lattner break; 6977bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber } 6987bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber } 6997bfaaaecb3113f955db31e8d8a51acffd1bc0c27Nico Weber} 700cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek 701cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek/// IncludeInDiagnosticCounts - This method (whose default implementation 702cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek/// returns true) indicates whether the diagnostics handled by this 703cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek/// DiagnosticClient should be included in the number of diagnostics 704cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek/// reported by Diagnostic. 705cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenekbool DiagnosticClient::IncludeInDiagnosticCounts() const { return true; } 706