1 //===--- TrailingReturnCheck.cpp - clang-tidy------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TrailingReturnCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchersInternal.h"
13 
14 using namespace clang::ast_matchers;
15 
16 namespace clang {
17 namespace tidy {
18 namespace fuchsia {
19 
20 namespace {
AST_MATCHER(FunctionDecl,hasTrailingReturn)21 AST_MATCHER(FunctionDecl, hasTrailingReturn) {
22   return Node.getType()->castAs<FunctionProtoType>()->hasTrailingReturn();
23 }
24 } // namespace
25 
registerMatchers(MatchFinder * Finder)26 void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) {
27   // Functions that have trailing returns are disallowed, except for those
28   // using decltype specifiers and lambda with otherwise unutterable
29   // return types.
30   Finder->addMatcher(
31       functionDecl(hasTrailingReturn(),
32                    unless(anyOf(returns(decltypeType()),
33                                 hasParent(cxxRecordDecl(isLambda())))))
34           .bind("decl"),
35       this);
36 }
37 
check(const MatchFinder::MatchResult & Result)38 void TrailingReturnCheck::check(const MatchFinder::MatchResult &Result) {
39   if (const auto *D = Result.Nodes.getNodeAs<Decl>("decl"))
40     diag(D->getBeginLoc(),
41          "a trailing return type is disallowed for this type of declaration");
42 }
43 
44 } // namespace fuchsia
45 } // namespace tidy
46 } // namespace clang
47