From: Argyrios Kyrtzidis Date: Wed, 25 May 2011 05:05:01 +0000 (+0000) Subject: A StringRef-ication of the DiagnosticIDs API and internals. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=477aab6782795e7472055a54108d2df270ce1a89;p=clang A StringRef-ication of the DiagnosticIDs API and internals. Patch by Matthieu Monrocq with tweaks by me to avoid StringRefs in the static diagnostic data structures, which resulted in a huge global-var-init function. Depends on llvm commit r132046. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132047 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/UsersManual.html b/docs/UsersManual.html index d4f9dfbb01..4962a92110 100644 --- a/docs/UsersManual.html +++ b/docs/UsersManual.html @@ -295,6 +295,12 @@ Changes diagnostic output format to better match IDEs and command line tools. + +
-f[no-]diagnostics-show-name: +Enable the display of the diagnostic name.
+
This option, which defaults to off, controls whether or not +Clang prints the associated name.
+
-f[no-]diagnostics-show-option: Enable [-Woption] information in diagnostic line.
@@ -522,6 +528,8 @@ it:

  • A categorization of the diagnostic as a note, warning, error, or fatal error.
  • A text string that describes what the problem is.
  • +
  • An option that indicates whether to print the diagnostic name [-fdiagnostics-show-name].
  • An option that indicates how to control the diagnostic (for diagnostics that support it) [-fdiagnostics-show-option].
  • diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 22d2569e30..fa763246d1 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -425,7 +425,7 @@ public: /// /// 'Loc' is the source location that this change of diagnostic state should /// take affect. It can be null if we are setting the state from command-line. - bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map, + bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, SourceLocation Loc = SourceLocation()) { return Diags->setDiagnosticGroupMapping(Group, Map, Loc, *this); } diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 0296b96d00..fa816de4fd 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -101,7 +101,7 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - const char *getDescription(unsigned DiagID) const; + llvm::StringRef getDescription(unsigned DiagID) const; /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic /// level of the specified diagnostic ID is a Warning or Extension. @@ -132,15 +132,18 @@ public: /// getWarningOptionForDiag - Return the lowest-level warning option that /// enables the specified diagnostic. If there is no -Wfoo flag that controls /// the diagnostic, this returns null. - static const char *getWarningOptionForDiag(unsigned DiagID); - + static llvm::StringRef getWarningOptionForDiag(unsigned DiagID); + /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. static unsigned getCategoryNumberForDiag(unsigned DiagID); + /// getNumberOfCategories - Return the number of categories + static unsigned getNumberOfCategories(); + /// getCategoryNameFromID - Given a category ID, return the name of the /// category. - static const char *getCategoryNameFromID(unsigned CategoryID); + static llvm::StringRef getCategoryNameFromID(unsigned CategoryID); /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. @@ -179,24 +182,24 @@ public: static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); /// getName - Given a diagnostic ID, return its name - static const char *getName(unsigned DiagID); + static llvm::StringRef getName(unsigned DiagID); /// getIdFromName - Given a diagnostic name, return its ID, or 0 - static unsigned getIdFromName(char const *Name); + static unsigned getIdFromName(llvm::StringRef Name); /// getBriefExplanation - Given a diagnostic ID, return a brief explanation /// of the issue - static const char *getBriefExplanation(unsigned DiagID); + static llvm::StringRef getBriefExplanation(unsigned DiagID); /// getFullExplanation - Given a diagnostic ID, return a full explanation /// of the issue - static const char *getFullExplanation(unsigned DiagID); + static llvm::StringRef getFullExplanation(unsigned DiagID); private: /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. /// "unknown-pragmas" to have the specified mapping. This returns true and /// ignores the request if "Group" was unknown, false otherwise. - bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map, + bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, SourceLocation Loc, Diagnostic &Diag) const; /// \brief Based on the way the client configured the Diagnostic diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index c79fe7b83d..11887ab0fe 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -527,10 +527,10 @@ FormatDiagnostic(llvm::SmallVectorImpl &OutStr) const { return; } - const char *DiagStr = getDiags()->getDiagnosticIDs()->getDescription(getID()); - const char *DiagEnd = DiagStr+strlen(DiagStr); + llvm::StringRef Diag = + getDiags()->getDiagnosticIDs()->getDescription(getID()); - FormatDiagnostic(DiagStr, DiagEnd, OutStr); + FormatDiagnostic(Diag.begin(), Diag.end(), OutStr); } void DiagnosticInfo:: diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index b4dd575a96..6d7e3204cb 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -45,14 +45,37 @@ struct StaticDiagInfoRec { unsigned SFINAE : 1; unsigned AccessControl : 1; unsigned Category : 5; - - const char *Name; - - const char *Description; - const char *OptionGroup; - const char *BriefExplanation; - const char *FullExplanation; + uint8_t NameLen; + uint8_t OptionGroupLen; + + uint16_t DescriptionLen; + uint16_t BriefExplanationLen; + uint16_t FullExplanationLen; + + const char *NameStr; + const char *OptionGroupStr; + + const char *DescriptionStr; + const char *BriefExplanationStr; + const char *FullExplanationStr; + + llvm::StringRef getName() const { + return llvm::StringRef(NameStr, NameLen); + } + llvm::StringRef getOptionGroup() const { + return llvm::StringRef(OptionGroupStr, OptionGroupLen); + } + + llvm::StringRef getDescription() const { + return llvm::StringRef(DescriptionStr, DescriptionLen); + } + llvm::StringRef getBriefExplanation() const { + return llvm::StringRef(BriefExplanationStr, BriefExplanationLen); + } + llvm::StringRef getFullExplanation() const { + return llvm::StringRef(FullExplanationStr, FullExplanationLen); + } bool operator<(const StaticDiagInfoRec &RHS) const { return DiagID < RHS.DiagID; @@ -60,27 +83,42 @@ struct StaticDiagInfoRec { }; struct StaticDiagNameIndexRec { - const char *Name; + const char *NameStr; unsigned short DiagID; - + uint8_t NameLen; + + llvm::StringRef getName() const { + return llvm::StringRef(NameStr, NameLen); + } + bool operator<(const StaticDiagNameIndexRec &RHS) const { - assert(Name && RHS.Name && "Null Diagnostic Name"); - return strcmp(Name, RHS.Name) == -1; + return getName() < RHS.getName(); } bool operator==(const StaticDiagNameIndexRec &RHS) const { - assert(Name && RHS.Name && "Null Diagnostic Name"); - return strcmp(Name, RHS.Name) == 0; + return getName() == RHS.getName(); } }; -} +template +class StringSizerHelper { + char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1]; +public: + enum { Size = SizeOfStr }; +}; + +} // namespace anonymous + +#define STR_SIZE(str, fieldTy) StringSizerHelper::Size static const StaticDiagInfoRec StaticDiagInfo[] = { -#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) \ - { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, \ - ACCESS, CATEGORY, #ENUM, DESC, GROUP, BRIEF, FULL }, +#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \ + SFINAE,ACCESS,CATEGORY,BRIEF,FULL) \ + { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, CATEGORY, \ + STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t), \ + STR_SIZE(DESC, uint16_t), STR_SIZE(BRIEF, uint16_t), \ + STR_SIZE(FULL, uint16_t), \ + #ENUM, GROUP, DESC, BRIEF, FULL }, #include "clang/Basic/DiagnosticCommonKinds.inc" #include "clang/Basic/DiagnosticDriverKinds.inc" #include "clang/Basic/DiagnosticFrontendKinds.inc" @@ -90,7 +128,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = { #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; static const unsigned StaticDiagInfoSize = @@ -98,10 +136,10 @@ static const unsigned StaticDiagInfoSize = /// To be sorted before first use (since it's splitted among multiple files) static StaticDiagNameIndexRec StaticDiagNameIndex[] = { -#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM }, +#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) }, #include "clang/Basic/DiagnosticIndexName.inc" #undef DIAG_NAME_INDEX - { 0, 0 } + { 0, 0, 0 } }; static const unsigned StaticDiagNameIndexSize = @@ -127,7 +165,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { #endif // Search the diagnostic table with a binary search. - StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 }; const StaticDiagInfoRec *Found = std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find); @@ -147,10 +185,10 @@ static unsigned GetDefaultDiagMapping(unsigned DiagID) { /// getWarningOptionForDiag - Return the lowest-level warning option that /// enables the specified diagnostic. If there is no -Wfoo flag that controls /// the diagnostic, this returns null. -const char *DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { +llvm::StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->OptionGroup; - return 0; + return Info->getOptionGroup(); + return llvm::StringRef(); } /// getCategoryNumberForDiag - Return the category number that a specified @@ -161,23 +199,36 @@ unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) { return 0; } -/// getCategoryNameFromID - Given a category ID, return the name of the -/// category, an empty string if CategoryID is zero, or null if CategoryID is -/// invalid. -const char *DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) { - // Second the table of options, sorted by name for fast binary lookup. - static const char *CategoryNameTable[] = { +// The diagnostic category names. +struct StaticDiagCategoryRec { + const char *NameStr; + uint8_t NameLen; + + llvm::StringRef getName() const { + return llvm::StringRef(NameStr, NameLen); + } +}; + +static StaticDiagCategoryRec CategoryNameTable[] = { #define GET_CATEGORY_TABLE -#define CATEGORY(X) X, +#define CATEGORY(X) { X, STR_SIZE(X, uint8_t) }, #include "clang/Basic/DiagnosticGroups.inc" #undef GET_CATEGORY_TABLE - "<>" - }; - static const size_t CategoryNameTableSize = - sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1; - - if (CategoryID >= CategoryNameTableSize) return 0; - return CategoryNameTable[CategoryID]; + { 0, 0 } +}; + +/// getNumberOfCategories - Return the number of categories +unsigned DiagnosticIDs::getNumberOfCategories() { + return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1; +} + +/// getCategoryNameFromID - Given a category ID, return the name of the +/// category, an empty string if CategoryID is zero, or null if CategoryID is +/// invalid. +llvm::StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) { + if (CategoryID >= getNumberOfCategories()) + return llvm::StringRef(); + return CategoryNameTable[CategoryID].getName(); } @@ -202,25 +253,25 @@ DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) { } /// getName - Given a diagnostic ID, return its name -const char *DiagnosticIDs::getName(unsigned DiagID) { +llvm::StringRef DiagnosticIDs::getName(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->Name; - return 0; + return Info->getName(); + return llvm::StringRef(); } /// getIdFromName - Given a diagnostic name, return its ID, or 0 -unsigned DiagnosticIDs::getIdFromName(char const *Name) { +unsigned DiagnosticIDs::getIdFromName(llvm::StringRef Name) { StaticDiagNameIndexRec *StaticDiagNameIndexEnd = StaticDiagNameIndex + StaticDiagNameIndexSize; - if (Name == 0) { return diag::DIAG_UPPER_LIMIT; } + if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; } - StaticDiagNameIndexRec Find = { Name, 0 }; + StaticDiagNameIndexRec Find = { Name.data(), 0, Name.size() }; const StaticDiagNameIndexRec *Found = std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find); if (Found == StaticDiagNameIndexEnd || - strcmp(Found->Name, Name) != 0) + Found->getName() != Name) return diag::DIAG_UPPER_LIMIT; return Found->DiagID; @@ -228,18 +279,18 @@ unsigned DiagnosticIDs::getIdFromName(char const *Name) { /// getBriefExplanation - Given a diagnostic ID, return a brief explanation /// of the issue -const char *DiagnosticIDs::getBriefExplanation(unsigned DiagID) { +llvm::StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->BriefExplanation; - return 0; + return Info->getBriefExplanation(); + return llvm::StringRef(); } /// getFullExplanation - Given a diagnostic ID, return a full explanation /// of the issue -const char *DiagnosticIDs::getFullExplanation(unsigned DiagID) { +llvm::StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->FullExplanation; - return 0; + return Info->getFullExplanation(); + return llvm::StringRef(); } /// getBuiltinDiagClass - Return the class field of the diagnostic. @@ -264,10 +315,10 @@ namespace clang { /// getDescription - Return the description of the specified custom /// diagnostic. - const char *getDescription(unsigned DiagID) const { + llvm::StringRef getDescription(unsigned DiagID) const { assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && "Invalid diagnosic ID"); - return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str(); + return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; } /// getLevel - Return the level of the specified custom diagnostic. @@ -352,9 +403,9 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, /// getDescription - Given a diagnostic ID, return a description of the /// issue. -const char *DiagnosticIDs::getDescription(unsigned DiagID) const { +llvm::StringRef DiagnosticIDs::getDescription(unsigned DiagID) const { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->Description; + return Info->getDescription(); return CustomDiagInfo->getDescription(DiagID); } @@ -493,9 +544,15 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, } struct WarningOption { - const char *Name; + // Be safe with the size of 'NameLen' because we don't statically check if the + // size will fit in the field; the struct size won't decrease with a shorter + // type anyway. + size_t NameLen; + const char *NameStr; const short *Members; const short *SubGroups; + + llvm::StringRef getName() const { return llvm::StringRef(NameStr, NameLen); } }; #define GET_DIAG_ARRAYS @@ -513,7 +570,7 @@ sizeof(OptionTable) / sizeof(OptionTable[0]); static bool WarningOptionCompare(const WarningOption &LHS, const WarningOption &RHS) { - return strcmp(LHS.Name, RHS.Name) < 0; + return LHS.getName() < RHS.getName(); } static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping, @@ -534,10 +591,10 @@ static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping, /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. /// "unknown-pragmas" to have the specified mapping. This returns true and /// ignores the request if "Group" was unknown, false otherwise. -bool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group, - diag::Mapping Map, - SourceLocation Loc, - Diagnostic &Diag) const { +bool DiagnosticIDs::setDiagnosticGroupMapping(llvm::StringRef Group, + diag::Mapping Map, + SourceLocation Loc, + Diagnostic &Diag) const { assert((Loc.isValid() || Diag.DiagStatePoints.empty() || Diag.DiagStatePoints.back().Loc.isInvalid()) && @@ -548,12 +605,12 @@ bool DiagnosticIDs::setDiagnosticGroupMapping(const char *Group, Diag.DiagStatePoints.back().Loc)) && "Source location of new mapping is before the previous one!"); - WarningOption Key = { Group, 0, 0 }; + WarningOption Key = { Group.size(), Group.data(), 0, 0 }; const WarningOption *Found = std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key, WarningOptionCompare); if (Found == OptionTable + OptionTableSize || - strcmp(Found->Name, Group) != 0) + Found->getName() != Group) return true; // Option not found. MapGroupMembers(Found, Map, Loc, Diag); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index fe650547f1..9ebf850c3a 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -398,9 +398,10 @@ void Driver::PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const { /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories /// option. static void PrintDiagnosticCategories(llvm::raw_ostream &OS) { - for (unsigned i = 1; // Skip the empty category. - const char *CategoryName = DiagnosticIDs::getCategoryNameFromID(i); ++i) - OS << i << ',' << CategoryName << '\n'; + // Skip the empty category. + for (unsigned i = 1, max = DiagnosticIDs::getNumberOfCategories(); + i != max; ++i) + OS << i << ',' << DiagnosticIDs::getCategoryNameFromID(i) << '\n'; } bool Driver::HandleImmediateArgs(const Compilation &C) { diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 46ebd18487..0d048a3030 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -939,8 +939,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OptionName += "-Werror"; } - if (const char * - Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID())) { + llvm::StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID()); + if (!Opt.empty()) { if (!OptionName.empty()) OptionName += ','; OptionName += "-W"; diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp index 8cc56168e0..829ac9e661 100644 --- a/lib/Frontend/Warnings.cpp +++ b/lib/Frontend/Warnings.cpp @@ -55,17 +55,14 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, Diags.setExtensionHandlingBehavior(Diagnostic::Ext_Ignore); for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) { - const std::string &Opt = Opts.Warnings[i]; - const char *OptStart = &Opt[0]; - const char *OptEnd = OptStart+Opt.size(); - assert(*OptEnd == 0 && "Expect null termination for lower-bound search"); + llvm::StringRef Opt = Opts.Warnings[i]; // Check to see if this warning starts with "no-", if so, this is a negative // form of the option. bool isPositive = true; - if (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) { + if (Opt.startswith("no-")) { isPositive = false; - OptStart += 3; + Opt = Opt.substr(3); } // Figure out how this option affects the warning. If -Wfoo, map the @@ -74,49 +71,47 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, // -Wsystem-headers is a special case, not driven by the option table. It // cannot be controlled with -Werror. - if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) { + if (Opt == "system-headers") { Diags.setSuppressSystemWarnings(!isPositive); continue; } // -Werror/-Wno-error is a special case, not controlled by the option table. // It also has the "specifier" form of -Werror=foo and -Werror-foo. - if (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) { - const char *Specifier = 0; - if (OptEnd-OptStart != 5) { // Specifier must be present. - if ((OptStart[5] != '=' && OptStart[5] != '-') || - OptEnd-OptStart == 6) { + if (Opt.startswith("error")) { + llvm::StringRef Specifier; + if (Opt.size() > 5) { // Specifier must be present. + if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) { Diags.Report(diag::warn_unknown_warning_specifier) - << "-Werror" << ("-W" + Opt); + << "-Werror" << ("-W" + Opt.str()); continue; } - Specifier = OptStart+6; + Specifier = Opt.substr(6); } - if (Specifier == 0) { + if (Specifier.empty()) { Diags.setWarningsAsErrors(isPositive); continue; } // -Werror=foo maps foo to Error, -Wno-error=foo maps it to Warning. Mapping = isPositive ? diag::MAP_ERROR : diag::MAP_WARNING_NO_WERROR; - OptStart = Specifier; + Opt = Specifier; } // -Wfatal-errors is yet another special case. - if (OptEnd-OptStart >= 12 && memcmp(OptStart, "fatal-errors", 12) == 0) { - const char* Specifier = 0; - if (OptEnd-OptStart != 12) { - if ((OptStart[12] != '=' && OptStart[12] != '-') || - OptEnd-OptStart == 13) { + if (Opt.startswith("fatal-errors")) { + llvm::StringRef Specifier; + if (Opt.size() != 12) { + if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) { Diags.Report(diag::warn_unknown_warning_specifier) - << "-Wfatal-errors" << ("-W" + Opt); + << "-Wfatal-errors" << ("-W" + Opt.str()); continue; } - Specifier = OptStart + 13; + Specifier = Opt.substr(13); } - if (Specifier == 0) { + if (Specifier.empty()) { Diags.setErrorsAsFatal(isPositive); continue; } @@ -124,10 +119,10 @@ void clang::ProcessWarningOptions(Diagnostic &Diags, // -Wfatal-errors=foo maps foo to Fatal, -Wno-fatal-errors=foo // maps it to Error. Mapping = isPositive ? diag::MAP_FATAL : diag::MAP_ERROR_NO_WFATAL; - OptStart = Specifier; + Opt = Specifier; } - if (Diags.setDiagnosticGroupMapping(OptStart, Mapping)) - Diags.Report(diag::warn_unknown_warning_option) << ("-W" + Opt); + if (Diags.setDiagnosticGroupMapping(Opt, Mapping)) + Diags.Report(diag::warn_unknown_warning_option) << ("-W" + Opt.str()); } } diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index a1c4498a94..ecbf4cf4a0 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -898,8 +898,7 @@ public: return; } - std::string WarningName(Literal.GetString(), - Literal.GetString()+Literal.GetStringLength()); + llvm::StringRef WarningName(Literal.GetString(), Literal.GetStringLength()); if (WarningName.size() < 3 || WarningName[0] != '-' || WarningName[1] != 'W') { @@ -908,7 +907,7 @@ public: return; } - if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.c_str()+2, + if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2), Map, DiagLoc)) PP.Diag(StrToks[0].getLocation(), diag::warn_pragma_diagnostic_unknown_warning) << WarningName; diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp index fa3b1cec7f..0fcdab70be 100644 --- a/tools/libclang/CIndexDiagnostic.cpp +++ b/tools/libclang/CIndexDiagnostic.cpp @@ -220,7 +220,8 @@ CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) { return createCXString(""); unsigned ID = StoredDiag->Diag.getID(); - if (const char *Option = DiagnosticIDs::getWarningOptionForDiag(ID)) { + llvm::StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID); + if (!Option.empty()) { if (Disable) *Disable = createCXString((llvm::Twine("-Wno-") + Option).str()); return createCXString((llvm::Twine("-W") + Option).str());