如果您使用-fvisibility=hidden
或使用 msvc 进行编译,则必须手动导出共享库符号。作为一个实验,如何使用 AST 匹配器(clang-query)自动找到它们?
这并不容易,因为需要一组最小的导出声明,并且内联函数、模板、外联模板定义、静态数据成员等很快就会变得复杂。
也欢迎 LLVM IR 或 C++ 标准用语的一般答案。
如果您使用-fvisibility=hidden
或使用 msvc 进行编译,则必须手动导出共享库符号。作为一个实验,如何使用 AST 匹配器(clang-query)自动找到它们?
这并不容易,因为需要一组最小的导出声明,并且内联函数、模板、外联模板定义、静态数据成员等很快就会变得复杂。
也欢迎 LLVM IR 或 C++ 标准用语的一般答案。
不确定,clang-query
但如果您的图书馆的客户使用现有的公共标头,您可以通过期望它们来收集声明libclang
。ShlibVisibilityChecker 项目中给出了一个简单的例子(它识别来自共享库的虚假导出)。
您应该能够通过 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中有很多例子。