2

現在、LLVM + Clangを使用しています。ASTUnitを使用してツリーを構築し、RecursiveASTVisitorを使用してツリーをトラバースします。

    clang::ASTUnit* AST;
    clang::DiagnosticOptions diagOpts;
    llvm::IntrusiveRefCntPtr<clang::Diagnostic> diags = clang::CompilerInstance::createDiagnostics(diagOpts, 0, 0);

    const char** ptr = new const char*[1];
    ptr[0] = argv[1];

    clang::CompilerInvocation *ci = new clang::CompilerInvocation();
    clang::CompilerInvocation::CreateFromArgs(*ci, ptr, ptr+1, *diags);
    ci->setLangDefaults(clang::IK_CXX, clang::LangStandard::lang_cxx98);
    ci->getPreprocessorOutputOpts().ShowComments = 1;
    ci->getPreprocessorOutputOpts().ShowLineMarkers = 1;

    AST = clang::ASTUnit::LoadFromCompilerInvocation(ci, diags);

    ...
    ...

    MyRecursiveASTVisitor myvis(AST->getASTContext());
    myvis.TraverseDecl(AST->getASTContext().getTranslationUnitDecl());

含まれているシステムライブラリにアクセスすることは避けたいと思います。出来ますか?

4

1 に答える 1

3

私はある種の解決策を見つけたと思いますが、最終的な解決策ではありません!

継承されたASTVisitorクラスの場合:

class MyRecursiveASTVisitor : public clang::RecursiveASTVisitor<MyRecursiveASTVisitor>

関数TraverseDeclをオーバーライドできます。この関数では、宣言をトラバースできます。この関数を再帰的に呼び出さない場合、宣言がメインファイルからのものでない場合は、他のファイルからの宣言をトラバースすることを回避できます。

bool TraverseDecl ( clang::Decl *D )
{
    bool rval;

    if (!D) return true;

    if (sm.isFromMainFile(D->getLocation()) || std::string(D->getDeclKindName()) == "TranslationUnit")
    {
        bool rval = clang::RecursiveASTVisitor<MyRecursiveASTVisitor>::TraverseDecl(D);
    }
    else
        rval = true;

    return rval;
}

このコンテキストでは、smはクラスMyRecursiveASTVisitorのclang::SourceManagerです。オーバーライドされたTraverseStmt関数で、同じ方法で他のファイルからステートメントをトラバースすることを回避できます。

ここで、ステートメントまたは宣言がシステムライブラリからのものか、ユーザー定義ライブラリからのものかを知る方法だけを説明します。

于 2012-05-07T16:41:18.217 に答える