comparison clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp @ 252:1f2b6ac9f198 llvm-original

LLVM16-1
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 18 Aug 2023 09:04:13 +0900
parents c4bab56944e8
children
comparison
equal deleted inserted replaced
237:c80f45b162ad 252:1f2b6ac9f198
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 8
9 #include "QualifiedAutoCheck.h" 9 #include "QualifiedAutoCheck.h"
10 #include "../utils/LexerUtils.h" 10 #include "../utils/LexerUtils.h"
11 #include "clang/ASTMatchers/ASTMatchers.h" 11 #include "clang/ASTMatchers/ASTMatchers.h"
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/SmallVector.h" 12 #include "llvm/ADT/SmallVector.h"
13 #include <optional>
14 14
15 using namespace clang::ast_matchers; 15 using namespace clang::ast_matchers;
16 16
17 namespace clang { 17 namespace clang::tidy::readability {
18 namespace tidy {
19 namespace readability {
20 18
21 namespace { 19 namespace {
22 20
23 // FIXME move to ASTMatchers 21 // FIXME move to ASTMatchers
24 AST_MATCHER_P(QualType, hasUnqualifiedType, 22 AST_MATCHER_P(QualType, hasUnqualifiedType,
26 return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder); 24 return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder);
27 } 25 }
28 26
29 enum class Qualifier { Const, Volatile, Restrict }; 27 enum class Qualifier { Const, Volatile, Restrict };
30 28
31 llvm::Optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual, 29 std::optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
32 const MatchFinder::MatchResult &Result) { 30 const MatchFinder::MatchResult &Result) {
33 // Since either of the locs can be in a macro, use `makeFileCharRange` to be 31 // Since either of the locs can be in a macro, use `makeFileCharRange` to be
34 // sure that we have a consistent `CharSourceRange`, located entirely in the 32 // sure that we have a consistent `CharSourceRange`, located entirely in the
35 // source file. 33 // source file.
36 34
37 assert((Qual == Qualifier::Const || Qual == Qualifier::Volatile || 35 assert((Qual == Qualifier::Const || Qual == Qualifier::Volatile ||
46 CharSourceRange FileRange = Lexer::makeFileCharRange( 44 CharSourceRange FileRange = Lexer::makeFileCharRange(
47 CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager, 45 CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager,
48 Result.Context->getLangOpts()); 46 Result.Context->getLangOpts());
49 47
50 if (FileRange.isInvalid()) 48 if (FileRange.isInvalid())
51 return llvm::None; 49 return std::nullopt;
52 50
53 tok::TokenKind Tok = 51 tok::TokenKind Tok =
54 Qual == Qualifier::Const 52 Qual == Qualifier::Const
55 ? tok::kw_const 53 ? tok::kw_const
56 : Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict; 54 : Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict;
57 55
58 return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context, 56 return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context,
59 *Result.SourceManager); 57 *Result.SourceManager);
60 } 58 }
61 59
62 llvm::Optional<SourceRange> 60 std::optional<SourceRange>
63 getTypeSpecifierLocation(const VarDecl *Var, 61 getTypeSpecifierLocation(const VarDecl *Var,
64 const MatchFinder::MatchResult &Result) { 62 const MatchFinder::MatchResult &Result) {
65 SourceRange TypeSpecifier( 63 SourceRange TypeSpecifier(
66 Var->getTypeSpecStartLoc(), 64 Var->getTypeSpecStartLoc(),
67 Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength( 65 Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength(
68 Var->getTypeSpecEndLoc(), *Result.SourceManager, 66 Var->getTypeSpecEndLoc(), *Result.SourceManager,
69 Result.Context->getLangOpts()))); 67 Result.Context->getLangOpts())));
70 68
71 if (TypeSpecifier.getBegin().isMacroID() || 69 if (TypeSpecifier.getBegin().isMacroID() ||
72 TypeSpecifier.getEnd().isMacroID()) 70 TypeSpecifier.getEnd().isMacroID())
73 return llvm::None; 71 return std::nullopt;
74 return TypeSpecifier; 72 return TypeSpecifier;
75 } 73 }
76 74
77 llvm::Optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier, 75 std::optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
78 const Token &ConstToken) { 76 const Token &ConstToken) {
79 if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) { 77 if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
80 TypeSpecifier.setBegin(ConstToken.getLocation()); 78 TypeSpecifier.setBegin(ConstToken.getLocation());
81 return llvm::None; 79 return std::nullopt;
82 } 80 }
83 if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) { 81 if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) {
84 TypeSpecifier.setEnd(ConstToken.getEndLoc()); 82 TypeSpecifier.setEnd(ConstToken.getEndLoc());
85 return llvm::None; 83 return std::nullopt;
86 } 84 }
87 return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc()); 85 return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
88 } 86 }
89 87
90 bool isPointerConst(QualType QType) { 88 bool isPointerConst(QualType QType) {
159 } 157 }
160 158
161 void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) { 159 void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
162 if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) { 160 if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
163 SourceRange TypeSpecifier; 161 SourceRange TypeSpecifier;
164 if (llvm::Optional<SourceRange> TypeSpec = 162 if (std::optional<SourceRange> TypeSpec =
165 getTypeSpecifierLocation(Var, Result)) { 163 getTypeSpecifierLocation(Var, Result)) {
166 TypeSpecifier = *TypeSpec; 164 TypeSpecifier = *TypeSpec;
167 } else 165 } else
168 return; 166 return;
169 167
170 llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange; 168 llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange;
171 auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) { 169 auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) {
172 if (IsPresent) { 170 if (IsPresent) {
173 llvm::Optional<Token> Token = findQualToken(Var, Qual, Result); 171 std::optional<Token> Token = findQualToken(Var, Qual, Result);
174 if (!Token || Token->getLocation().isMacroID()) 172 if (!Token || Token->getLocation().isMacroID())
175 return true; // Disregard this VarDecl. 173 return true; // Disregard this VarDecl.
176 if (llvm::Optional<SourceRange> Result = 174 if (std::optional<SourceRange> Result =
177 mergeReplacementRange(TypeSpecifier, *Token)) 175 mergeReplacementRange(TypeSpecifier, *Token))
178 RemoveQualifiersRange.push_back(*Result); 176 RemoveQualifiersRange.push_back(*Result);
179 } 177 }
180 return false; 178 return false;
181 }; 179 };
232 if (!isAutoPointerConst(Var->getType())) 230 if (!isAutoPointerConst(Var->getType()))
233 return; // Const isn't wrapped in the auto type, so must be declared 231 return; // Const isn't wrapped in the auto type, so must be declared
234 // explicitly. 232 // explicitly.
235 233
236 if (Var->getType().isLocalConstQualified()) { 234 if (Var->getType().isLocalConstQualified()) {
237 llvm::Optional<Token> Token = 235 std::optional<Token> Token = findQualToken(Var, Qualifier::Const, Result);
238 findQualToken(Var, Qualifier::Const, Result);
239 if (!Token || Token->getLocation().isMacroID()) 236 if (!Token || Token->getLocation().isMacroID())
240 return; 237 return;
241 } 238 }
242 if (Var->getType().isLocalVolatileQualified()) { 239 if (Var->getType().isLocalVolatileQualified()) {
243 llvm::Optional<Token> Token = 240 std::optional<Token> Token =
244 findQualToken(Var, Qualifier::Volatile, Result); 241 findQualToken(Var, Qualifier::Volatile, Result);
245 if (!Token || Token->getLocation().isMacroID()) 242 if (!Token || Token->getLocation().isMacroID())
246 return; 243 return;
247 } 244 }
248 if (Var->getType().isLocalRestrictQualified()) { 245 if (Var->getType().isLocalRestrictQualified()) {
249 llvm::Optional<Token> Token = 246 std::optional<Token> Token =
250 findQualToken(Var, Qualifier::Restrict, Result); 247 findQualToken(Var, Qualifier::Restrict, Result);
251 if (!Token || Token->getLocation().isMacroID()) 248 if (!Token || Token->getLocation().isMacroID())
252 return; 249 return;
253 } 250 }
254 251
255 if (llvm::Optional<SourceRange> TypeSpec = 252 if (std::optional<SourceRange> TypeSpec =
256 getTypeSpecifierLocation(Var, Result)) { 253 getTypeSpecifierLocation(Var, Result)) {
257 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() || 254 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
258 TypeSpec->getEnd().isMacroID()) 255 TypeSpec->getEnd().isMacroID())
259 return; 256 return;
260 SourceLocation InsertPos = TypeSpec->getBegin(); 257 SourceLocation InsertPos = TypeSpec->getBegin();
272 return; // Pointer isn't const, no need to add const qualifier. 269 return; // Pointer isn't const, no need to add const qualifier.
273 if (!isAutoPointerConst(Var->getType())) 270 if (!isAutoPointerConst(Var->getType()))
274 // Const isn't wrapped in the auto type, so must be declared explicitly. 271 // Const isn't wrapped in the auto type, so must be declared explicitly.
275 return; 272 return;
276 273
277 if (llvm::Optional<SourceRange> TypeSpec = 274 if (std::optional<SourceRange> TypeSpec =
278 getTypeSpecifierLocation(Var, Result)) { 275 getTypeSpecifierLocation(Var, Result)) {
279 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() || 276 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
280 TypeSpec->getEnd().isMacroID()) 277 TypeSpec->getEnd().isMacroID())
281 return; 278 return;
282 SourceLocation InsertPos = TypeSpec->getBegin(); 279 SourceLocation InsertPos = TypeSpec->getBegin();
285 } 282 }
286 return; 283 return;
287 } 284 }
288 } 285 }
289 286
290 } // namespace readability 287 } // namespace clang::tidy::readability
291 } // namespace tidy
292 } // namespace clang