Skip to content

Commit cbc95f8

Browse files
authored
Issue llvm#45: Implement is_noexcept meta function (llvm#56)
1 parent 9ac1246 commit cbc95f8

File tree

3 files changed

+358
-0
lines changed

3 files changed

+358
-0
lines changed

clang/lib/Sema/Metafunctions.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ static bool is_explicit(APValue &Result, Sema &S, EvalFn Evaluator,
159159
QualType ResultTy, SourceRange Range,
160160
ArrayRef<Expr *> Args);
161161

162+
static bool is_noexcept(APValue &Result, Sema &S, EvalFn Evaluator,
163+
QualType ResultTy, SourceRange Range,
164+
ArrayRef<Expr *> Args);
165+
162166
static bool is_bit_field(APValue &Result, Sema &S, EvalFn Evaluator,
163167
QualType ResultTy, SourceRange Range,
164168
ArrayRef<Expr *> Args);
@@ -396,6 +400,7 @@ static constexpr Metafunction Metafunctions[] = {
396400
{ Metafunction::MFRK_bool, 1, 1, is_deleted },
397401
{ Metafunction::MFRK_bool, 1, 1, is_defaulted },
398402
{ Metafunction::MFRK_bool, 1, 1, is_explicit },
403+
{ Metafunction::MFRK_bool, 1, 1, is_noexcept },
399404
{ Metafunction::MFRK_bool, 1, 1, is_bit_field },
400405
{ Metafunction::MFRK_bool, 1, 1, has_static_storage_duration },
401406
{ Metafunction::MFRK_bool, 1, 1, has_internal_linkage },
@@ -1103,6 +1108,25 @@ bool isAccessible(Sema &S, DeclContext *AccessDC, NamedDecl *D) {
11031108
return Result;
11041109
}
11051110

1111+
static bool isFunctionOrMethodNoexcept(const QualType QT) {
1112+
const Type* T = QT.getTypePtr();
1113+
1114+
if (T->isFunctionProtoType()) {
1115+
// This covers (virtual) methods & functions
1116+
const auto *FPT = T->getAs<FunctionProtoType>();
1117+
1118+
switch (FPT->getExceptionSpecType()) {
1119+
case EST_BasicNoexcept:
1120+
case EST_NoexceptTrue:
1121+
return true;
1122+
default:
1123+
return false;
1124+
}
1125+
}
1126+
1127+
return false;
1128+
}
1129+
11061130
// -----------------------------------------------------------------------------
11071131
// Metafunction implementations
11081132
// -----------------------------------------------------------------------------
@@ -2645,6 +2669,39 @@ bool is_explicit(APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
26452669
llvm_unreachable("invalid reflection type");
26462670
}
26472671

2672+
bool is_noexcept(APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
2673+
SourceRange Range, ArrayRef<Expr *> Args) {
2674+
assert(Args[0]->getType()->isReflectionType());
2675+
assert(ResultTy == S.Context.BoolTy);
2676+
2677+
APValue R;
2678+
if (!Evaluator(R, Args[0], true))
2679+
return true;
2680+
2681+
switch (R.getReflection().getKind()) {
2682+
case ReflectionValue::RK_null:
2683+
case ReflectionValue::RK_expr_result:
2684+
case ReflectionValue::RK_template:
2685+
case ReflectionValue::RK_namespace:
2686+
case ReflectionValue::RK_base_specifier:
2687+
case ReflectionValue::RK_data_member_spec:
2688+
return SetAndSucceed(Result, makeBool(S.Context, false));
2689+
case ReflectionValue::RK_type: {
2690+
const QualType QT = R.getReflectedType();
2691+
const auto result = isFunctionOrMethodNoexcept(QT);
2692+
2693+
return SetAndSucceed(Result, makeBool(S.Context, result));
2694+
}
2695+
case ReflectionValue::RK_declaration: {
2696+
const ValueDecl *D = R.getReflectedDecl();
2697+
const auto result = isFunctionOrMethodNoexcept(D->getType());
2698+
2699+
return SetAndSucceed(Result, makeBool(S.Context, result));
2700+
}
2701+
}
2702+
llvm_unreachable("invalid reflection type");
2703+
}
2704+
26482705
bool is_bit_field(APValue &Result, Sema &S, EvalFn Evaluator, QualType ResultTy,
26492706
SourceRange Range, ArrayRef<Expr *> Args) {
26502707
assert(Args[0]->getType()->isReflectionType());

libcxx/include/experimental/meta

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ consteval auto is_override(info) -> bool;
120120
consteval auto is_deleted(info) -> bool;
121121
consteval auto is_defaulted(info) -> bool;
122122
consteval auto is_explicit(info) -> bool;
123+
consteval bool is_noexcept(info) -> bool;
123124
consteval auto is_bit_field(info) -> bool;
124125
consteval auto has_static_storage_duration(info) -> bool;
125126
consteval auto has_internal_linkage(info) -> bool;
@@ -394,6 +395,7 @@ enum : unsigned {
394395
__metafn_is_deleted,
395396
__metafn_is_defaulted,
396397
__metafn_is_explicit,
398+
__metafn_is_noexcept,
397399
__metafn_is_bit_field,
398400
__metafn_has_static_storage_duration,
399401
__metafn_has_internal_linkage,
@@ -907,6 +909,12 @@ consteval auto is_explicit(info r) -> bool {
907909
return __metafunction(detail::__metafn_is_explicit, r);
908910
}
909911

912+
// Returns whether the reflected function type, function or member function
913+
// is noexcept.
914+
consteval auto is_noexcept(info r) -> bool {
915+
return __metafunction(detail::__metafn_is_noexcept, r);
916+
}
917+
910918
// Returns whether the reflected class data member is a bit field.
911919
consteval auto is_bit_field(info r) -> bool {
912920
return __metafunction(detail::__metafn_is_bit_field, r);

0 commit comments

Comments
 (0)