Mercurial > hg > CbC > CbC_llvm
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 |