void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) { // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a // macro or ``__attribute__`` with pre c++17 compilers by using // ReplacementString option. if ((NoDiscardMacro == "[[nodiscard]]" && !getLangOpts().CPlusPlus17) || !getLangOpts().CPlusPlus) return; auto FunctionObj = cxxRecordDecl(hasAnyName("::std::function", "::boost::function")); // Find all non-void const methods which have not already been marked to // warn on unused result. Finder->addMatcher( cxxMethodDecl( allOf(isConst(), isDefinitionOrInline(), unless(anyOf( returns(voidType()), isNoReturn(), isOverloadedOperator(), isVariadic(), hasTemplateReturnType(), hasClassMutableFields(), isConversionOperator(), hasAttr(clang::attr::WarnUnusedResult), hasType(isInstantiationDependentType()), hasAnyParameter(anyOf( parmVarDecl(anyOf(hasType(FunctionObj), hasType(references(FunctionObj)))), hasType(isNonConstReferenceOrPointer()), hasParameterPack())))))) .bind("no_discard"), this); }
void OpDeleteExprHandler::run(const clang::ast_matchers::MatchFinder::MatchResult& result) { const clang::CallExpr* deleteExpr = result.Nodes.getNodeAs<clang::CallExpr>("deleteStmt"); const clang::FunctionDecl* funDecl = result.Nodes.getNodeAs<clang::FunctionDecl>("fun"); if (nullptr == deleteExpr) { llvm::errs() << "Couldn't convert MatcherResult to CallExpr!\n"; return; } clang::SourceLocation startLoc = deleteExpr->getArg(0)->getLocStart(); clang::SourceLocation endLoc = deleteExpr->getArg(0)->getLocEnd(); const clang::Expr* pointerExpr = deleteExpr->getArg(0)->IgnoreCasts(); auto deletedType = pointerExpr->getType(); auto ptr = deletedType.getTypePtr(); if (!ptr->isInstantiationDependentType() && !ptr->hasUnnamedOrLocalType()) { handleSpecializedType(pointerExpr->getType(), startLoc.getRawEncoding(), CONVERT_TO_POINTEE); } if (!processingLocation(startLoc)) return; MacroAdder deleteLoggerMacro(funDecl->getNameInfo().getName().getAsString() == "operator delete[]" ? "TYPEGRIND_LOG_OP_DELETE_ARRAY" : "TYPEGRIND_LOG_OP_DELETE", startLoc, endLoc, mRewriter); // 2nd and 3rd paramter: name of the type. addTypeInformationParameters(deleteLoggerMacro, deletedType, startLoc.getRawEncoding(), CONVERT_TO_POINTEE); // last parameter: the pointer expression // parenthesis around it, for multiple template parameters deleteLoggerMacro.startBuffer() << "("; deleteLoggerMacro.endBuffer() << ")"; deleteLoggerMacro.commitAroundLocations(); }