例 4:継承情報へのアクセス
この例では、例 3 からカスタム述語を拡張して、データメンバーを継承チェーンからログにダンプできるようにします。まず、テストケースを拡張して継承を含めます。
class CBar{private:int m_z;};class CFoo : public CBar { ... };
次に、チェッカー定義を変更して、以下のパターンを使用します。
<pattern> // FuncDef [ getName() = ‘init’] [ listAllClassInfo() ] </pattern>
継承チェーンのメンバーを確認するには、基本クラスをトラバースする機能を導入する必要があります。
#include <stdio.h> #include <XPath_plugins.h> #include <ktcAPI.h> // Forward declarations void logClassInfo(ktc_semanticInfo_t); void logBaseClasses(ktc_semanticInfo_t); // Called by ktc_sema_forAllClassDeclarations, filter to variables void logger(ktc_semanticInfo_t mi) { if( ktc_sema_isVariable(mi) ) fprintf(stderr, "\tMember: %s\n", ktc_sema_getQualifiedName(mi)); } // Log information about the members of a specific class void logClassInfo(ktc_semanticInfo_t ci) { fprintf(stderr, "Class name: %s\n", ktc_sema_getIdentifier(ci)); ktc_sema_forAllClassDeclarations(ci, logger); logBaseClasses(ci); } // Traverse the inheritance hierarchy void logBaseClasses(ktc_semanticInfo_t ci) { int nr = ktc_sema_getNumberOfBaseInfo(ci); for( int i = 0; i < nr; i++ ) logClassInfo(ktc_sema_getBaseInfo(ci, i)); } // Custom predicate int listAllClassInfo(ktc_tree_t node) { ktc_semanticInfo_t si = ktc_getSemanticInfo(node); if( ktc_sema_isFunction(si) ) { ktc_semanticInfo_t ci = ktc_sema_getScope(si); if( ci && ktc_sema_isClass(ci) ) logClassInfo(ci); } return 1; } HOOKS_SET_START XPath_register_int_hook("listAllClassInfo", listAllClassInfo); HOOKS_SET_END
テストを再度実行すると、次の情報がビルドログに表示されます。
Class name: CFoo Member: CFoo::m_x Member: CFoo::m_y Class name: CBar Member: CBar::m_z