如何使用 clang-tool 检测 SEXP 类型

问题描述

我想使用 clang-tool 检测“SEXP”返回类型函数,并打印出来。

我的叮当工具:

//define vistor
class myVisitor : public RecursiveASTVisitor<myVisitor>{
    private:
        ASTContext *ast_c ;
    public:
        explicit myVisitor(CompilerInstance *CI): ast_c(&(CI->getASTContext())){
            myrewrite.setSourceMgr(ast_c->getSourceManager(),ast_c->getLangOpts());
        }
        virtual bool VisitFunctionDecl(FunctionDecl *func){
            string funcType = func->getDeclaredReturnTypeSourceRange().getAsstring();
            std::cerr<<"type is "<<funcType<<endl;
            return true;
        }
};

//define consumer
class myASTConsumer : public ASTConsumer {
    private:
        myVisitor *visitor; 
    public:
        explicit myASTConsumer(CompilerInstance *CI): visitor(new myVisitor(CI)) {}// initialize the visitor

        virtual void HandleTranslationUnit(ASTContext &Context) {
            visitor->TraverseDecl(Context.getTranslationUnitDecl());
        }
};
//define frontend action
class FA : public ASTFrontendAction {
    public:
        FA() {}
        virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,StringRef file) {
            return  make_unique<myASTConsumer>(&CI);
        }
};
int main(int argc,const char **argv){
    auto ExpectedParser = CommonoptionsParser::create(argc,argv,MyToolCategory);
    if (!ExpectedParser) {
        // Fail gracefully for unsupported options.
        llvm::errs() << ExpectedParser.takeError();
        return 1;
    }
    CommonoptionsParser& op = ExpectedParser.get();
    ClangTool Tool(op.getCompilations(),op.getSourcePathList());

    int result = Tool.run(newFrontendActionFactory<FA>().get());
    return result;
}

我的 test.cpp :

SEXP test() { 
    int a=0;
    SEXP result;
    for(int i=0;i<2;i++){
        a++;
    }
    return result; 
}

预期输出type is SEXP

但结果是 type is int错误信息未知类型名称 'SEXP'

如何编辑我的工具以获取函数的 SEXP 类型?

解决方法

我找到了问题所在。

  1. 需要在代码顶部添加#include<R.h> #include<Rinternal.h>

  2. R 的头部在 /usr/share/R/include 但是clang的路径会在正常的包含路径中找到header,所以我们需要将它们复制到/usr/local/include/