ajohnson-uoregon created this revision. ajohnson-uoregon added reviewers: klimek, jdoerfert. Herald added a project: All. ajohnson-uoregon requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
new AST matcher that matches the expected return type of a ReturnStmt by looking at the enclosing function's stated return type; matches against the function's type Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D120959 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -314,6 +314,7 @@ REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); REGISTER_MATCHER(hasElse); + REGISTER_MATCHER(hasExpectedReturnType); REGISTER_MATCHER(hasExplicitSpecifier); REGISTER_MATCHER(hasExternalFormalLinkage); REGISTER_MATCHER(hasFalseExpression); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3965,6 +3965,44 @@ return false; } +/// Matches the type of a return statement as declared by the enclosing +/// function. +/// +/// Example: returnStmt(hasExpectedReturnType(asString("int *"))) will match +/// return 0; in +/// \code +/// int* foo() { +/// return 0; +/// } +/// \endcode +/// despite the return value being an IntegerLiteral. + +AST_MATCHER_P(ReturnStmt, hasExpectedReturnType, internal::Matcher<QualType>, + InnerMatcher) { + const auto &Parents = Finder->getASTContext().getParents(Node); + + llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end()); + const FunctionDecl* FuncDeclNode; + while (!Stack.empty()) { + const auto &CurNode = Stack.back(); + Stack.pop_back(); + FuncDeclNode = CurNode.get<FunctionDecl>(); + if (FuncDeclNode != nullptr) { + break; + } + else { + for (const auto &Parent : Finder->getASTContext().getParents(CurNode)) + Stack.push_back(Parent); + } + } + if (FuncDeclNode == nullptr) { + return false; + } + else { + return InnerMatcher.matches(FuncDeclNode->getReturnType(), Finder, Builder); + } +} + /// Matches if the type location of a node matches the inner matcher. /// /// Examples:
Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -314,6 +314,7 @@ REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); REGISTER_MATCHER(hasElse); + REGISTER_MATCHER(hasExpectedReturnType); REGISTER_MATCHER(hasExplicitSpecifier); REGISTER_MATCHER(hasExternalFormalLinkage); REGISTER_MATCHER(hasFalseExpression); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3965,6 +3965,44 @@ return false; } +/// Matches the type of a return statement as declared by the enclosing +/// function. +/// +/// Example: returnStmt(hasExpectedReturnType(asString("int *"))) will match +/// return 0; in +/// \code +/// int* foo() { +/// return 0; +/// } +/// \endcode +/// despite the return value being an IntegerLiteral. + +AST_MATCHER_P(ReturnStmt, hasExpectedReturnType, internal::Matcher<QualType>, + InnerMatcher) { + const auto &Parents = Finder->getASTContext().getParents(Node); + + llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end()); + const FunctionDecl* FuncDeclNode; + while (!Stack.empty()) { + const auto &CurNode = Stack.back(); + Stack.pop_back(); + FuncDeclNode = CurNode.get<FunctionDecl>(); + if (FuncDeclNode != nullptr) { + break; + } + else { + for (const auto &Parent : Finder->getASTContext().getParents(CurNode)) + Stack.push_back(Parent); + } + } + if (FuncDeclNode == nullptr) { + return false; + } + else { + return InnerMatcher.matches(FuncDeclNode->getReturnType(), Finder, Builder); + } +} + /// Matches if the type location of a node matches the inner matcher. /// /// Examples:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits