You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:32:44