81 const std::vector<StringRef> &NewSuffixes) {
83 if (NewSuffixes.empty())
84 return OldSuffix.upper();
87 llvm::find_if(NewSuffixes, [OldSuffix](StringRef PotentialNewSuffix) {
88 return OldSuffix.equals_insensitive(PotentialNewSuffix);
91 if (NewSuffix != NewSuffixes.end())
92 return NewSuffix->str();
100 const std::vector<StringRef> &NewSuffixes,
101 const SourceManager &SM,
const LangOptions &LO) {
102 NewSuffix ReplacementDsc;
104 const auto &L = cast<typename LiteralType::type>(Literal);
107 ReplacementDsc.LiteralLocation = L.getSourceRange();
110 const bool RangeCanBeFixed =
114 std::optional<SourceRange> Range =
120 ReplacementDsc.LiteralLocation = *Range;
124 bool Invalid =
false;
125 const StringRef LiteralSourceText = Lexer::getSourceText(
126 CharSourceRange::getTokenRange(*Range), SM, LO, &Invalid);
127 assert(!Invalid &&
"Failed to retrieve the source text.");
131 if (!std::isdigit(
static_cast<unsigned char>(LiteralSourceText.front())))
137 if (!LiteralType::SkipFirst.empty()) {
141 Skip = LiteralSourceText.find_first_of(LiteralType::SkipFirst);
143 if (Skip == StringRef::npos)
150 Skip = LiteralSourceText.find_first_of(LiteralType::Suffixes, Skip);
154 if (Skip == StringRef::npos)
158 Range->setBegin(Range->getBegin().getLocWithOffset(Skip));
160 ReplacementDsc.OldSuffix = LiteralSourceText.drop_front(Skip);
161 assert(!ReplacementDsc.OldSuffix.empty() &&
162 "We still should have some chars left.");
165 std::optional<std::string> NewSuffix =
167 if (!NewSuffix || ReplacementDsc.OldSuffix == *NewSuffix)
171 ReplacementDsc.FixIt = FixItHint::CreateReplacement(*Range, *NewSuffix);
173 return ReplacementDsc;
195 stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
196 floatLiteral().bind(FloatingLiteralCheck::Name)),
197 unless(anyOf(hasParent(userDefinedLiteral()),
198 hasAncestor(substNonTypeTemplateParmExpr())))),
203bool UppercaseLiteralSuffixCheck::checkBoundMatch(
204 const MatchFinder::MatchResult &Result) {
205 const auto *Literal =
206 Result.Nodes.getNodeAs<
typename LiteralType::type>(LiteralType::Name);
213 *Literal, NewSuffixes, *Result.SourceManager, getLangOpts())) {
214 if (Details->LiteralLocation.getBegin().isMacroID() && IgnoreMacros)
216 auto Complaint = diag(Details->LiteralLocation.getBegin(),
217 "%0 literal has suffix '%1', which is not uppercase")
218 << LiteralType::Name << Details->OldSuffix;
220 Complaint << *(Details->FixIt);
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.