Index: include/clang/Basic/DiagnosticIDs.h =================================================================== --- include/clang/Basic/DiagnosticIDs.h +++ include/clang/Basic/DiagnosticIDs.h @@ -124,8 +124,8 @@ DiagnosticIDs(); ~DiagnosticIDs(); - /// \brief Return an ID for a diagnostic with the specified format string and - /// level. + /// \brief Return an ID for a diagnostic with the specified format string, + /// level and warning option. /// /// If this is the first request for this diagnostic, it is registered and /// created, otherwise the existing ID is returned. @@ -133,7 +133,8 @@ // FIXME: Replace this function with a create-only facilty like // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of // writing, nearly all callers of this function were invalid. - unsigned getCustomDiagID(Level L, StringRef FormatString); + unsigned getCustomDiagID(Level L, StringRef FormatString, + StringRef WarningOption = ""); //===--------------------------------------------------------------------===// // Diagnostic classification and reporting interfaces. @@ -142,6 +143,16 @@ /// \brief Given a diagnostic ID, return a description of the issue. StringRef getDescription(unsigned DiagID) const; + /// \brief Return the lowest-level warning option that enables the specified + /// diagnostic. + /// + /// This method is similar to getWarningOptionForDiag, but it also handles + /// custom diagnostic DiagIDs. + /// + /// If there is no -Wfoo flag that controls the diagnostic, this returns an + /// empty string. + StringRef getWarningOption(unsigned DiagID) const; + /// \brief Return true if the unmapped diagnostic levelof the specified /// diagnostic ID is a Warning or Extension. /// Index: lib/Basic/DiagnosticIDs.cpp =================================================================== --- lib/Basic/DiagnosticIDs.cpp +++ lib/Basic/DiagnosticIDs.cpp @@ -256,7 +256,25 @@ namespace clang { namespace diag { class CustomDiagInfo { - typedef std::pair DiagDesc; + struct DiagDesc { + DiagnosticIDs::Level Level; + std::string Description; + std::string WarningOption; + DiagDesc(DiagnosticIDs::Level Level, std::string Description, + std::string WarningOption) + : Level(Level), Description(Description), + WarningOption(WarningOption) {} + bool operator==(const DiagDesc &RHS) const { + return Level == RHS.Level && Description == RHS.Description && + WarningOption == RHS.WarningOption; + } + bool operator<(const DiagDesc &RHS) const { + return Level < RHS.Level || + (Level == RHS.Level && Description < RHS.Description) || + (Level == RHS.Level && Description == RHS.Description && + WarningOption < RHS.WarningOption); + } + }; std::vector DiagInfo; std::map DiagIDs; public: @@ -266,19 +284,27 @@ StringRef getDescription(unsigned DiagID) const { assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && "Invalid diagnostic ID"); - return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; + return DiagInfo[DiagID-DIAG_UPPER_LIMIT].Description; } /// getLevel - Return the level of the specified custom diagnostic. DiagnosticIDs::Level getLevel(unsigned DiagID) const { assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && "Invalid diagnostic ID"); - return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; + return DiagInfo[DiagID-DIAG_UPPER_LIMIT].Level; } + /// getLevel - Return the warning option of the specified custom + /// diagnostic. + StringRef getWarningOption(unsigned DiagID) const { + assert(this); + assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && + "Invalid diagnostic ID"); + return DiagInfo[DiagID-DIAG_UPPER_LIMIT].WarningOption; + } unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message, - DiagnosticIDs &Diags) { - DiagDesc D(L, Message); + StringRef WarningOption) { + DiagDesc D(L, Message, WarningOption); // Check to see if it already exists. std::map::iterator I = DiagIDs.lower_bound(D); if (I != DiagIDs.end() && I->first == D) @@ -314,12 +340,19 @@ /// /// \param FormatString A fixed diagnostic format string that will be hashed and /// mapped to a unique DiagID. -unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) { +unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString, + StringRef WarningOption /*= ""*/) { if (CustomDiagInfo == 0) CustomDiagInfo = new diag::CustomDiagInfo(); - return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this); + return CustomDiagInfo->getOrCreateDiagID(L, FormatString, WarningOption); } +StringRef DiagnosticIDs::getWarningOption(unsigned DiagID) const { + if (DiagID >= diag::DIAG_UPPER_LIMIT) + return CustomDiagInfo->getWarningOption(DiagID); + + return getWarningOptionForDiag(DiagID); +} /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic /// level of the specified diagnostic ID is a Warning or Extension.