2014-07-03 62 views
1

我想定義一個函數,它將使用Clang LibTooling庫返回一個指向最後定義的公共方法的指針。Clang:檢索公共方法

目前我有一個CXXRecordDecl指針*decl和下面一行來獲取第一個方法的源位置。

const SourceLocation method_begin_location = decl->method_begin()->getLocation(); 

理想情況下,我想如果沒有方法如下用一個函數來代替它來獲取最後定義的公共方法的位置或公衆聲明的開頭的位置。

const SourceLocation last_public_method_location = get_last_public_method_loc(decl); 

對寫這個函數有什麼見解? method_end()指向方法定義的末尾,所以它沒有我期望的那麼有用。

+0

這種級別的編譯時反射不支持(但)。甚至有更少的運行時類型infortmation。 – Deduplicator

回答

2

這可能是你可以嘗試的東西。我有一個變量,它應該存儲您定義的顯式定義的最後一個公共方法的名稱,這意味着它不會被編譯器自動添加。匹配methodDecl(isPublic(), unless(isImplicit()))匹配器的每個函數都將存儲在lastPublicMethodName字符串變量中,最終將包含最後訪問的方法。

我強烈建議您把這個網站放在您的後面的口袋裏,用於所有的AST匹配器:http://clang.llvm.org/docs/LibASTMatchersReference.html。此外,tools/clang/unitests/ASTMatchers/ASTMatchersTest.cpp是一個寶貴的資源,如果你想找出一個特定的匹配器如何工作。

這是我解析代碼:

/tmp/Foo.hpp:

class Foo { 
    public: 
     virtual ~Foo() {} 
     virtual void somePublicFunction1() = 0; 
     virtual void somePublicFunction2() = 0; 
     virtual void somePublicFunction3() = 0; 
     virtual void somePublicFunction4() = 0; 
     virtual void somePublicFunction5() = 0; 
    private: 
     virtual void somePrivateFunction1() = 0; 
     virtual void somePrivateFunction2() = 0; 
     virtual void somePrivateFunction3() = 0; 
     virtual void somePrivateFunction4() = 0; 
     virtual void somePrivateFunction5() = 0; 
}; 

這是我鏘工具的程序代碼:

LLVM /工具/鐺/tools/extra/mytool/MyTool.cpp

// Declares clang::SyntaxOnlyAction. 
#include "clang/Frontend/FrontendActions.h" 
#include "clang/Tooling/CommonOptionsParser.h" 
#include "clang/Tooling/Tooling.h" 
// Declares llvm::cl::extrahelp. 
#include "llvm/Support/CommandLine.h" 
#include "clang/ASTMatchers/ASTMatchers.h" 
#include "clang/ASTMatchers/ASTMatchFinder.h" 
#include <iostream> 

using namespace clang; 
using namespace clang::ast_matchers; 
using namespace clang::tooling; 
using namespace llvm; 

// Apply a custom category to all command-line options so that they are the 
// only ones displayed. 
static llvm::cl::OptionCategory MyToolCategory("my-tool options"); 

// CommonOptionsParser declares HelpMessage with a description of the common 
// command-line options related to the compilation database and input files. 
// It's nice to have this help message in all tools. 
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); 

// A help message for this specific tool can be added afterwards. 
static cl::extrahelp MoreHelp("\nMore help text..."); 

DeclarationMatcher methodMatcher = methodDecl(isPublic(),unless(isImplicit())).bind("methods"); 

class MethodPrinter : public MatchFinder::MatchCallback { 
public : 
    virtual void run(const MatchFinder::MatchResult &Result) { 
    if (const CXXMethodDecl *md = Result.Nodes.getNodeAs<clang::CXXMethodDecl>("methods")) {  
     lastPublicMethodName = md->getNameAsString(); 
    } 
    } 

    std::string lastPublicMethodName; 
}; 

int main(int argc, const char **argv) { 
    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); 
    ClangTool Tool(OptionsParser.getCompilations(), 
       OptionsParser.getSourcePathList()); 

    MethodPrinter Printer; 
    MatchFinder Finder; 
    Finder.addMatcher(methodMatcher, &Printer); 

    Tool.run(newFrontendActionFactory(&Finder).get()); 

    std::cout << "The last public method is: " << Printer.lastPublicMethodName << std::endl; 
    return 0; 
} 

我希望這可以幫助你。

+0

我想這雖然「技術上」起作用。我在我的匹配器中有其他功能,我不能等到整個匹配過程完成之後纔有指向最後一個公共方法的指針。感謝這個例子,我想我最終可能會爲公共方法體寫一個匹配器。我希望有人能夠幫助我使用method_iterator,我是C++的新手。 – Lucas