使用 Clang LibTooling 扫描C++在模板化父类中调用本地类的源



要扫描的源代码:

template <typename T>
class HB {
T m;
public:
void HBfunc1();
};
template <typename T>
void HB<T>::HBfunc1() {  
class HC {      
public:
void HCfunc2() { };
};    
HC().HCfunc2();
}
void TestTemplate() { HB<int>().HBfunc1(); };

上面的代码在VS2019中工作正常,当使用Clang LibTooling扫描AST时:

virtual bool VisitCallExpr(CallExpr *call) {
std::cout << "VisitCallExpr: ";
if (call->getDirectCallee()) {
std::cout << " "<<call->getDirectCallee()->getQualifiedNameAsString();
}
else {
Decl *callee = call->getCalleeDecl();
if (!callee) {
std::cout << "nNow dump call:n";
call->dump();
}
}
std::cout<<"n";
return true;
}

在扫描的源中访问此行的 CallExpr 时:

HC().HCfunc2();

被调用方为空,CallExpr 的转储为:

VisitCallExpr:
Now dump call:
CallExpr 0x1c2ef83b3a0 '<dependent type>'
`-CXXDependentScopeMemberExpr 0x1c2ef83b348 '<dependent type>' lvalue .HCfunc2
`-CXXUnresolvedConstructExpr 0x1c2ef83b320 'class HC' 'class HC'

Clang在扫描过程中不会报告错误(因为代码工作正常(。

在LLVM源代码中,有:

// This represents the type of an expression whose type is
// totally unknown, e.g. 'T::foo'.  It is permitted for this to
// appear in situations where the structure of the type is
// theoretically deducible.
BUILTIN_TYPE(Dependent, DependentTy)

为什么HC类型被认为是未知的?扫描 AST 而不发出任何警告/错误时,是否有任何类型是未知的?如何访问这样的调用并提取有关其被调用方的信息?扫描的代码有问题吗?

Clang 在这种情况下是保守的,将函数调用标记为未解析(也称为依赖(。依赖事物仅出现在模板中。这意味着某些语法结构可能取决于模板参数。

HC类不是通常的类,您将拥有与HB的实例化数量一样多的单独HC类。因此,如果HC不使用T,则将其放置在HBfunc1内几乎没有意义。否则,它确实是依赖性的。Clang更喜欢安全,并避免在依赖上下文中定义smth时不依赖于的假设。

由于这些原因,拥有这样的 AST 节点是绝对正常的。这不是解析器错误,一切都按预期工作。根据有关被调用方的确切信息,简短的回答是 - 分析模板时没有办法。但是,clang 为每个实例生成 AST。那些具有通常的AST结构,可以很容易地访问。

我希望这些信息对您有所帮助!

最新更新