1 //===---- CheckerHelpers.cpp - Helper functions for checkers ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines several static functions for use in checkers.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
15 #include "clang/AST/Expr.h"
16 
17 // Recursively find any substatements containing macros
18 bool clang::ento::containsMacro(const Stmt *S) {
19   if (S->getLocStart().isMacroID())
20     return true;
21 
22   if (S->getLocEnd().isMacroID())
23     return true;
24 
25   for (const Stmt *Child : S->children())
26     if (Child && containsMacro(Child))
27       return true;
28 
29   return false;
30 }
31 
32 // Recursively find any substatements containing enum constants
33 bool clang::ento::containsEnum(const Stmt *S) {
34   const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
35 
36   if (DR && isa<EnumConstantDecl>(DR->getDecl()))
37     return true;
38 
39   for (const Stmt *Child : S->children())
40     if (Child && containsEnum(Child))
41       return true;
42 
43   return false;
44 }
45 
46 // Recursively find any substatements containing static vars
47 bool clang::ento::containsStaticLocal(const Stmt *S) {
48   const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
49 
50   if (DR)
51     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
52       if (VD->isStaticLocal())
53         return true;
54 
55   for (const Stmt *Child : S->children())
56     if (Child && containsStaticLocal(Child))
57       return true;
58 
59   return false;
60 }
61 
62 // Recursively find any substatements containing __builtin_offsetof
63 bool clang::ento::containsBuiltinOffsetOf(const Stmt *S) {
64   if (isa<OffsetOfExpr>(S))
65     return true;
66 
67   for (const Stmt *Child : S->children())
68     if (Child && containsBuiltinOffsetOf(Child))
69       return true;
70 
71   return false;
72 }
73