@@ -34,27 +34,6 @@ static bool isNoReturnCallStatement(const Stmt *S) {
34
34
return Func->isNoReturn ();
35
35
}
36
36
37
- static bool isLiteral (const Expr *E) {
38
- return isa<StringLiteral, CharacterLiteral, IntegerLiteral, FloatingLiteral,
39
- CXXBoolLiteralExpr, CXXNullPtrLiteralExpr>(E);
40
- }
41
-
42
- static bool isUnaryExprOfLiteral (const Expr *E) {
43
- if (const auto *UnOp = dyn_cast<UnaryOperator>(E))
44
- return isLiteral (UnOp->getSubExpr ());
45
- return false ;
46
- }
47
-
48
- static bool shouldBeDefaultMemberInitializer (const Expr *Value) {
49
- if (isLiteral (Value) || isUnaryExprOfLiteral (Value))
50
- return true ;
51
-
52
- if (const auto *DRE = dyn_cast<DeclRefExpr>(Value))
53
- return isa<EnumConstantDecl>(DRE->getDecl ());
54
-
55
- return false ;
56
- }
57
-
58
37
namespace {
59
38
60
39
AST_MATCHER_P (FieldDecl, indexNotLessThan, unsigned , Index) {
@@ -166,19 +145,7 @@ isAssignmentToMemberOf(const CXXRecordDecl *Rec, const Stmt *S,
166
145
167
146
PreferMemberInitializerCheck::PreferMemberInitializerCheck (
168
147
StringRef Name, ClangTidyContext *Context)
169
- : ClangTidyCheck(Name, Context),
170
- IsUseDefaultMemberInitEnabled (
171
- Context->isCheckEnabled (" modernize-use-default-member-init" )),
172
- UseAssignment(
173
- Options.get(" UseAssignment" ,
174
- OptionsView (" modernize-use-default-member-init" ,
175
- Context->getOptions ().CheckOptions, Context)
176
- .get(" UseAssignment" , false ))) {}
177
-
178
- void PreferMemberInitializerCheck::storeOptions (
179
- ClangTidyOptions::OptionMap &Opts) {
180
- Options.store (Opts, " UseAssignment" , UseAssignment);
181
- }
148
+ : ClangTidyCheck(Name, Context) {}
182
149
183
150
void PreferMemberInitializerCheck::registerMatchers (MatchFinder *Finder) {
184
151
Finder->addMatcher (cxxConstructorDecl (hasBody (compoundStmt ()),
@@ -230,139 +197,99 @@ void PreferMemberInitializerCheck::check(
230
197
updateAssignmentLevel (Field, InitValue, Ctor, AssignedFields);
231
198
if (!canAdvanceAssignment (AssignedFields[Field]))
232
199
continue ;
233
- const bool IsInDefaultMemberInitializer =
234
- IsUseDefaultMemberInitEnabled && getLangOpts ().CPlusPlus11 &&
235
- Ctor->isDefaultConstructor () &&
236
- (getLangOpts ().CPlusPlus20 || !Field->isBitField ()) &&
237
- !Field->hasInClassInitializer () &&
238
- (!isa<RecordDecl>(Class->getDeclContext ()) ||
239
- !cast<RecordDecl>(Class->getDeclContext ())->isUnion ()) &&
240
- shouldBeDefaultMemberInitializer (InitValue);
241
- if (IsInDefaultMemberInitializer) {
242
- bool InvalidFix = false ;
243
- SourceLocation FieldEnd =
244
- Lexer::getLocForEndOfToken (Field->getSourceRange ().getEnd (), 0 ,
245
- *Result.SourceManager , getLangOpts ());
246
- InvalidFix |= FieldEnd.isInvalid () || FieldEnd.isMacroID ();
247
- SourceLocation SemiColonEnd;
248
- if (auto NextToken = Lexer::findNextToken (
249
- S->getEndLoc (), *Result.SourceManager , getLangOpts ()))
250
- SemiColonEnd = NextToken->getEndLoc ();
251
- else
252
- InvalidFix = true ;
253
- auto Diag =
254
- diag (S->getBeginLoc (), " %0 should be initialized in an in-class"
255
- " default member initializer" )
256
- << Field;
257
- if (InvalidFix)
258
- continue ;
259
- CharSourceRange StmtRange =
260
- CharSourceRange::getCharRange (S->getBeginLoc (), SemiColonEnd);
261
200
262
- SmallString<128 > Insertion (
263
- {UseAssignment ? " = " : " {" ,
264
- Lexer::getSourceText (Result.SourceManager ->getExpansionRange (
265
- InitValue->getSourceRange ()),
266
- *Result.SourceManager , getLangOpts ()),
267
- UseAssignment ? " " : " }" });
268
-
269
- Diag << FixItHint::CreateInsertion (FieldEnd, Insertion)
270
- << FixItHint::CreateRemoval (StmtRange);
271
-
272
- } else {
273
- StringRef InsertPrefix = " " ;
274
- bool HasInitAlready = false ;
275
- SourceLocation InsertPos;
276
- SourceRange ReplaceRange;
277
- bool AddComma = false ;
278
- bool InvalidFix = false ;
279
- unsigned Index = Field->getFieldIndex ();
280
- const CXXCtorInitializer *LastInListInit = nullptr ;
281
- for (const CXXCtorInitializer *Init : Ctor->inits ()) {
282
- if (!Init->isWritten () || Init->isInClassMemberInitializer ())
283
- continue ;
284
- if (Init->getMember () == Field) {
285
- HasInitAlready = true ;
286
- if (isa<ImplicitValueInitExpr>(Init->getInit ()))
287
- InsertPos = Init->getRParenLoc ();
288
- else {
289
- ReplaceRange = Init->getInit ()->getSourceRange ();
290
- }
291
- break ;
292
- }
293
- if (Init->isMemberInitializer () &&
294
- Index < Init->getMember ()->getFieldIndex ()) {
295
- InsertPos = Init->getSourceLocation ();
296
- // There are initializers after the one we are inserting, so add a
297
- // comma after this insertion in order to not break anything.
298
- AddComma = true ;
299
- break ;
201
+ StringRef InsertPrefix = " " ;
202
+ bool HasInitAlready = false ;
203
+ SourceLocation InsertPos;
204
+ SourceRange ReplaceRange;
205
+ bool AddComma = false ;
206
+ bool InvalidFix = false ;
207
+ unsigned Index = Field->getFieldIndex ();
208
+ const CXXCtorInitializer *LastInListInit = nullptr ;
209
+ for (const CXXCtorInitializer *Init : Ctor->inits ()) {
210
+ if (!Init->isWritten () || Init->isInClassMemberInitializer ())
211
+ continue ;
212
+ if (Init->getMember () == Field) {
213
+ HasInitAlready = true ;
214
+ if (isa<ImplicitValueInitExpr>(Init->getInit ()))
215
+ InsertPos = Init->getRParenLoc ();
216
+ else {
217
+ ReplaceRange = Init->getInit ()->getSourceRange ();
300
218
}
301
- LastInListInit = Init ;
219
+ break ;
302
220
}
303
- if (HasInitAlready) {
304
- if (InsertPos.isValid ())
305
- InvalidFix |= InsertPos.isMacroID ();
306
- else
307
- InvalidFix |= ReplaceRange.getBegin ().isMacroID () ||
308
- ReplaceRange.getEnd ().isMacroID ();
309
- } else {
310
- if (InsertPos.isInvalid ()) {
311
- if (LastInListInit) {
312
- InsertPos = Lexer::getLocForEndOfToken (
313
- LastInListInit->getRParenLoc (), 0 , *Result.SourceManager ,
314
- getLangOpts ());
315
- // Inserting after the last constructor initializer, so we need a
316
- // comma.
317
- InsertPrefix = " , " ;
318
- } else {
319
- InsertPos = Lexer::getLocForEndOfToken (
320
- Ctor->getTypeSourceInfo ()
321
- ->getTypeLoc ()
322
- .getAs <clang::FunctionTypeLoc>()
323
- .getLocalRangeEnd (),
324
- 0 , *Result.SourceManager , getLangOpts ());
325
-
326
- // If this is first time in the loop, there are no initializers so
327
- // `:` declares member initialization list. If this is a
328
- // subsequent pass then we have already inserted a `:` so continue
329
- // with a comma.
330
- InsertPrefix = FirstToCtorInits ? " : " : " , " ;
331
- }
332
- }
221
+ if (Init->isMemberInitializer () &&
222
+ Index < Init->getMember ()->getFieldIndex ()) {
223
+ InsertPos = Init->getSourceLocation ();
224
+ // There are initializers after the one we are inserting, so add a
225
+ // comma after this insertion in order to not break anything.
226
+ AddComma = true ;
227
+ break ;
228
+ }
229
+ LastInListInit = Init;
230
+ }
231
+ if (HasInitAlready) {
232
+ if (InsertPos.isValid ())
333
233
InvalidFix |= InsertPos.isMacroID ();
234
+ else
235
+ InvalidFix |= ReplaceRange.getBegin ().isMacroID () ||
236
+ ReplaceRange.getEnd ().isMacroID ();
237
+ } else {
238
+ if (InsertPos.isInvalid ()) {
239
+ if (LastInListInit) {
240
+ InsertPos =
241
+ Lexer::getLocForEndOfToken (LastInListInit->getRParenLoc (), 0 ,
242
+ *Result.SourceManager , getLangOpts ());
243
+ // Inserting after the last constructor initializer, so we need a
244
+ // comma.
245
+ InsertPrefix = " , " ;
246
+ } else {
247
+ InsertPos = Lexer::getLocForEndOfToken (
248
+ Ctor->getTypeSourceInfo ()
249
+ ->getTypeLoc ()
250
+ .getAs <clang::FunctionTypeLoc>()
251
+ .getLocalRangeEnd (),
252
+ 0 , *Result.SourceManager , getLangOpts ());
253
+
254
+ // If this is first time in the loop, there are no initializers so
255
+ // `:` declares member initialization list. If this is a
256
+ // subsequent pass then we have already inserted a `:` so continue
257
+ // with a comma.
258
+ InsertPrefix = FirstToCtorInits ? " : " : " , " ;
259
+ }
334
260
}
261
+ InvalidFix |= InsertPos.isMacroID ();
262
+ }
335
263
336
- SourceLocation SemiColonEnd;
337
- if (auto NextToken = Lexer::findNextToken (
338
- S->getEndLoc (), *Result.SourceManager , getLangOpts ()))
339
- SemiColonEnd = NextToken->getEndLoc ();
264
+ SourceLocation SemiColonEnd;
265
+ if (auto NextToken = Lexer::findNextToken (
266
+ S->getEndLoc (), *Result.SourceManager , getLangOpts ()))
267
+ SemiColonEnd = NextToken->getEndLoc ();
268
+ else
269
+ InvalidFix = true ;
270
+
271
+ auto Diag = diag (S->getBeginLoc (), " %0 should be initialized in a member"
272
+ " initializer of the constructor" )
273
+ << Field;
274
+ if (InvalidFix)
275
+ continue ;
276
+ StringRef NewInit = Lexer::getSourceText (
277
+ Result.SourceManager ->getExpansionRange (InitValue->getSourceRange ()),
278
+ *Result.SourceManager , getLangOpts ());
279
+ if (HasInitAlready) {
280
+ if (InsertPos.isValid ())
281
+ Diag << FixItHint::CreateInsertion (InsertPos, NewInit);
340
282
else
341
- InvalidFix = true ;
342
-
343
- auto Diag = diag (S->getBeginLoc (), " %0 should be initialized in a member"
344
- " initializer of the constructor" )
345
- << Field;
346
- if (InvalidFix)
347
- continue ;
348
- StringRef NewInit = Lexer::getSourceText (
349
- Result.SourceManager ->getExpansionRange (InitValue->getSourceRange ()),
350
- *Result.SourceManager , getLangOpts ());
351
- if (HasInitAlready) {
352
- if (InsertPos.isValid ())
353
- Diag << FixItHint::CreateInsertion (InsertPos, NewInit);
354
- else
355
- Diag << FixItHint::CreateReplacement (ReplaceRange, NewInit);
356
- } else {
357
- SmallString<128 > Insertion ({InsertPrefix, Field->getName (), " (" ,
358
- NewInit, AddComma ? " ), " : " )" });
359
- Diag << FixItHint::CreateInsertion (InsertPos, Insertion,
360
- FirstToCtorInits);
361
- FirstToCtorInits = areDiagsSelfContained ();
362
- }
363
- Diag << FixItHint::CreateRemoval (
364
- CharSourceRange::getCharRange (S->getBeginLoc (), SemiColonEnd));
283
+ Diag << FixItHint::CreateReplacement (ReplaceRange, NewInit);
284
+ } else {
285
+ SmallString<128 > Insertion ({InsertPrefix, Field->getName (), " (" , NewInit,
286
+ AddComma ? " ), " : " )" });
287
+ Diag << FixItHint::CreateInsertion (InsertPos, Insertion,
288
+ FirstToCtorInits);
289
+ FirstToCtorInits = areDiagsSelfContained ();
365
290
}
291
+ Diag << FixItHint::CreateRemoval (
292
+ CharSourceRange::getCharRange (S->getBeginLoc (), SemiColonEnd));
366
293
}
367
294
}
368
295
0 commit comments