annotate clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents 1f2b6ac9f198
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- QualifiedAutoCheck.cpp - clang-tidy ------------------------------===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "QualifiedAutoCheck.h"
anatofuz
parents:
diff changeset
10 #include "../utils/LexerUtils.h"
anatofuz
parents:
diff changeset
11 #include "clang/ASTMatchers/ASTMatchers.h"
anatofuz
parents:
diff changeset
12 #include "llvm/ADT/SmallVector.h"
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
13 #include <optional>
150
anatofuz
parents:
diff changeset
14
anatofuz
parents:
diff changeset
15 using namespace clang::ast_matchers;
anatofuz
parents:
diff changeset
16
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
17 namespace clang::tidy::readability {
150
anatofuz
parents:
diff changeset
18
anatofuz
parents:
diff changeset
19 namespace {
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 // FIXME move to ASTMatchers
anatofuz
parents:
diff changeset
22 AST_MATCHER_P(QualType, hasUnqualifiedType,
anatofuz
parents:
diff changeset
23 ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
anatofuz
parents:
diff changeset
24 return InnerMatcher.matches(Node.getUnqualifiedType(), Finder, Builder);
anatofuz
parents:
diff changeset
25 }
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 enum class Qualifier { Const, Volatile, Restrict };
anatofuz
parents:
diff changeset
28
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
29 std::optional<Token> findQualToken(const VarDecl *Decl, Qualifier Qual,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
30 const MatchFinder::MatchResult &Result) {
150
anatofuz
parents:
diff changeset
31 // Since either of the locs can be in a macro, use `makeFileCharRange` to be
anatofuz
parents:
diff changeset
32 // sure that we have a consistent `CharSourceRange`, located entirely in the
anatofuz
parents:
diff changeset
33 // source file.
anatofuz
parents:
diff changeset
34
anatofuz
parents:
diff changeset
35 assert((Qual == Qualifier::Const || Qual == Qualifier::Volatile ||
anatofuz
parents:
diff changeset
36 Qual == Qualifier::Restrict) &&
anatofuz
parents:
diff changeset
37 "Invalid Qualifier");
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 SourceLocation BeginLoc = Decl->getQualifierLoc().getBeginLoc();
anatofuz
parents:
diff changeset
40 if (BeginLoc.isInvalid())
anatofuz
parents:
diff changeset
41 BeginLoc = Decl->getBeginLoc();
anatofuz
parents:
diff changeset
42 SourceLocation EndLoc = Decl->getLocation();
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 CharSourceRange FileRange = Lexer::makeFileCharRange(
anatofuz
parents:
diff changeset
45 CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager,
anatofuz
parents:
diff changeset
46 Result.Context->getLangOpts());
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 if (FileRange.isInvalid())
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
49 return std::nullopt;
150
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 tok::TokenKind Tok =
anatofuz
parents:
diff changeset
52 Qual == Qualifier::Const
anatofuz
parents:
diff changeset
53 ? tok::kw_const
anatofuz
parents:
diff changeset
54 : Qual == Qualifier::Volatile ? tok::kw_volatile : tok::kw_restrict;
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context,
anatofuz
parents:
diff changeset
57 *Result.SourceManager);
anatofuz
parents:
diff changeset
58 }
anatofuz
parents:
diff changeset
59
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
60 std::optional<SourceRange>
150
anatofuz
parents:
diff changeset
61 getTypeSpecifierLocation(const VarDecl *Var,
anatofuz
parents:
diff changeset
62 const MatchFinder::MatchResult &Result) {
anatofuz
parents:
diff changeset
63 SourceRange TypeSpecifier(
anatofuz
parents:
diff changeset
64 Var->getTypeSpecStartLoc(),
anatofuz
parents:
diff changeset
65 Var->getTypeSpecEndLoc().getLocWithOffset(Lexer::MeasureTokenLength(
anatofuz
parents:
diff changeset
66 Var->getTypeSpecEndLoc(), *Result.SourceManager,
anatofuz
parents:
diff changeset
67 Result.Context->getLangOpts())));
anatofuz
parents:
diff changeset
68
anatofuz
parents:
diff changeset
69 if (TypeSpecifier.getBegin().isMacroID() ||
anatofuz
parents:
diff changeset
70 TypeSpecifier.getEnd().isMacroID())
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
71 return std::nullopt;
150
anatofuz
parents:
diff changeset
72 return TypeSpecifier;
anatofuz
parents:
diff changeset
73 }
anatofuz
parents:
diff changeset
74
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
75 std::optional<SourceRange> mergeReplacementRange(SourceRange &TypeSpecifier,
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
76 const Token &ConstToken) {
150
anatofuz
parents:
diff changeset
77 if (TypeSpecifier.getBegin().getLocWithOffset(-1) == ConstToken.getEndLoc()) {
anatofuz
parents:
diff changeset
78 TypeSpecifier.setBegin(ConstToken.getLocation());
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
79 return std::nullopt;
150
anatofuz
parents:
diff changeset
80 }
anatofuz
parents:
diff changeset
81 if (TypeSpecifier.getEnd().getLocWithOffset(1) == ConstToken.getLocation()) {
anatofuz
parents:
diff changeset
82 TypeSpecifier.setEnd(ConstToken.getEndLoc());
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
83 return std::nullopt;
150
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85 return SourceRange(ConstToken.getLocation(), ConstToken.getEndLoc());
anatofuz
parents:
diff changeset
86 }
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 bool isPointerConst(QualType QType) {
anatofuz
parents:
diff changeset
89 QualType Pointee = QType->getPointeeType();
anatofuz
parents:
diff changeset
90 assert(!Pointee.isNull() && "can't have a null Pointee");
anatofuz
parents:
diff changeset
91 return Pointee.isConstQualified();
anatofuz
parents:
diff changeset
92 }
anatofuz
parents:
diff changeset
93
anatofuz
parents:
diff changeset
94 bool isAutoPointerConst(QualType QType) {
anatofuz
parents:
diff changeset
95 QualType Pointee =
anatofuz
parents:
diff changeset
96 cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar();
anatofuz
parents:
diff changeset
97 assert(!Pointee.isNull() && "can't have a null Pointee");
anatofuz
parents:
diff changeset
98 return Pointee.isConstQualified();
anatofuz
parents:
diff changeset
99 }
anatofuz
parents:
diff changeset
100
anatofuz
parents:
diff changeset
101 } // namespace
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 void QualifiedAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
anatofuz
parents:
diff changeset
104 Options.store(Opts, "AddConstToQualified", AddConstToQualified);
anatofuz
parents:
diff changeset
105 }
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) {
anatofuz
parents:
diff changeset
108 auto ExplicitSingleVarDecl =
anatofuz
parents:
diff changeset
109 [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
anatofuz
parents:
diff changeset
110 llvm::StringRef ID) {
anatofuz
parents:
diff changeset
111 return declStmt(
anatofuz
parents:
diff changeset
112 unless(isInTemplateInstantiation()),
anatofuz
parents:
diff changeset
113 hasSingleDecl(
anatofuz
parents:
diff changeset
114 varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
anatofuz
parents:
diff changeset
115 };
anatofuz
parents:
diff changeset
116 auto ExplicitSingleVarDeclInTemplate =
anatofuz
parents:
diff changeset
117 [](const ast_matchers::internal::Matcher<VarDecl> &InnerMatcher,
anatofuz
parents:
diff changeset
118 llvm::StringRef ID) {
anatofuz
parents:
diff changeset
119 return declStmt(
anatofuz
parents:
diff changeset
120 isInTemplateInstantiation(),
anatofuz
parents:
diff changeset
121 hasSingleDecl(
anatofuz
parents:
diff changeset
122 varDecl(unless(isImplicit()), InnerMatcher).bind(ID)));
anatofuz
parents:
diff changeset
123 };
anatofuz
parents:
diff changeset
124
anatofuz
parents:
diff changeset
125 auto IsBoundToType = refersToType(equalsBoundNode("type"));
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
126 auto UnlessFunctionType = unless(hasUnqualifiedDesugaredType(functionType()));
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
127 auto IsAutoDeducedToPointer = [](const auto &...InnerMatchers) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
128 return autoType(hasDeducedType(
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
129 hasUnqualifiedDesugaredType(pointerType(pointee(InnerMatchers...)))));
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
130 };
150
anatofuz
parents:
diff changeset
131
anatofuz
parents:
diff changeset
132 Finder->addMatcher(
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
133 ExplicitSingleVarDecl(hasType(IsAutoDeducedToPointer(UnlessFunctionType)),
150
anatofuz
parents:
diff changeset
134 "auto"),
anatofuz
parents:
diff changeset
135 this);
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 Finder->addMatcher(
anatofuz
parents:
diff changeset
138 ExplicitSingleVarDeclInTemplate(
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
139 allOf(hasType(IsAutoDeducedToPointer(
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
140 hasUnqualifiedType(qualType().bind("type")),
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
141 UnlessFunctionType)),
150
anatofuz
parents:
diff changeset
142 anyOf(hasAncestor(
anatofuz
parents:
diff changeset
143 functionDecl(hasAnyTemplateArgument(IsBoundToType))),
anatofuz
parents:
diff changeset
144 hasAncestor(classTemplateSpecializationDecl(
anatofuz
parents:
diff changeset
145 hasAnyTemplateArgument(IsBoundToType))))),
anatofuz
parents:
diff changeset
146 "auto"),
anatofuz
parents:
diff changeset
147 this);
anatofuz
parents:
diff changeset
148 if (!AddConstToQualified)
anatofuz
parents:
diff changeset
149 return;
anatofuz
parents:
diff changeset
150 Finder->addMatcher(ExplicitSingleVarDecl(
anatofuz
parents:
diff changeset
151 hasType(pointerType(pointee(autoType()))), "auto_ptr"),
anatofuz
parents:
diff changeset
152 this);
anatofuz
parents:
diff changeset
153 Finder->addMatcher(
anatofuz
parents:
diff changeset
154 ExplicitSingleVarDecl(hasType(lValueReferenceType(pointee(autoType()))),
anatofuz
parents:
diff changeset
155 "auto_ref"),
anatofuz
parents:
diff changeset
156 this);
anatofuz
parents:
diff changeset
157 }
anatofuz
parents:
diff changeset
158
anatofuz
parents:
diff changeset
159 void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) {
anatofuz
parents:
diff changeset
160 if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto")) {
anatofuz
parents:
diff changeset
161 SourceRange TypeSpecifier;
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
162 if (std::optional<SourceRange> TypeSpec =
150
anatofuz
parents:
diff changeset
163 getTypeSpecifierLocation(Var, Result)) {
anatofuz
parents:
diff changeset
164 TypeSpecifier = *TypeSpec;
anatofuz
parents:
diff changeset
165 } else
anatofuz
parents:
diff changeset
166 return;
anatofuz
parents:
diff changeset
167
anatofuz
parents:
diff changeset
168 llvm::SmallVector<SourceRange, 4> RemoveQualifiersRange;
anatofuz
parents:
diff changeset
169 auto CheckQualifier = [&](bool IsPresent, Qualifier Qual) {
anatofuz
parents:
diff changeset
170 if (IsPresent) {
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
171 std::optional<Token> Token = findQualToken(Var, Qual, Result);
150
anatofuz
parents:
diff changeset
172 if (!Token || Token->getLocation().isMacroID())
anatofuz
parents:
diff changeset
173 return true; // Disregard this VarDecl.
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
174 if (std::optional<SourceRange> Result =
150
anatofuz
parents:
diff changeset
175 mergeReplacementRange(TypeSpecifier, *Token))
anatofuz
parents:
diff changeset
176 RemoveQualifiersRange.push_back(*Result);
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178 return false;
anatofuz
parents:
diff changeset
179 };
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 bool IsLocalConst = Var->getType().isLocalConstQualified();
anatofuz
parents:
diff changeset
182 bool IsLocalVolatile = Var->getType().isLocalVolatileQualified();
anatofuz
parents:
diff changeset
183 bool IsLocalRestrict = Var->getType().isLocalRestrictQualified();
anatofuz
parents:
diff changeset
184
anatofuz
parents:
diff changeset
185 if (CheckQualifier(IsLocalConst, Qualifier::Const) ||
anatofuz
parents:
diff changeset
186 CheckQualifier(IsLocalVolatile, Qualifier::Volatile) ||
anatofuz
parents:
diff changeset
187 CheckQualifier(IsLocalRestrict, Qualifier::Restrict))
anatofuz
parents:
diff changeset
188 return;
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 // Check for bridging the gap between the asterisk and name.
anatofuz
parents:
diff changeset
191 if (Var->getLocation() == TypeSpecifier.getEnd().getLocWithOffset(1))
anatofuz
parents:
diff changeset
192 TypeSpecifier.setEnd(TypeSpecifier.getEnd().getLocWithOffset(1));
anatofuz
parents:
diff changeset
193
anatofuz
parents:
diff changeset
194 CharSourceRange FixItRange = CharSourceRange::getCharRange(TypeSpecifier);
anatofuz
parents:
diff changeset
195 if (FixItRange.isInvalid())
anatofuz
parents:
diff changeset
196 return;
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 SourceLocation FixitLoc = FixItRange.getBegin();
anatofuz
parents:
diff changeset
199 for (SourceRange &Range : RemoveQualifiersRange) {
anatofuz
parents:
diff changeset
200 if (Range.getBegin() < FixitLoc)
anatofuz
parents:
diff changeset
201 FixitLoc = Range.getBegin();
anatofuz
parents:
diff changeset
202 }
anatofuz
parents:
diff changeset
203
anatofuz
parents:
diff changeset
204 std::string ReplStr = [&] {
anatofuz
parents:
diff changeset
205 llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : "";
anatofuz
parents:
diff changeset
206 llvm::StringRef LocalConst = IsLocalConst ? "const " : "";
anatofuz
parents:
diff changeset
207 llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : "";
anatofuz
parents:
diff changeset
208 llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : "";
anatofuz
parents:
diff changeset
209 return (PtrConst + "auto *" + LocalConst + LocalVol + LocalRestrict)
anatofuz
parents:
diff changeset
210 .str();
anatofuz
parents:
diff changeset
211 }();
anatofuz
parents:
diff changeset
212
anatofuz
parents:
diff changeset
213 DiagnosticBuilder Diag =
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
214 diag(FixitLoc,
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
215 "'%select{|const }0%select{|volatile }1%select{|__restrict }2auto "
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
216 "%3' can be declared as '%4%3'")
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
217 << IsLocalConst << IsLocalVolatile << IsLocalRestrict << Var->getName()
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
218 << ReplStr;
150
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 for (SourceRange &Range : RemoveQualifiersRange) {
anatofuz
parents:
diff changeset
221 Diag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(Range));
anatofuz
parents:
diff changeset
222 }
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 Diag << FixItHint::CreateReplacement(FixItRange, ReplStr);
anatofuz
parents:
diff changeset
225 return;
anatofuz
parents:
diff changeset
226 }
anatofuz
parents:
diff changeset
227 if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ptr")) {
anatofuz
parents:
diff changeset
228 if (!isPointerConst(Var->getType()))
anatofuz
parents:
diff changeset
229 return; // Pointer isn't const, no need to add const qualifier.
anatofuz
parents:
diff changeset
230 if (!isAutoPointerConst(Var->getType()))
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
231 return; // Const isn't wrapped in the auto type, so must be declared
150
anatofuz
parents:
diff changeset
232 // explicitly.
anatofuz
parents:
diff changeset
233
anatofuz
parents:
diff changeset
234 if (Var->getType().isLocalConstQualified()) {
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
235 std::optional<Token> Token = findQualToken(Var, Qualifier::Const, Result);
150
anatofuz
parents:
diff changeset
236 if (!Token || Token->getLocation().isMacroID())
anatofuz
parents:
diff changeset
237 return;
anatofuz
parents:
diff changeset
238 }
anatofuz
parents:
diff changeset
239 if (Var->getType().isLocalVolatileQualified()) {
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
240 std::optional<Token> Token =
150
anatofuz
parents:
diff changeset
241 findQualToken(Var, Qualifier::Volatile, Result);
anatofuz
parents:
diff changeset
242 if (!Token || Token->getLocation().isMacroID())
anatofuz
parents:
diff changeset
243 return;
anatofuz
parents:
diff changeset
244 }
anatofuz
parents:
diff changeset
245 if (Var->getType().isLocalRestrictQualified()) {
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
246 std::optional<Token> Token =
150
anatofuz
parents:
diff changeset
247 findQualToken(Var, Qualifier::Restrict, Result);
anatofuz
parents:
diff changeset
248 if (!Token || Token->getLocation().isMacroID())
anatofuz
parents:
diff changeset
249 return;
anatofuz
parents:
diff changeset
250 }
anatofuz
parents:
diff changeset
251
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
252 if (std::optional<SourceRange> TypeSpec =
150
anatofuz
parents:
diff changeset
253 getTypeSpecifierLocation(Var, Result)) {
anatofuz
parents:
diff changeset
254 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
anatofuz
parents:
diff changeset
255 TypeSpec->getEnd().isMacroID())
anatofuz
parents:
diff changeset
256 return;
anatofuz
parents:
diff changeset
257 SourceLocation InsertPos = TypeSpec->getBegin();
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
258 diag(InsertPos,
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
259 "'auto *%select{|const }0%select{|volatile }1%2' can be declared as "
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
260 "'const auto *%select{|const }0%select{|volatile }1%2'")
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
261 << Var->getType().isLocalConstQualified()
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
262 << Var->getType().isLocalVolatileQualified() << Var->getName()
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
263 << FixItHint::CreateInsertion(InsertPos, "const ");
150
anatofuz
parents:
diff changeset
264 }
anatofuz
parents:
diff changeset
265 return;
anatofuz
parents:
diff changeset
266 }
anatofuz
parents:
diff changeset
267 if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("auto_ref")) {
anatofuz
parents:
diff changeset
268 if (!isPointerConst(Var->getType()))
anatofuz
parents:
diff changeset
269 return; // Pointer isn't const, no need to add const qualifier.
anatofuz
parents:
diff changeset
270 if (!isAutoPointerConst(Var->getType()))
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
271 // Const isn't wrapped in the auto type, so must be declared explicitly.
150
anatofuz
parents:
diff changeset
272 return;
anatofuz
parents:
diff changeset
273
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
274 if (std::optional<SourceRange> TypeSpec =
150
anatofuz
parents:
diff changeset
275 getTypeSpecifierLocation(Var, Result)) {
anatofuz
parents:
diff changeset
276 if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() ||
anatofuz
parents:
diff changeset
277 TypeSpec->getEnd().isMacroID())
anatofuz
parents:
diff changeset
278 return;
anatofuz
parents:
diff changeset
279 SourceLocation InsertPos = TypeSpec->getBegin();
anatofuz
parents:
diff changeset
280 diag(InsertPos, "'auto &%0' can be declared as 'const auto &%0'")
anatofuz
parents:
diff changeset
281 << Var->getName() << FixItHint::CreateInsertion(InsertPos, "const ");
anatofuz
parents:
diff changeset
282 }
anatofuz
parents:
diff changeset
283 return;
anatofuz
parents:
diff changeset
284 }
anatofuz
parents:
diff changeset
285 }
anatofuz
parents:
diff changeset
286
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
287 } // namespace clang::tidy::readability