例 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