clang-tidy: [misc-use-override] Fix 'override' insertion.

Before:
  void f() __attribute__((override unused))

After:
  void f() override __attribute__((unused))

llvm-svn: 225519
This commit is contained in:
Daniel Jasper 2015-01-09 13:56:35 +00:00
parent 0fe3f4d731
commit e73cfbf6ba
2 changed files with 28 additions and 9 deletions

View File

@ -23,15 +23,16 @@ void UseOverride::registerMatchers(MatchFinder *Finder) {
// Re-lex the tokens to get precise locations to insert 'override' and remove // Re-lex the tokens to get precise locations to insert 'override' and remove
// 'virtual'. // 'virtual'.
static SmallVector<Token, 16> ParseTokens(CharSourceRange Range, static SmallVector<Token, 16>
const SourceManager &Sources, ParseTokens(CharSourceRange Range, const MatchFinder::MatchResult &Result) {
LangOptions LangOpts) { const SourceManager &Sources = *Result.SourceManager;
std::pair<FileID, unsigned> LocInfo = std::pair<FileID, unsigned> LocInfo =
Sources.getDecomposedLoc(Range.getBegin()); Sources.getDecomposedLoc(Range.getBegin());
StringRef File = Sources.getBufferData(LocInfo.first); StringRef File = Sources.getBufferData(LocInfo.first);
const char *TokenBegin = File.data() + LocInfo.second; const char *TokenBegin = File.data() + LocInfo.second;
Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first), LangOpts, Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
File.begin(), TokenBegin, File.end()); Result.Context->getLangOpts(), File.begin(), TokenBegin,
File.end());
SmallVector<Token, 16> Tokens; SmallVector<Token, 16> Tokens;
Token Tok; Token Tok;
while (!RawLexer.LexFromRawLexer(Tok)) { while (!RawLexer.LexFromRawLexer(Tok)) {
@ -39,6 +40,12 @@ static SmallVector<Token, 16> ParseTokens(CharSourceRange Range,
break; break;
if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation())) if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
break; 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());
}
Tokens.push_back(Tok); Tokens.push_back(Tok);
} }
return Tokens; return Tokens;
@ -87,18 +94,25 @@ void UseOverride::check(const MatchFinder::MatchResult &Result) {
// FIXME: Instead of re-lexing and looking for specific macros such as // FIXME: Instead of re-lexing and looking for specific macros such as
// 'ABSTRACT', properly store the location of 'virtual' and '= 0' in each // 'ABSTRACT', properly store the location of 'virtual' and '= 0' in each
// FunctionDecl. // FunctionDecl.
SmallVector<Token, 16> Tokens = ParseTokens(FileRange, Sources, SmallVector<Token, 16> Tokens = ParseTokens(FileRange, Result);
Result.Context->getLangOpts());
// Add 'override' on inline declarations that don't already have it. // Add 'override' on inline declarations that don't already have it.
if (!HasFinal && !HasOverride) { if (!HasFinal && !HasOverride) {
SourceLocation InsertLoc; SourceLocation InsertLoc;
StringRef ReplacementText = "override "; StringRef ReplacementText = "override ";
for (Token T : Tokens) {
if (T.is(tok::kw___attribute)) {
InsertLoc = T.getLocation();
break;
}
}
if (Method->hasAttrs()) { if (Method->hasAttrs()) {
for (const clang::Attr *A : Method->getAttrs()) { for (const clang::Attr *A : Method->getAttrs()) {
if (!A->isImplicit()) { if (!A->isImplicit()) {
SourceLocation Loc = Sources.getExpansionLoc(A->getLocation()); SourceLocation Loc =
Sources.getExpansionLoc(A->getRange().getBegin());
if (!InsertLoc.isValid() || if (!InsertLoc.isValid() ||
Sources.isBeforeInTranslationUnit(Loc, InsertLoc)) Sources.isBeforeInTranslationUnit(Loc, InsertLoc))
InsertLoc = Loc; InsertLoc = Loc;
@ -134,7 +148,7 @@ void UseOverride::check(const MatchFinder::MatchResult &Result) {
if (Method->isVirtualAsWritten()) { if (Method->isVirtualAsWritten()) {
for (Token Tok : Tokens) { for (Token Tok : Tokens) {
if (Tok.is(tok::raw_identifier) && GetText(Tok, Sources) == "virtual") { if (Tok.is(tok::kw_virtual)) {
Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(
Tok.getLocation(), Tok.getLocation())); Tok.getLocation(), Tok.getLocation()));
break; break;

View File

@ -29,6 +29,7 @@ struct Base {
virtual bool n() MUST_USE_RESULT UNUSED; virtual bool n() MUST_USE_RESULT UNUSED;
virtual void m(); virtual void m();
virtual void o() __attribute__((unused));
}; };
struct SimpleCases : public Base { struct SimpleCases : public Base {
@ -84,6 +85,10 @@ public:
virtual void m() override final; virtual void m() override final;
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Annotate this
// CHECK-FIXES: {{^ void m\(\) final;}} // CHECK-FIXES: {{^ void m\(\) final;}}
virtual void o() __attribute__((unused));
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: Prefer using
// CHECK-FIXES: {{^ void o\(\) override __attribute__\(\(unused\)\);}}
}; };
// CHECK-MESSAGES-NOT: warning: // CHECK-MESSAGES-NOT: warning: