Skip to content

Commit 2789043

Browse files
committedFeb 15, 2017
[clang-tidy] Add check 'modernize-return-braced-init-list'
Summary: Replaces explicit calls to the constructor in a return with a braced initializer list. This way the return type is not needlessly duplicated in the return type and the return statement. ``` Foo bar() { Baz baz; return Foo(baz); } // transforms to: Foo bar() { Baz baz; return {baz}; } ``` Reviewers: hokein, Prazek, aaron.ballman, alexfh Reviewed By: Prazek, aaron.ballman, alexfh Subscribers: malcolm.parsons, mgorny, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D28768 llvm-svn: 295199
1 parent 0ac6d12 commit 2789043

File tree

8 files changed

+365
-0
lines changed

8 files changed

+365
-0
lines changed
 

‎clang-tools-extra/clang-tidy/modernize/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_clang_library(clangTidyModernizeModule
1313
RawStringLiteralCheck.cpp
1414
RedundantVoidArgCheck.cpp
1515
ReplaceAutoPtrCheck.cpp
16+
ReturnBracedInitListCheck.cpp
1617
ShrinkToFitCheck.cpp
1718
UseAutoCheck.cpp
1819
UseBoolLiteralsCheck.cpp

‎clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "RawStringLiteralCheck.h"
2020
#include "RedundantVoidArgCheck.h"
2121
#include "ReplaceAutoPtrCheck.h"
22+
#include "ReturnBracedInitListCheck.h"
2223
#include "ShrinkToFitCheck.h"
2324
#include "UseAutoCheck.h"
2425
#include "UseBoolLiteralsCheck.h"
@@ -53,6 +54,8 @@ class ModernizeModule : public ClangTidyModule {
5354
"modernize-redundant-void-arg");
5455
CheckFactories.registerCheck<ReplaceAutoPtrCheck>(
5556
"modernize-replace-auto-ptr");
57+
CheckFactories.registerCheck<ReturnBracedInitListCheck>(
58+
"modernize-return-braced-init-list");
5659
CheckFactories.registerCheck<ShrinkToFitCheck>("modernize-shrink-to-fit");
5760
CheckFactories.registerCheck<UseAutoCheck>("modernize-use-auto");
5861
CheckFactories.registerCheck<UseBoolLiteralsCheck>(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- ReturnBracedInitListCheck.cpp - clang-tidy------------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "ReturnBracedInitListCheck.h"
11+
#include "clang/AST/ASTContext.h"
12+
#include "clang/ASTMatchers/ASTMatchFinder.h"
13+
#include "clang/Lex/Lexer.h"
14+
#include "clang/Tooling/FixIt.h"
15+
16+
using namespace clang::ast_matchers;
17+
18+
namespace clang {
19+
namespace tidy {
20+
namespace modernize {
21+
22+
void ReturnBracedInitListCheck::registerMatchers(MatchFinder *Finder) {
23+
// Only register the matchers for C++.
24+
if (!getLangOpts().CPlusPlus11)
25+
return;
26+
27+
// Skip list initialization and constructors with an initializer list.
28+
auto ConstructExpr =
29+
cxxConstructExpr(
30+
unless(anyOf(hasDeclaration(cxxConstructorDecl(isExplicit())),
31+
isListInitialization(), hasDescendant(initListExpr()),
32+
isInTemplateInstantiation())))
33+
.bind("ctor");
34+
35+
auto CtorAsArgument = materializeTemporaryExpr(anyOf(
36+
has(ConstructExpr), has(cxxFunctionalCastExpr(has(ConstructExpr)))));
37+
38+
Finder->addMatcher(
39+
functionDecl(isDefinition(), // Declarations don't have return statements.
40+
returns(unless(anyOf(builtinType(), autoType()))),
41+
hasDescendant(returnStmt(hasReturnValue(
42+
has(cxxConstructExpr(has(CtorAsArgument)))))))
43+
.bind("fn"),
44+
this);
45+
}
46+
47+
void ReturnBracedInitListCheck::check(const MatchFinder::MatchResult &Result) {
48+
const auto *MatchedFunctionDecl = Result.Nodes.getNodeAs<FunctionDecl>("fn");
49+
const auto *MatchedConstructExpr =
50+
Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");
51+
52+
// Don't make replacements in macro.
53+
SourceLocation Loc = MatchedConstructExpr->getExprLoc();
54+
if (Loc.isMacroID())
55+
return;
56+
57+
// Make sure that the return type matches the constructed type.
58+
const QualType ReturnType =
59+
MatchedFunctionDecl->getReturnType().getCanonicalType();
60+
const QualType ConstructType =
61+
MatchedConstructExpr->getType().getCanonicalType();
62+
if (ReturnType != ConstructType)
63+
return;
64+
65+
auto Diag = diag(Loc, "avoid repeating the return type from the "
66+
"declaration; use a braced initializer list instead");
67+
68+
const SourceRange CallParensRange =
69+
MatchedConstructExpr->getParenOrBraceRange();
70+
71+
// Make sure there is an explicit constructor call.
72+
if (CallParensRange.isInvalid())
73+
return;
74+
75+
// Make sure that the ctor arguments match the declaration.
76+
for (unsigned I = 0, NumParams = MatchedConstructExpr->getNumArgs();
77+
I < NumParams; ++I) {
78+
if (const auto *VD = dyn_cast<VarDecl>(
79+
MatchedConstructExpr->getConstructor()->getParamDecl(I))) {
80+
if (MatchedConstructExpr->getArg(I)->getType().getCanonicalType() !=
81+
VD->getType().getCanonicalType())
82+
return;
83+
}
84+
}
85+
86+
// Range for constructor name and opening brace.
87+
CharSourceRange CtorCallSourceRange = CharSourceRange::getTokenRange(
88+
Loc, CallParensRange.getBegin().getLocWithOffset(-1));
89+
90+
Diag << FixItHint::CreateRemoval(CtorCallSourceRange)
91+
<< FixItHint::CreateReplacement(CallParensRange.getBegin(), "{")
92+
<< FixItHint::CreateReplacement(CallParensRange.getEnd(), "}");
93+
}
94+
95+
} // namespace modernize
96+
} // namespace tidy
97+
} // namespace clang
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===--- ReturnBracedInitListCheck.h - clang-tidy----------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H
11+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H
12+
13+
#include "../ClangTidy.h"
14+
15+
namespace clang {
16+
namespace tidy {
17+
namespace modernize {
18+
19+
/// Use a braced init list for return statements rather than unnecessary
20+
/// repeating the return type name.
21+
///
22+
/// For the user-facing documentation see:
23+
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-return-braced-init-list.html
24+
class ReturnBracedInitListCheck : public ClangTidyCheck {
25+
public:
26+
ReturnBracedInitListCheck(StringRef Name, ClangTidyContext *Context)
27+
: ClangTidyCheck(Name, Context) {}
28+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
29+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
30+
};
31+
32+
} // namespace modernize
33+
} // namespace tidy
34+
} // namespace clang
35+
36+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H

‎clang-tools-extra/docs/ReleaseNotes.rst

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ Improvements to clang-tidy
6767

6868
Finds uses of inline assembler.
6969

70+
- New `modernize-return-braced-init-list
71+
<http://clang.llvm.org/extra/clang-tidy/checks/modernize-return-braced-init-list.html>`_ check
72+
73+
Finds and replaces explicit calls to the constructor in a return statement by
74+
a braced initializer list so that the return type is not needlessly repeated.
75+
7076
Improvements to include-fixer
7177
-----------------------------
7278

‎clang-tools-extra/docs/clang-tidy/checks/list.rst

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Clang-Tidy Checks
109109
modernize-raw-string-literal
110110
modernize-redundant-void-arg
111111
modernize-replace-auto-ptr
112+
modernize-return-braced-init-list
112113
modernize-shrink-to-fit
113114
modernize-use-auto
114115
modernize-use-bool-literals
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.. title:: clang-tidy - modernize-return-braced-init-list
2+
3+
modernize-return-braced-init-list
4+
=================================
5+
6+
Replaces explicit calls to the constructor in a return with a braced
7+
initializer list. This way the return type is not needlessly duplicated in the
8+
function definition and the return statement.
9+
10+
.. code:: c++
11+
12+
Foo bar() {
13+
Baz baz;
14+
return Foo(baz);
15+
}
16+
17+
// transforms to:
18+
19+
Foo bar() {
20+
Baz baz;
21+
return {baz};
22+
}

0 commit comments

Comments
 (0)
Please sign in to comment.