Skip to content

Commit

Permalink
[Clang] Add attribute for consteval builtin functions (llvm#91894)
Browse files Browse the repository at this point in the history
Builtins with the new `Consteval` attribute will also be marked
`Constexpr` and will only be available in C++20 mode where `consteval`
makes sense.
  • Loading branch information
MitalAshok authored Jul 17, 2024
1 parent 8917d52 commit 396a5ba
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 6 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Builtins.def
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,4 @@
// M_0, ..., M_k as payload
// z -> this is a function in (possibly-versioned) namespace std
// E -> this function can be constant evaluated by Clang frontend
// G -> this is a C++20 consteval function
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/Builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ class Context {
return strchr(getRecord(ID).Attributes, 'E') != nullptr;
}

/// Returns true if this is an immediate (consteval) function
bool isImmediate(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'G') != nullptr;
}

private:
const Info &getRecord(unsigned ID) const;

Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsBase.td
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class VScanfFormat<int I> : IndexedAttribute<"S", I>;

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

// Builtin kinds
// =============
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
/* CPlusPlus Unsupported */
if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
return false;
/* consteval Unsupported */
if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr)
return false;
return true;
}

Expand Down
15 changes: 11 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2294,10 +2294,17 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
Parent = CLinkageDecl;
}

FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type,
/*TInfo=*/nullptr, SC_Extern,
getCurFPFeatures().isFPConstrained(),
false, Type->isFunctionProtoType());
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified;
if (Context.BuiltinInfo.isImmediate(ID)) {
assert(getLangOpts().CPlusPlus20 &&
"consteval builtins should only be available in C++20 mode");
ConstexprKind = ConstexprSpecKind::Consteval;
}

FunctionDecl *New = FunctionDecl::Create(
Context, Parent, Loc, Loc, II, Type, /*TInfo=*/nullptr, SC_Extern,
getCurFPFeatures().isFPConstrained(), /*isInlineSpecified=*/false,
Type->isFunctionProtoType(), ConstexprKind);
New->setImplicit();
New->addAttr(BuiltinAttr::CreateImplicit(Context, ID));

Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6770,8 +6770,12 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
}

// Bail out early if calling a builtin with custom type checking.
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) {
ExprResult E = CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
if (!E.isInvalid() && Context.BuiltinInfo.isImmediate(BuiltinID))
E = CheckForImmediateInvocation(E, FDecl);
return E;
}

if (getLangOpts().CUDA) {
if (Config) {
Expand Down

0 comments on commit 396a5ba

Please sign in to comment.