summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp59
1 files changed, 38 insertions, 21 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
index 55a518c1aec..de525926c89 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
@@ -25,9 +25,10 @@ void UseUsingCheck::registerMatchers(MatchFinder *Finder) {
// Checks if 'typedef' keyword can be removed - we do it only if
// it is the only declaration in a declaration chain.
-static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart,
- const SourceLocation &LocEnd, ASTContext &Context) {
- std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(LocStart);
+static bool CheckRemoval(SourceManager &SM, SourceLocation StartLoc,
+ ASTContext &Context) {
+ assert(StartLoc.isFileID() && "StartLoc must not be in a macro");
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(StartLoc);
StringRef File = SM.getBufferData(LocInfo.first);
const char *TokenBegin = File.data() + LocInfo.second;
Lexer DeclLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
@@ -35,28 +36,39 @@ static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart,
Token Tok;
int ParenLevel = 0;
+ bool FoundTypedef = false;
- while (!DeclLexer.LexFromRawLexer(Tok)) {
- if (SM.isBeforeInTranslationUnit(LocEnd, Tok.getLocation()))
- break;
- if (Tok.getKind() == tok::TokenKind::l_paren)
+ while (!DeclLexer.LexFromRawLexer(Tok) && !Tok.is(tok::semi)) {
+ switch (Tok.getKind()) {
+ case tok::l_brace:
+ case tok::r_brace:
+ // This might be the `typedef struct {...} T;` case.
+ return false;
+ case tok::l_paren:
ParenLevel++;
- if (Tok.getKind() == tok::TokenKind::r_paren)
+ break;
+ case tok::r_paren:
ParenLevel--;
- if (Tok.getKind() == tok::TokenKind::semi)
break;
- // if there is comma and we are not between open parenthesis then it is
- // two or more declatarions in this chain
- if (ParenLevel == 0 && Tok.getKind() == tok::TokenKind::comma)
- return false;
-
- if (Tok.is(tok::TokenKind::raw_identifier)) {
- if (Tok.getRawIdentifier() == "typedef")
- return true;
+ case tok::comma:
+ if (ParenLevel == 0) {
+ // If there is comma and we are not between open parenthesis then it is
+ // two or more declarations in this chain.
+ return false;
+ }
+ break;
+ case tok::raw_identifier:
+ if (Tok.getRawIdentifier() == "typedef") {
+ FoundTypedef = true;
+ }
+ break;
+ default:
+ break;
}
}
- return false;
+ // Sanity check against weird macro cases.
+ return FoundTypedef;
}
void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
@@ -67,14 +79,19 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
auto &Context = *Result.Context;
auto &SM = *Result.SourceManager;
+ if (auto *D = MatchedDecl->getUnderlyingType()->getAsCXXRecordDecl()) {
+ //TypeLoc TL = MatchedDecl->getTypeSourceInfo()->getTypeLoc();
+ llvm::errs() << D->getNameAsString() << "\n";
+ }
+
auto Diag =
diag(MatchedDecl->getLocStart(), "use 'using' instead of 'typedef'");
- if (MatchedDecl->getLocStart().isMacroID())
+ SourceLocation StartLoc = MatchedDecl->getLocStart();
+ if (StartLoc.isMacroID())
return;
- if (CheckRemoval(SM, MatchedDecl->getLocStart(), MatchedDecl->getLocEnd(),
- Context)) {
+ if (CheckRemoval(SM, StartLoc, Context)) {
Diag << FixItHint::CreateReplacement(
MatchedDecl->getSourceRange(),
"using " + MatchedDecl->getNameAsString() + " = " +
OpenPOWER on IntegriCloud