/* Pedantic checking of DWARF files Copyright (C) 2009,2010,2011 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. elfutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DWARFLINT_HH #define DWARFLINT_HH #include #include #include #include #include "../libelf/libelf.h" #include "checks_i.hh" #include "checkdescriptor_i.hh" #include "checkrule.hh" #include "check_registrar.hh" #include "dwarflint_i.hh" #include "highlevel_check_i.hh" // Classes for full-blown check passes. struct main_check_item { virtual checkdescriptor const *descriptor () const = 0; virtual ~main_check_item () {} virtual void run (checkstack &stack, dwarflint &lint) = 0; }; class main_check_registrar : public check_registrar_T { public: friend class dwarflint; void run (dwarflint &lint); }; class checkstack : public std::vector {}; std::ostream &operator << (std::ostream &o, checkstack const &stack); class dwarflint { typedef std::map check_map; check_map _m_checks; char const *_m_fname; int _m_fd; checkrules const &_m_rules; static void *const marker; // Return a pointer to check, or NULL if the check hasn't been done // yet. Throws check_base::failed if the check was requested // earlier but failed, or aborts program via assertion if recursion // was detected. void *find_check (void const *key); template static check_base * create_check_object (checkstack &stack, dwarflint &lint) { return new T (stack, lint); } void *dispatch_check (checkstack &stack, checkdescriptor const &cd, void const *key, check_base *(* create) (checkstack &, dwarflint &)); public: dwarflint (char const *fname, checkrules const &rules); ~dwarflint (); int fd () { return _m_fd; } char const *fname () { return _m_fname; } template T * check (checkstack &stack) { void const *key = T::key (); T *c = static_cast (find_check (key)); checkdescriptor const &cd = *T::descriptor (); if (c == NULL) c = (T *)dispatch_check (stack, cd, key, &create_check_object); return c; } template T * check (checkstack &stack, T *) { return check (stack); } template T *toplev_check (checkstack &stack, T *fake = NULL); template T * check_if (bool whether, checkstack &stack, __attribute__ ((unused)) T *fake = NULL) { if (whether) return check (stack); else return NULL; } checkrules const & rules () const { return _m_rules; } static main_check_registrar *main_registrar (); static void list_checks (); }; #endif//DWARFLINT_HH