Skip to main content

ExprKind

Enum ExprKind 

Source
pub enum ExprKind {
Show 21 variants Error, Const(ConstId), Str(StrId), Decl(DeclId), Member { base: ExprId, field: u32, }, Subscript { base: ExprId, index: ExprId, }, Call { callee: ExprId, args: ExprList, }, Unary { op: UnaryOp, operand: ExprId, }, Binary { op: BinaryOp, lhs: ExprId, rhs: ExprId, }, Assign { op: Option<BinaryOp>, computation: TypeId, lhs: ExprId, rhs: ExprId, }, Cond { cond: ExprId, then: ExprId, otherwise: ExprId, }, Comma { lhs: ExprId, rhs: ExprId, }, Cast(ExprId), Convert { kind: Conversion, operand: ExprId, }, CompoundLiteral(DeclId), StmtExpr(StmtId), LabelAddr(LabelId), VaArg { list: ExprId, }, VaStart { list: ExprId, }, VaEnd { list: ExprId, }, VaCopy { dst: ExprId, src: ExprId, },
}
Expand description

What an expression is.

Variants§

§

Error

A node that was already the subject of a diagnostic.

Poisoned, in the sense of spec/06-lexer-and-parser.md section 6.8: nothing is reported about one of these, which is what stops one bad declaration becoming forty bad uses.

§

Const(ConstId)

A constant, in the value table. Every constant that could be folded already has been.

§

Str(StrId)

A string literal, which is an array of characters with static storage duration.

§

Decl(DeclId)

A use of a declared object or function.

§

Member

base.field or, after the pointer has been dereferenced, base->field.

Fields

§base: ExprId

The object the field is in.

§field: u32

Which field, as an index into the record’s field list rather than as a name, since the lookup happened here and nothing after this should repeat it.

§

Subscript

base[index], with the pointer operand first however it was written.

Kept as a subscript rather than rewritten into *(base + index) because the rewriting has exactly one home, which is the walk to the IR, and because a diagnostic about a subscript should talk about a subscript.

Fields

§base: ExprId

The pointer, which has already decayed if it was an array.

§index: ExprId

The integer.

§

Call

callee(args), with the arguments already converted to the parameter types.

Fields

§callee: ExprId

The function, which is a pointer to a function after its decay.

§args: ExprList

The arguments, in order, each converted to what the prototype asks for and each promoted where the prototype does not say.

§

Unary

A prefix or postfix operator on one operand.

Fields

§op: UnaryOp

Which operator.

§operand: ExprId

What it applies to.

§

Binary

A binary operator on two operands of the same type, except for the shifts and the pointer arithmetic, where the two sides legitimately differ.

Fields

§op: BinaryOp

Which operator.

§lhs: ExprId

The left side.

§rhs: ExprId

The right side.

§

Assign

lhs = rhs, or a compound assignment with the operator kept as written.

Fields

§op: Option<BinaryOp>

The operator of a compound assignment, absent for a plain one.

§computation: TypeId

The type the operation is performed in, which is the node’s own type for a plain assignment and for most compound ones.

It is here because a op= b is not a = a op b with the conversions left out, and the difference is not academic: in int i = 5; i /= 0.5; the division happens in double and the answer is ten, and a compiler that converts the right side to int first divides by zero. The left side is an lvalue and cannot carry a conversion node of its own, so the type it is read into is written here instead, which is what clang calls the computation type and for the same reason.

§lhs: ExprId

What is assigned to, which is an lvalue.

§rhs: ExprId

What is assigned.

§

Cond

cond ? then : otherwise, with both arms already converted to the common type.

Fields

§cond: ExprId

The condition, converted to bool.

§then: ExprId

The arm taken when it is true. GNU’s cond ?: otherwise has this equal to the condition before its conversion, so the value is computed once.

§otherwise: ExprId

The arm taken when it is false.

§

Comma

lhs, rhs, whose value is the right side and whose left side is evaluated and dropped.

Fields

§lhs: ExprId

Evaluated first, for its effects.

§rhs: ExprId

The value.

§

Cast(ExprId)

A cast the program wrote. The type is the node’s type.

§

Convert

A conversion the language performed. The type is the node’s type.

Fields

§kind: Conversion

Which conversion, so that a reader and the verifier can both tell what happened rather than comparing the two types and guessing.

§operand: ExprId

What was converted.

§

CompoundLiteral(DeclId)

(T){ ... }, which is an unnamed object with an initializer and not a conversion.

§

StmtExpr(StmtId)

({ ... }), GNU’s statement expression, whose value is its last expression statement.

§

LabelAddr(LabelId)

&&label, GNU’s label address.

§

VaArg

va_arg(list, T), which reads the next argument and moves the list on.

The type it fetches is the node’s own type, so there is nothing else to hold. It is a node rather than a call because what it becomes is the target’s own sequence of loads and not a function anything links against.

Fields

§list: ExprId

The address of the list, which is what this reads through and moves on.

§

VaStart

va_start(list, last), which sets a list to the first argument past the named ones.

What the source wrote as the second argument is not here. It names where the named arguments stopped, which the enclosing function’s own type already says, and it is not evaluated: gcc rewrites va_start(ap, last) to a call with a zero in that place and C23 lets the program leave it out altogether.

Fields

§list: ExprId

The address of the list, which this writes.

§

VaEnd

va_end(list), which is the end of the reading and is nothing at all on most targets.

Fields

§list: ExprId

The address of the list.

§

VaCopy

va_copy(dst, src), which makes a second list standing where the first one stands.

Fields

§dst: ExprId

The address of the list being written.

§src: ExprId

The address of the list being read, which stays where it is.

Trait Implementations§

Source§

impl Clone for ExprKind

Source§

fn clone(&self) -> ExprKind

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for ExprKind

Source§

impl Debug for ExprKind

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for ExprKind

Source§

impl PartialEq for ExprKind

Source§

fn eq(&self, other: &ExprKind) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ExprKind

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.