Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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
- Loading branch information
1 parent
0ac6d12
commit 2789043
Showing
8 changed files
with
365 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
//===--- ReturnBracedInitListCheck.cpp - clang-tidy------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "ReturnBracedInitListCheck.h" | ||
#include "clang/AST/ASTContext.h" | ||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
#include "clang/Lex/Lexer.h" | ||
#include "clang/Tooling/FixIt.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace modernize { | ||
|
||
void ReturnBracedInitListCheck::registerMatchers(MatchFinder *Finder) { | ||
// Only register the matchers for C++. | ||
if (!getLangOpts().CPlusPlus11) | ||
return; | ||
|
||
// Skip list initialization and constructors with an initializer list. | ||
auto ConstructExpr = | ||
cxxConstructExpr( | ||
unless(anyOf(hasDeclaration(cxxConstructorDecl(isExplicit())), | ||
isListInitialization(), hasDescendant(initListExpr()), | ||
isInTemplateInstantiation()))) | ||
.bind("ctor"); | ||
|
||
auto CtorAsArgument = materializeTemporaryExpr(anyOf( | ||
has(ConstructExpr), has(cxxFunctionalCastExpr(has(ConstructExpr))))); | ||
|
||
Finder->addMatcher( | ||
functionDecl(isDefinition(), // Declarations don't have return statements. | ||
returns(unless(anyOf(builtinType(), autoType()))), | ||
hasDescendant(returnStmt(hasReturnValue( | ||
has(cxxConstructExpr(has(CtorAsArgument))))))) | ||
.bind("fn"), | ||
this); | ||
} | ||
|
||
void ReturnBracedInitListCheck::check(const MatchFinder::MatchResult &Result) { | ||
const auto *MatchedFunctionDecl = Result.Nodes.getNodeAs<FunctionDecl>("fn"); | ||
const auto *MatchedConstructExpr = | ||
Result.Nodes.getNodeAs<CXXConstructExpr>("ctor"); | ||
|
||
// Don't make replacements in macro. | ||
SourceLocation Loc = MatchedConstructExpr->getExprLoc(); | ||
if (Loc.isMacroID()) | ||
return; | ||
|
||
// Make sure that the return type matches the constructed type. | ||
const QualType ReturnType = | ||
MatchedFunctionDecl->getReturnType().getCanonicalType(); | ||
const QualType ConstructType = | ||
MatchedConstructExpr->getType().getCanonicalType(); | ||
if (ReturnType != ConstructType) | ||
return; | ||
|
||
auto Diag = diag(Loc, "avoid repeating the return type from the " | ||
"declaration; use a braced initializer list instead"); | ||
|
||
const SourceRange CallParensRange = | ||
MatchedConstructExpr->getParenOrBraceRange(); | ||
|
||
// Make sure there is an explicit constructor call. | ||
if (CallParensRange.isInvalid()) | ||
return; | ||
|
||
// Make sure that the ctor arguments match the declaration. | ||
for (unsigned I = 0, NumParams = MatchedConstructExpr->getNumArgs(); | ||
I < NumParams; ++I) { | ||
if (const auto *VD = dyn_cast<VarDecl>( | ||
MatchedConstructExpr->getConstructor()->getParamDecl(I))) { | ||
if (MatchedConstructExpr->getArg(I)->getType().getCanonicalType() != | ||
VD->getType().getCanonicalType()) | ||
return; | ||
} | ||
} | ||
|
||
// Range for constructor name and opening brace. | ||
CharSourceRange CtorCallSourceRange = CharSourceRange::getTokenRange( | ||
Loc, CallParensRange.getBegin().getLocWithOffset(-1)); | ||
|
||
Diag << FixItHint::CreateRemoval(CtorCallSourceRange) | ||
<< FixItHint::CreateReplacement(CallParensRange.getBegin(), "{") | ||
<< FixItHint::CreateReplacement(CallParensRange.getEnd(), "}"); | ||
} | ||
|
||
} // namespace modernize | ||
} // namespace tidy | ||
} // namespace clang |
36 changes: 36 additions & 0 deletions
36
clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//===--- ReturnBracedInitListCheck.h - clang-tidy----------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H | ||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H | ||
|
||
#include "../ClangTidy.h" | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace modernize { | ||
|
||
/// Use a braced init list for return statements rather than unnecessary | ||
/// repeating the return type name. | ||
/// | ||
/// For the user-facing documentation see: | ||
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-return-braced-init-list.html | ||
class ReturnBracedInitListCheck : public ClangTidyCheck { | ||
public: | ||
ReturnBracedInitListCheck(StringRef Name, ClangTidyContext *Context) | ||
: ClangTidyCheck(Name, Context) {} | ||
void registerMatchers(ast_matchers::MatchFinder *Finder) override; | ||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
}; | ||
|
||
} // namespace modernize | ||
} // namespace tidy | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_RETURN_BRACED_INIT_LIST_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
clang-tools-extra/docs/clang-tidy/checks/modernize-return-braced-init-list.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
.. title:: clang-tidy - modernize-return-braced-init-list | ||
|
||
modernize-return-braced-init-list | ||
================================= | ||
|
||
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 | ||
function definition and the return statement. | ||
|
||
.. code:: c++ | ||
|
||
Foo bar() { | ||
Baz baz; | ||
return Foo(baz); | ||
} | ||
|
||
// transforms to: | ||
|
||
Foo bar() { | ||
Baz baz; | ||
return {baz}; | ||
} |
Oops, something went wrong.