84 const std::vector<StringRef> &NewSuffixes) {
86 if (NewSuffixes.empty())
87 return OldSuffix.upper();
90 llvm::find_if(NewSuffixes, [OldSuffix](StringRef PotentialNewSuffix) {
91 return OldSuffix.equals_insensitive(PotentialNewSuffix);
94 if (NewSuffix != NewSuffixes.end())
95 return NewSuffix->str();
103 const std::vector<StringRef> &NewSuffixes,
104 const SourceManager &SM,
const LangOptions &LO) {
105 NewSuffix ReplacementDsc;
107 const auto &L = cast<typename LiteralType::type>(Literal);
110 ReplacementDsc.LiteralLocation = L.getSourceRange();
113 bool RangeCanBeFixed =
117 std::optional<SourceRange> Range =
123 ReplacementDsc.LiteralLocation = *Range;
127 bool Invalid =
false;
128 const StringRef LiteralSourceText = Lexer::getSourceText(
129 CharSourceRange::getTokenRange(*Range), SM, LO, &Invalid);
130 assert(!Invalid &&
"Failed to retrieve the source text.");
134 if (!std::isdigit(
static_cast<unsigned char>(LiteralSourceText.front())))
140 if (!LiteralType::SkipFirst.empty()) {
144 Skip = LiteralSourceText.find_first_of(LiteralType::SkipFirst);
146 if (Skip == StringRef::npos)
153 Skip = LiteralSourceText.find_first_of(LiteralType::Suffixes, Skip);
157 if (Skip == StringRef::npos)
161 Range->setBegin(Range->getBegin().getLocWithOffset(Skip));
163 ReplacementDsc.OldSuffix = LiteralSourceText.drop_front(Skip);
164 assert(!ReplacementDsc.OldSuffix.empty() &&
165 "We still should have some chars left.");
168 std::optional<std::string> NewSuffix =
170 if (!NewSuffix || ReplacementDsc.OldSuffix == *NewSuffix)
174 ReplacementDsc.FixIt = FixItHint::CreateReplacement(*Range, *NewSuffix);
176 return ReplacementDsc;
198 stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
199 floatLiteral().bind(FloatingLiteralCheck::Name)),
200 unless(anyOf(hasParent(userDefinedLiteral()),
201 hasAncestor(substNonTypeTemplateParmExpr())))),
206bool UppercaseLiteralSuffixCheck::checkBoundMatch(
207 const MatchFinder::MatchResult &Result) {
208 const auto *Literal =
209 Result.Nodes.getNodeAs<
typename LiteralType::type>(LiteralType::Name);
216 *Literal, NewSuffixes, *Result.SourceManager, getLangOpts())) {
217 if (Details->LiteralLocation.getBegin().isMacroID() && IgnoreMacros)
219 auto Complaint = diag(Details->LiteralLocation.getBegin(),
220 "%0 literal has suffix '%1', which is not uppercase")
221 << LiteralType::Name << Details->OldSuffix;
223 Complaint << *(Details->FixIt);
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.