2014-07-03 116 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