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:
parent
0fe3f4d731
commit
e73cfbf6ba
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue