1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 #include <clang/AST/RecursiveASTVisitor.h>
13 #include <unordered_set>
17 * Common code for checking if the address of a function was taken.
21 template<typename Base
>
22 class FunctionAddress
: public Base
25 explicit FunctionAddress( const InstantiationData
& data
) : Base(data
) {}
27 bool TraverseCallExpr(CallExpr
* expr
) {
28 auto const saved
= callee_
;
29 callee_
= expr
->getCallee();
30 auto const ret
= Base::TraverseCallExpr(expr
);
35 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr
* expr
) {
36 auto const saved
= callee_
;
37 callee_
= expr
->getCallee();
38 auto const ret
= Base::TraverseCXXOperatorCallExpr(expr
);
43 bool TraverseCXXMemberCallExpr(CXXMemberCallExpr
* expr
) {
44 auto const saved
= callee_
;
45 callee_
= expr
->getCallee();
46 auto const ret
= Base::TraverseCXXMemberCallExpr(expr
);
51 bool TraverseCUDAKernelCallExpr(CUDAKernelCallExpr
* expr
) {
52 auto const saved
= callee_
;
53 callee_
= expr
->getCallee();
54 auto const ret
= Base::TraverseCUDAKernelCallExpr(expr
);
59 bool TraverseUserDefinedLiteral(UserDefinedLiteral
* expr
) {
60 auto const saved
= callee_
;
61 callee_
= expr
->getCallee();
62 auto const ret
= Base::TraverseUserDefinedLiteral(expr
);
67 bool VisitImplicitCastExpr(ImplicitCastExpr
const * expr
) {
68 if (expr
== callee_
) {
71 if (this->ignoreLocation(expr
)) {
74 if (expr
->getCastKind() != CK_FunctionToPointerDecay
) {
77 auto const dre
= dyn_cast
<DeclRefExpr
>(
78 expr
->getSubExpr()->IgnoreParens());
82 auto const fd
= dyn_cast
<FunctionDecl
>(dre
->getDecl());
86 ignoredFunctions_
.insert(fd
->getCanonicalDecl());
90 bool VisitUnaryOperator(UnaryOperator
* expr
) {
91 if (expr
->getOpcode() != UO_AddrOf
) {
92 return Base::VisitUnaryOperator(expr
);
94 if (this->ignoreLocation(expr
)) {
97 auto const dre
= dyn_cast
<DeclRefExpr
>(
98 expr
->getSubExpr()->IgnoreParenImpCasts());
102 auto const fd
= dyn_cast
<FunctionDecl
>(dre
->getDecl());
106 ignoredFunctions_
.insert(fd
->getCanonicalDecl());
111 std::unordered_set
<FunctionDecl
const *> const & getFunctionsWithAddressTaken() { return ignoredFunctions_
; }
114 std::unordered_set
<FunctionDecl
const *> ignoredFunctions_
;
115 Expr
const * callee_
= nullptr;
120 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */