如何找到应该导出的符号

时间:2018-11-11 07:00:48

标签: c++ shared-libraries llvm visibility clang-query

如果使用-fvisibility=hidden或msvc进行编译,则必须手动导出共享库符号。作为实验,如何使用AST匹配器(ers查询)自动找到它们?

这并不是一件容易的事,因为需要最少的一组导出声明,并且内联函数,模板,脱机模板定义,静态数据成员等使事情迅速复杂化。

也欢迎以LLVM IR或C ++标准的说法来回答。

2 个答案:

答案 0 :(得分:0)

不确定clang-query,但是如果您的库的客户端使用现有的公共头,则可以通过期望通过libclang来声明它们。 ShlibVisibilityChecker project中给出了一个简单的示例(它标识了来自共享库的虚假导出)。

答案 1 :(得分:0)

您应该能够通过AST MatchFinder获得此信息。

之类的简单匹配器
namedDecl().bind("named_decl")

将匹配所有NamedDecl个节点。然后在回调中,您可以获取节点的Linkage属性,并相应地处理该节点。打印出哪些符号具有外部链接的回调可能看起来像这样:

struct LinkagePrinter : public MatchFinder::Callback {
  void run(MatchResult const & result) override {
    using namespace clang;
    NamedDecl const * n_decl =     
      result.Nodes.getNodeAs<NamedDecl("named_decl");
    if(n_decl){
      Linkage l = n_decl->getLinkage();
      switch(l){
        case ExternalLinkage:
          std::cout << "symbol " << n_decl->getNameAsString() 
             << " has external linkage\n";
        // ... etc 
      } 
    } 
    return;
  }
}; // LinkagePrinter

这大致是正确的-我没有检查过是否可以编译。向MatchFinder注册匹配器和回调,将MatchFinder加载到工具中,您就应该做生意。 https://github.com/lanl/CoARCT中有很多示例。