@@ -86,6 +86,26 @@ class Callback : public clang::ast_matchers::MatchFinder::MatchCallback {
8686 void run (const clang::ast_matchers::MatchFinder::MatchResult &R) override {
8787 assert (sema_);
8888 Mapper::PushASTContext scoped (*R.Context );
89+ if (auto func = R.Nodes .getNodeAs <clang::FunctionDecl>(" validate_func" )) {
90+ const char *err = nullptr ;
91+ if (auto body =
92+ clang::dyn_cast_or_null<clang::CompoundStmt>(func->getBody ())) {
93+ if (body->size () != 1 ) {
94+ err = " body must contain exactly one statement (a return)" ;
95+ } else if (!clang::isa<clang::ReturnStmt>(*body->body_begin ())) {
96+ err = " body must be a return statement" ;
97+ }
98+ } else {
99+ err = " body cannot be empty" ;
100+ }
101+
102+ if (err) {
103+ llvm::errs () << " ERROR: " << func->getQualifiedNameAsString () << " : "
104+ << err << ' \n ' ;
105+ std::exit (EXIT_FAILURE);
106+ }
107+ return ;
108+ }
89109 if (auto var = R.Nodes .getNodeAs <clang::TypeAliasDecl>(" tvar" )) {
90110 clang::QualType type;
91111 if (auto *tdecl = var->getDescribedAliasTemplate ()) {
@@ -687,6 +707,12 @@ class ActionFactory : public clang::tooling::FrontendActionFactory {
687707 typeAliasDecl (matchesName (" (^|::)t[0-9]+$" ), isExpansionInMainFile ())
688708 .bind (" tvar" ),
689709 &cb_);
710+
711+ finder_.addMatcher (functionDecl (isDefinition (),
712+ matchesName (" (^|::)f[0-9]+$" ),
713+ isExpansionInMainFile ())
714+ .bind (" validate_func" ),
715+ &cb_);
690716 }
691717
692718 std::unique_ptr<clang::FrontendAction> create () override {
0 commit comments