diff options
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp')
| -rw-r--r-- | clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp index 197befa4f4f..b93aee927d3 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverrideActions.cpp @@ -26,16 +26,41 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +namespace { + +SourceLocation +backwardSkipWhitespacesAndComments(const SourceManager &SM, + const clang::ASTContext &Context, + SourceLocation Loc) { + for (;;) { + do { + Loc = Loc.getLocWithOffset(-1); + } while (isWhitespace(*FullSourceLoc(Loc, SM).getCharacterData())); + + Token Tok; + SourceLocation Beginning = + Lexer::GetBeginningOfToken(Loc, SM, Context.getLangOpts()); + const bool Invalid = + Lexer::getRawToken(Beginning, Tok, SM, Context.getLangOpts()); + + assert(!Invalid && "Expected a valid token."); + if (Invalid || Tok.getKind() != tok::comment) + return Loc.getLocWithOffset(1); + } +} + +} // end anonymous namespace + void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) { SourceManager &SM = *Result.SourceManager; const CXXMethodDecl *M = Result.Nodes.getDeclAs<CXXMethodDecl>(MethodId); assert(M && "Bad Callback. No node provided"); - // Check that the method declaration in the main file - if (!SM.isFromMainFile(M->getLocStart())) - return; + if (const FunctionDecl *TemplateMethod = M->getTemplateInstantiationPattern()) + M = cast<CXXMethodDecl>(TemplateMethod); + // Check that the method declaration is in the main file if (!SM.isFromMainFile(M->getLocStart())) return; @@ -48,24 +73,14 @@ void AddOverrideFixer::run(const MatchFinder::MatchResult &Result) { if (M->isPure()) return; - if (const FunctionDecl *TemplateMethod = M->getTemplateInstantiationPattern()) - M = cast<CXXMethodDecl>(TemplateMethod); - if (M->getParent()->hasAnyDependentBases()) return; SourceLocation StartLoc; if (M->hasInlineBody()) { - // Start at the beginning of the body and rewind back to the last - // non-whitespace character. We will insert the override keyword - // after that character. - // FIXME: This transform won't work if there is a comment between - // the end of the function prototype and the start of the body. - StartLoc = M->getBody()->getLocStart(); - do { - StartLoc = StartLoc.getLocWithOffset(-1); - } while (isWhitespace(*FullSourceLoc(StartLoc, SM).getCharacterData())); - StartLoc = StartLoc.getLocWithOffset(1); + // Insert the override specifier before the function body. + StartLoc = backwardSkipWhitespacesAndComments(SM, *Result.Context, + M->getBody()->getLocStart()); } else { StartLoc = SM.getSpellingLoc(M->getLocEnd()); StartLoc = Lexer::getLocForEndOfToken(StartLoc, 0, SM, LangOptions()); |

