C++ 为什么Clang';相同类型的语法分析器是什么?

C++ 为什么Clang';相同类型的语法分析器是什么?,c++,types,clang,abstract-syntax-tree,C++,Types,Clang,Abstract Syntax Tree,我正在使用Clang的API为我正在编写的工具解析以下代码片段: namespace NS { struct X { }; } struct Y { NS::X foo(); }; 。调用VisitCXXRecordDecl()函数时,我可以得到一个指向声明的Type对象的指针: bool VisitCXXRecordDecl(CXXRecordDecl* const decl) { auto declared_type = decl->getT

我正在使用Clang的API为我正在编写的工具解析以下代码片段:

namespace NS
{
    struct X
    {
    };
}

struct Y
{
    NS::X foo();
};
。调用
VisitCXXRecordDecl()
函数时,我可以得到一个指向声明的
Type
对象的指针:

bool VisitCXXRecordDecl(CXXRecordDecl* const decl)
{
    auto declared_type = decl->getTypeForDecl();
    // ...
}
类似地,当调用
VisitCXXMethodDecl()
函数时,我可以得到一个指向函数返回
类型的指针,如下所示:

bool VisitCXXMethodDecl(CXXMethodDecl* const func) 
{
    auto return_type = func->getReturnType().getTypePtr();
    // ...
}
令我惊讶的是,上述两个函数中的变量
声明的类型
返回类型
没有指向相同的
类型
对象

现在我确实知道了规范类型,事实上,如果我在
VisitCXXMethodDecl()
中编写以下内容,我将得到一个指向相同
类型的
对象
声明类型的指针:

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().

然而,我认为一个类型只有在涉及类型别名时才有一个与自身不同的规范类型(至少这是我从和中收集到的)。我不确定在这里创建两个
Type
对象的原因是什么,这让我相信我不理解
Type
对象和规范类型在Clang设计中的作用。

原因是Clang如何解释函数的返回类型

NS::X foo();
^^^^^
,一种
精巧的类型

表示使用复杂类型关键字(例如struct S)或通过限定名称(例如N::M::type)或两者都引用的类型

这意味着
声明的类型
指向一个
记录类型
对象,但
返回类型
实际上指向一个
详细类型

如果您已将此源代码传递给访问者:

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();
};
您将收到所有三个指针的相同地址


这种区别是由设计造成的,与符号的可见性无关。

clang可能试图记住类型拼写为NS::X,而不是X(这要归功于using指令)。为什么不更仔细地研究那个非规范类型(可能在调试器中),看看它存储了什么信息?