Checker.h revision ec8605f1d7ec846dbf51047bfd5c56d32d1ff91c
1ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=// 29fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// 39fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 49fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// 59fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 69fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 79fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// 89fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 99fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// 10ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis// This file defines Checker, used to create and register checkers. 119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// 129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 14ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKER 15ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKER 169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 18b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/Support/Casting.h" 209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace clang { 229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace ento { 239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis class BugReporter; 249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace check { 269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisstruct _VoidCheck { 289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _register(void *checker, CheckerManager &mgr) { } 299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}; 309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidistemplate <typename DECL> 329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTDecl { 339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr, 359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis ((const CHECKER *)checker)->checkASTDecl(llvm::cast<DECL>(D), mgr, BR); 379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static bool _handlesDecl(const Decl *D) { 409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis return llvm::isa<DECL>(D); 419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic: 439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 45769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker, 46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _checkDecl<CHECKER>), 47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _handlesDecl); 489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}; 509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisclass ASTCodeBody { 529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr, 549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis BugReporter &BR) { 559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR); 569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic: 599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForBody(CheckerManager::CheckDeclFunc(checker, 62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _checkBody<CHECKER>)); 63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT> 67769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreStmt { 68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { 70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ((const CHECKER *)checker)->checkPreStmt(llvm::cast<STMT>(S), C); 71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 72769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static bool _handlesStmt(const Stmt *S) { 74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return llvm::isa<STMT>(S); 75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 77769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker, 80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _checkStmt<CHECKER>), 81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _handlesStmt); 82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename STMT> 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostStmt { 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) { 89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ((const CHECKER *)checker)->checkPostStmt(llvm::cast<STMT>(S), C); 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static bool _handlesStmt(const Stmt *S) { 93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return llvm::isa<STMT>(S); 94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 96769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 97769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker, 99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _checkStmt<CHECKER>), 100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis _handlesStmt); 101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 102769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PreObjCMessage { 105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _checkObjCMessage(void *checker, const ObjCMessage &msg, 107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext &C) { 108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ((const CHECKER *)checker)->checkPreObjCMessage(msg, C); 109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForPreObjCMessage( 115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); 116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass PostObjCMessage { 120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 121769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _checkObjCMessage(void *checker, const ObjCMessage &msg, 122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext &C) { 123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ((const CHECKER *)checker)->checkPostObjCMessage(msg, C); 124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 125769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForPostObjCMessage( 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); 131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass Location { 135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _checkLocation(void *checker, const SVal &location, bool isLoad, 137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerContext &C) { 138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ((const CHECKER *)checker)->checkLocation(location, isLoad, C); 139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic: 142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis template <typename CHECKER> 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis mgr._registerForLocation( 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>)); 1469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 1479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}; 1489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 149312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Bind { 150312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis template <typename CHECKER> 151312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis static void _checkBind(void *checker, const SVal &location, const SVal &val, 152312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckerContext &C) { 153312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ((const CHECKER *)checker)->checkBind(location, val, C); 154312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 155312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 156312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic: 157312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis template <typename CHECKER> 158312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 159312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis mgr._registerForBind( 160312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>)); 161312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 162312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}; 163312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 16430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisclass EndAnalysis { 16530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis template <typename CHECKER> 16630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis static void _checkEndAnalysis(void *checker, ExplodedGraph &G, 16730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis BugReporter &BR, ExprEngine &Eng) { 16830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng); 16930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis } 17030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 17130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidispublic: 17230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis template <typename CHECKER> 17330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 17430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis mgr._registerForEndAnalysis( 17530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>)); 17630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis } 17730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}; 17830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 179af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisclass EndPath { 180af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis template <typename CHECKER> 181af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis static void _checkEndPath(void *checker, EndOfFunctionNodeBuilder &B, 182af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ExprEngine &Eng) { 183af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ((const CHECKER *)checker)->checkEndPath(B, Eng); 184af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis } 185af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 186af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidispublic: 187af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis template <typename CHECKER> 188af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 189af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis mgr._registerForEndPath( 190af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis CheckerManager::CheckEndPathFunc(checker, _checkEndPath<CHECKER>)); 191af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis } 192af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis}; 193af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis 194cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisclass BranchCondition { 195cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis template <typename CHECKER> 196cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis static void _checkBranchCondition(void *checker, const Stmt *condition, 197cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis BranchNodeBuilder &B, ExprEngine &Eng) { 198cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis ((const CHECKER *)checker)->checkBranchCondition(condition, B, Eng); 199cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis } 200cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 201cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidispublic: 202cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis template <typename CHECKER> 203cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 204cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis mgr._registerForBranchCondition( 205cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis CheckerManager::CheckBranchConditionFunc(checker, 206cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis _checkBranchCondition<CHECKER>)); 207cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis } 208cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis}; 209cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 210183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass LiveSymbols { 211183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 212183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static void _checkLiveSymbols(void *checker, const GRState *state, 213183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SR) { 214183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ((const CHECKER *)checker)->checkLiveSymbols(state, SR); 215183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 216183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 217183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic: 218183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 219183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 220183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis mgr._registerForLiveSymbols( 221183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>)); 222183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 223183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}; 224183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 225183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass DeadSymbols { 226183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static void _checkDeadSymbols(void *checker, 228183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis SymbolReaper &SR, CheckerContext &C) { 229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ((const CHECKER *)checker)->checkDeadSymbols(SR, C); 230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 231183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 232183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic: 233183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 234183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 235183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis mgr._registerForDeadSymbols( 236183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>)); 237183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 238183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}; 239183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 240183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisclass RegionChanges { 241183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 242183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static const GRState *_checkRegionChanges(void *checker, const GRState *state, 243183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *Begin, 244183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const MemRegion * const *End) { 245183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End); 246183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 247183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 248183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) { 249183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return ((const CHECKER *)checker)->wantsRegionChangeUpdate(state); 250183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 251183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 252183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidispublic: 253183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis template <typename CHECKER> 254183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 255183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis mgr._registerForRegionChanges( 256183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckerManager::CheckRegionChangesFunc(checker, 257183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis _checkRegionChanges<CHECKER>), 258183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis CheckerManager::WantsRegionChangeUpdateFunc(checker, 259183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis _wantsRegionChangeUpdate<CHECKER>)); 260183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 261183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}; 262183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 263deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT> 264deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass Event { 265deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename CHECKER> 266deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void _checkEvent(void *checker, const void *event) { 267deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event); 268deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 269deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic: 270deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename CHECKER> 271deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 272deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis mgr._registerListenerForEvent<EVENT>( 273deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>)); 274deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 275deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis}; 276deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 2779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end check namespace 2789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 279e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisnamespace eval { 280e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 281312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisclass Assume { 282312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis template <typename CHECKER> 283312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis static const GRState *_evalAssume(void *checker, const GRState *state, 284312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis const SVal &cond, bool assumption) { 285312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return ((const CHECKER *)checker)->evalAssume(state, cond, assumption); 286312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 287312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 288312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidispublic: 289312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis template <typename CHECKER> 290312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 291312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis mgr._registerForEvalAssume( 292312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>)); 293312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 294312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}; 295312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 296e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass Call { 297e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis template <typename CHECKER> 298e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) { 299e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis return ((const CHECKER *)checker)->evalCall(CE, C); 300e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 301e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 302e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic: 303e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis template <typename CHECKER> 304e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 305e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis mgr._registerForEvalCall( 306e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>)); 307e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis } 308e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}; 309e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 310e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} // end eval namespace 311e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 3129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidistemplate <typename CHECK1, typename CHECK2=check::_VoidCheck, 3139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck, 3149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck, 3159fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck, 3169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck, 3179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck> 318ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass Checker; 319deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 320deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <> 321ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, 322deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, 323deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis check::_VoidCheck, check::_VoidCheck, check::_VoidCheck, 324deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis check::_VoidCheck, check::_VoidCheck, check::_VoidCheck> { 325deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic: 326deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void _register(void *checker, CheckerManager &mgr) { } 327deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis}; 328deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 329deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4, 330deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8, 331deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12> 332ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass Checker 333deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis : public CHECK1, 334ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, 335deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CHECK9, CHECK10, CHECK11, CHECK12> { 3369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidispublic: 3379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis template <typename CHECKER> 3389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 3399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis CHECK1::_register(checker, mgr); 340ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, CHECK8, CHECK9, 341deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CHECK10, CHECK11,CHECK12>::_register(checker, mgr); 342deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 343deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis}; 344deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 345deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidistemplate <typename EVENT> 346deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisclass EventDispatcher { 347deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis CheckerManager *Mgr; 348deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidispublic: 349deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis EventDispatcher() : Mgr(0) { } 350deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 351deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis template <typename CHECKER> 352deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static void _register(CHECKER *checker, CheckerManager &mgr) { 353deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis mgr._registerDispatcherForEvent<EVENT>(); 354deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr; 355deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis } 356deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 357deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis void dispatchEvent(const EVENT &event) const { 358deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis Mgr->_dispatchEvent(event); 3599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis } 3609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}; 3619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 362b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis/// \brief We dereferenced a location that may be null. 363b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidisstruct ImplicitNullDerefEvent { 364b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis SVal Location; 365b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis bool IsLoad; 366b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis ExplodedNode *SinkNode; 367b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis BugReporter *BR; 368b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis}; 369b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidis 3709fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end ento namespace 3719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 3729fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis} // end clang namespace 3739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 3749fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#endif 375