Skip to content

Commit

Permalink
add __rvalue(expression) builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Dec 3, 2024
1 parent 347c883 commit 8ced753
Show file tree
Hide file tree
Showing 20 changed files with 187 additions and 112 deletions.
1 change: 1 addition & 0 deletions compiler/src/dmd/astbase.d
Original file line number Diff line number Diff line change
Expand Up @@ -4548,6 +4548,7 @@ struct ASTBase
EXP op;
ubyte size;
ubyte parens;
ubyte rvalue; // consider this an rvalue, even if it is an lvalue
Type type;
Loc loc;

Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/clone.d
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,7 @@ private Statement generateCopyCtorBody(StructDeclaration sd)
*/
bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
{
//printf("needCopyCtor() %s\n", sd.toChars());
if (global.errors)
return false;

Expand Down Expand Up @@ -1655,7 +1656,7 @@ bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)

if (cpCtor)
{
if (rvalueCtor)
if (0 && rvalueCtor)
{
.error(sd.loc, "`struct %s` may not define both a rvalue constructor and a copy constructor", sd.toChars());
errorSupplemental(rvalueCtor.loc,"rvalue constructor defined here");
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import dmd.dclass;
import dmd.declaration;
import dmd.dmodule;
import dmd.doc;
import dmd.dstruct;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
Expand Down Expand Up @@ -156,6 +157,7 @@ extern (C++) struct Scope

AliasDeclaration aliasAsg; /// if set, then aliasAsg is being assigned a new value,
/// do not set wasRead for it
StructDeclaration argStruct; /// elimiate recursion when looking for rvalue construction

extern (D) __gshared Scope* freelist;

Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/e2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -5532,6 +5532,8 @@ elem *callfunc(const ref Loc loc,
v = ve.var.isVarDeclaration();
bool copy = !(v && (v.isArgDtorVar || v.storage_class & STC.rvalue)); // copy unless the destructor is going to be run on it
// then assume the frontend took care of the copying and pass it by ref
if (arg.rvalue) // marked with __rvalue
copy = false;

elems[i] = addressElem(ea, arg.type, copy);
continue;
Expand Down
39 changes: 24 additions & 15 deletions compiler/src/dmd/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ extern (C++) abstract class Expression : ASTNode
Loc loc; // file location
const EXP op; // to minimize use of dynamic_cast
bool parens; // if this is a parenthesized expression
bool rvalue; // true if this is considered to be an rvalue, even if it is an lvalue

extern (D) this(const ref Loc loc, EXP op) scope @safe
{
Expand Down Expand Up @@ -1307,7 +1308,7 @@ extern (C++) class IdentifierExp : Expression

override final bool isLvalue()
{
return true;
return !this.rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1351,7 +1352,7 @@ extern (C++) final class DsymbolExp : Expression

override bool isLvalue()
{
return true;
return !rvalue;

Check warning on line 1355 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L1355

Added line #L1355 was not covered by tests
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1397,7 +1398,7 @@ extern (C++) class ThisExp : Expression
override final bool isLvalue()
{
// Class `this` should be an rvalue; struct `this` should be an lvalue.
return type.toBasetype().ty != Tclass;
return !rvalue && type.toBasetype().ty != Tclass;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -1782,7 +1783,7 @@ extern (C++) final class StringExp : Expression
/* string literal is rvalue in default, but
* conversion to reference of static array is only allowed.
*/
return (type && type.toBasetype().ty == Tsarray);
return !rvalue && (type && type.toBasetype().ty == Tsarray);
}

/********************************
Expand Down Expand Up @@ -2719,7 +2720,7 @@ extern (C++) final class VarExp : SymbolExp

override bool isLvalue()
{
if (var.storage_class & (STC.lazy_ | STC.rvalue | STC.manifest))
if (rvalue || var.storage_class & (STC.lazy_ | STC.rvalue | STC.manifest))
return false;
return true;
}
Expand Down Expand Up @@ -3098,7 +3099,7 @@ extern (C++) class BinAssignExp : BinExp

override final bool isLvalue()
{
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3303,6 +3304,8 @@ extern (C++) final class DotVarExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3308 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3308

Added line #L3308 was not covered by tests
if (e1.op != EXP.structLiteral)
return true;
auto vd = var.isVarDeclaration();
Expand Down Expand Up @@ -3530,6 +3533,8 @@ extern (C++) final class CallExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3537 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3537

Added line #L3537 was not covered by tests
Type tb = e1.type.toBasetype();
if (tb.ty == Tdelegate || tb.ty == Tpointer)
tb = tb.nextOf();
Expand Down Expand Up @@ -3648,7 +3653,7 @@ extern (C++) final class PtrExp : UnaExp

override bool isLvalue()
{
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3777,7 +3782,7 @@ extern (C++) final class CastExp : UnaExp
override bool isLvalue()
{
//printf("e1.type = %s, to.type = %s\n", e1.type.toChars(), to.toChars());
if (!e1.isLvalue())
if (rvalue || !e1.isLvalue())
return false;
return (to.ty == Tsarray && (e1.type.ty == Tvector || e1.type.ty == Tsarray)) ||
e1.type.mutableOf.unSharedOf().equals(to.mutableOf().unSharedOf());
Expand Down Expand Up @@ -3834,7 +3839,7 @@ extern (C++) final class VectorArrayExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();
}

override void accept(Visitor v)
Expand Down Expand Up @@ -3891,7 +3896,7 @@ extern (C++) final class SliceExp : UnaExp
/* slice expression is rvalue in default, but
* conversion to reference of static array is only allowed.
*/
return (type && type.toBasetype().ty == Tsarray);
return !rvalue && (type && type.toBasetype().ty == Tsarray);
}

override Optional!bool toBool()
Expand Down Expand Up @@ -3956,6 +3961,8 @@ extern (C++) final class ArrayExp : UnaExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 3965 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L3964-L3965

Added lines #L3964 - L3965 were not covered by tests
if (type && type.toBasetype().ty == Tvoid)
return false;
return true;
Expand Down Expand Up @@ -4005,7 +4012,7 @@ extern (C++) final class CommaExp : BinExp

override bool isLvalue()
{
return e2.isLvalue();
return !rvalue && e2.isLvalue();
}

override Optional!bool toBool()
Expand Down Expand Up @@ -4080,7 +4087,7 @@ extern (C++) final class DelegatePtrExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();
}

override void accept(Visitor v)
Expand All @@ -4103,7 +4110,7 @@ extern (C++) final class DelegateFuncptrExp : UnaExp

override bool isLvalue()
{
return e1.isLvalue();
return !rvalue && e1.isLvalue();

Check warning on line 4113 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L4113

Added line #L4113 was not covered by tests
}

override void accept(Visitor v)
Expand Down Expand Up @@ -4143,6 +4150,8 @@ extern (C++) final class IndexExp : BinExp

override bool isLvalue()
{
if (rvalue)
return false;

Check warning on line 4154 in compiler/src/dmd/expression.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/expression.d#L4154

Added line #L4154 was not covered by tests
auto t1b = e1.type.toBasetype();
if (t1b.isTypeAArray() || t1b.isTypeSArray() ||
(e1.isIndexExp() && t1b != t1b.isTypeDArray()))
Expand Down Expand Up @@ -4251,7 +4260,7 @@ extern (C++) class AssignExp : BinExp
{
return false;
}
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -4982,7 +4991,7 @@ extern (C++) final class CondExp : BinExp

override bool isLvalue()
{
return e1.isLvalue() && e2.isLvalue();
return !rvalue && e1.isLvalue() && e2.isLvalue();
}

override void accept(Visitor v)
Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class Expression : public ASTNode
Loc loc; // file location
EXP op; // to minimize use of dynamic_cast
d_bool parens; // if this is a parenthesized expression
d_bool rvalue; // consider this an rvalue, even if it is an lvalue

size_t size() const;
static void _init();
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -3892,6 +3892,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}

scope (success) result.rvalue = exp.rvalue;

Dsymbol scopesym;
Dsymbol s = sc.search(exp.loc, exp.ident, scopesym);
if (s)
Expand Down
76 changes: 41 additions & 35 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -2068,6 +2068,7 @@ enum class EXP : uint8_t
_Generic_ = 125u,
interval = 126u,
loweredAssignExp = 127u,
rvalue = 128u,
};

typedef uint64_t dinteger_t;
Expand Down Expand Up @@ -2105,6 +2106,7 @@ class Expression : public ASTNode
Loc loc;
const EXP op;
bool parens;
bool rvalue;
size_t size() const;
static void _init();
static void deinitialize();
Expand Down Expand Up @@ -2888,33 +2890,34 @@ enum class TOK : uint8_t
wchar_tLiteral = 196u,
endOfLine = 197u,
whitespace = 198u,
inline_ = 199u,
register_ = 200u,
restrict_ = 201u,
signed_ = 202u,
sizeof_ = 203u,
typedef_ = 204u,
unsigned_ = 205u,
volatile_ = 206u,
_Alignas_ = 207u,
_Alignof_ = 208u,
_Atomic_ = 209u,
_Bool_ = 210u,
_Complex_ = 211u,
_Generic_ = 212u,
_Imaginary_ = 213u,
_Noreturn_ = 214u,
_Static_assert_ = 215u,
_Thread_local_ = 216u,
_assert_ = 217u,
_import_ = 218u,
__cdecl_ = 219u,
__declspec_ = 220u,
__stdcall_ = 221u,
__thread_ = 222u,
__pragma_ = 223u,
__int128_ = 224u,
__attribute___ = 225u,
rvalue = 199u,
inline_ = 200u,
register_ = 201u,
restrict_ = 202u,
signed_ = 203u,
sizeof_ = 204u,
typedef_ = 205u,
unsigned_ = 206u,
volatile_ = 207u,
_Alignas_ = 208u,
_Alignof_ = 209u,
_Atomic_ = 210u,
_Bool_ = 211u,
_Complex_ = 212u,
_Generic_ = 213u,
_Imaginary_ = 214u,
_Noreturn_ = 215u,
_Static_assert_ = 216u,
_Thread_local_ = 217u,
_assert_ = 218u,
_import_ = 219u,
__cdecl_ = 220u,
__declspec_ = 221u,
__stdcall_ = 222u,
__thread_ = 223u,
__pragma_ = 224u,
__int128_ = 225u,
__attribute___ = 226u,
};

class FuncExp final : public Expression
Expand Down Expand Up @@ -5259,18 +5262,18 @@ struct UnionExp final
private:
union _AnonStruct_u
{
char exp[30LLU];
char exp[31LLU];
char integerexp[40LLU];
char errorexp[30LLU];
char errorexp[31LLU];
char realexp[48LLU];
char complexexp[64LLU];
char symoffexp[64LLU];
char stringexp[51LLU];
char arrayliteralexp[48LLU];
char stringexp[59LLU];
char arrayliteralexp[56LLU];
char assocarrayliteralexp[56LLU];
char structliteralexp[76LLU];
char compoundliteralexp[40LLU];
char nullexp[30LLU];
char nullexp[31LLU];
char dotvarexp[49LLU];
char addrexp[40LLU];
char indexexp[74LLU];
Expand Down Expand Up @@ -7137,6 +7140,7 @@ struct Scope final
void* anchorCounts;
Identifier* prevAnchor;
AliasDeclaration* aliasAsg;
StructDeclaration* argStruct;
Dsymbol* search(const Loc& loc, Identifier* ident, Dsymbol*& pscopesym, uint32_t flags = 0u);
Scope() :
enclosing(),
Expand Down Expand Up @@ -7177,10 +7181,11 @@ struct Scope final
userAttribDecl(),
lastdc(),
prevAnchor(),
aliasAsg()
aliasAsg(),
argStruct()
{
}
Scope(Scope* enclosing, Module* _module = nullptr, ScopeDsymbol* scopesym = nullptr, FuncDeclaration* func = nullptr, VarDeclaration* varDecl = nullptr, Dsymbol* parent = nullptr, LabelStatement* slabel = nullptr, SwitchStatement* sw = nullptr, Statement* tryBody = nullptr, TryFinallyStatement* tf = nullptr, ScopeGuardStatement* os = nullptr, Statement* sbreak = nullptr, Statement* scontinue = nullptr, ForeachStatement* fes = nullptr, Scope* callsc = nullptr, Dsymbol* inunion = nullptr, bool nofree = false, bool inLoop = false, bool inDefaultArg = false, int32_t intypeof = 0, VarDeclaration* lastVar = nullptr, ErrorSink* eSink = nullptr, Module* minst = nullptr, TemplateInstance* tinst = nullptr, CtorFlow ctorflow = CtorFlow(), AlignDeclaration* aligndecl = nullptr, CPPNamespaceDeclaration* namespace_ = nullptr, LINK linkage = (LINK)1u, CPPMANGLE cppmangle = (CPPMANGLE)0u, PragmaDeclaration* inlining = nullptr, Visibility visibility = Visibility((Visibility::Kind)5u, nullptr), int32_t explicitVisibility = 0, uint64_t stc = 0LLU, DeprecatedDeclaration* depdecl = nullptr, uint32_t bitFields = 0u, UserAttributeDeclaration* userAttribDecl = nullptr, DocComment* lastdc = nullptr, void* anchorCounts = nullptr, Identifier* prevAnchor = nullptr, AliasDeclaration* aliasAsg = nullptr) :
Scope(Scope* enclosing, Module* _module = nullptr, ScopeDsymbol* scopesym = nullptr, FuncDeclaration* func = nullptr, VarDeclaration* varDecl = nullptr, Dsymbol* parent = nullptr, LabelStatement* slabel = nullptr, SwitchStatement* sw = nullptr, Statement* tryBody = nullptr, TryFinallyStatement* tf = nullptr, ScopeGuardStatement* os = nullptr, Statement* sbreak = nullptr, Statement* scontinue = nullptr, ForeachStatement* fes = nullptr, Scope* callsc = nullptr, Dsymbol* inunion = nullptr, bool nofree = false, bool inLoop = false, bool inDefaultArg = false, int32_t intypeof = 0, VarDeclaration* lastVar = nullptr, ErrorSink* eSink = nullptr, Module* minst = nullptr, TemplateInstance* tinst = nullptr, CtorFlow ctorflow = CtorFlow(), AlignDeclaration* aligndecl = nullptr, CPPNamespaceDeclaration* namespace_ = nullptr, LINK linkage = (LINK)1u, CPPMANGLE cppmangle = (CPPMANGLE)0u, PragmaDeclaration* inlining = nullptr, Visibility visibility = Visibility((Visibility::Kind)5u, nullptr), int32_t explicitVisibility = 0, uint64_t stc = 0LLU, DeprecatedDeclaration* depdecl = nullptr, uint32_t bitFields = 0u, UserAttributeDeclaration* userAttribDecl = nullptr, DocComment* lastdc = nullptr, void* anchorCounts = nullptr, Identifier* prevAnchor = nullptr, AliasDeclaration* aliasAsg = nullptr, StructDeclaration* argStruct = nullptr) :
enclosing(enclosing),
_module(_module),
scopesym(scopesym),
Expand Down Expand Up @@ -7220,7 +7225,8 @@ struct Scope final
lastdc(lastdc),
anchorCounts(anchorCounts),
prevAnchor(prevAnchor),
aliasAsg(aliasAsg)
aliasAsg(aliasAsg),
argStruct(argStruct)
{}
};

Expand Down
6 changes: 6 additions & 0 deletions compiler/src/dmd/hdrgen.d
Original file line number Diff line number Diff line change
Expand Up @@ -2888,6 +2888,12 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
buf.writestring(e.value.toChars());
}

if (e.rvalue)
buf.writestring("__rvalue(");

Check warning on line 2892 in compiler/src/dmd/hdrgen.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/hdrgen.d#L2892

Added line #L2892 was not covered by tests
scope (success)
if (e.rvalue)
buf.writeByte(')');

Check warning on line 2895 in compiler/src/dmd/hdrgen.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/hdrgen.d#L2895

Added line #L2895 was not covered by tests

switch (e.op)
{
default:
Expand Down
Loading

0 comments on commit 8ced753

Please sign in to comment.