[clang-tidy] fix readability-avoid-const-params-in-decls creating invalid code in fix-its

Summary:
The Fix-Its for the added test cases were before:
-void F11(const unsigned int /*version*/);
+void F11(unsigned int int /*version*/);

-void F12(const bool b = true);
+void F12(_Bool true);

Reviewers: fowles, hokein, sbenza, alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D18993

llvm-svn: 266044
This commit is contained in:
Matthias Gehre 2016-04-12 05:45:13 +00:00
parent c27d8d8fd8
commit 018c1d4243
2 changed files with 50 additions and 10 deletions

View File

@ -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

View File

@ -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);