Skip to content

Commit 45bce19

Browse files
committed
[clang-tidy] Optimize readability-identifier-naming
- Reduce disk IO usage by adding cache to an realpath introduced by #81985 - Refactor HungarianNotation::getDeclTypeName to remove some string copies and use more safe string API.
1 parent e90126e commit 45bce19

File tree

2 files changed

+37
-33
lines changed

2 files changed

+37
-33
lines changed

clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -305,27 +305,20 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName(
305305
auto &SM = VD->getASTContext().getSourceManager();
306306
const char *Begin = SM.getCharacterData(VD->getBeginLoc());
307307
const char *End = SM.getCharacterData(VD->getEndLoc());
308-
intptr_t StrLen = End - Begin;
308+
if (End < Begin)
309+
return {};
309310

310311
// FIXME: Sometimes the value that returns from ValDecl->getEndLoc()
311312
// is wrong(out of location of Decl). This causes `StrLen` will be assigned
312313
// an unexpected large value. Current workaround to find the terminated
313314
// character instead of the `getEndLoc()` function.
314-
const char *EOL = strchr(Begin, '\n');
315-
if (!EOL)
316-
EOL = Begin + strlen(Begin);
317-
318-
const char *PosList[] = {strchr(Begin, '='), strchr(Begin, ';'),
319-
strchr(Begin, ','), strchr(Begin, ')'), EOL};
320-
for (const auto &Pos : PosList) {
321-
if (Pos > Begin)
322-
EOL = std::min(EOL, Pos);
323-
}
315+
llvm::StringRef NameRef(Begin, End - Begin);
316+
auto Pos = NameRef.find_first_of("\n\r=;,)");
317+
if (Pos != llvm::StringRef::npos)
318+
NameRef = NameRef.substr(0, Pos);
324319

325-
StrLen = EOL - Begin;
326-
std::string TypeName;
327-
if (StrLen > 0) {
328-
std::string Type(Begin, StrLen);
320+
if (!NameRef.empty()) {
321+
std::string Type(NameRef.begin(), NameRef.end());
329322

330323
static constexpr StringRef Keywords[] = {
331324
// Constexpr specifiers
@@ -339,66 +332,67 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName(
339332

340333
// Remove keywords
341334
for (StringRef Kw : Keywords) {
342-
for (size_t Pos = 0;
343-
(Pos = Type.find(Kw.data(), Pos)) != std::string::npos;) {
335+
for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;) {
344336
Type.replace(Pos, Kw.size(), "");
345337
}
346338
}
347-
TypeName = Type.erase(0, Type.find_first_not_of(' '));
348339

349340
// Remove template parameters
350341
const size_t Pos = Type.find('<');
351342
if (Pos != std::string::npos) {
352-
TypeName = Type.erase(Pos, Type.size() - Pos);
343+
Type.erase(Pos);
353344
}
354345

355346
// Replace spaces with single space.
356347
for (size_t Pos = 0; (Pos = Type.find(" ", Pos)) != std::string::npos;
357-
Pos += strlen(" ")) {
358-
Type.replace(Pos, strlen(" "), " ");
348+
Pos += 2U) {
349+
Type.replace(Pos, 2U, " ");
359350
}
360351

361352
// Replace " &" with "&".
362353
for (size_t Pos = 0; (Pos = Type.find(" &", Pos)) != std::string::npos;
363-
Pos += strlen("&")) {
364-
Type.replace(Pos, strlen(" &"), "&");
354+
Pos += 2U) {
355+
Type.replace(Pos, 2U, "&");
365356
}
366357

367358
// Replace " *" with "* ".
368359
for (size_t Pos = 0; (Pos = Type.find(" *", Pos)) != std::string::npos;
369-
Pos += strlen("*")) {
370-
Type.replace(Pos, strlen(" *"), "* ");
360+
Pos += 1U) {
361+
Type.replace(Pos, 2U, "* ");
371362
}
372363

364+
Type.erase(0, Type.find_first_not_of(' '));
365+
373366
// Remove redundant tailing.
374367
static constexpr StringRef TailsOfMultiWordType[] = {
375368
" int", " char", " double", " long", " short"};
376369
bool RedundantRemoved = false;
377370
for (auto Kw : TailsOfMultiWordType) {
378-
size_t Pos = Type.rfind(Kw.data());
371+
size_t Pos = Type.rfind(Kw);
379372
if (Pos != std::string::npos) {
380373
const size_t PtrCount = getAsteriskCount(Type, ND);
381-
Type = Type.substr(0, Pos + Kw.size() + PtrCount);
374+
Type.erase(Pos + Kw.size() + PtrCount);
382375
RedundantRemoved = true;
383376
break;
384377
}
385378
}
386379

387-
TypeName = Type.erase(0, Type.find_first_not_of(' '));
380+
Type.erase(0, Type.find_first_not_of(' '));
388381
if (!RedundantRemoved) {
389382
std::size_t FoundSpace = Type.find(' ');
390383
if (FoundSpace != std::string::npos)
391384
Type = Type.substr(0, FoundSpace);
392385
}
393386

394-
TypeName = Type.erase(0, Type.find_first_not_of(' '));
387+
Type.erase(0, Type.find_first_not_of(' '));
395388

396389
QualType QT = VD->getType();
397390
if (!QT.isNull() && QT->isArrayType())
398-
TypeName.append("[]");
391+
Type.append("[]");
392+
return Type;
399393
}
400394

401-
return TypeName;
395+
return {};
402396
}
403397

404398
IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
@@ -1414,13 +1408,21 @@ IdentifierNamingCheck::getDiagInfo(const NamingCheckId &ID,
14141408
}};
14151409
}
14161410

1411+
StringRef IdentifierNamingCheck::getRealFileName(StringRef FileName) const {
1412+
auto Iter = RealFileNameCache.try_emplace(FileName);
1413+
SmallString<256U> &RealFileName = Iter.first->getValue();
1414+
if (!Iter.second)
1415+
return RealFileName;
1416+
llvm::sys::fs::real_path(FileName, RealFileName);
1417+
return RealFileName;
1418+
}
1419+
14171420
const IdentifierNamingCheck::FileStyle &
14181421
IdentifierNamingCheck::getStyleForFile(StringRef FileName) const {
14191422
if (!GetConfigPerFile)
14201423
return *MainFileStyle;
14211424

1422-
SmallString<128> RealFileName;
1423-
llvm::sys::fs::real_path(FileName, RealFileName);
1425+
StringRef RealFileName = getRealFileName(FileName);
14241426
StringRef Parent = llvm::sys::path::parent_path(RealFileName);
14251427
auto Iter = NamingStylesCache.find(Parent);
14261428
if (Iter != NamingStylesCache.end())

clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
205205
const NamingCheckFailure &Failure) const override;
206206

207207
const FileStyle &getStyleForFile(StringRef FileName) const;
208+
StringRef getRealFileName(StringRef FileName) const;
208209

209210
/// Find the style kind of a field in an anonymous record.
210211
StyleKind findStyleKindForAnonField(
@@ -222,6 +223,7 @@ class IdentifierNamingCheck final : public RenamerClangTidyCheck {
222223
/// Stores the style options as a vector, indexed by the specified \ref
223224
/// StyleKind, for a given directory.
224225
mutable llvm::StringMap<FileStyle> NamingStylesCache;
226+
mutable llvm::StringMap<SmallString<256U>> RealFileNameCache;
225227
FileStyle *MainFileStyle;
226228
ClangTidyContext *Context;
227229
const bool GetConfigPerFile;

0 commit comments

Comments
 (0)