82getNewSuffix(StringRef OldSuffix,
const std::vector<StringRef> &NewSuffixes) {
84 if (NewSuffixes.empty())
85 return OldSuffix.upper();
88 llvm::find_if(NewSuffixes, [OldSuffix](StringRef PotentialNewSuffix) {
89 return OldSuffix.equals_insensitive(PotentialNewSuffix);
92 if (NewSuffix != NewSuffixes.end())
93 return NewSuffix->str();
100 const LiteralParameters &Parameters,
101 const std::vector<StringRef> &NewSuffixes,
102 const SourceManager &SM,
const LangOptions &LO) {
103 NewSuffix ReplacementDsc;
106 ReplacementDsc.LiteralLocation = Literal.getSourceRange();
109 const bool RangeCanBeFixed =
113 std::optional<SourceRange> Range =
119 ReplacementDsc.LiteralLocation = *Range;
123 bool Invalid =
false;
124 const StringRef LiteralSourceText = Lexer::getSourceText(
125 CharSourceRange::getTokenRange(*Range), SM, LO, &Invalid);
126 assert(!Invalid &&
"Failed to retrieve the source text.");
130 if (!std::isdigit(
static_cast<unsigned char>(LiteralSourceText.front())))
136 if (!Parameters.SkipFirst.empty()) {
140 Skip = LiteralSourceText.find_first_of(Parameters.SkipFirst);
142 if (Skip == StringRef::npos)
149 Skip = LiteralSourceText.find_first_of(Parameters.Suffixes, Skip);
153 if (Skip == StringRef::npos)
157 Range->setBegin(Range->getBegin().getLocWithOffset(Skip));
159 ReplacementDsc.OldSuffix = LiteralSourceText.drop_front(Skip);
160 assert(!ReplacementDsc.OldSuffix.empty() &&
161 "We still should have some chars left.");
164 std::optional<std::string> NewSuffix =
166 if (!NewSuffix || ReplacementDsc.OldSuffix == *NewSuffix)
170 ReplacementDsc.FixIt = FixItHint::CreateReplacement(*Range, *NewSuffix);
172 return ReplacementDsc;
202 const MatchFinder::MatchResult &Result) {
203 const auto *
const Literal = Result.Nodes.getNodeAs<Expr>(
"expr");
204 const bool IsInteger = isa<IntegerLiteral>(Literal);
210 NewSuffixes, *Result.SourceManager, getLangOpts())) {
211 if (Details->LiteralLocation.getBegin().isMacroID() && IgnoreMacros)
213 auto Complaint = diag(Details->LiteralLocation.getBegin(),
214 "%select{floating point|integer}0 literal has suffix "
215 "'%1', which is not uppercase")
216 << IsInteger << Details->OldSuffix;
218 Complaint << *(Details->FixIt);
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.