summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp47
-rw-r--r--clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp13
2 files changed, 50 insertions, 10 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp
index 9eea2f56d6d..8a2a053c4ae 100644
--- a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp
+++ b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp
@@ -28,7 +28,6 @@ SourceRange getTypeRange(const ParmVarDecl &Param) {
} // namespace
-
void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
const auto ConstParamDecl =
parmVarDecl(hasType(qualType(isConstQualified()))).bind("param");
@@ -38,16 +37,41 @@ void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
this);
}
+// Re-lex the tokens to get precise location of last 'const'
+static Token ConstTok(CharSourceRange Range,
+ const MatchFinder::MatchResult &Result) {
+ const SourceManager &Sources = *Result.SourceManager;
+ std::pair<FileID, unsigned> LocInfo =
+ Sources.getDecomposedLoc(Range.getBegin());
+ StringRef File = Sources.getBufferData(LocInfo.first);
+ const char *TokenBegin = File.data() + LocInfo.second;
+ Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
+ Result.Context->getLangOpts(), File.begin(), TokenBegin,
+ File.end());
+ Token Tok;
+ Token ConstTok;
+ while (!RawLexer.LexFromRawLexer(Tok)) {
+ if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
+ break;
+ if (Tok.is(tok::raw_identifier)) {
+ IdentifierInfo &Info = Result.Context->Idents.get(StringRef(
+ Sources.getCharacterData(Tok.getLocation()), Tok.getLength()));
+ Tok.setIdentifierInfo(&Info);
+ Tok.setKind(Info.getTokenID());
+ }
+ if (Tok.is(tok::kw_const))
+ ConstTok = Tok;
+ }
+ return ConstTok;
+}
+
void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param");
- QualType Type = Param->getType();
- if (!Type.isLocalConstQualified())
+ if (!Param->getType().isLocalConstQualified())
return;
- Type.removeLocalConst();
-
auto Diag = diag(Param->getLocStart(),
"parameter %0 is const-qualified in the function "
"declaration; const-qualification of parameters only has an "
@@ -62,8 +86,17 @@ void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
} else {
Diag << Param;
}
- Diag << FixItHint::CreateReplacement(getTypeRange(*Param),
- Type.getAsString());
+
+ CharSourceRange FileRange = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(getTypeRange(*Param)),
+ *Result.SourceManager, Result.Context->getLangOpts());
+
+ if (!FileRange.isValid())
+ return;
+
+ Token Tok = ConstTok(FileRange, Result);
+ Diag << FixItHint::CreateRemoval(
+ CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getLocation()));
}
} // namespace readability
diff --git a/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp b/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
index 4bf8456e142..aa70700c95b 100644
--- a/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
+++ b/clang-tools-extra/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
@@ -10,7 +10,7 @@ void F1(const int i);
void F2(const int *const i);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
-// CHECK-FIXES: void F2(const int * i);
+// CHECK-FIXES: void F2(const int *i);
void F3(int const i);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
@@ -26,7 +26,7 @@ void F5(const int);
void F6(const int *const);
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
-// BUG(b/27584482): void F6(const int *); should be produced
+// CHECK-FIXES: void F6(const int *);
void F7(int, const int);
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 2 is const-qualified
@@ -43,8 +43,15 @@ void F9(const int long_name);
void F10(const int *const *const long_name);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'long_name'
-// CHECK-FIXES: void F10(const int *const * long_name);
+// CHECK-FIXES: void F10(const int *const *long_name);
+void F11(const unsigned int /*v*/);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 1
+// CHECK-FIXES: void F11(unsigned int /*v*/);
+
+void F12(const bool b = true);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'b'
+// CHECK-FIXES: void F12(bool b = true);
struct Foo {
Foo(const int i);
OpenPOWER on IntegriCloud