我有以下代码片段,我正在使用 Clang 的 API 解析我正在编写的工具:
namespace NS
{
struct X
{
};
}
struct Y
{
NS::X foo();
};
I use a (type that derives from) RecursiveASTVisitor
to visit the AST .当 VisitCXXRecordDecl()
函数被调用,我可以获得指向声明的 Type
的指针对象:
bool VisitCXXRecordDecl(CXXRecordDecl* const decl)
{
auto declared_type = decl->getTypeForDecl();
// ...
}
同样,当 VisitCXXMethodDecl()
调用函数,我可以获得指向函数返回值的指针 Type
像这样:
bool VisitCXXMethodDecl(CXXMethodDecl* const func)
{
auto return_type = func->getReturnType().getTypePtr();
// ...
}
令我惊讶的是,变量 declared_type
和 return_type
上面两个函数中不要指向同一个Type
目的。
现在我确实了解规范类型,而且如果我在 VisitCXXMethodDecl()
中写入以下内容,确实如此我会得到一个指向相同 Type
的指针对象 declared_type
指向:
auto canonical_type = return_type->getCanonicalTypeInternal().getTypePtr();
// Now `canonical_type` holds a pointer to the same Type object as the
// `declared_type` variable inside VisitCXXRecordDecl().
但是,我认为只有在涉及类型别名时,类型才具有不同于自身的规范类型(至少这是我从 the Doxygen docs 和 the CFE Internals Manual 收集到的)。我不确定两个 Type
的原因是什么对象是在这里创建的,这让我相信我不明白 Type
的作用Clang 设计中的对象和规范类型。
最佳答案
这是因为 clang 如何解释函数的返回类型
NS::X foo();
^^^^^
According to the documentation , 一个 ElaboratedType
represents a type that was referred to using an elaborated type keyword, e.g., struct S, or via a qualified name, e.g., N::M::type, or both.
这意味着 declared_type
指向一个 RecordType
对象,但 return_type
实际上指向一个 ElaboratedType
。
如果您已将此源代码传递给访问者:
namespace NS
{
struct X
{
};
}
using namespace NS;
// struct NS::X -> heavily sugar'd
// NS::X -> sugar'd
// struct X -> sugar'd
// X -> not sugar'd
struct Y
{
X foo();
};
您会收到所有三个指针的相同地址。
这种区别是设计使然,与符号的可见性无关。
关于c++ - 为什么 Clang 的解析器会为同一类型生成不同的 Type 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29901376/