10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Lex/Lexer.h" 13 #include "clang/Tooling/FixIt.h" 21 void ReturnBracedInitListCheck::registerMatchers(MatchFinder *Finder) {
23 if (!getLangOpts().CPlusPlus11)
29 unless(anyOf(hasDeclaration(cxxConstructorDecl(isExplicit())),
30 isListInitialization(), hasDescendant(initListExpr()),
31 isInTemplateInstantiation())))
34 auto CtorAsArgument = materializeTemporaryExpr(anyOf(
35 has(ConstructExpr), has(cxxFunctionalCastExpr(has(ConstructExpr)))));
38 functionDecl(isDefinition(),
39 returns(unless(anyOf(builtinType(), autoType()))),
40 hasDescendant(returnStmt(hasReturnValue(
41 has(cxxConstructExpr(has(CtorAsArgument)))))))
46 void ReturnBracedInitListCheck::check(
const MatchFinder::MatchResult &
Result) {
47 const auto *MatchedFunctionDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"fn");
48 const auto *MatchedConstructExpr =
49 Result.Nodes.getNodeAs<CXXConstructExpr>(
"ctor");
52 SourceLocation
Loc = MatchedConstructExpr->getExprLoc();
58 MatchedFunctionDecl->getReturnType().getCanonicalType();
59 const QualType ConstructType =
60 MatchedConstructExpr->getType().getCanonicalType();
61 if (ReturnType != ConstructType)
64 auto Diag = diag(Loc,
"avoid repeating the return type from the " 65 "declaration; use a braced initializer list instead");
67 const SourceRange CallParensRange =
68 MatchedConstructExpr->getParenOrBraceRange();
71 if (CallParensRange.isInvalid())
75 for (
unsigned I = 0, NumParams = MatchedConstructExpr->getNumArgs();
77 if (
const auto *VD = dyn_cast<VarDecl>(
78 MatchedConstructExpr->getConstructor()->getParamDecl(I))) {
79 if (MatchedConstructExpr->getArg(I)->getType().getCanonicalType() !=
80 VD->getType().getCanonicalType())
87 Loc, CallParensRange.getBegin().getLocWithOffset(-1));
89 Diag << FixItHint::CreateRemoval(CtorCallSourceRange)
90 << FixItHint::CreateReplacement(CallParensRange.getBegin(),
"{")
91 << FixItHint::CreateReplacement(CallParensRange.getEnd(),
"}");
SourceLocation Loc
'#' location in the include directive
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result