Skip to content

Commit 6709e28

Browse files
author
Yaraslau Tamashevich
committed
Introduce misc-fix-type-conversion check
1 parent 44880a9 commit 6709e28

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

clang-tools-extra/clang-tidy/misc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_clang_library(clangTidyMiscModule STATIC
2323
DefinitionsInHeadersCheck.cpp
2424
ConfusableIdentifierCheck.cpp
2525
FixStdstringDataAccessCheck.cpp
26+
FixTypeConversionCheck.cpp
2627
HeaderIncludeCycleCheck.cpp
2728
IncludeCleanerCheck.cpp
2829
MiscTidyModule.cpp
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===--- FixStdstringDataAccessCheck.cpp - clang-tidy ---------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "FixTypeConversionCheck.h"
10+
#include "clang/ASTMatchers/ASTMatchFinder.h"
11+
#include "clang/Lex/Lexer.h"
12+
13+
#include <iostream>
14+
15+
16+
17+
18+
using namespace clang::ast_matchers;
19+
20+
namespace clang::tidy::misc {
21+
22+
void FixTypeConversionCheck::registerMatchers(MatchFinder *Finder) {
23+
24+
const auto rnStringTypeMatch = qualType(anyOf(asString("RNString"),
25+
asString("const RNString")));
26+
27+
28+
const auto cStringTypeMatch = qualType(anyOf(asString("CString"),
29+
asString("const CString")));
30+
31+
32+
Finder->addMatcher(
33+
declStmt(unless(isExpansionInSystemHeader()),
34+
has(varDecl(
35+
hasType(cStringTypeMatch),
36+
hasDescendant(
37+
cxxBindTemporaryExpr(
38+
hasType(rnStringTypeMatch),
39+
unless(hasAncestor(cxxMemberCallExpr(
40+
callee(cxxMethodDecl(hasName("GetString"))))))
41+
42+
)
43+
.bind("cxxBindTemporaryExpr"))))
44+
45+
)
46+
.bind("declStmt"),
47+
this);
48+
Finder->addMatcher(
49+
declStmt(
50+
unless(isExpansionInSystemHeader()),
51+
has(varDecl(hasType(rnStringTypeMatch),
52+
anyOf(hasDescendant(declRefExpr(hasType(cStringTypeMatch))
53+
.bind("declRefExpr")),
54+
hasDescendant(memberExpr(hasType(cStringTypeMatch))
55+
.bind("memberExpr"))))))
56+
.bind("declStmt"),
57+
this);
58+
}
59+
60+
void FixTypeConversionCheck::check(const MatchFinder::MatchResult &Result) {
61+
62+
const auto *Call =
63+
Result.Nodes.getNodeAs<CXXBindTemporaryExpr>("cxxBindTemporaryExpr");
64+
65+
if (Call) {
66+
67+
diag(Call->getEndLoc(),
68+
"Consider adding .GetString() to the CString object")
69+
<< FixItHint::CreateInsertion(Call->getEndLoc().getLocWithOffset(1),
70+
".GetString()");
71+
}
72+
73+
74+
const auto processExpr = [&](auto* expr){
75+
if(!expr)
76+
return;
77+
78+
const SourceManager &SM = *Result.SourceManager;
79+
const LangOptions &LangOpts = Result.Context->getLangOpts();
80+
81+
SourceLocation EndLoc =
82+
Lexer::getLocForEndOfToken(expr->getEndLoc(), 0, SM, LangOpts);
83+
84+
diag(expr->getEndLoc(), "Consider adding .GetString() call")
85+
<< FixItHint::CreateInsertion(EndLoc, ".GetString()");
86+
};
87+
88+
const auto *declRefExpr = Result.Nodes.getNodeAs<DeclRefExpr>("declRefExpr");
89+
processExpr(declRefExpr);
90+
91+
const auto *memberExpr = Result.Nodes.getNodeAs<MemberExpr>("memberExpr");
92+
processExpr(memberExpr);
93+
}
94+
95+
} // namespace clang::tidy::misc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===--- FixTypeConversionCheck.h - clang-tidy -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include "../ClangTidyCheck.h"
12+
13+
namespace clang::tidy::misc {
14+
15+
struct FixTypeConversionCheck : public ClangTidyCheck {
16+
FixTypeConversionCheck(StringRef Name, ClangTidyContext *Context)
17+
: ClangTidyCheck(Name, Context) {}
18+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
19+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
20+
};
21+
22+
} // namespace clang::tidy::misc

clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CoroutineHostileRAIICheck.h"
1515
#include "DefinitionsInHeadersCheck.h"
1616
#include "FixStdstringDataAccessCheck.h"
17+
#include "FixTypeConversionCheck.h"
1718
#include "HeaderIncludeCycleCheck.h"
1819
#include "IncludeCleanerCheck.h"
1920
#include "MisleadingBidirectional.h"
@@ -51,6 +52,8 @@ class MiscModule : public ClangTidyModule {
5152
"misc-definitions-in-headers");
5253
CheckFactories.registerCheck<FixStdstringDataAccessCheck>(
5354
"misc-fix-stdstring-data-access");
55+
CheckFactories.registerCheck<FixTypeConversionCheck>(
56+
"misc-fix-type-conversion");
5457
CheckFactories.registerCheck<HeaderIncludeCycleCheck>(
5558
"misc-header-include-cycle");
5659
CheckFactories.registerCheck<IncludeCleanerCheck>("misc-include-cleaner");

0 commit comments

Comments
 (0)