2016-07-08 30 views
0

こんにちは私はASTビジターを実装していますが、これはかなりうまく動作していますし、変数宣言、関数宣言、関数呼び出し。今日私が実験している間、私は関数呼び出しとして認識されない関数呼び出しに出くわしました。 Syntacticalyは関数呼び出しと同じです。ここでは、コードは次のようになります。ASTvisitorのASTビジター関数呼び出し式が関数呼び出しを正しく認識しない

void 
TIFFError(const char* module, const char* fmt, ...) 
{ 
    va_list ap; 
    va_start(ap, fmt); <------------------------------ THIS IS THE FUNCTION CALL 
    if (_TIFFerrorHandler) 
     (*_TIFFerrorHandler)(module, fmt, ap); 
    if (_TIFFerrorHandlerExt) 
     (*_TIFFerrorHandlerExt)(0, module, fmt, ap); 
    va_end(ap);   <--------------------------------AND THIS ONE 
} 

私のコードはこれです:

bool VisitStmt(Stmt *st) 
{ 
    FullSourceLoc FullLocation = astContext->getFullLoc(st->getLocStart()); 
    FileID fileID = FullLocation.getFileID(); 
    unsigned int thisFileID = fileID.getHashValue(); 
    if(thisFileID == 1) //checks if the node is in the main = input file. 
    { 
     if (CallExpr *call = dyn_cast<CallExpr>(st)) 
     { 
      numFuncCalls++; 
      //call->dump(); //prints the corresponding line of the AST. 
      FunctionDecl *func_decl; 
      if(call->getDirectCallee()) 
      { 
       func_decl = call ->getDirectCallee(); 
       string funcCall = func_decl->getNameInfo().getName().getAsString(); 
       cout << "Function call: " << funcCall << " with arguments "; 
       APIs << funcCall << ","; 
       for(int i=0, j = call->getNumArgs(); i<j; i++) 
       { 
        //For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type. 
        APIs << call->getArg(i)->getType().getAsString()<< ","; 
        cout << call->getArg(i)->getType().getAsString() << ", "; 
       } 
       cout << "\n"; 
      } 
      else 
      { 
       Expr *expr = call->getCallee(); 
       string exprCall = expr->getStmtClassName(); 
       cout << "Expression call: " << exprCall << " with arguments "; 
       APIs << exprCall << ","; 
       for(int i=0, j = call->getNumArgs(); i<j; i++) 
       { 
        //For each argument it prints its type. The function must be declared otherwise it will return int-for unknown argument type. 
        APIs << call->getArg(i)->getType().getAsString()<< ","; 
        cout << call->getArg(i)->getType().getAsString() << ", "; 
       } 
       cout << "\n"; 
      } 
     } 
    } 
    return true; 
} 

式があれば(call-> getDirectCallee())これらの呼び出しのために真実ではありません。

「通常の」関数呼び出しで行っているように、「関数名」とその引数を抽出するにはどうすればよいですか? また、通常の関数呼び出しと同じようにAST再帰的訪問者がこれらの呼び出しを認識しない理由についての洞察もあります。

ありがとうございます。

答えて

0

実際には関数ではないため、関数としてあなたに表示されない理由があります。あなたは<cstdarg>ヘッダファイルを見に行く場合は、それが指しています実際のfunctiondeclにリンクしますLinkageSpecDeclと呼ばれています何か、関数は今MACRO

#define va_start(ap, param) __builtin_va_start(ap, param) 

であることがわかります。

このような問題を解決するには、解析するコードの生のASTDumpを見て、何を期待するかを教えてください。

たとえば、私はあなたの機能をこれに変更しました。その後、

#include <cstdarg> 

void TIFFError(const char* module, const char* fmt, ...) 
{ 
    va_list ap; 
    va_start(ap, fmt); <------------------------------ THIS IS THE FUNCTION CALL 
    if (_TIFFerrorHandler) 
     (*_TIFFerrorHandler)(module, fmt, ap); 
    if (_TIFFerrorHandlerExt) 
     (*_TIFFerrorHandlerExt)(0, module, fmt, ap); 
    va_end(ap);   <--------------------------------AND THIS ONE 
} 

そして、それはAST(上位コードがtemp.cppに格納されていると仮定する)を使ってダンプしています生成:

clang -Xclang -ast-dump -fsyntax-only temp.cpp 

別のポインタではなくvisitStmtであることと、その中でfunctiondeclをチェックし、何visitFuncDecl、visitDeclRefなどを実装することができます。別々に訪問するためです。適切な機能ですべてがあなたに来るので、キャストしてケースを維持する必要はありません。訪問者パターンがそのためにどのように働くかについて詳しく読むことができます。私は非常に良いリンクを持っていない場合は、私はあなたにもそれを与えていたでしょう。

+0

ありがとうございます。これは事を明確にし、私を動かすでしょう。私は対応する行をダンプして、__builtin_va_start(ap、param)を見ることができますが、これまでのようなことは一度もありませんでした(関数呼び出し用のマクロを定義しています)。最後に、私はすでにVisitVarDeclとVisitFuctionDeclを実装しています。 VisitStmtは関数呼び出しを手助けすることです。それらを得るよりよい方法があるなら私に知らせてください。 –

+0

通常の関数とメンバー関数呼び出しの場合は、visitCallExpr、visitCXXMemberCallExprなどの関数を呼び出すことができます。もっとあるかもしれないが、私はそれを認識していない。また、元の質問が解決された場合は、それをマークしていただければ幸いです。 –

+0

ご意見ありがとうございます。私はvisitCallExprが存在することを知りませんでした!私はdoxygenのその機能を見逃していませんでした。私はこのソースを使用していたhttp://clang.llvm.org/doxygen/classclang_1_1idx_1_1ASTVisitor.html あなたは正しいです。 VisitCallExpr()も存在します.. –

関連する問題