Skip to content

Commit 47c93c6

Browse files
MitalAshokyuxuanchen1997
authored andcommitted
[Clang] Add attribute for consteval builtin functions (#91894)
Summary: Builtins with the new `Consteval` attribute will also be marked `Constexpr` and will only be available in C++20 mode where `consteval` makes sense. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251624
1 parent 03e85e3 commit 47c93c6

File tree

6 files changed

+28
-6
lines changed

6 files changed

+28
-6
lines changed

clang/include/clang/Basic/Builtins.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,4 @@
101101
// M_0, ..., M_k as payload
102102
// z -> this is a function in (possibly-versioned) namespace std
103103
// E -> this function can be constant evaluated by Clang frontend
104+
// G -> this is a C++20 consteval function

clang/include/clang/Basic/Builtins.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ class Context {
280280
return strchr(getRecord(ID).Attributes, 'E') != nullptr;
281281
}
282282

283+
/// Returns true if this is an immediate (consteval) function
284+
bool isImmediate(unsigned ID) const {
285+
return strchr(getRecord(ID).Attributes, 'G') != nullptr;
286+
}
287+
283288
private:
284289
const Info &getRecord(unsigned ID) const;
285290

clang/include/clang/Basic/BuiltinsBase.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class VScanfFormat<int I> : IndexedAttribute<"S", I>;
7070

7171
// Builtin can be constant evaluated
7272
def Constexpr : Attribute<"E">;
73+
// Builtin is immediate and must be constant evaluated. Implies Constexpr, and will only be supported in C++20 mode.
74+
def Consteval : Attribute<"EG">;
7375

7476
// Builtin kinds
7577
// =============

clang/lib/Basic/Builtins.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
119119
/* CPlusPlus Unsupported */
120120
if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
121121
return false;
122+
/* consteval Unsupported */
123+
if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr)
124+
return false;
122125
return true;
123126
}
124127

clang/lib/Sema/SemaDecl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,10 +2294,17 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
22942294
Parent = CLinkageDecl;
22952295
}
22962296

2297-
FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type,
2298-
/*TInfo=*/nullptr, SC_Extern,
2299-
getCurFPFeatures().isFPConstrained(),
2300-
false, Type->isFunctionProtoType());
2297+
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified;
2298+
if (Context.BuiltinInfo.isImmediate(ID)) {
2299+
assert(getLangOpts().CPlusPlus20 &&
2300+
"consteval builtins should only be available in C++20 mode");
2301+
ConstexprKind = ConstexprSpecKind::Consteval;
2302+
}
2303+
2304+
FunctionDecl *New = FunctionDecl::Create(
2305+
Context, Parent, Loc, Loc, II, Type, /*TInfo=*/nullptr, SC_Extern,
2306+
getCurFPFeatures().isFPConstrained(), /*isInlineSpecified=*/false,
2307+
Type->isFunctionProtoType(), ConstexprKind);
23012308
New->setImplicit();
23022309
New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));
23032310

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6770,8 +6770,12 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
67706770
}
67716771

67726772
// Bail out early if calling a builtin with custom type checking.
6773-
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
6774-
return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
6773+
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) {
6774+
ExprResult E = CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
6775+
if (!E.isInvalid() && Context.BuiltinInfo.isImmediate(BuiltinID))
6776+
E = CheckForImmediateInvocation(E, FDecl);
6777+
return E;
6778+
}
67756779

67766780
if (getLangOpts().CUDA) {
67776781
if (Config) {

0 commit comments

Comments
 (0)