1 //===--- TrailingReturnCheck.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 "TrailingReturnCheck.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/ASTMatchers/ASTMatchersInternal.h" 14 15 using namespace clang::ast_matchers; 16 17 namespace clang { 18 namespace tidy { 19 namespace fuchsia { 20 21 namespace { 22 const internal::VariadicDynCastAllOfMatcher<Type, DecltypeType> decltypeType; 23 24 AST_MATCHER(FunctionDecl, hasTrailingReturn) { 25 return Node.getType()->castAs<FunctionProtoType>()->hasTrailingReturn(); 26 } 27 } // namespace 28 29 void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) { 30 31 // Requires C++11 or later. 32 if (!getLangOpts().CPlusPlus11) 33 return; 34 35 // Functions that have trailing returns are disallowed, except for those 36 // using decltype specifiers and lambda with otherwise unutterable 37 // return types. 38 Finder->addMatcher( 39 functionDecl(allOf(hasTrailingReturn(), 40 unless(anyOf(returns(decltypeType()), 41 hasParent(cxxRecordDecl(isLambda())))))) 42 .bind("decl"), 43 this); 44 } 45 46 void TrailingReturnCheck::check(const MatchFinder::MatchResult &Result) { 47 if (const auto *D = Result.Nodes.getNodeAs<Decl>("decl")) 48 diag(D->getLocStart(), 49 "a trailing return type is disallowed for this type of declaration"); 50 } 51 52 } // namespace fuchsia 53 } // namespace tidy 54 } // namespace clang 55