如何在Clang中获取FunctionDecl的noexcept属性?
如何通过clang::FunctionDecl获取函数的noexcept属性
针对你遇到的问题——默认构造函数在clang-query中显示为noexcept,但调用fd->getExceptionSpecType()返回EST_None,原因在于C++17起noexcept成为函数类型的一部分,而隐式生成的函数(如默认构造函数)的noexcept是编译器自动推断的,并非显式声明的异常规范,因此getExceptionSpecType()无法直接反映这一信息。
以下是正确的提取方式:
核心思路
从函数的类型对象(而非直接从FunctionDecl)中提取noexcept信息,具体步骤如下:
- 获取函数的类型,并转换为
FunctionProtoType(包含函数原型细节,包括异常规范); - 通过
FunctionProtoType的成员函数判断是否带有noexcept属性。
代码示例
#include "clang/AST/AST.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" using namespace clang; bool isFunctionNoexcept(FunctionDecl *fd) { // 获取函数类型并转换为FunctionProtoType if (auto *protoType = fd->getType()->getAs<FunctionProtoType>()) { // hasNoExcept() 返回是否带有noexcept属性(包括隐式推断的情况) return protoType->hasNoExcept(); } // 非原型函数类型(如函数指针的旧类型),默认返回false return false; } // 针对构造函数的特殊处理(可选,通用方法已覆盖该场景) bool isConstructorNoexcept(CXXConstructorDecl *ctor) { if (auto *protoType = ctor->getType()->getAs<FunctionProtoType>()) { return protoType->hasNoExcept(); } return false; }
关键说明
getExceptionSpecType()仅返回显式声明的异常规范类型(如throw()、noexcept(true)等),对于编译器隐式推断的noexcept(如你的默认构造函数,因trivial而自动成为noexcept),会返回EST_None,这是符合预期的行为。FunctionProtoType::hasNoExcept()会同时考虑显式声明和隐式推断的noexcept属性,与clang-query显示的结果一致。- 对于C++17及以后的代码,所有带原型的函数类型都会被表示为
FunctionProtoType,因此上述方法具有通用性。
内容的提问来源于stack exchange,提问作者GKxx
相关产品推荐
相关产品推荐

