From 331c61e385b5d5b43a320666fd49ff30dea1548e Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Wed, 27 Sep 2023 16:02:04 +0800 Subject: [PATCH] implement `pragma(__ctfe [,bool])` --- dmd/dsymbolsem.d | 16 ++++++++++++-- dmd/statementsem.d | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/dmd/dsymbolsem.d b/dmd/dsymbolsem.d index a777d695dde..5915f2b97f2 100644 --- a/dmd/dsymbolsem.d +++ b/dmd/dsymbolsem.d @@ -1711,7 +1711,7 @@ version (IN_LLVM) } return se; } - void declarations() + void declarations(bool skipCodegen = false) { if (!pd.decl) return; @@ -1729,7 +1729,13 @@ version (IN_LLVM) s.dsymbolSemantic(sc2); continue; } - + if (pd.ident == Id.ctfe) + { + if (auto fd = s.isFuncDeclaration()) + { + fd.skipCodegen = skipCodegen; + } + } s.dsymbolSemantic(sc2); if (pd.ident != Id.mangle) { @@ -1893,6 +1899,12 @@ else // !IN_LLVM return declarations(); } + else if (pd.ident == Id.ctfe) + { + bool skipCodegen; + pragmaCtfeSemanitc(pd.loc, sc, pd.args, skipCodegen); + return declarations(skipCodegen); + } else if (pd.ident == Id.mangle) { if (!pd.args) diff --git a/dmd/statementsem.d b/dmd/statementsem.d index c35449a6897..3e1369058dc 100644 --- a/dmd/statementsem.d +++ b/dmd/statementsem.d @@ -1844,6 +1844,21 @@ Statement statementSemanticVisit(Statement s, Scope* sc) return setError(); } } + else if (ps.ident == Id.ctfe) + { + if (auto fd = sc.func) + { + bool skipCodegen; + if (!pragmaCtfeSemanitc(ps.loc, sc, ps.args, skipCodegen)) + return setError(); + fd.skipCodegen = skipCodegen; + } + else + { + ps.error("`pragma(__ctfe)` is not inside a function"); + return setError(); + } + } else if (!global.params.ignoreUnsupportedPragmas) { ps.error("unrecognized `pragma(%s)`", ps.ident.toChars()); @@ -5033,6 +5048,44 @@ private void debugThrowWalker(Statement s) s.accept(walker); } +bool pragmaCtfeSemanitc(Loc loc, Scope* sc, Expressions *args, out bool skipCodegen) +{ + if (!args) + { + skipCodegen = true; + return true; + } + if (args.length != 1) + { + .error(loc, "one `bool` argument expected for `__ctfe`"); + skipCodegen = true; + return false; + } + Expression e = (*args)[0]; + sc = sc.startCTFE(); + e = e.expressionSemantic(sc); + e = resolveProperties(sc, e); + sc = sc.endCTFE(); + + e = e.ctfeInterpret(); + if (!e) + { + skipCodegen = true; + return false; + } + (*args)[0] = e; + auto opt = e.toBool(); + if (opt.isEmpty()) + { + .error(loc, "one `bool` argument expected for `__ctfe`"); + skipCodegen = true; + return false; + } + skipCodegen = opt.get(); + return true; + +} + /*********************************************************** * Evaluate and print a `pragma(msg, args)` *