Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add __rvalue(expression) builtin #17050

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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 @@
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 @@

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

override void accept(Visitor v)
Expand Down Expand Up @@ -1351,7 +1352,7 @@

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 @@
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 @@
/* 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 @@

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 @@

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

override void accept(Visitor v)
Expand Down Expand Up @@ -3303,6 +3304,8 @@

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 @@

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 @@

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

override void accept(Visitor v)
Expand Down Expand Up @@ -3777,7 +3782,7 @@
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 @@

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

override void accept(Visitor v)
Expand Down Expand Up @@ -3891,7 +3896,7 @@
/* 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 @@

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 @@

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

override Optional!bool toBool()
Expand Down Expand Up @@ -4080,7 +4087,7 @@

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

override void accept(Visitor v)
Expand All @@ -4103,7 +4110,7 @@

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 @@

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 @@
{
return false;
}
return true;
return !rvalue;
}

override void accept(Visitor v)
Expand Down Expand Up @@ -4982,7 +4991,7 @@

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
67 changes: 35 additions & 32 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
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 @@
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
10 changes: 10 additions & 0 deletions compiler/src/dmd/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -5877,6 +5877,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.moduleString:
case TOK.functionString:
case TOK.prettyFunction:
case TOK.rvalue:
Lexp:
{
AST.Expression exp = parseExpression();
Expand Down Expand Up @@ -8423,6 +8424,15 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
e = new AST.TypeidExp(loc, o);
break;
}
case TOK.rvalue:
{
nextToken();
check(TOK.leftParenthesis, "`__rvalue`");
e = parseAssignExp();
e.rvalue = true;
check(TOK.rightParenthesis);
break;
}
case TOK.traits:
{
/* __traits(identifier, args...)
Expand Down
7 changes: 7 additions & 0 deletions compiler/src/dmd/tokens.d
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ enum TOK : ubyte
{
reserved,

// if this list changes, update
// tokens.h, ../tests/cxxfrontend.cc and ../../test/unit/lexer/location_offset.d to match

// Other
leftParenthesis,
rightParenthesis,
Expand Down Expand Up @@ -249,6 +252,7 @@ enum TOK : ubyte
wchar_tLiteral,
endOfLine, // \n, \r, \u2028, \u2029
whitespace,
rvalue,

// C only keywords
inline,
Expand Down Expand Up @@ -425,6 +429,7 @@ enum EXP : ubyte
interval,

loweredAssignExp,
rvalue,
}

enum FirstCKeyword = TOK.inline;
Expand Down Expand Up @@ -556,6 +561,7 @@ private immutable TOK[] keywords =
TOK.prettyFunction,
TOK.shared_,
TOK.immutable_,
TOK.rvalue,

// C only keywords
TOK.inline,
Expand Down Expand Up @@ -680,6 +686,7 @@ extern (C++) struct Token
TOK.pragma_: "pragma",
TOK.typeof_: "typeof",
TOK.typeid_: "typeid",
TOK.rvalue: "__rvalue",
TOK.template_: "template",
TOK.void_: "void",
TOK.int8: "byte",
Expand Down
Loading
Loading