I'm currently implementing a clang tool. I have no idea how to find out the noexcept-ness of a function given its clang::FunctionDecl
. For the following code
我目前正在实现一个Clang工具。在给定clang::FunctionDecl的情况下,我不知道如何找出函数的非异常。对于以下代码,
struct X {
X() = default;
};
int main() {
X x;
}
clang-query
shows that the default constructor of X
is noexcept
:
Clang-Query显示X的默认构造函数为NOEXCEPT:
-CXXConstructorDecl 0x563b8aea50e8 <line:2:3, col:15> col:3 used constexpr X 'void () noexcept' default trivial implicit-inline
`-CompoundStmt 0x563b8aea5768 <col:15>
but fd->getExceptionSpecType()
returns clang::ExceptionSpecificationType::EST_None
. Moreover, I think the noexcept-ness might also be encoded in the function type (since it is part of the function type since C++17), but I don't know how to extract that information.
但是fd->getExceptionspecType()返回clang::ExceptionSpecificationType::est_None。此外,我认为异常也可能编码在函数类型中(因为它是从C++17开始的函数类型的一部分),但我不知道如何提取该信息。
更多回答
Can you use the noexcept
operator? Like if (noexcept(X())) cout << "Yep, it is noexcept\n";
你能用NOEXCED运算符吗?Like if(noExcept(X()cout<<“是的,它是NOEXCEPT\n”;
@Eljay The problem is in the development of a clang tool (using clang compiler frontend APIs), not in the C++ source code. clang::FunctionDecl
is the AST node representing a function declaration, and I want to know whether the function being declared is noexcept
.
@Eljay问题出在clang工具的开发中(使用clang编译器前端API),而不是C++源代码。Clang::FunctionDecl是代表函数声明的AST节点,我想知道声明的函数是否为noExcept。
To get the ExceptionSpecificationType
of a
FunctionDecl
,
call
ValueDecl::getType()
to get its
QualType
,
call getTypePtr()
on that to get its
Type
,
then use
dyn_cast
to downcast that to a
FunctionProtoType
,
and finally call
FunctionProtoType::getExceptionSpecType()
.
要获取FunctionDecl的ExceptionSpecificationType,请调用ValueDecl::getType()以获取其QualType,对其调用getTypePtr()以获取其Type,然后使用dyn_cast将其向下转换为FunctionProtoType,最后调用FunctionProtoType::getExceptionspecType()。
For example:
例如:
clang::FunctionDecl const *functionDecl = /*wherever*/;
clang::Type const *type = functionDecl->getType().getTypePtr();
if (auto fpt = dyn_cast<clang::FunctionProtoType>(type)) {
clang::ExceptionSpecificationType est = fpt->getExceptionSpecType();
// Now do something with 'est'.
}
On your example, for X::X()
, the above yields EST_BasicNoexcept
.
在您的示例中,对于X::X(),上面的代码会生成EST_BasicNoExcept。
(I'm using Clang+LLVM-16.0.0 on Linux, but this should be the same
across a fairly wide range of versions.)
(我在Linux上使用的是Clang+LLVM-16.0.0,但在相当广泛的版本中应该是相同的。)
Why doesn't FunctionDecl::getExceptionSpecType work?
The documentation for FunctionDecl::getExceptionSpecType()
says:
FunctionDecl::getExceptionspecType()的文档中写道:
Gets the ExceptionSpecificationType as declared.
The "as declared" part means it only includes noexcept
if that was
syntactically present.
“如声明的”部分意味着它只包括no,除非它在句法上存在。
In contrast, by going through the FunctionProtoType
, we get implicit
exception specifications too.
相反,通过FunctionProtoType,我们也得到了隐式异常规范。
Caveat: Unevaluated exception specifications
If you remove the main
function from the example, then the above
snippet instead yields EST_Unevaluated
, whose documentation says:
如果从示例中删除Main函数,则上面的代码段将生成EST_UNEVALUATED,其文档如下所示:
not evaluated yet, for special member function
Digging through the sources (e.g.,
SemaExceptionSpec.cpp:1056
,
etc.), it seems that implicit exception specifications for constructors
and the like are not computed until needed. A call site is a "need", as
is a virtual override, perhaps among a few other cases.
深入研究源代码(例如,SemaExceptionspec.cpp:1056等),似乎直到需要时才计算构造函数等的隐式异常规范。调用点是一种“需要”,就像虚拟覆盖一样,或许还有其他几种情况。
Supplementary
If you want to go deeper on exception specifications, you may want to
look at
ExceptionAnalyzer.cpp
in the Clang sources, since that does a bunch of analysis of exception
specification semantics.
如果您想更深入地了解异常规范,您可能需要查看Clang源代码中的ExceptionAnalyzer.cpp,因为它会对异常规范语义进行大量分析。
更多回答
我是一名优秀的程序员,十分优秀!