ilya created this revision.
Herald added subscribers: cfe-commits, xazax.hun.
Herald added a project: clang.

Replace tidy::utils::lexer::getConstQualifyingToken with a corrected and also
generalized to other qualifiers variant - getQualifyingToken.

Fixes: http://llvm.org/PR44326


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71666

Files:
  clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
  clang-tools-extra/clang-tidy/utils/LexerUtils.h
  clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-const-return-type.cpp
@@ -37,6 +37,9 @@
 template <typename T>
 typename std::add_const<T>::type n15(T v) { return v; }
 
+template <bool B>
+struct MyStruct {};
+
 template <typename A>
 class Klazz {
 public:
@@ -128,10 +131,46 @@
 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int>'
 // CHECK-FIXES: Klazz<const int> p12() {}
 
+const Klazz<const Klazz<const int>> p33() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<
+// CHECK-FIXES: Klazz<const Klazz<const int>> p33() {}
+
 const Klazz<const int>* const p13() {}
 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
 // CHECK-FIXES: const Klazz<const int>* p13() {}
 
+const Klazz<const int>* const volatile p14() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const int> *
+// CHECK-FIXES: const Klazz<const int>* volatile p14() {}
+
+const MyStruct<0 < 1> p34() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const MyStruct<0 < 1>'
+// CHECK-FIXES: MyStruct<0 < 1> p34() {}
+
+MyStruct<0 < 1> const p35() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const MyStruct<0 < 1>'
+// CHECK-FIXES: MyStruct<0 < 1> p35() {}
+
+Klazz<MyStruct<0 < 1> const> const p36() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
+// CHECK-FIXES: Klazz<MyStruct<0 < 1> const> p36() {}
+
+const Klazz<MyStruct<0 < 1> const> *const p37() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
+// CHECK-FIXES: const Klazz<MyStruct<0 < 1> const> *p37() {}
+
+Klazz<const MyStruct<0 < 1>> const p38() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
+// CHECK-FIXES: Klazz<const MyStruct<0 < 1>> p38() {}
+
+const Klazz<const MyStruct<0 < 1>> p39() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<
+// CHECK-FIXES: Klazz<const MyStruct<0 < 1>> p39() {}
+
+const Klazz<const MyStruct<(0 > 1)>> p40() {}
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: return type 'const Klazz<const MyStru
+// CHECK-FIXES: Klazz<const MyStruct<(0 > 1)>> p40() {}
+
 // re-declaration of p15.
 const int p15();
 // CHECK-FIXES: int p15();
Index: clang-tools-extra/clang-tidy/utils/LexerUtils.h
===================================================================
--- clang-tools-extra/clang-tidy/utils/LexerUtils.h
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.h
@@ -96,9 +96,14 @@
 /// token in ``Range`` that is responsible for const qualification. ``Range``
 /// must be valid with respect to ``SM``.  Returns ``None`` if no ``const``
 /// tokens are found.
-llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range,
-                                              const ASTContext &Context,
-                                              const SourceManager &SM);
+///
+/// Similar to ``getConstQualifyingToken`` above, but generalized to any
+/// of the following qualifier tokens: kw_const, kw_volatile, kw_restrict,
+/// kw___cm, kw___lpm.
+llvm::Optional<Token> getQualifyingToken(tok::TokenKind TK,
+                                         CharSourceRange Range,
+                                         const ASTContext &Context,
+                                         const SourceManager &SM);
 
 } // namespace lexer
 } // namespace utils
Index: clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
===================================================================
--- clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
+++ clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
@@ -102,15 +102,20 @@
   return false;
 }
 
-llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range,
-                                              const ASTContext &Context,
-                                              const SourceManager &SM) {
+llvm::Optional<Token> getQualifyingToken(tok::TokenKind TK,
+                                         CharSourceRange Range,
+                                         const ASTContext &Context,
+                                         const SourceManager &SM) {
+  assert((TK == tok::kw_const || TK == tok::kw_volatile ||
+          TK == tok::kw_restrict) &&
+         "TK is not a qualifier keyword");
   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getBegin());
   StringRef File = SM.getBufferData(LocInfo.first);
   Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
                  File.begin(), File.data() + LocInfo.second, File.end());
-  llvm::Optional<Token> FirstConstTok;
-  Token LastTokInRange;
+  llvm::Optional<Token> LastMatchBeforeTemplate;
+  llvm::Optional<Token> LastMatchAfterTemplate;
+  bool SawTemplate = false;
   Token Tok;
   while (!RawLexer.LexFromRawLexer(Tok) &&
          Range.getEnd() != Tok.getLocation() &&
@@ -121,13 +126,19 @@
       Tok.setIdentifierInfo(&Info);
       Tok.setKind(Info.getTokenID());
     }
-    if (Tok.is(tok::kw_const) && !FirstConstTok)
-      FirstConstTok = Tok;
-    LastTokInRange = Tok;
+    if (Tok.is(tok::less))
+      SawTemplate = true;
+    else if (Tok.isOneOf(tok::greater, tok::greatergreater))
+      LastMatchAfterTemplate = None;
+    else if (Tok.is(TK)) {
+      if (SawTemplate)
+        LastMatchAfterTemplate = Tok;
+      else
+        LastMatchBeforeTemplate = Tok;
+    }
   }
-  // If the last token in the range is a `const`, then it const qualifies the
-  // type.  Otherwise, the first `const` token, if any, is the qualifier.
-  return LastTokInRange.is(tok::kw_const) ? LastTokInRange : FirstConstTok;
+  return LastMatchAfterTemplate != None ? LastMatchAfterTemplate
+                                        : LastMatchBeforeTemplate;
 }
 } // namespace lexer
 } // namespace utils
Index: clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp
@@ -47,8 +47,8 @@
   if (FileRange.isInvalid())
     return None;
 
-  return utils::lexer::getConstQualifyingToken(FileRange, *Result.Context,
-                                               *Result.SourceManager);
+  return utils::lexer::getQualifyingToken(
+      tok::kw_const, FileRange, *Result.Context, *Result.SourceManager);
 }
 
 namespace {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to