Diagnostic.h revision 08d6e032a2a0a8656d12b3b7b93942987bb12eb7
1710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===// 26091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer// 36091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer// The LLVM Compiler Infrastructure 46091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 76091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer// 86091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer//===----------------------------------------------------------------------===// 927107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling// 1027107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling// This file defines the Diagnostic-related interfaces. 1127107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling// 1227107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling//===----------------------------------------------------------------------===// 1327107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling 146091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer#ifndef LLVM_CLANG_DIAGNOSTIC_H 156091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer#define LLVM_CLANG_DIAGNOSTIC_H 16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak 17674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#include "clang/Basic/DiagnosticIDs.h" 186091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer#include "clang/Basic/SourceLocation.h" 19d509d0b532ec2358b3f341d4a4cd1411cb8b5db2Chris Lattner#include "llvm/ADT/ArrayRef.h" 200319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling#include "llvm/ADT/DenseMap.h" 213467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling#include "llvm/ADT/IntrusiveRefCntPtr.h" 2222bd64173981bf1251c4b3bfc684207340534ba3Bill Wendling#include "llvm/ADT/OwningPtr.h" 2322bd64173981bf1251c4b3bfc684207340534ba3Bill Wendling#include "llvm/Support/type_traits.h" 2458d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 256091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer#include <vector> 266091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer#include <list> 27d426a642a23a234547cbc7061f5bfec157673249Bill Wendling 28702cc91aa1bd41540e8674921ae7ac89a4ff061fBill Wendlingnamespace clang { 29f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling class DiagnosticConsumer; 30a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling class DiagnosticBuilder; 312c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling class IdentifierInfo; 32ad9a9e15595bc9d5ba1ed752caf8572957f77a3dDuncan Sands class DeclContext; 33ad9a9e15595bc9d5ba1ed752caf8572957f77a3dDuncan Sands class LangOptions; 341d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling class Preprocessor; 3527107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling class DiagnosticErrorTrap; 3627107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling class StoredDiagnostic; 371d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling 381d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling/// \brief Annotates a diagnostic with some code that should be 391d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling/// inserted, removed, or replaced to fix the problem. 40034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling/// 416765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling/// This kind of hint should be used when we are certain that the 421d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling/// introduction, removal, or modification of a particular (small!) 431d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling/// amount of code will correct a compilation error. The compiler 44f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling/// should also provide full recovery from such errors, such that 451d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling/// suppressing the diagnostic output can still result in successful 4611d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling/// compilation. 4711d00420e42ba88c3b48cab997965a7be79315e2Bill Wendlingclass FixItHint { 48f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendlingpublic: 4911d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// \brief Code that should be replaced to correct the error. Empty for an 5011d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// insertion hint. 5111d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling CharSourceRange RemoveRange; 52f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling 5311d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// \brief The actual code to insert at the insertion location, as a 5411d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// string. 5511d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling std::string CodeToInsert; 5611d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling 5711d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// \brief Empty code modification hint, indicating that no code 5811d00420e42ba88c3b48cab997965a7be79315e2Bill Wendling /// modification is known. 59629fb82419d9bfff6ae475363bcce66192dfcc8eBill Wendling FixItHint() : RemoveRange() { } 605a0eeb5a9d727940b1dbe8dff6e9aa292ada0f6aBill Wendling 61480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling bool isNull() const { 62480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling return !RemoveRange.isValid(); 63480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling } 646765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling 65f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling /// \brief Create a code modification hint that inserts the given 66480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /// code string at a specific location. 67480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling static FixItHint CreateInsertion(SourceLocation InsertionLoc, 68480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling StringRef Code) { 69480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling FixItHint Hint; 709a419f656e278b96e9dfe739cd63c7bff9a4e1fdQuentin Colombet Hint.RemoveRange = 71480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false); 72480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling Hint.CodeToInsert = Code; 73480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling return Hint; 74480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling } 7567ae13575900e8efd056672987249fd0adbf5e73James Molloy 76480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /// \brief Create a code modification hint that removes the given 77480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /// source range. 78480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling static FixItHint CreateRemoval(CharSourceRange RemoveRange) { 793a106e60366a51b4594ec303ff8dbbc58913227fBill Wendling FixItHint Hint; 80480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling Hint.RemoveRange = RemoveRange; 81480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling return Hint; 82480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling } 83480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling static FixItHint CreateRemoval(SourceRange RemoveRange) { 84480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling return CreateRemoval(CharSourceRange::getTokenRange(RemoveRange)); 85480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling } 86480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling 87480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /// \brief Create a code modification hint that replaces the given 88480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling /// source range with the given code string. 896765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling static FixItHint CreateReplacement(CharSourceRange RemoveRange, 906765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling StringRef Code) { 91f6670729aabc1fab85238d2b306a1c1767a807bbBill Wendling FixItHint Hint; 92480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling Hint.RemoveRange = RemoveRange; 93480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling Hint.CodeToInsert = Code; 94114baee1fa017daefad2339c77b45b9ca3d79a41Bill Wendling return Hint; 95480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling } 96480b1b28ea6fc1bb5c78d99472df624cfd3fce47Bill Wendling 970319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling static FixItHint CreateReplacement(SourceRange RemoveRange, 980319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling StringRef Code) { 993a4779a9211281a1d0c27c97037342329035a185NAKAMURA Takumi return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code); 1003a4779a9211281a1d0c27c97037342329035a185NAKAMURA Takumi } 1016f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth}; 1026f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth 1036765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling/// DiagnosticsEngine - This concrete class is used by the front-end to report 1046765834754cbb3cb0f15b4b15e98c5e73fa50066Bill Wendling/// problems and issues. It massages the diagnostics (e.g. handling things like 10527107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling/// "report warnings as errors" and passes them off to the DiagnosticConsumer 10627107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling/// for reporting to the user. DiagnosticsEngine is tied to one translation unit 107d426a642a23a234547cbc7061f5bfec157673249Bill Wendling/// and one SourceManager. 10827107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendlingclass DiagnosticsEngine : public llvm::RefCountedBase<DiagnosticsEngine> { 1092c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendlingpublic: 110c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling /// Level - The level of the diagnostic, after it has been through mapping. 11116f95669ec814d98ce28ad514df603c01d662ee8Bill Wendling enum Level { 112034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Ignored = DiagnosticIDs::Ignored, 1132c79ecbd704c656178ffa43d5a58ebe3ca188b40Bill Wendling Note = DiagnosticIDs::Note, 114c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling Warning = DiagnosticIDs::Warning, 115c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling Error = DiagnosticIDs::Error, 116c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling Fatal = DiagnosticIDs::Fatal 117c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling }; 118c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling 1191d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling /// ExtensionHandling - How do we handle otherwise-unmapped extension? This 120629fb82419d9bfff6ae475363bcce66192dfcc8eBill Wendling /// is controlled by -pedantic and -pedantic-errors. 1212e879bcd52583335c753c005d203bf2ffe8b67b5Bill Wendling enum ExtensionHandling { 1221d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling Ext_Ignore, Ext_Warn, Ext_Error 12305cc40d20c0f3b2f1bd5cb86ceb9f32d07cae110Bill Wendling }; 1242e879bcd52583335c753c005d203bf2ffe8b67b5Bill Wendling 1251d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling enum ArgumentKind { 126ef99fe8efaa6cb74c66e570a6ef467debca92911Bill Wendling ak_std_string, // std::string 127e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling ak_c_string, // const char * 128ef99fe8efaa6cb74c66e570a6ef467debca92911Bill Wendling ak_sint, // int 1291d3dcfe4246b4d45fa78a8dfd0a11c7fff842c15Bill Wendling ak_uint, // unsigned 130943c29135e03e55f9a5dab393786171a4a536482Bill Wendling ak_identifierinfo, // IdentifierInfo 131e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling ak_qualtype, // QualType 13230b483c94001927b3593ed200e823104bab51660Bill Wendling ak_declarationname, // DeclarationName 13360507d53e7e8e6b0c537675f68204a93c3033de7Bill Wendling ak_nameddecl, // NamedDecl * 13492e287f5bde8d34af9c3f2979afb6cd05bfb452cBill Wendling ak_nestednamespec, // NestedNameSpecifier * 13592e287f5bde8d34af9c3f2979afb6cd05bfb452cBill Wendling ak_declcontext // DeclContext * 13692e287f5bde8d34af9c3f2979afb6cd05bfb452cBill Wendling }; 137c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling 1383467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling /// Specifies which overload candidates to display when overload resolution 1393467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling /// fails. 140c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling enum OverloadsShown { 141c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling Ovl_All, ///< Show all overloads. 142c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling Ovl_Best ///< Show just the "best" overload candidates. 143c08a5ef6581f2c7550e92d31f63cd65ec29c39e0Bill Wendling }; 144bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling 145bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling /// ArgumentValue - This typedef represents on argument value, which is a 146bb08593980b16fbd9758da6ca4fa9c7964f2f926Bill Wendling /// union discriminated by ArgumentKind, with a value. 1473467e30edf63b6d8a8d446186674ba9e4b7885a9Bill Wendling typedef std::pair<ArgumentKind, intptr_t> ArgumentValue; 1481db9b6957c2565a2322206bd5907530895f1c7acBill Wendling 149827cde1c8319e51463007078a7ce3660ebc93036Duncan Sandsprivate: 150827cde1c8319e51463007078a7ce3660ebc93036Duncan Sands unsigned char AllExtensionsSilenced; // Used by __extension__ 151e66f3d3ba0ea9f82f65a29c47fc37e997cbf0aceBill Wendling bool IgnoreAllWarnings; // Ignore all warnings: -w 15227107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling bool WarningsAsErrors; // Treat warnings like errors. 1530319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling bool EnableAllWarnings; // Enable all warnings. 1540319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling bool ErrorsAsFatal; // Treat errors like fatal errors. 1550319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling bool SuppressSystemWarnings; // Suppress warnings in system headers. 1560319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling bool SuppressAllDiagnostics; // Suppress all diagnostics. 1576f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth OverloadsShown ShowOverloads; // Which overload candidates to show. 1580319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit. 1590319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack, 1606f78fbbc630d2b86fb752574f5ad74473f57dfb1Chandler Carruth // 0 -> no limit. 1610319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation 1620319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling // backtrace stack, 0 -> no limit. 1630319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors? 1640319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags; 1650319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling DiagnosticConsumer *Client; 1660319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling bool OwnsDiagClient; 1670319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling SourceManager *SourceMgr; 1680319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling 1690319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling /// \brief Mapping information for diagnostics. Mapping info is 1700319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling /// packed into four bits per diagnostic. The low three bits are the mapping 1710319888773b36dd61d7d2283cb9a26cac1e5abe8Bill Wendling /// (an instance of diag::Mapping), or zero if unset. The high bit is set 17299faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling /// when the mapping was established as a user mapping. If the high bit is 17358d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// clear, then the low bits are set to the default value, and should be 17458d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// mapped with -pedantic, -Werror, etc. 175a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// 17618e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// A new DiagState is created and kept around when diagnostic pragmas modify 17708c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling /// the state so that we know what is the diagnostic state at any given 17808c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling /// source location. 17908c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling class DiagState { 18008c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap; 18108c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling 18208c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling public: 18308c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator 18408c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling iterator; 18508c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator 18608c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling const_iterator; 18708c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling 18808c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) { 18908c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling DiagMap[Diag] = Info; 19008c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling } 19108c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling 19208c11d302325b3715d77f4208d183c9b2a253b14Bill Wendling DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag); 193710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 19418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling const_iterator begin() const { return DiagMap.begin(); } 19527107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling const_iterator end() const { return DiagMap.end(); } 19627107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling }; 19718e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 19899faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling /// \brief Keeps and automatically disposes all DiagStates that we create. 19907aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling std::list<DiagState> DiagStates; 20007aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling 20107aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling /// \brief Represents a point in source where the diagnostic state was 20207aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling /// modified because of a pragma. 'Loc' can be null if the point represents 20307aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling /// the diagnostic state modifications done through the command-line. 20407aae2e7d58fe23e370e0cbb9e1a3def99434c36Bill Wendling struct DiagStatePoint { 205a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling DiagState *State; 2067d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling FullSourceLoc Loc; 207a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling DiagStatePoint(DiagState *State, FullSourceLoc Loc) 20818e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling : State(State), Loc(Loc) { } 2090976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling 210ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling bool operator<(const DiagStatePoint &RHS) const { 2110976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling // If Loc is invalid it means it came from <command-line>, in which case 21218e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling // we regard it as coming before any valid source location. 2130976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling if (RHS.Loc.isInvalid()) 214034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling return false; 2150976e00fd1cbf4128daeb72efd8957d00383fda9Bill Wendling if (Loc.isInvalid()) 216defaca00b8087d452df2b783250a48a32658a910Bill Wendling return true; 217defaca00b8087d452df2b783250a48a32658a910Bill Wendling return Loc.isBeforeInTranslationUnitThan(RHS.Loc); 218defaca00b8087d452df2b783250a48a32658a910Bill Wendling } 219defaca00b8087d452df2b783250a48a32658a910Bill Wendling }; 220defaca00b8087d452df2b783250a48a32658a910Bill Wendling 2218246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// \brief A vector of all DiagStatePoints representing changes in diagnostic 2228246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// state due to diagnostic pragmas. The vector is always sorted according to 2238246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// the SourceLocation of the DiagStatePoint. 2248246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling typedef std::vector<DiagStatePoint> DiagStatePointsTy; 2258246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling mutable DiagStatePointsTy DiagStatePoints; 2267d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling 2277d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling /// \brief Keeps the DiagState that was active during each diagnostic 'push' 2287d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling /// so we can get back at it when we 'pop'. 2297d38c109aab8654e63e9071c7d948661f6b58433Bill Wendling std::vector<DiagState *> DiagStateOnPushStack; 230ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling 23158d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner DiagState *GetCurDiagState() const { 232ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling assert(!DiagStatePoints.empty()); 233ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling return DiagStatePoints.back().State; 23499faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling } 235710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 23658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner void PushDiagStatePoint(DiagState *State, SourceLocation L) { 2370598866c052147c31b808391f58434ce3dbfb838Devang Patel FullSourceLoc Loc(L, *SourceMgr); 23858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner // Make sure that DiagStatePoints is always sorted according to Loc. 239710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov assert((Loc.isValid() || DiagStatePoints.empty()) && 24018e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling "Adding invalid loc point after another point"); 2418e47daf2858e980210f3e1f007036b24da342c29Bill Wendling assert((Loc.isInvalid() || DiagStatePoints.empty() || 24228d65722d6f283b327b5815914382077fe9c0ab4Bill Wendling DiagStatePoints.back().Loc.isInvalid() || 24332a57958226e369f964a034da2ce7083a1a34297Bill Wendling DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) && 2441bbd644301ed4d8a7efd4ceb15f71c56fa914f28Bill Wendling "Previous point loc comes after or is the same as new one"); 24558d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner DiagStatePoints.push_back(DiagStatePoint(State, 246defaca00b8087d452df2b783250a48a32658a910Bill Wendling FullSourceLoc(Loc, *SourceMgr))); 247defaca00b8087d452df2b783250a48a32658a910Bill Wendling } 248defaca00b8087d452df2b783250a48a32658a910Bill Wendling 249defaca00b8087d452df2b783250a48a32658a910Bill Wendling /// \brief Finds the DiagStatePoint that contains the diagnostic state of 250710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov /// the given source location. 251e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const; 252e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling 253e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling /// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or 254e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling /// fatal error is emitted, and is sticky. 255e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling bool ErrorOccurred; 2561b0c54f1c5dd61e56cb7cbc435fcb3319cff628fBill Wendling bool FatalErrorOccurred; 2571b0c54f1c5dd61e56cb7cbc435fcb3319cff628fBill Wendling 258e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling /// \brief Indicates that an unrecoverable error has occurred. 259e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling bool UnrecoverableErrorOccurred; 260e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling 2611b0c54f1c5dd61e56cb7cbc435fcb3319cff628fBill Wendling /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred 262956f13440a4aa0297606a4412f4aa091d931592aBill Wendling /// during a parsing section, e.g. during parsing a function. 263956f13440a4aa0297606a4412f4aa091d931592aBill Wendling unsigned TrapNumErrorsOccurred; 264e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling unsigned TrapNumUnrecoverableErrorsOccurred; 265e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling 266e4e85f17564c28cd571dda30146c3f310521acf0Bill Wendling /// LastDiagLevel - This is the level of the last diagnostic emitted. This is 267956f13440a4aa0297606a4412f4aa091d931592aBill Wendling /// used to emit continuation diagnostics with the same level as the 26818e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// diagnostic that they follow. 2698246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling DiagnosticIDs::Level LastDiagLevel; 27018e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 2718246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling unsigned NumWarnings; // Number of warnings reported 2728246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling unsigned NumErrors; // Number of errors reported 2738246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling unsigned NumErrorsSuppressed; // Number of errors suppressed 2748246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling 2758246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// ArgToStringFn - A function pointer that converts an opaque diagnostic 2768246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// argument to a strings. This takes the modifiers and argument that was 2778246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// present in the diagnostic. 2788246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling /// 279710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous 28058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// arguments formatted for this diagnostic. Implementations of this function 2810598866c052147c31b808391f58434ce3dbfb838Devang Patel /// can use this information to avoid redundancy across arguments. 28258d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// 28318e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// This is a hack to avoid a layering violation between libbasic and libsema. 28418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling typedef void (*ArgToStringFnTy)( 28528d65722d6f283b327b5815914382077fe9c0ab4Bill Wendling ArgumentKind Kind, intptr_t Val, 28619c874638d9478a5d5028854817a5ee72293bb2bDevang Patel const char *Modifier, unsigned ModifierLen, 28718e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling const char *Argument, unsigned ArgumentLen, 2883fc4b96b503fa202411317684a2ba02e41e43072Bill Wendling const ArgumentValue *PrevArgs, 28919c874638d9478a5d5028854817a5ee72293bb2bDevang Patel unsigned NumPrevArgs, 29018e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling SmallVectorImpl<char> &Output, 291c5f1bc88a2eb7ad9ff924ca90cf88494e5f947b9Bill Wendling void *Cookie, 292710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov SmallVectorImpl<intptr_t> &QualTypeVals); 29318e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling void *ArgToStringCookie; 294956f13440a4aa0297606a4412f4aa091d931592aBill Wendling ArgToStringFnTy ArgToStringFn; 295710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov 296831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling /// \brief ID of the "delayed" diagnostic, which is a (typically 297831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling /// fatal) diagnostic that had to be delayed because it was found 298831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling /// while emitting another diagnostic. 299831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling unsigned DelayedDiagID; 300831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling 301831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling /// \brief First string argument for the delayed diagnostic. 3028e47daf2858e980210f3e1f007036b24da342c29Bill Wendling std::string DelayedDiagArg1; 3038e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 3048e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \brief Second string argument for the delayed diagnostic. 3058e47daf2858e980210f3e1f007036b24da342c29Bill Wendling std::string DelayedDiagArg2; 306831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling 307831737d329a727f53a1fb0572f7b7a8127208881Bill Wendlingpublic: 308831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling explicit DiagnosticsEngine( 309831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags, 310831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling DiagnosticConsumer *client = 0, 311831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling bool ShouldOwnClient = true); 3121db9b6957c2565a2322206bd5907530895f1c7acBill Wendling ~DiagnosticsEngine(); 313831737d329a727f53a1fb0572f7b7a8127208881Bill Wendling 31418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const { 31518e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling return Diags; 316629fb82419d9bfff6ae475363bcce66192dfcc8eBill Wendling } 31758d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 318041221c0972ff575b07f76808c504833d629ae1fChris Lattner DiagnosticConsumer *getClient() { return Client; } 31918e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling const DiagnosticConsumer *getClient() const { return Client; } 320ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling 32118e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// \brief Determine whether this \c DiagnosticsEngine object own its client. 32218e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling bool ownsClient() const { return OwnsDiagClient; } 323ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling 32418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// \brief Return the current diagnostic client along with ownership of that 325710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov /// client. 32658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner DiagnosticConsumer *takeClient() { 3270598866c052147c31b808391f58434ce3dbfb838Devang Patel OwnsDiagClient = false; 32858d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner return Client; 329710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov } 33018e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 33158d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner bool hasSourceManager() const { return SourceMgr != 0; } 332ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling SourceManager &getSourceManager() const { 33358d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner assert(SourceMgr && "SourceManager not set!"); 334710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov return *SourceMgr; 335034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling } 336034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; } 337034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling 338710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov //===--------------------------------------------------------------------===// 33918e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling // DiagnosticsEngine characterization methods, used by a client to customize 34058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner // how diagnostics are emitted. 341ec2589863b32da169240c4fa120ef1e3798615d4Bill Wendling // 34258d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner 343710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov /// pushMappings - Copies the current DiagMappings and pushes the new copy 34418e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling /// onto the top of the stack. 34518e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling void pushMappings(SourceLocation Loc); 34618e7211068c9d2c6204512f9c468ee179818a4b6Bill Wendling 34758d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// popMappings - Pops the current DiagMappings off the top of the stack 348710632d07b13609444626367bebd34c0af3acb6aMikhail Glushenkov /// causing the new top of the stack to be the active mappings. Returns 349e1f95db4803a48a30fc2a1d5868281a87a36fb85Bill Wendling /// true if the pop happens, false if there is only one DiagMapping on the 350e1f95db4803a48a30fc2a1d5868281a87a36fb85Bill Wendling /// stack. 351e1f95db4803a48a30fc2a1d5868281a87a36fb85Bill Wendling bool popMappings(SourceLocation Loc); 3528e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 3538e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \brief Set the diagnostic client associated with this diagnostic object. 3548e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// 355f3d1500ab2c7364d3d0fb73a7e1b8c6339ab48b1Bill Wendling /// \param ShouldOwnClient true if the diagnostic object should take 35658d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner /// ownership of \c client. 3574f859aa532dbf061736f9c23e0d0882b5cdfe566Reid Spencer void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true); 358a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 359a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setErrorLimit - Specify a limit for the number of errors we should 360a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// emit before giving up. Zero disables the limit. 361a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; } 362a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 363a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Specify the maximum number of template instantiation 364a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// notes to emit along with a given diagnostic. 365a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setTemplateBacktraceLimit(unsigned Limit) { 366a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling TemplateBacktraceLimit = Limit; 367a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 368a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 369a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Retrieve the maximum number of template instantiation 370a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// notes to emit along with a given diagnostic. 371a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned getTemplateBacktraceLimit() const { 372a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling return TemplateBacktraceLimit; 373a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 374a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 375a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Specify the maximum number of constexpr evaluation 376a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// notes to emit along with a given diagnostic. 377a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setConstexprBacktraceLimit(unsigned Limit) { 378a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling ConstexprBacktraceLimit = Limit; 379a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 380a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 381a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Retrieve the maximum number of constexpr evaluation 382a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// notes to emit along with a given diagnostic. 383a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling unsigned getConstexprBacktraceLimit() const { 384a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling return ConstexprBacktraceLimit; 385a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 386a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 387a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setIgnoreAllWarnings - When set to true, any unmapped warnings are 388a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// ignored. If this and WarningsAsErrors are both set, then this one wins. 389a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } 390a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } 391a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 392a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setEnableAllWarnings - When set to true, any unmapped ignored warnings 393a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// are no longer ignored. If this and IgnoreAllWarnings are both set, 394a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// then that one wins. 395a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; } 396a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getEnableAllWarnngs() const { return EnableAllWarnings; } 397a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 398a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setWarningsAsErrors - When set to true, any warnings reported are issued 399a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// as errors. 400a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } 401a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getWarningsAsErrors() const { return WarningsAsErrors; } 402a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 403a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setErrorsAsFatal - When set to true, any error reported is made a 404a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// fatal error. 405a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; } 406a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getErrorsAsFatal() const { return ErrorsAsFatal; } 407a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 408a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setSuppressSystemWarnings - When set to true mask warnings that 409a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// come from system headers. 410a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; } 411a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; } 412a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 413a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Suppress all diagnostics, to silence the front end when we 414a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// know that we don't want any more diagnostics to be passed along to the 415a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// client 416a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setSuppressAllDiagnostics(bool Val = true) { 417a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling SuppressAllDiagnostics = Val; 418a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 419a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; } 420a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 421a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Specify which overload candidates to show when overload resolution 422a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// fails. By default, we show all candidates. 423a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setShowOverloads(OverloadsShown Val) { 424a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling ShowOverloads = Val; 425a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 426a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling OverloadsShown getShowOverloads() const { return ShowOverloads; } 427a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 428a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief Pretend that the last diagnostic issued was ignored. This can 429a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// be used by clients who suppress diagnostics themselves. 430a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setLastDiagnosticIgnored() { 431a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling LastDiagLevel = DiagnosticIDs::Ignored; 432a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 433a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 434a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped 435a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// extension diagnostics are mapped onto ignore/warning/error. This 436a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// corresponds to the GCC -pedantic and -pedantic-errors option. 437a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setExtensionHandlingBehavior(ExtensionHandling H) { 438a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling ExtBehavior = H; 439a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling } 440a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; } 441a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 442a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// AllExtensionsSilenced - This is a counter bumped when an __extension__ 443a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// block is encountered. When non-zero, all extension diagnostics are 444114baee1fa017daefad2339c77b45b9ca3d79a41Bill Wendling /// entirely silenced, no matter how they are mapped. 445a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; } 446a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; } 447a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; } 448a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 449a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \brief This allows the client to specify that certain 450a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// warnings are ignored. Notes can never be mapped, errors can only be 451a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily. 452a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// 453a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// \param Loc The source location that this change of diagnostic state should 454a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// take affect. It can be null if we are setting the latest state. 455a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map, 456a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling SourceLocation Loc); 457a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling 4581db9b6957c2565a2322206bd5907530895f1c7acBill Wendling /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. 459a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// "unknown-pragmas" to have the specified mapping. This returns true and 460a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// ignores the request if "Group" was unknown, false otherwise. 461a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// 462a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// 'Loc' is the source location that this change of diagnostic state should 463a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling /// take affect. It can be null if we are setting the state from command-line. 464a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map, 465a90a99a82b9c5c39fc6dbee9c266dcd7b107fe2fBill Wendling SourceLocation Loc = SourceLocation()); 4668e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 4678e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \brief Set the warning-as-error flag for the given diagnostic group. This 4688e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// function always only operates on the current diagnostic state. 4698e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// 4708e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \returns True if the given group is unknown, false otherwise. 4718e47daf2858e980210f3e1f007036b24da342c29Bill Wendling bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled); 4728e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 4738e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \brief Set the error-as-fatal flag for the given diagnostic group. This 4748e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// function always only operates on the current diagnostic state. 4758e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// 4768e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \returns True if the given group is unknown, false otherwise. 4778e47daf2858e980210f3e1f007036b24da342c29Bill Wendling bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled); 4788e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 4798e47daf2858e980210f3e1f007036b24da342c29Bill Wendling bool hasErrorOccurred() const { return ErrorOccurred; } 4808e47daf2858e980210f3e1f007036b24da342c29Bill Wendling bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } 4818e47daf2858e980210f3e1f007036b24da342c29Bill Wendling 4828e47daf2858e980210f3e1f007036b24da342c29Bill Wendling /// \brief Determine whether any kind of unrecoverable error has occurred. 4838e47daf2858e980210f3e1f007036b24da342c29Bill Wendling bool hasUnrecoverableErrorOccurred() const { 48427107f6ab4627fa38bcacad6757ed6d52910f880Bill Wendling return FatalErrorOccurred || UnrecoverableErrorOccurred; 4856091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer } 4866091ebd172a16a10f1ea66061a5fa7cbf5139e56Reid Spencer 487 unsigned getNumWarnings() const { return NumWarnings; } 488 489 void setNumWarnings(unsigned NumWarnings) { 490 this->NumWarnings = NumWarnings; 491 } 492 493 /// getCustomDiagID - Return an ID for a diagnostic with the specified message 494 /// and level. If this is the first request for this diagnosic, it is 495 /// registered and created, otherwise the existing ID is returned. 496 unsigned getCustomDiagID(Level L, StringRef Message) { 497 return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message); 498 } 499 500 /// ConvertArgToString - This method converts a diagnostic argument (as an 501 /// intptr_t) into the string that represents it. 502 void ConvertArgToString(ArgumentKind Kind, intptr_t Val, 503 const char *Modifier, unsigned ModLen, 504 const char *Argument, unsigned ArgLen, 505 const ArgumentValue *PrevArgs, unsigned NumPrevArgs, 506 SmallVectorImpl<char> &Output, 507 SmallVectorImpl<intptr_t> &QualTypeVals) const { 508 ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, 509 PrevArgs, NumPrevArgs, Output, ArgToStringCookie, 510 QualTypeVals); 511 } 512 513 void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) { 514 ArgToStringFn = Fn; 515 ArgToStringCookie = Cookie; 516 } 517 518 /// \brief Reset the state of the diagnostic object to its initial 519 /// configuration. 520 void Reset(); 521 522 //===--------------------------------------------------------------------===// 523 // DiagnosticsEngine classification and reporting interfaces. 524 // 525 526 /// \brief Based on the way the client configured the DiagnosticsEngine 527 /// object, classify the specified diagnostic ID into a Level, consumable by 528 /// the DiagnosticConsumer. 529 /// 530 /// \param Loc The source location we are interested in finding out the 531 /// diagnostic state. Can be null in order to query the latest state. 532 Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const { 533 return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this); 534 } 535 536 /// Report - Issue the message to the client. @c DiagID is a member of the 537 /// @c diag::kind enum. This actually returns aninstance of DiagnosticBuilder 538 /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed. 539 /// @c Pos represents the source location associated with the diagnostic, 540 /// which can be an invalid location if no position information is available. 541 inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID); 542 inline DiagnosticBuilder Report(unsigned DiagID); 543 544 void Report(const StoredDiagnostic &storedDiag); 545 546 /// \brief Determine whethere there is already a diagnostic in flight. 547 bool isDiagnosticInFlight() const { return CurDiagID != ~0U; } 548 549 /// \brief Set the "delayed" diagnostic that will be emitted once 550 /// the current diagnostic completes. 551 /// 552 /// If a diagnostic is already in-flight but the front end must 553 /// report a problem (e.g., with an inconsistent file system 554 /// state), this routine sets a "delayed" diagnostic that will be 555 /// emitted after the current diagnostic completes. This should 556 /// only be used for fatal errors detected at inconvenient 557 /// times. If emitting a delayed diagnostic causes a second delayed 558 /// diagnostic to be introduced, that second delayed diagnostic 559 /// will be ignored. 560 /// 561 /// \param DiagID The ID of the diagnostic being delayed. 562 /// 563 /// \param Arg1 A string argument that will be provided to the 564 /// diagnostic. A copy of this string will be stored in the 565 /// DiagnosticsEngine object itself. 566 /// 567 /// \param Arg2 A string argument that will be provided to the 568 /// diagnostic. A copy of this string will be stored in the 569 /// DiagnosticsEngine object itself. 570 void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "", 571 StringRef Arg2 = ""); 572 573 /// \brief Clear out the current diagnostic. 574 void Clear() { CurDiagID = ~0U; } 575 576private: 577 /// \brief Report the delayed diagnostic. 578 void ReportDelayed(); 579 580 // This is private state used by DiagnosticBuilder. We put it here instead of 581 // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight 582 // object. This implementation choice means that we can only have one 583 // diagnostic "in flight" at a time, but this seems to be a reasonable 584 // tradeoff to keep these objects small. Assertions verify that only one 585 // diagnostic is in flight at a time. 586 friend class DiagnosticIDs; 587 friend class DiagnosticBuilder; 588 friend class Diagnostic; 589 friend class PartialDiagnostic; 590 friend class DiagnosticErrorTrap; 591 592 /// CurDiagLoc - This is the location of the current diagnostic that is in 593 /// flight. 594 SourceLocation CurDiagLoc; 595 596 /// CurDiagID - This is the ID of the current diagnostic that is in flight. 597 /// This is set to ~0U when there is no diagnostic in flight. 598 unsigned CurDiagID; 599 600 enum { 601 /// MaxArguments - The maximum number of arguments we can hold. We currently 602 /// only support up to 10 arguments (%0-%9). A single diagnostic with more 603 /// than that almost certainly has to be simplified anyway. 604 MaxArguments = 10 605 }; 606 607 /// NumDiagArgs - This contains the number of entries in Arguments. 608 signed char NumDiagArgs; 609 /// NumRanges - This is the number of ranges in the DiagRanges array. 610 unsigned char NumDiagRanges; 611 /// \brief The number of code modifications hints in the 612 /// FixItHints array. 613 unsigned char NumFixItHints; 614 615 /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum 616 /// values, with one for each argument. This specifies whether the argument 617 /// is in DiagArgumentsStr or in DiagArguments. 618 unsigned char DiagArgumentsKind[MaxArguments]; 619 620 /// DiagArgumentsStr - This holds the values of each string argument for the 621 /// current diagnostic. This value is only used when the corresponding 622 /// ArgumentKind is ak_std_string. 623 std::string DiagArgumentsStr[MaxArguments]; 624 625 /// DiagArgumentsVal - The values for the various substitution positions. This 626 /// is used when the argument is not an std::string. The specific value is 627 /// mangled into an intptr_t and the interpretation depends on exactly what 628 /// sort of argument kind it is. 629 intptr_t DiagArgumentsVal[MaxArguments]; 630 631 /// DiagRanges - The list of ranges added to this diagnostic. It currently 632 /// only support 10 ranges, could easily be extended if needed. 633 CharSourceRange DiagRanges[10]; 634 635 enum { MaxFixItHints = 6 }; 636 637 /// FixItHints - If valid, provides a hint with some code 638 /// to insert, remove, or modify at a particular position. 639 FixItHint FixItHints[MaxFixItHints]; 640 641 DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) { 642 bool isPragma = L.isValid(); 643 DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make( 644 Map, /*IsUser=*/true, isPragma); 645 646 // If this is a pragma mapping, then set the diagnostic mapping flags so 647 // that we override command line options. 648 if (isPragma) { 649 MappingInfo.setNoWarningAsError(true); 650 MappingInfo.setNoErrorAsFatal(true); 651 } 652 653 return MappingInfo; 654 } 655 656 /// ProcessDiag - This is the method used to report a diagnostic that is 657 /// finally fully formed. 658 /// 659 /// \returns true if the diagnostic was emitted, false if it was 660 /// suppressed. 661 bool ProcessDiag() { 662 return Diags->ProcessDiag(*this); 663 } 664 665 friend class ASTReader; 666 friend class ASTWriter; 667}; 668 669/// \brief RAII class that determines when any errors have occurred 670/// between the time the instance was created and the time it was 671/// queried. 672class DiagnosticErrorTrap { 673 DiagnosticsEngine &Diag; 674 unsigned NumErrors; 675 unsigned NumUnrecoverableErrors; 676 677public: 678 explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag) 679 : Diag(Diag) { reset(); } 680 681 /// \brief Determine whether any errors have occurred since this 682 /// object instance was created. 683 bool hasErrorOccurred() const { 684 return Diag.TrapNumErrorsOccurred > NumErrors; 685 } 686 687 /// \brief Determine whether any unrecoverable errors have occurred since this 688 /// object instance was created. 689 bool hasUnrecoverableErrorOccurred() const { 690 return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors; 691 } 692 693 // Set to initial state of "no errors occurred". 694 void reset() { 695 NumErrors = Diag.TrapNumErrorsOccurred; 696 NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred; 697 } 698}; 699 700//===----------------------------------------------------------------------===// 701// DiagnosticBuilder 702//===----------------------------------------------------------------------===// 703 704/// DiagnosticBuilder - This is a little helper class used to produce 705/// diagnostics. This is constructed by the DiagnosticsEngine::Report method, 706/// and allows insertion of extra information (arguments and source ranges) into 707/// the currently "in flight" diagnostic. When the temporary for the builder is 708/// destroyed, the diagnostic is issued. 709/// 710/// Note that many of these will be created as temporary objects (many call 711/// sites), so we want them to be small and we never want their address taken. 712/// This ensures that compilers with somewhat reasonable optimizers will promote 713/// the common fields to registers, eliminating increments of the NumArgs field, 714/// for example. 715class DiagnosticBuilder { 716 mutable DiagnosticsEngine *DiagObj; 717 mutable unsigned NumArgs, NumRanges, NumFixItHints; 718 719 void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT 720 friend class DiagnosticsEngine; 721 explicit DiagnosticBuilder(DiagnosticsEngine *diagObj) 722 : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {} 723 724 friend class PartialDiagnostic; 725 726protected: 727 void FlushCounts(); 728 729public: 730 /// Copy constructor. When copied, this "takes" the diagnostic info from the 731 /// input and neuters it. 732 DiagnosticBuilder(const DiagnosticBuilder &D) { 733 DiagObj = D.DiagObj; 734 D.DiagObj = 0; 735 NumArgs = D.NumArgs; 736 NumRanges = D.NumRanges; 737 NumFixItHints = D.NumFixItHints; 738 } 739 740 /// \brief Simple enumeration value used to give a name to the 741 /// suppress-diagnostic constructor. 742 enum SuppressKind { Suppress }; 743 744 /// \brief Create an empty DiagnosticBuilder object that represents 745 /// no actual diagnostic. 746 explicit DiagnosticBuilder(SuppressKind) 747 : DiagObj(0), NumArgs(0), NumRanges(0), NumFixItHints(0) { } 748 749 /// \brief Force the diagnostic builder to emit the diagnostic now. 750 /// 751 /// Once this function has been called, the DiagnosticBuilder object 752 /// should not be used again before it is destroyed. 753 /// 754 /// \returns true if a diagnostic was emitted, false if the 755 /// diagnostic was suppressed. 756 bool Emit(); 757 758 /// Destructor - The dtor emits the diagnostic if it hasn't already 759 /// been emitted. 760 ~DiagnosticBuilder() { Emit(); } 761 762 /// isActive - Determine whether this diagnostic is still active. 763 bool isActive() const { return DiagObj != 0; } 764 765 /// \brief Retrieve the active diagnostic ID. 766 /// 767 /// \pre \c isActive() 768 unsigned getDiagID() const { 769 assert(isActive() && "DiagnosticsEngine is inactive"); 770 return DiagObj->CurDiagID; 771 } 772 773 /// \brief Retrieve the active diagnostic's location. 774 /// 775 /// \pre \c isActive() 776 SourceLocation getLocation() const { return DiagObj->CurDiagLoc; } 777 778 /// \brief Clear out the current diagnostic. 779 void Clear() { DiagObj = 0; } 780 781 /// Operator bool: conversion of DiagnosticBuilder to bool always returns 782 /// true. This allows is to be used in boolean error contexts like: 783 /// return Diag(...); 784 operator bool() const { return true; } 785 786 void AddString(StringRef S) const { 787 assert(NumArgs < DiagnosticsEngine::MaxArguments && 788 "Too many arguments to diagnostic!"); 789 if (DiagObj) { 790 DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string; 791 DiagObj->DiagArgumentsStr[NumArgs++] = S; 792 } 793 } 794 795 void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { 796 assert(NumArgs < DiagnosticsEngine::MaxArguments && 797 "Too many arguments to diagnostic!"); 798 if (DiagObj) { 799 DiagObj->DiagArgumentsKind[NumArgs] = Kind; 800 DiagObj->DiagArgumentsVal[NumArgs++] = V; 801 } 802 } 803 804 void AddSourceRange(const CharSourceRange &R) const { 805 assert(NumRanges < 806 sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) && 807 "Too many arguments to diagnostic!"); 808 if (DiagObj) 809 DiagObj->DiagRanges[NumRanges++] = R; 810 } 811 812 void AddFixItHint(const FixItHint &Hint) const { 813 assert(NumFixItHints < DiagnosticsEngine::MaxFixItHints && 814 "Too many fix-it hints!"); 815 if (NumFixItHints >= DiagnosticsEngine::MaxFixItHints) 816 return; // Don't crash in release builds 817 if (DiagObj) 818 DiagObj->FixItHints[NumFixItHints++] = Hint; 819 } 820}; 821 822inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 823 StringRef S) { 824 DB.AddString(S); 825 return DB; 826} 827 828inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 829 const char *Str) { 830 DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str), 831 DiagnosticsEngine::ak_c_string); 832 return DB; 833} 834 835inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { 836 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); 837 return DB; 838} 839 840inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) { 841 DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); 842 return DB; 843} 844 845inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 846 unsigned I) { 847 DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint); 848 return DB; 849} 850 851inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 852 const IdentifierInfo *II) { 853 DB.AddTaggedVal(reinterpret_cast<intptr_t>(II), 854 DiagnosticsEngine::ak_identifierinfo); 855 return DB; 856} 857 858// Adds a DeclContext to the diagnostic. The enable_if template magic is here 859// so that we only match those arguments that are (statically) DeclContexts; 860// other arguments that derive from DeclContext (e.g., RecordDecls) will not 861// match. 862template<typename T> 863inline 864typename llvm::enable_if<llvm::is_same<T, DeclContext>, 865 const DiagnosticBuilder &>::type 866operator<<(const DiagnosticBuilder &DB, T *DC) { 867 DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC), 868 DiagnosticsEngine::ak_declcontext); 869 return DB; 870} 871 872inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 873 const SourceRange &R) { 874 DB.AddSourceRange(CharSourceRange::getTokenRange(R)); 875 return DB; 876} 877 878inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 879 const CharSourceRange &R) { 880 DB.AddSourceRange(R); 881 return DB; 882} 883 884inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 885 const FixItHint &Hint) { 886 DB.AddFixItHint(Hint); 887 return DB; 888} 889 890/// Report - Issue the message to the client. DiagID is a member of the 891/// diag::kind enum. This actually returns a new instance of DiagnosticBuilder 892/// which emits the diagnostics (through ProcessDiag) when it is destroyed. 893inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, 894 unsigned DiagID){ 895 assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); 896 CurDiagLoc = Loc; 897 CurDiagID = DiagID; 898 return DiagnosticBuilder(this); 899} 900inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { 901 return Report(SourceLocation(), DiagID); 902} 903 904//===----------------------------------------------------------------------===// 905// Diagnostic 906//===----------------------------------------------------------------------===// 907 908/// Diagnostic - This is a little helper class (which is basically a smart 909/// pointer that forward info from DiagnosticsEngine) that allows clients to 910/// enquire about the currently in-flight diagnostic. 911class Diagnostic { 912 const DiagnosticsEngine *DiagObj; 913 StringRef StoredDiagMessage; 914public: 915 explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {} 916 Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage) 917 : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {} 918 919 const DiagnosticsEngine *getDiags() const { return DiagObj; } 920 unsigned getID() const { return DiagObj->CurDiagID; } 921 const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; } 922 bool hasSourceManager() const { return DiagObj->hasSourceManager(); } 923 SourceManager &getSourceManager() const { return DiagObj->getSourceManager();} 924 925 unsigned getNumArgs() const { return DiagObj->NumDiagArgs; } 926 927 /// getArgKind - Return the kind of the specified index. Based on the kind 928 /// of argument, the accessors below can be used to get the value. 929 DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const { 930 assert(Idx < getNumArgs() && "Argument index out of range!"); 931 return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx]; 932 } 933 934 /// getArgStdStr - Return the provided argument string specified by Idx. 935 const std::string &getArgStdStr(unsigned Idx) const { 936 assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string && 937 "invalid argument accessor!"); 938 return DiagObj->DiagArgumentsStr[Idx]; 939 } 940 941 /// getArgCStr - Return the specified C string argument. 942 const char *getArgCStr(unsigned Idx) const { 943 assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string && 944 "invalid argument accessor!"); 945 return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]); 946 } 947 948 /// getArgSInt - Return the specified signed integer argument. 949 int getArgSInt(unsigned Idx) const { 950 assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint && 951 "invalid argument accessor!"); 952 return (int)DiagObj->DiagArgumentsVal[Idx]; 953 } 954 955 /// getArgUInt - Return the specified unsigned integer argument. 956 unsigned getArgUInt(unsigned Idx) const { 957 assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint && 958 "invalid argument accessor!"); 959 return (unsigned)DiagObj->DiagArgumentsVal[Idx]; 960 } 961 962 /// getArgIdentifier - Return the specified IdentifierInfo argument. 963 const IdentifierInfo *getArgIdentifier(unsigned Idx) const { 964 assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo && 965 "invalid argument accessor!"); 966 return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]); 967 } 968 969 /// getRawArg - Return the specified non-string argument in an opaque form. 970 intptr_t getRawArg(unsigned Idx) const { 971 assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string && 972 "invalid argument accessor!"); 973 return DiagObj->DiagArgumentsVal[Idx]; 974 } 975 976 977 /// getNumRanges - Return the number of source ranges associated with this 978 /// diagnostic. 979 unsigned getNumRanges() const { 980 return DiagObj->NumDiagRanges; 981 } 982 983 const CharSourceRange &getRange(unsigned Idx) const { 984 assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!"); 985 return DiagObj->DiagRanges[Idx]; 986 } 987 988 /// \brief Return an array reference for this diagnostic's ranges. 989 ArrayRef<CharSourceRange> getRanges() const { 990 return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges); 991 } 992 993 unsigned getNumFixItHints() const { 994 return DiagObj->NumFixItHints; 995 } 996 997 const FixItHint &getFixItHint(unsigned Idx) const { 998 return DiagObj->FixItHints[Idx]; 999 } 1000 1001 const FixItHint *getFixItHints() const { 1002 return DiagObj->NumFixItHints? 1003 &DiagObj->FixItHints[0] : 0; 1004 } 1005 1006 /// FormatDiagnostic - Format this diagnostic into a string, substituting the 1007 /// formal arguments into the %0 slots. The result is appended onto the Str 1008 /// array. 1009 void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const; 1010 1011 /// FormatDiagnostic - Format the given format-string into the 1012 /// output buffer using the arguments stored in this diagnostic. 1013 void FormatDiagnostic(const char *DiagStr, const char *DiagEnd, 1014 SmallVectorImpl<char> &OutStr) const; 1015}; 1016 1017/** 1018 * \brief Represents a diagnostic in a form that can be retained until its 1019 * corresponding source manager is destroyed. 1020 */ 1021class StoredDiagnostic { 1022 unsigned ID; 1023 DiagnosticsEngine::Level Level; 1024 FullSourceLoc Loc; 1025 std::string Message; 1026 std::vector<CharSourceRange> Ranges; 1027 std::vector<FixItHint> FixIts; 1028 1029public: 1030 StoredDiagnostic(); 1031 StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); 1032 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1033 StringRef Message); 1034 StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, 1035 StringRef Message, FullSourceLoc Loc, 1036 ArrayRef<CharSourceRange> Ranges, 1037 ArrayRef<FixItHint> Fixits); 1038 ~StoredDiagnostic(); 1039 1040 /// \brief Evaluates true when this object stores a diagnostic. 1041 operator bool() const { return Message.size() > 0; } 1042 1043 unsigned getID() const { return ID; } 1044 DiagnosticsEngine::Level getLevel() const { return Level; } 1045 const FullSourceLoc &getLocation() const { return Loc; } 1046 StringRef getMessage() const { return Message; } 1047 1048 void setLocation(FullSourceLoc Loc) { this->Loc = Loc; } 1049 1050 typedef std::vector<CharSourceRange>::const_iterator range_iterator; 1051 range_iterator range_begin() const { return Ranges.begin(); } 1052 range_iterator range_end() const { return Ranges.end(); } 1053 unsigned range_size() const { return Ranges.size(); } 1054 1055 typedef std::vector<FixItHint>::const_iterator fixit_iterator; 1056 fixit_iterator fixit_begin() const { return FixIts.begin(); } 1057 fixit_iterator fixit_end() const { return FixIts.end(); } 1058 unsigned fixit_size() const { return FixIts.size(); } 1059}; 1060 1061/// DiagnosticConsumer - This is an abstract interface implemented by clients of 1062/// the front-end, which formats and prints fully processed diagnostics. 1063class DiagnosticConsumer { 1064protected: 1065 unsigned NumWarnings; // Number of warnings reported 1066 unsigned NumErrors; // Number of errors reported 1067 1068public: 1069 DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { } 1070 1071 unsigned getNumErrors() const { return NumErrors; } 1072 unsigned getNumWarnings() const { return NumWarnings; } 1073 1074 virtual ~DiagnosticConsumer(); 1075 1076 /// BeginSourceFile - Callback to inform the diagnostic client that processing 1077 /// of a source file is beginning. 1078 /// 1079 /// Note that diagnostics may be emitted outside the processing of a source 1080 /// file, for example during the parsing of command line options. However, 1081 /// diagnostics with source range information are required to only be emitted 1082 /// in between BeginSourceFile() and EndSourceFile(). 1083 /// 1084 /// \arg LO - The language options for the source file being processed. 1085 /// \arg PP - The preprocessor object being used for the source; this optional 1086 /// and may not be present, for example when processing AST source files. 1087 virtual void BeginSourceFile(const LangOptions &LangOpts, 1088 const Preprocessor *PP = 0) {} 1089 1090 /// EndSourceFile - Callback to inform the diagnostic client that processing 1091 /// of a source file has ended. The diagnostic client should assume that any 1092 /// objects made available via \see BeginSourceFile() are inaccessible. 1093 virtual void EndSourceFile() {} 1094 1095 /// \brief Callback to inform the diagnostic client that processing of all 1096 /// source files has ended. 1097 virtual void finish() {} 1098 1099 /// IncludeInDiagnosticCounts - This method (whose default implementation 1100 /// returns true) indicates whether the diagnostics handled by this 1101 /// DiagnosticConsumer should be included in the number of diagnostics 1102 /// reported by DiagnosticsEngine. 1103 virtual bool IncludeInDiagnosticCounts() const; 1104 1105 /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or 1106 /// capturing it to a log as needed. 1107 /// 1108 /// Default implementation just keeps track of the total number of warnings 1109 /// and errors. 1110 virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 1111 const Diagnostic &Info); 1112 1113 /// \brief Clone the diagnostic consumer, producing an equivalent consumer 1114 /// that can be used in a different context. 1115 virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0; 1116}; 1117 1118/// IgnoringDiagConsumer - This is a diagnostic client that just ignores all 1119/// diags. 1120class IgnoringDiagConsumer : public DiagnosticConsumer { 1121 void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 1122 const Diagnostic &Info) { 1123 // Just ignore it. 1124 } 1125 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { 1126 return new IgnoringDiagConsumer(); 1127 } 1128}; 1129 1130} // end namespace clang 1131 1132#endif 1133