void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()), unless(isExternC())) .bind(FunctionId), this); Finder->addMatcher(typedefNameDecl().bind(TypedefId), this); auto ParenFunctionType = parenType(innerType(functionType())); auto PointerToFunctionType = pointee(ParenFunctionType); auto FunctionOrMemberPointer = anyOf(hasType(pointerType(PointerToFunctionType)), hasType(memberPointerType(PointerToFunctionType))); Finder->addMatcher(fieldDecl(FunctionOrMemberPointer).bind(FieldId), this); Finder->addMatcher(varDecl(FunctionOrMemberPointer).bind(VarId), this); auto CastDestinationIsFunction = hasDestinationType(pointsTo(ParenFunctionType)); Finder->addMatcher( cStyleCastExpr(CastDestinationIsFunction).bind(CStyleCastId), this); Finder->addMatcher( cxxStaticCastExpr(CastDestinationIsFunction).bind(NamedCastId), this); Finder->addMatcher( cxxReinterpretCastExpr(CastDestinationIsFunction).bind(NamedCastId), this); Finder->addMatcher( cxxConstCastExpr(CastDestinationIsFunction).bind(NamedCastId), this); Finder->addMatcher(lambdaExpr().bind(LambdaId), this); }
void CloexecSocketCheck::registerMatchers(MatchFinder *Finder) { registerMatchersImpl(Finder, functionDecl(isExternC(), returns(isInteger()), hasName("socket"), hasParameter(0, hasType(isInteger())), hasParameter(1, hasType(isInteger())), hasParameter(2, hasType(isInteger())))); }
bool DeclReferencer::Reference(const clang::NamedDecl *D) { if (D->isInvalidDecl()) return true; for (const clang::Decl *DI = D; !isa<clang::TranslationUnitDecl>(DI); DI = cast<clang::Decl>(DI->getDeclContext())) if (auto RD = dyn_cast<clang::CXXRecordDecl>(DI)) if (RD->isLocalClass()) return true; // are local records emitted when emitting a function? if no this is a FIXME if (auto VD = dyn_cast<clang::VarDecl>(D)) if (!VD->isFileVarDecl()) return true; if (auto FD = dyn_cast<clang::FunctionDecl>(D)) { if (!isMapped(D)) return true; if (FD->getBuiltinID() || (FD->isOverloadedOperator() && FD->isImplicit())) return true; if (FD->isExternC()) return true; // FIXME: Clang 3.6 doesn't always map decls to the right source file, // so the path generated by typeQualifiedFor although correct will result in a failed lookup. // This may get fixed by 3.7. } if (Referenced.count(D->getCanonicalDecl())) return true; Referenced.insert(D->getCanonicalDecl()); // Although we try to add all the needed imports during importAll(), sometimes we miss a module so ensure it gets loaded auto im = mapper.AddImplicitImportForDecl(loc, D, true); im->isstatic = true; auto dst = Package::resolve(im->packages, NULL, &im->pkg); if (!dst->lookup(im->id)) { im->semantic(sc); im->semantic2(sc); } ReferenceTemplateArguments(D); auto Func = dyn_cast<clang::FunctionDecl>(D); if (Func && Func->getPrimaryTemplate()) D = cast<clang::NamedDecl>(getCanonicalDecl(getSpecializedDeclOrExplicit(Func))); // HACK FIXME if (Func && Func->isOutOfLine() && Func->getFriendObjectKind() != clang::Decl::FOK_None) { auto Pattern = Func; if (auto MemberFunc = Func->getInstantiatedFromMemberFunction()) Pattern = MemberFunc; if (Pattern->isDependentContext()) return true; } auto e = expmap.fromExpressionDeclRef(loc, const_cast<clang::NamedDecl*>(D), nullptr, TQ_OverOpSkipSpecArg); e = e->semantic(sc); if (Func && Func->getPrimaryTemplate()) { assert(e->op == TOKvar || e->op == TOKtemplate || e->op == TOKimport); Dsymbol *s; if (e->op == TOKvar) s = static_cast<SymbolExp*>(e)->var; else if (e->op == TOKtemplate) s = static_cast<TemplateExp*>(e)->td; else s = static_cast<ScopeExp*>(e)->sds; // if it's a non-template function there's nothing to do, it will be semantic'd along with its declcontext // if it's a template spec we must instantiate the right overload struct DEquals { const clang::Decl* D; Dsymbol *s = nullptr; // return value static int fp(void *param, Dsymbol *s) { if (!isCPP(s)) return 0; auto fd = s->isFuncDeclaration(); auto td = static_cast<cpp::TemplateDeclaration*>( s->isTemplateDeclaration()); DEquals *p = (DEquals *)param; decltype(D) s_D = fd ? getFD(fd) : td->TempOrSpec; if (p->D == getCanonicalDecl(s_D)) { p->s = s; return 1; } return 0; } }; DEquals p; p.D = D; overloadApply(s, &p, &DEquals::fp); assert(p.s && p.s->isTemplateDeclaration()); auto td = static_cast<cpp::TemplateDeclaration*>(p.s->isTemplateDeclaration()); if (td->semanticRun == PASSinit) { assert(td->scope); td->semantic(td->scope); // this must be done here because havetempdecl being set to true it won't be done by findTempDecl() assert(td->semanticRun > PASSinit); } auto tiargs = mapper.fromTemplateArguments(loc, Func->getTemplateSpecializationArgs()); assert(tiargs); SpecValue spec(mapper); getIdentifier(Func, &spec, true); if (spec) tiargs->shift(spec.toTemplateArg(loc)); auto tempinst = new cpp::TemplateInstance(loc, td, tiargs); tempinst->Inst = const_cast<clang::FunctionDecl*>(Func); tempinst->semantictiargsdone = false; // NOTE: the "havetempdecl" ctor of Templateinstance set semantictiargsdone to true... // Time was lost finding this out for the second or third time. td->makeForeignInstance(tempinst); tempinst->semantic(sc); } // Memory usage can skyrocket when using a large library if (im->packages) delete im->packages; delete im; delete e; return true; }