src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml (805 lines of code) (raw):

<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. --> <!-- To re-generate source from this file, run build/scripts/generate-compiler-code.cmd Important things to know about reference types, value types, and nulls. By default, all fields of reference type are checked (in debug) to be non-null. This can be modified by used the "Null" attribute, which can be one of the following values: disallow (default) - disallow null values allow - allow null values always - always null - only used in an override to indicate that this subclass always sets this field to null. notApplicable - its a value type, so it cannot be null In order to generate code, the generator needs to know what types beyond the built-in types are value types. This is indicated via a "ValueType" declaration. --> <Tree Root="BoundNode"> <!-- Don't put ImmutableArray here, that's handled in a special way internally.--> <ValueType Name="ConversionKind"/> <ValueType Name="Conversion"/> <ValueType Name="TextSpan"/> <ValueType Name="UnaryOperatorKind"/> <ValueType Name="BinaryOperatorKind"/> <ValueType Name="LookupResultKind"/> <ValueType Name="NoOpStatementFlavor"/> <ValueType Name="RefKind"/> <ValueType Name="BoundTypeOrValueData"/> <AbstractNode Name="BoundInitializer" Base="BoundNode"/> <Node Name="BoundFieldInitializer" Base="BoundInitializer"> <Field Name="Field" Type="FieldSymbol"/> <Field Name="InitialValue" Type="BoundExpression"/> </Node> <AbstractNode Name="BoundEqualsValue" Base="BoundNode"> <!-- Expression representing the value. --> <Field Name="Value" Type="BoundExpression"/> </AbstractNode> <!-- Bound node that represents the binding of an "= Value" construct in a field declaration. Appears only in bound trees generated by a SemanticModel. --> <Node Name="BoundFieldEqualsValue" Base="BoundEqualsValue"> <!-- Field receiving the value. --> <Field Name="Field" Type="FieldSymbol"/> </Node> <!-- Bound node that represents the binding of an "= Value" construct in a property declaration. Appears only in bound trees generated by a SemanticModel. --> <Node Name="BoundPropertyEqualsValue" Base="BoundEqualsValue"> <!-- Property receiving the value. --> <Field Name="Property" Type="PropertySymbol"/> </Node> <!-- Bound node that represents the binding of an "= Value" construct in a parameter declaration. Appears only in bound trees generated by a SemanticModel. --> <Node Name="BoundParameterEqualsValue" Base="BoundEqualsValue"> <!-- Parameter receiving the value. --> <Field Name="Parameter" Type="ParameterSymbol"/> </Node> <Node Name="BoundGlobalStatementInitializer" Base="BoundInitializer"> <Field Name="Statement" Type="BoundStatement"/> </Node> <AbstractNode Name="BoundExpression" Base="BoundNode"> <Field Name="Type" Type="TypeSymbol" Null="allow"/> </AbstractNode> <AbstractNode Name="BoundValuePlaceholderBase" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </AbstractNode> <!-- This node is used to represent an expression returning value of a certain type. It is used to perform intermediate binding, and will not survive the local rewriting. --> <Node Name="BoundDeconstructValuePlaceholder" Base="BoundValuePlaceholderBase"> <Field Name="ValEscape" Type="uint" Null="NotApplicable"/> </Node> <!-- only used by codegen --> <Node Name="BoundDup" Base="BoundExpression"> <!-- when duplicating a local or parameter, must remember original ref kind --> <Field Name="RefKind" Type="RefKind" Null="NotApplicable"/> </Node> <!-- An expression is classified as one of the following: A value. Every value has an associated type. A variable. Every variable has an associated type. A namespace. A type. A method group. ... A null literal. An anonymous function. A property access. An event access. An indexer access. Nothing. (An expression which is a method call that returns void.) --> <!-- This node is used when we can't create a real expression node because things are too broken. Example: lookup of a name fails to find anything. --> <Node Name="BoundBadExpression" Base="BoundExpression"> <!-- Categorizes the way in which "Symbols" is bad. --> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> <!-- These symbols will be returned from the GetSemanticInfo API if it examines this bound node. --> <Field Name="Symbols" Type="ImmutableArray&lt;Symbol&gt;"/> <!-- Any child bound nodes that we need to preserve are put here. --> <Field Name="ChildBoundNodes" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <!-- This node is used when we can't create a real statement because things are too broken. --> <Node Name="BoundBadStatement" Base="BoundStatement"> <!-- Any child bound nodes that we need to preserve are put here. --> <Field Name="ChildBoundNodes" Type="ImmutableArray&lt;BoundNode&gt;"/> </Node> <Node Name="BoundTypeExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="AliasOpt" Type="AliasSymbol" Null="allow"/> <!-- Was the type inferred via "var"? --> <Field Name="InferredType" Type="bool"/> <!-- We're going to stash some extra information in the Color Color case so that the binding API can return the correct information. Consider the following example: class C { public class Inner { public static C M() { return null; } } } class F { public C C; void M(C c) { M(/*<bind>*/C/*</bind>*/.Inner.M()); } } The bound tree for "C.Inner.M()" is a bound call with a bound type expression (C.Inner) as its receiver. However, there is no bound node corresponding to C. As a result, the semantic model will attempt to bind it and the binder will return F.C, since it will have no context. That's why we need to have a node for C in the (initial) bound tree. It could conceivably be useful to store other types of expressions as well (e.g. BoundNamespaceExpressions), but then it would be much harder to identify the scenarios in which this property is populated. --> <Field Name="BoundContainingTypeOpt" Type="BoundTypeExpression" Null="allow"/> </Node> <!-- When binding "name1.name2" we normally can tell what name1 is. There is however a case where name1 could be either a value (field, property, parameter, local) or its type. This only happens if value named exactly the same as its type - famous "Color As Color". That alone is not enough to cause trouble as we can do a lookup for name2 and see if it requires a receiver (then name1 is a value) or if it does not (then name1 is a type). The problem only arises when name2 is an overloaded method or property. In such case we must defer type/value decision until overload resolution selects one of the candidates. As a result we need this node that represents name1 in the state where we only know its type and syntax, but do not know yet if it is a Type or Value. NOTE: * The node can only be a qualifier of a method or a property group access as only those may require overload resolution. * It is possible for a node of this type to appear in a tree where there are no errors. Consider (Color.M is Object). M may be overloaded to contain both static and instance methods. In this case the expression is always *false*, but the left-hand-side of the is operator is a method group whose receiver is a BoundTypeOrValueExpression. --> <Node Name="BoundTypeOrValueExpression" Base="BoundExpression"> <!-- Type is required for this node type; may not be null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Data" Type="BoundTypeOrValueData"/> </Node> <Node Name="BoundNamespaceExpression" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> <Field Name="NamespaceSymbol" Type="NamespaceSymbol"/> <Field Name="AliasOpt" Type="AliasSymbol" Null="allow"/> </Node> <!-- EricLi thought we might need a node like this to do "Color Color" correctly. Currently we're handling that in a different way. Dev10 compiler had a node like this. [removed 3/30/2011 by petergo] <Node Name="BoundTypeOrName" Base="BoundExpression"> <Field Name="Type" Type="BoundTypeExpression"/> <Field Name="Name" Type="BoundExpression"/> </Node> --> <Node Name="BoundUnaryOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="OperatorKind" Type="UnaryOperatorKind"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> <Field Name="MethodOpt" Type="MethodSymbol" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundIncrementOperator" Base="BoundExpression"> <!-- x++ might need a conversion from the type of x to the operand type of the ++ operator (that produces the incremented value) and a conversion from the result of the ++ operator back to x. --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="OperatorKind" Type="UnaryOperatorKind"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="MethodOpt" Type="MethodSymbol" Null="allow"/> <Field Name="OperandConversion" Type="Conversion"/> <Field Name="ResultConversion" Type="Conversion"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <!-- Not really an operator since overload resolution is never required. --> <Node Name="BoundAddressOfOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> </Node> <Node Name="BoundPointerIndirectionOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> </Node> <Node Name="BoundPointerElementAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Expression" Type="BoundExpression"/> <Field Name="Index" Type="BoundExpression"/> <Field Name="Checked" Type="Boolean"/> </Node> <Node Name="BoundRefTypeOperator" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> <!-- Well-known member populated during lowering --> <Field Name="GetTypeFromHandle" Type="MethodSymbol" Null="allow"/> </Node> <Node Name="BoundMakeRefOperator" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> </Node> <Node Name="BoundRefValueOperator" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> </Node> <Node Name="BoundBinaryOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="OperatorKind" Type="BinaryOperatorKind"/> <Field Name="Left" Type="BoundExpression"/> <Field Name="Right" Type="BoundExpression"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> <Field Name="MethodOpt" Type="MethodSymbol" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundUserDefinedConditionalLogicalOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="OperatorKind" Type="BinaryOperatorKind"/> <Field Name="Left" Type="BoundExpression"/> <Field Name="Right" Type="BoundExpression"/> <Field Name="LogicalOperator" Type="MethodSymbol"/> <Field Name="TrueOperator" Type="MethodSymbol"/> <Field Name="FalseOperator" Type="MethodSymbol"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundCompoundAssignmentOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- A compound assignment operator has the following facts that must be deduced about it for codegen to work. Suppose you have shorts "x |= y;" That will be analyzed as "x = (short)(((int)x)|((int)y));" We need to know what the left hand and right hand sides are, what the binary operator is, how the left and right sides are converted to the types expected by the operator, whether the operator should check for overflow, and how the result of the binary operator is converted to the target variable's type. We'll lower this to operations on temporaries before codegen. Thought we can represent the operation as these seven facts, in fact we can conflate three of them. We need never do the right-hand-side-of-the-operator conversion during the rewrite. We can get away with binding the conversion on the right early and just having the converted right operand in the bound node. We also conflate whether we should check for overflow with the identity of the operator. This makes it a bit easier to handle the lambda case; when we have something like d += lambda, we want to represent the lambda in its bound form, not in its unbound form to be converted to the bound form later. This helps us maintain the invariant that non-error cases never produce an "unbound" lambda from the initial binding pass. --> <Field Name="Operator" Type="BinaryOperatorSignature" Null="NotApplicable"/> <Field Name="Left" Type="BoundExpression"/> <Field Name="Right" Type="BoundExpression"/> <Field Name="LeftConversion" Type="Conversion"/> <Field Name="FinalConversion" Type="Conversion"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundAssignmentOperator" Base="BoundExpression"> <Field Name="Left" Type="BoundExpression"/> <Field Name="Right" Type="BoundExpression" Null="NotApplicable"/> <!-- This is almost always false. In C# most assignments to a variable are simply writes to the logical variable. For example, when you say void M(ref int x){ x = C.y } that writes the value of C.y to the variable that x is an alias for. It does not write the address of C.y to the actual underlying storage of the parameter, which is of course actually a ref to an int variable. However, in some codegen scenarios we need to distinguish between a ref local assignment and a value assignment. When you say int s = 123; s+=10; then we generate that as int s = 123; ref int addr = ref s; int sum = addr + 10; addr = sum; Note that there are two assignment to addr; one assigns the address of s to addr; the other assigns the value of sum to s, indirectly through addr. We therefore need to disambiguate what kind of assignment we are doing based on something other than the refness of the left hand side. --> <Field Name="IsRef" Type="bool" Null="NotApplicable"/> </Node> <Node Name="BoundDeconstructionAssignmentOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Left" Type="BoundTupleExpression" Null="disallow"/> <Field Name="Right" Type="BoundConversion" Null="disallow"/> <Field Name="IsUsed" Type="Boolean" Null="NotApplicable"/> </Node> <Node Name="BoundNullCoalescingOperator" Base="BoundExpression"> <Field Name="LeftOperand" Type="BoundExpression"/> <Field Name="RightOperand" Type="BoundExpression"/> <Field Name="LeftConversion" Type="Conversion"/> </Node> <Node Name="BoundConditionalOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="IsRef" Type="bool"/> <Field Name="Condition" Type="BoundExpression"/> <Field Name="Consequence" Type="BoundExpression"/> <Field Name="Alternative" Type="BoundExpression"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundArrayAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Expression" Type="BoundExpression"/> <Field Name="Indices" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <!-- Represents an operation that is special in both IL and Expression trees - getting length of a one-dimensional 0-based array (vector) This node should not be produced in initial binding since it is not a part of language (.Length is just a property on System.Array) and is normally introduced during the lowering phases. --> <Node Name="BoundArrayLength" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Expression" Type="BoundExpression"/> </Node> <Node Name="BoundAwaitExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Expression" Type="BoundExpression"/> <Field Name="GetAwaiter" Type="MethodSymbol" Null="allow"/> <Field Name="IsCompleted" Type="PropertySymbol" Null="allow"/> <Field Name="GetResult" Type="MethodSymbol" Null="allow"/> </Node> <AbstractNode Name="BoundTypeOf" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- Well-known member populated during lowering --> <Field Name="GetTypeFromHandle" Type="MethodSymbol" Null="allow"/> </AbstractNode> <Node Name="BoundTypeOfOperator" Base="BoundTypeOf"> <Field Name="SourceType" Type="BoundTypeExpression"/> </Node> <!-- Represents the raw metadata token index value for a method definition. Used by dynamic instrumentation to index into tables or arrays of per-method information. --> <Node Name="BoundMethodDefIndex" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Method" Type="MethodSymbol"/> </Node> <!-- Represents the maximum raw metadata token index value for any method definition in the current module. --> <Node Name="BoundMaximumMethodDefIndex" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <!-- Represents the dynamic analysis instrumentation payload array for the analysis kind in the current module. Implemented as a reference to a field of PrivateImplementationDetails, which has no language-level symbol. --> <Node Name="BoundInstrumentationPayloadRoot" Base="BoundExpression"> <Field Name="AnalysisKind" Type="int"/> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <!-- Represents the GUID that is the current module's MVID. Implemented as a reference to PrivateImplementationDetails.MVID, which has no language-level symbol. --> <Node Name="BoundModuleVersionId" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <!-- Represents a string encoding of the GUID that is the current module's MVID. Implemented as a reference to a string constant that is backpatched after the MVID is computed. --> <Node Name="BoundModuleVersionIdString" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <!-- Represents the index in the documents table of the source document containing a method definition. Used by dynamic instrumentation to identify the source document containing a method. --> <Node Name="BoundSourceDocumentIndex" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Document" Type="Cci.DebugSourceDocument"/> </Node> <Node Name="BoundMethodInfo" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Method" Type="MethodSymbol"/> <!-- Well-known member populated during lowering --> <Field Name="GetMethodFromHandle" Type="MethodSymbol" Null="allow"/> </Node> <Node Name="BoundFieldInfo" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Field" Type="FieldSymbol"/> <!-- Well-known member populated during lowering --> <Field Name="GetFieldFromHandle" Type="MethodSymbol" Null="allow"/> </Node> <Node Name="BoundDefaultExpression" Base="BoundExpression"> <!-- Type is null in the case of a default literal, and non-null for default(T). --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundIsOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="TargetType" Type="BoundTypeExpression"/> <Field Name="Conversion" Type="Conversion"/> </Node> <Node Name="BoundAsOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="TargetType" Type="BoundTypeExpression"/> <Field Name="Conversion" Type="Conversion"/> </Node> <Node Name="BoundSizeOfOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="SourceType" Type="BoundTypeExpression"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundConversion" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="Conversion" Type="Conversion"/> <Field Name="IsBaseConversion" Type="Boolean"/> <Field Name="Checked" Type="Boolean"/> <Field Name="ExplicitCastInCode" Type="Boolean"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <!-- <Node Name="BoundRefValueOperator" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Operand" Type="BoundExpression"/> <Field Name="SourceType" Type="BoundTypeExpression"/> </Node> --> <Node Name="BoundArgList" Base="BoundExpression"> <!-- This is the "__arglist" expression that may appear inside a varargs method. --> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <Node Name="BoundArgListOperator" Base="BoundExpression"> <!-- This is the "__arglist(x, y, z)" expression that may appear in a call to a varargs method. --> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> </Node> <!-- Used when a fixed statement local is initialized with either a string or an array. Encapsulates extra info that will be required during rewriting. --> <Node Name="BoundFixedLocalCollectionInitializer" Base="BoundExpression"> <!-- Either string or an array type. --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- char* for type string, T* for type T[]. --> <Field Name="ElementPointerType" Type="TypeSymbol" Null="disallow"/> <!-- Conversion from ElementPointerType to the type of the corresponding local. --> <Field Name="ElementPointerTypeConversion" Type="Conversion"/> <!-- Wrapped expression. --> <Field Name="Expression" Type="BoundExpression" Null="disallow"/> </Node> <AbstractNode Name="BoundStatement" Base="BoundNode"/> <Node Name="BoundSequencePoint" Base="BoundStatement"> <!-- if Statement is null, a NOP may be emitted, to make sure the point is not associated with next statement (which could be a fairly random statement in random scope). --> <Field Name="StatementOpt" Type="BoundStatement" Null="allow"/> </Node> <!-- Use this in the event that the sequence point must be applied to expression.--> <Node Name="BoundSequencePointExpression" Base="BoundExpression"> <Field Name="Expression" Type="BoundExpression" Null="disallow"/> </Node> <!--EDMAURER Use this in the event that the span you must represent is not that of a SyntaxNode. If a SyntaxNode captures the correct span, use a BoundSequencePoint.--> <Node Name="BoundSequencePointWithSpan" Base="BoundStatement"> <!-- if Statement is null, a NOP may be emitted, to make sure the point is not associated with next statement (which could be a fairly random statement in random scope). --> <Field Name="StatementOpt" Type="BoundStatement" Null="allow"/> <Field Name="Span" Type="TextSpan"/> </Node> <!-- BoundBlock contains a) Statements - actions performed within the scope of the block b) Locals - local variable symbols that are visible within the scope of the block BoundBlock specify SCOPE (visibility) of a variable. TODO: it appears in C#, variable's extent (life time) never escapes its scope. Is that always guaranteed or there are exceptions? Note - in VB variable's extent is the whole method and can be larger than its scope. That is why unassigned use is just a warning and jumps into blocks are generally allowed. --> <Node Name="BoundBlock" Base="BoundStatementList"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="LocalFunctions" Type="ImmutableArray&lt;LocalFunctionSymbol&gt;"/> </Node> <!-- This node is used to represent a visibility scope for locals, for which lifetime is extended beyond the visibility scope. At the moment, only locals declared within CasePatternSwitchLabelSyntax have their lifetime expanded to the entire switch body, whereas their visibility scope is the declaring switch section. The node is added into the tree during lowering phase. --> <Node Name="BoundScope" Base="BoundStatementList"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> </Node> <!-- BoundStateMachineScope represents a scope within a translated iterator/async method. It is used to emit debugging information that allows the EE to map fields to locals. --> <Node Name="BoundStateMachineScope" Base="BoundStatement"> <Field Name="Fields" Type="ImmutableArray&lt;StateMachineFieldSymbol&gt;"/> <Field Name="Statement" Type="BoundStatement" Null="disallow"/> </Node> <!-- Bound node that represents a single local declaration: int x = Foo(); NOTE: The node does NOT introduce the referenced local into surrounding scope. A local must be explicitly declared in a BoundBlock to be usable inside it. NOTE: In an error recovery scenario we might have a local declaration parsed as int x[123] - This is an error commonly made by C++ developers who come to C#. We will give a good error about it at parse time, but we should preserve the semantic analysis of the argument list in the bound tree. --> <Node Name="BoundLocalDeclaration" Base="BoundStatement"> <Field Name="LocalSymbol" Type="LocalSymbol"/> <Field Name="DeclaredType" Type="BoundTypeExpression"/> <Field Name="InitializerOpt" Type="BoundExpression" Null="allow"/> <Field Name="ArgumentsOpt" Type="ImmutableArray&lt;BoundExpression&gt;" Null="allow"/> </Node> <!-- Bound node that represents multiple local declarations: int x =1, y =2; Works like multiple BoundLocalDeclaration nodes. --> <Node Name="BoundMultipleLocalDeclarations" Base="BoundStatement"> <Field Name="LocalDeclarations" Type="ImmutableArray&lt;BoundLocalDeclaration&gt;"/> </Node> <!-- Bound node that represents a local function declaration: void Foo() { } --> <Node Name="BoundLocalFunctionStatement" Base="BoundStatement"> <Field Name="Symbol" Type="LocalFunctionSymbol"/> <Field Name="Body" Type="BoundBlock" Null="allow"/> </Node> <!-- A node specially to represent the idea of "compute this side effects while discarding results, and then compute this value" The node may also declare locals (temporaries). The sequence node is both SCOPE and EXTENT of these locals. As a result non-intersecting sequences can reuse variable slots. --> <Node Name="BoundSequence" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="SideEffects" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="Value" Type="BoundExpression"/> </Node> <Node Name="BoundNoOpStatement" Base="BoundStatement"> <!-- No operation. Empty statement. --> <!-- BoundNoOpStatement node may serve as a vehicle for passing some internal information between lowering phases and/or codegen; for example, async rewriter needs to mark some particular places in the emitted code so that we could emit proper PDB information for generated methods. --> <Field Name="Flavor" Type="NoOpStatementFlavor"/> </Node> <Node Name="BoundReturnStatement" Base="BoundStatement"> <Field Name="RefKind" Type="RefKind"/> <Field Name="ExpressionOpt" Type="BoundExpression" Null="allow"/> </Node> <Node Name="BoundYieldReturnStatement" Base="BoundStatement"> <Field Name="Expression" Type="BoundExpression" Null="disallow"/> </Node> <Node Name="BoundYieldBreakStatement" Base="BoundStatement"/> <Node Name="BoundThrowStatement" Base="BoundStatement"> <Field Name="ExpressionOpt" Type="BoundExpression" Null="allow"/> </Node> <Node Name="BoundExpressionStatement" Base="BoundStatement"> <Field Name="Expression" Type="BoundExpression"/> </Node> <Node Name="BoundSwitchStatement" Base="BoundStatement"> <Field Name="LoweredPreambleOpt" Type="BoundStatement" Null="allow"/> <Field Name="Expression" Type="BoundExpression"/> <Field Name="ConstantTargetOpt" Type="LabelSymbol" Null= "allow"/> <!-- Locals declared immediately within the switch block. --> <Field Name="InnerLocals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="InnerLocalFunctions" Type="ImmutableArray&lt;LocalFunctionSymbol&gt;"/> <Field Name="SwitchSections" Type="ImmutableArray&lt;BoundSwitchSection&gt;"/> <Field Name="BreakLabel" Type="GeneratedLabelSymbol"/> <!-- Well-known member populated during lowering --> <Field Name="StringEquality" Type="MethodSymbol" Null="allow" /> </Node> <Node Name="BoundSwitchSection" Base="BoundStatementList"> <Field Name="SwitchLabels" Type="ImmutableArray&lt;BoundSwitchLabel&gt;"/> </Node> <Node Name="BoundSwitchLabel" Base="BoundNode"> <Field Name="Label" Type="LabelSymbol"/> <Field Name="ExpressionOpt" Type="BoundExpression" Null="allow"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundBreakStatement" Base="BoundStatement"> <Field Name="Label" Type="GeneratedLabelSymbol" /> </Node> <Node Name="BoundContinueStatement" Base="BoundStatement"> <Field Name="Label" Type="GeneratedLabelSymbol" /> </Node> <Node Name="BoundPatternSwitchStatement" Base="BoundStatement"> <Field Name="Expression" Type="BoundExpression"/> <!-- SomeValueMatched is true if some case label would always match. --> <Field Name="SomeLabelAlwaysMatches" Type="bool"/> <!-- Locals declared immediately within the switch block. --> <Field Name="InnerLocals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="InnerLocalFunctions" Type="ImmutableArray&lt;LocalFunctionSymbol&gt;"/> <Field Name="SwitchSections" Type="ImmutableArray&lt;BoundPatternSwitchSection&gt;"/> <Field Name="DefaultLabel" Type="BoundPatternSwitchLabel" Null="allow"/> <Field Name="BreakLabel" Type="GeneratedLabelSymbol"/> <!-- We store the pattern switch binder so we can perform some binding-like operations during control flow analysis. --> <Field Name="Binder" Type="PatternSwitchBinder"/> <!-- A switch is considered complete if every value of the switch expression's type is handled by some switch label that is either not guarded by a when clause, or for which the when clause expression has the constant value true. --> <Field Name="IsComplete" Type="bool"/> </Node> <Node Name="BoundPatternSwitchSection" Base="BoundStatementList"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="SwitchLabels" Type="ImmutableArray&lt;BoundPatternSwitchLabel&gt;"/> </Node> <Node Name="BoundPatternSwitchLabel" Base="BoundNode"> <Field Name="Label" Type="LabelSymbol"/> <Field Name="Pattern" Type="BoundPattern"/> <Field Name="Guard" Type="BoundExpression" Null="allow"/> <Field Name="IsReachable" Type="bool"/> </Node> <Node Name="BoundIfStatement" Base="BoundStatement"> <Field Name="Condition" Type="BoundExpression"/> <Field Name="Consequence" Type="BoundStatement"/> <Field Name="AlternativeOpt" Type="BoundStatement" Null="allow"/> </Node> <AbstractNode Name="BoundLoopStatement" Base="BoundStatement"> <Field Name="BreakLabel" Type="GeneratedLabelSymbol"/> <Field Name="ContinueLabel" Type="GeneratedLabelSymbol"/> </AbstractNode> <Node Name="BoundDoStatement" Base="BoundLoopStatement"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="Condition" Type="BoundExpression"/> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundWhileStatement" Base="BoundLoopStatement"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="Condition" Type="BoundExpression"/> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundForStatement" Base="BoundLoopStatement"> <!-- OuterLocals are the locals declared within the loop Initializer statement and are in scope throughout the whole loop statement --> <Field Name="OuterLocals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="Initializer" Type="BoundStatement" Null="allow"/> <!-- InnerLocals are the locals declared within the loop Condition and are in scope throughout the Condition, Increment and Body. They are considered to be declared per iteration. --> <Field Name="InnerLocals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="Condition" Type="BoundExpression" Null="allow"/> <Field Name="Increment" Type="BoundStatement" Null="allow"/> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundForEachStatement" Base="BoundLoopStatement"> <!-- Extracted information --> <Field Name="EnumeratorInfoOpt" Type="ForEachEnumeratorInfo" Null="allow"/> <Field Name="ElementConversion" Type="Conversion"/> <!-- Pieces corresponding to the syntax --> <!-- This is so the binding API can find produce semantic info if the type is "var". --> <!-- If there is a deconstruction, there will be no iteration variable (but we'll still have a type for it). --> <Field Name="IterationVariableType" Type="BoundTypeExpression"/> <Field Name="IterationVariables" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <!-- If this node does not have errors, then this is the foreach expression wrapped in a conversion to the collection type used by the foreach loop. The conversion is here so that the binding API can return the correct ConvertedType in semantic info. It will be stripped off in the rewriter if it is redundant or causes extra boxing. If this node has errors, then the conversion may not be present.--> <Field Name="Expression" Type="BoundExpression"/> <Field Name="DeconstructionOpt" Type="BoundForEachDeconstructStep" Null="allow"/> <Field Name="Body" Type="BoundStatement"/> <Field Name="Checked" Type="Boolean"/> </Node> <!-- All the information need to apply a deconstruction at each iteration of a foreach loop involving a deconstruction-declaration. --> <Node Name="BoundForEachDeconstructStep" Base="BoundNode"> <Field Name="DeconstructionAssignment" Type="BoundDeconstructionAssignmentOperator" Null="disallow"/> <Field Name="TargetPlaceholder" Type="BoundDeconstructValuePlaceholder" Null="disallow"/> </Node> <Node Name="BoundUsingStatement" Base="BoundStatement"> <!-- DeclarationsOpt and ExpressionOpt cannot both be non-null. --> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="DeclarationsOpt" Type="BoundMultipleLocalDeclarations" Null="allow"/> <Field Name="ExpressionOpt" Type="BoundExpression" Null="allow"/> <Field Name="IDisposableConversion" Type="Conversion" /> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundFixedStatement" Base="BoundStatement"> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <Field Name="Declarations" Type="BoundMultipleLocalDeclarations"/> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundLockStatement" Base="BoundStatement"> <Field Name="Argument" Type="BoundExpression"/> <Field Name="Body" Type="BoundStatement"/> </Node> <Node Name="BoundTryStatement" Base="BoundStatement"> <Field Name="TryBlock" Type="BoundBlock"/> <Field Name="CatchBlocks" Type="ImmutableArray&lt;BoundCatchBlock&gt;"/> <Field Name="FinallyBlockOpt" Type="BoundBlock" Null="allow"/> <!-- PreferFaultHandler is a hint to the codegen to emit Finally in the following shape - try { } fault { finallyBlock } finallyBlock This pattern preserves semantics of Finally while not using finally handler. As a result any kind of analysis can continue treating Finally blocks as Finally blocks. NOTE!! When Fault emit is used - 1) The code is emitted twice 2) The second copy is outside of a handler block. 3) Branches out of the try will NOT be intercepted by the surrogate finally. User of this flag must ensure that the above caveats are acceptable. For example when this flag is used in Iterator rewrite, the second copy is always unreachable and not intercepting the return is intended behavior since the only branch out of Iterator body is "goto exitLabel". --> <Field Name="PreferFaultHandler" Type="Boolean"/> </Node> <Node Name="BoundCatchBlock" Base="BoundNode"> <!-- Local symbols owned by the catch block. Empty if the catch syntax doesn't declare a local variable. In the initial bound tree the first variable is the exception variable (if present). After the node is lowered the exception variable might become a field and will be removed from the array, otherwise it will stay at the first position. --> <Field Name="Locals" Type="ImmutableArray&lt;LocalSymbol&gt;"/> <!-- Refers to the location where the exception object is stored. The expression is a local or a BoundSequence, whose last expression refers to the location of the exception object and the sideeffects initialize its storage (e.g. if the catch identifier is lifted into a closure the sideeffects initialize the closure). Null if the exception object is not referred to. --> <Field Name="ExceptionSourceOpt" Type="BoundExpression" Null="allow"/> <Field Name="ExceptionTypeOpt" Type="TypeSymbol" Null="allow"/> <Field Name="ExceptionFilterOpt" Type="BoundExpression" Null="allow"/> <Field Name="Body" Type="BoundBlock"/> <Field Name="IsSynthesizedAsyncCatchAll" Type="bool" /> </Node> <Node Name="BoundLiteral" Base="BoundExpression"> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundThisReference" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- Note that "this" is classified as a variable in some scenarios. We'll treat it as a value generally and special-case those cases. --> </Node> <Node Name="BoundPreviousSubmissionReference" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <Node Name="BoundHostObjectMemberReference" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <Node Name="BoundBaseReference" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> </Node> <Node Name="BoundLocal" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="LocalSymbol" Type="LocalSymbol"/> <Field Name="IsDeclaration" Type="bool"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundPseudoVariable" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="LocalSymbol" Type="LocalSymbol" Null="disallow"/> <Field Name="EmitExpressions" Type ="PseudoVariableExpressions" Null="disallow"/> </Node> <Node Name="BoundRangeVariable" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="RangeVariableSymbol" Type="RangeVariableSymbol"/> <Field Name="Value" Type="BoundExpression"/> </Node> <Node Name="BoundParameter" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ParameterSymbol" Type="ParameterSymbol"/> </Node> <Node Name="BoundLabelStatement" Base="BoundStatement"> <!-- A label is not actually a statement but it is convenient to model it as one because then you can do rewrites without having to know "what comes next". For example suppose you have statement list A(); if(B()) C(); else D(); E(); If you are rewriting the "if" then it is convenient to be able to rewrite it as GotoIfFalse B() LabElse C(); Goto LabDone LabElse D(); LabDone without having to rewrite E(); as a labeled statement. Note that this statement represents the label itself as a "stand-alone" statement, unattached to any other statement. Rewriting will remove this statement and replace it with a LabeledStatement, that references both this LabelSymbol and the specific other statement it actually labels. --> <Field Name="Label" Type="LabelSymbol"/> </Node> <Node Name="BoundGotoStatement" Base="BoundStatement"> <Field Name="Label" Type="LabelSymbol"/> <Field Name="CaseExpressionOpt" Type="BoundExpression" Null="allow"/> <Field Name="LabelExpressionOpt" Type="BoundLabel" Null="allow"/> </Node> <!-- This represents a statement which has been labeled. This allows us to recursively bind the labeled expression during binding. --> <Node Name="BoundLabeledStatement" Base="BoundStatement"> <Field Name="Label" Type="LabelSymbol"/> <Field Name="Body" Type="BoundStatement"/> </Node> <!-- This represents a the bound form of a label reference (i.e. in a goto). It is only used for the SemanticModel API. --> <Node Name="BoundLabel" Base="BoundExpression"> <Field Name="Label" Type="LabelSymbol"/> </Node> <Node Name="BoundStatementList" Base="BoundStatement"> <!-- A statement list is produced by a rewrite that turns one statement into multiple statements. It does not have the semantics of a block. --> <Field Name="Statements" Type="ImmutableArray&lt;BoundStatement&gt;"/> </Node> <Node Name="BoundConditionalGoto" Base="BoundStatement"> <!-- A compiler-generated conditional goto - jumps if condition == JumpIfTrue --> <Field Name="Condition" Type="BoundExpression"/> <Field Name="JumpIfTrue" Type="bool"/> <Field Name="Label" Type="LabelSymbol"/> </Node> <AbstractNode Name="BoundMethodOrPropertyGroup" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> <!--We wish to keep the left-hand-side of the member access in the method group even if the *instance* expression ought to be null. For example, if we have System.Console.WriteLine then we want to keep the System.Console type expression as the receiver, even though the spec says that the instance expression is null in this case. We'll add a helper property that gets the instance expression from the receiver should we need it. --> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </AbstractNode> <Node Name="BoundDynamicMemberAccess" Base="BoundExpression"> <!--Non-null type is required, and will always be "dynamic". --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Receiver" Type="BoundExpression"/> <Field Name="TypeArgumentsOpt" Type="ImmutableArray&lt;TypeSymbol&gt;" Null="allow"/> <Field Name="Name" Type="string" Null="disallow"/> <!-- TODO (tomat): do we really need these flags here? it should be possible to infer them from the context --> <Field Name="Invoked" Type="bool"/> <Field Name="Indexed" Type="bool"/> </Node> <Node Name="BoundDynamicInvocation" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Expression" Type="BoundExpression"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <!-- If the receiver is statically typed the set of applicable methods that may be invoked at runtime. Empty otherwise. --> <Field Name="ApplicableMethods" Type="ImmutableArray&lt;MethodSymbol&gt;" /> </Node> <Node Name="BoundConditionalAccess" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Receiver" Type="BoundExpression"/> <Field Name="AccessExpression" Type="BoundExpression"/> </Node> <Node Name="BoundLoweredConditionalAccess" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Receiver" Type="BoundExpression"/> <Field Name="HasValueMethodOpt" Type="MethodSymbol" Null="allow"/> <Field Name="WhenNotNull" Type="BoundExpression"/> <Field Name="WhenNullOpt" Type="BoundExpression" Null="allow"/> <!-- Async rewriter needs to replace receivers with their spilled values and for that it needs to match receivers and the containing conditional expressions. To be able to do that, during lowering, we will assign BoundLoweredConditionalAccess and corresponding BoundConditionalReceiver matching Id that are integers unique for the containing method body. --> <Field Name="Id" Type="int"/> </Node> <!-- represents the receiver of a conditional access expression --> <Node Name="BoundConditionalReceiver" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- See the comment in BoundLoweredConditionalAccess --> <Field Name="Id" Type="int"/> </Node> <!-- This node represents a complex receiver for a conditional access. At runtime, when its type is a value type, ValueTypeReceiver should be used as a receiver. Otherwise, ReferenceTypeReceiver should be used. This kind of receiver is created only by Async rewriter. --> <Node Name="BoundComplexConditionalReceiver" Base="BoundExpression"> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ValueTypeReceiver" Type="BoundExpression" Null="disallow"/> <Field Name="ReferenceTypeReceiver" Type="BoundExpression" Null="disallow"/> </Node> <Node Name="BoundMethodGroup" Base="BoundMethodOrPropertyGroup"> <!-- SPEC: A method group is a set of overloaded methods resulting from a member lookup. SPEC: A method group may have an associated instance expression and SPEC: an associated type argument list. --> <Field Name="TypeArgumentsOpt" Type="ImmutableArray&lt;TypeSymbol&gt;" Null="allow"/> <Field Name="Name" Type="string" Null="disallow"/> <Field Name="Methods" Type="ImmutableArray&lt;MethodSymbol&gt;" /> <Field Name="LookupSymbolOpt" Type="Symbol" Null="allow"/> <Field Name="LookupError" Type="DiagnosticInfo" Null="allow"/> <Field Name="Flags" Type="BoundMethodGroupFlags" Null="allow"/> </Node> <Node Name="BoundPropertyGroup" Base="BoundMethodOrPropertyGroup"> <Field Name="Properties" Type="ImmutableArray&lt;PropertySymbol&gt;" /> </Node> <Node Name="BoundCall" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="Method" Type="MethodSymbol"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <Field Name="IsDelegateCall" Type="bool"/> <Field Name="Expanded" Type="bool"/> <Field Name="InvokedAsExtensionMethod" Type="bool"/> <Field Name="ArgsToParamsOpt" Type="ImmutableArray&lt;int&gt;" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> <!-- BinderOpt is added as a temporary solution for IOperation implementation and should probably be removed in the future --> <Field Name="BinderOpt" Type="Binder" Null="allow"/> </Node> <Node Name="BoundEventAssignmentOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Event" Type="EventSymbol"/> <Field Name="IsAddition" Type="bool"/> <Field Name="IsDynamic" Type="bool"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="Argument" Type="BoundExpression"/> </Node> <Node Name="BoundAttribute" Base="BoundExpression"> <!-- Type is required for this node type; may not be null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Constructor" Type="MethodSymbol" Null="allow"/> <Field Name="ConstructorArguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ConstructorArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="NamedArguments" Type ="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <!-- Constructor is optional because value types can be created without calling any constructor - int x = new int(); --> <Node Name="BoundObjectCreationExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Constructor" Type="MethodSymbol"/> <!-- These symbols will be returned from the GetSemanticInfo API if it examines this bound node. --> <Field Name="ConstructorsGroup" Type="ImmutableArray&lt;MethodSymbol&gt;"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <Field Name="Expanded" Type="bool"/> <Field Name="ArgsToParamsOpt" Type="ImmutableArray&lt;int&gt;" Null="allow"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> <Field Name="InitializerExpressionOpt" Type="BoundExpression" Null="allow"/> <!-- BinderOpt is added as a temporary solution for IOperation implementation and should probably be removed in the future --> <Field Name="BinderOpt" Type="Binder" Null="allow"/> </Node> <!-- Tuple literals can exist in two forms - literal and converted literal. This is the base node for both forms. --> <AbstractNode Name="BoundTupleExpression" Base="BoundExpression"> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> </AbstractNode> <!-- Tuple literals can convert to the target type. Once converted to a target type, they cannot be target-typed again. The tuple literal is one which has not been converted to a target type. --> <Node Name="BoundTupleLiteral" Base="BoundTupleExpression"> <!-- It is possible for a tuple to not have a type in a literal form Ex: (a:=1, b:= (c:=1, d:=Nothing)) does not have a natural type, because "Nothing" does not have one --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <!-- Which argument names were inferred (as opposed to explicitly provided)? --> <Field Name="InferredNamesOpt" Type="ImmutableArray&lt;bool&gt;" Null="allow"/> </Node> <!-- Tuple literals can convert to the target type. Once converted to a target type, they cannot be target-typed again. The Converted tuple literal is one which has been already converted to a target type. Converted tuple literal always has a type. --> <Node Name="BoundConvertedTupleLiteral" Base="BoundTupleExpression"> <!-- Converted tuple must have a type --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- Natural type is preserved for the purpose of semantic model. Can be null --> <Field Name="NaturalTypeOpt" Type="TypeSymbol" Null="allow"/> </Node> <Node Name="BoundDynamicObjectCreationExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Name" Type="string" Null="disallow"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <Field Name="InitializerExpressionOpt" Type="BoundExpression" Null="allow"/> <Field Name="ApplicableMethods" Type="ImmutableArray&lt;MethodSymbol&gt;" /> </Node> <Node Name="BoundNoPiaObjectCreationExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="GuidString" Type="string" Null="allow"/> <Field Name="InitializerExpressionOpt" Type="BoundExpression" Null="allow"/> </Node> <Node Name="BoundObjectInitializerExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Initializers" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <Node Name="BoundObjectInitializerMember" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="MemberSymbol" Type="Symbol" Null="allow"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <Field Name="Expanded" Type="bool"/> <Field Name="ArgsToParamsOpt" Type="ImmutableArray&lt;int&gt;" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> <!-- Used by IOperation to reconstruct the receiver for this expression. --> <Field Name="ReceiverType" Type="TypeSymbol" Null="disallow"/> <!-- BinderOpt is a temporary solution for IOperation implementation and should probably be removed in the future --> <!-- Tracked by https://github.com/dotnet/roslyn/issues/20787 --> <Field Name="BinderOpt" Type="Binder" Null="allow"/> </Node> <Node Name="BoundDynamicObjectInitializerMember" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="MemberName" Type="string" Null="disallow"/> </Node> <Node Name="BoundCollectionInitializerExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Initializers" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <Node Name="BoundCollectionElementInitializer" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- We don't hold on BoundCall directly since dynamic invocation isn't specified explicitly in the source. --> <Field Name="AddMethod" Type="MethodSymbol"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="Expanded" Type="bool"/> <Field Name="ArgsToParamsOpt" Type="ImmutableArray&lt;int&gt;" Null="allow"/> <Field Name="InvokedAsExtensionMethod" Type="bool"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundDynamicCollectionElementInitializer" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- We don't hold on DynamicMethodInvocation directly since dynamic invocation isn't specified explicitly in the source. --> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <!-- The set of applicable Add methods that may be invoked at runtime. Empty otherwise. --> <Field Name="ApplicableMethods" Type="ImmutableArray&lt;MethodSymbol&gt;" /> </Node> <Node Name="BoundImplicitReceiver" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <Node Name="BoundAnonymousObjectCreationExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Constructor" Type="MethodSymbol" Null="disallow"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <!-- collection of BoundAnonymousPropertyDeclaration nodes representing bound identifiers for explicitly named field initializers, discarded during rewrite NOTE: 'Declarations' collection contain one node for each explicitly named field and does not have any for implicitly named ones, thus it may be empty in case there are no explicitly named fields --> <Field Name="Declarations" Type="ImmutableArray&lt;BoundAnonymousPropertyDeclaration&gt;"/> </Node> <Node Name="BoundAnonymousPropertyDeclaration" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Property" Type="PropertySymbol" Null="disallow"/> </Node> <Node Name="BoundNewT" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="InitializerExpressionOpt" Type="BoundExpression" Null="allow"/> </Node> <Node Name="BoundDelegateCreationExpression" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- Argument is one of the following: 1. A method group (before local lowering only). If the method is nonstatic or converted as an extension method, the method group contains a receiver expression (mg.ReceiverOpt) for the created delegate; or 2. A value of type dynamic (before local lowering only); or 3. A bound lambda (before lambda lowering only); or 4. A value of a delegate type with MethodOpt == null; or 5. The receiver of the method being converted to a delegate (after local lowering). It may be a BoundTypeExpression if the method is static and not converted as an extension method. --> <Field Name="Argument" Type="BoundExpression"/> <Field Name="MethodOpt" Type="MethodSymbol" Null="allow"/> <Field Name="IsExtensionMethod" Type="bool"/> </Node> <Node Name="BoundArrayCreation" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Bounds" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="InitializerOpt" Type="BoundArrayInitialization" Null="allow"/> </Node> <Node Name="BoundArrayInitialization" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> <Field Name="Initializers" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <Node Name="BoundStackAllocArrayCreation" Base="BoundExpression"> <Field Name="ElementType" Type="TypeSymbol" Null="disallow"/> <Field Name="Count" Type="BoundExpression"/> </Node> <Node Name="BoundConvertedStackAllocExpression" Base="BoundStackAllocArrayCreation"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> </Node> <Node Name="BoundFieldAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="FieldSymbol" Type="FieldSymbol"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="allow"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> <Field Name="IsByValue" Type="bool"/> <Field Name="IsDeclaration" Type="bool" /> </Node> <!-- Used as a placeholder for synthesized fields in the expressions that are used to replace hoisted locals. When the local access expression is used, these placeholders are rewritten as field accesses on the appropriate frame object. --> <Node Name="BoundHoistedFieldAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="FieldSymbol" Type="FieldSymbol"/> </Node> <Node Name="BoundPropertyAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="PropertySymbol" Type="PropertySymbol"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundEventAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="EventSymbol" Type="EventSymbol"/> <Field Name="IsUsableAsField" Type="bool"/> <Field Name="ResultKind" PropertyOverrides="true" Type="LookupResultKind"/> </Node> <Node Name="BoundIndexerAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="Indexer" Type="PropertySymbol"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <Field Name="Expanded" Type="bool"/> <Field Name="ArgsToParamsOpt" Type="ImmutableArray&lt;int&gt;" Null="allow"/> <!-- BinderOpt and UseSetterForDefaultArgumentGeneration are added as a temporary solution for IOperation implementation and should probably be removed in the future --> <!-- Tracked by https://github.com/dotnet/roslyn/issues/20787 --> <Field Name="BinderOpt" Type="Binder" Null="allow"/> <Field Name="UseSetterForDefaultArgumentGeneration" Type="bool"/> </Node> <Node Name="BoundDynamicIndexerAccess" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> <Field Name="Arguments" Type="ImmutableArray&lt;BoundExpression&gt;"/> <Field Name="ArgumentNamesOpt" Type="ImmutableArray&lt;string&gt;" Null="allow"/> <Field Name="ArgumentRefKindsOpt" Type="ImmutableArray&lt;RefKind&gt;" Null="allow"/> <!-- If the receiver is statically typed the set of applicable methods that may be invoked at runtime. Empty otherwise. --> <Field Name="ApplicableIndexers" Type="ImmutableArray&lt;PropertySymbol&gt;" /> </Node> <Node Name="BoundLambda" Base="BoundExpression"> <!-- LambdaSymbol may differ from Binder.MemberSymbol after rewriting. --> <Field Name="Symbol" Type="LambdaSymbol" Null="disallow"/> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> <Field Name="Body" Type="BoundBlock"/> <Field Name="Diagnostics" Type="ImmutableArray&lt;Microsoft.CodeAnalysis.Diagnostic&gt;" /> <Field Name="Binder" Type="Binder" Null="disallow" /> </Node> <Node Name="UnboundLambda" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> <Field Name="Data" Type="UnboundLambdaState" Null="disallow"/> </Node> <Node Name="BoundQueryClause" Base="BoundExpression"> <!-- Equal to Value.Type. --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <!-- The value computed for this query clause. --> <Field Name="Value" Type="BoundExpression" Null="disallow"/> <!-- The query variable introduced by this query clause, if any. --> <Field Name="DefinedSymbol" Type="RangeVariableSymbol" Null="allow"/> <!-- The enclosing binder in which the query clause was evaluated. --> <Field Name="Binder" Type="Binder" Null="disallow" /> </Node> <!-- Special node to encapsulate initializers added into a constructor. Helps to do special optimizations in lowering, doesn't survive the lowering. --> <Node Name="BoundTypeOrInstanceInitializers" Base="BoundStatementList"> </Node> <Node Name="BoundNameOfOperator" Base="BoundExpression"> <!-- Non-null type is required for this node kind --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> <Field Name="Argument" Type="BoundExpression" Null="disallow"/> <Field Name="ConstantValueOpt" Type="ConstantValue" Null="disallow"/> </Node> <Node Name="BoundInterpolatedString" Base="BoundExpression"> <!-- The sequence of parts of an interpolated string. The even numbered positions (starting with 0) are from the literal parts of the input. The odd numbered positions are the string inserts. When a width or format string are provided, the corresponding insert will be a BoundStringInsert --> <Field Name="Parts" Type="ImmutableArray&lt;BoundExpression&gt;"/> </Node> <Node Name="BoundStringInsert" Base="BoundExpression"> <Field Name="Value" Type="BoundExpression" Null="disallow"/> <Field Name="Alignment" Type="BoundExpression" Null="allow"/> <Field Name="Format" Type="BoundExpression" Null="allow"/> </Node> <Node Name="BoundIsPatternExpression" Base="BoundExpression"> <Field Name="Expression" Type="BoundExpression" Null="disallow"/> <Field Name="Pattern" Type="BoundPattern" Null="disallow"/> </Node> <AbstractNode Name="BoundPattern" Base="BoundNode"> <!-- CONSIDER: we might benefit from recording the input (matched value) type in the bound pattern. --> </AbstractNode> <Node Name="BoundDeclarationPattern" Base="BoundPattern"> <!-- Variable is a local symbol, or in the case of top-level code in scripts and interactive, a field that is a member of the script class. Variable is null if `_` is used. --> <Field Name="Variable" Type="Symbol" Null="allow"/> <!-- VariableAccess is an access to the declared variable, suitable for use in the lowered form in either an lvalue or rvalue position. We maintain it separately from the Symbol to facilitate lowerings in which the variable is no longer a simple variable access (e.g. in the expression evaluator). It is expected to be logically side-effect free. The necessity of this member is a consequence of a design issue documented in https://github.com/dotnet/roslyn/issues/13960 . When that is fixed this field can be removed. --> <Field Name="VariableAccess" Type="BoundExpression" Null="disallow"/> <Field Name="DeclaredType" Type="BoundTypeExpression" Null="allow"/> <Field Name="IsVar" Type="bool"/> </Node> <Node Name="BoundConstantPattern" Base="BoundPattern"> <Field Name="Value" Type="BoundExpression"/> <Field Name="ConstantValue" Type="ConstantValue" Null="allow"/> </Node> <Node Name="BoundWildcardPattern" Base="BoundPattern"> </Node> <Node Name="BoundDiscardExpression" Base="BoundExpression"> <!-- A discarded value, when a designator uses `_`. When the type is given as `var, its Type is null before type inference, and it is replaced by a BoundDiscardExpression with a non-null type after inference. --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="allow"/> </Node> <Node Name="BoundThrowExpression" Base="BoundExpression"> <Field Name="Expression" Type="BoundExpression" Null="disallow"/> </Node> <AbstractNode Name="VariablePendingInference" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> <!-- A local symbol or a field symbol representing the variable --> <Field Name="VariableSymbol" Type="Symbol"/> <!-- A field receiver when VariableSymbol is a field --> <Field Name="ReceiverOpt" Type="BoundExpression" Null="allow"/> </AbstractNode> <!-- The node is transformed into BoundLocal or BoundFieldAccess after inference --> <Node Name="OutVariablePendingInference" Base="VariablePendingInference" /> <!-- The node is transformed into BoundLocal or BoundFieldAccess after inference --> <Node Name="DeconstructionVariablePendingInference" Base="VariablePendingInference" /> <!-- The node is transformed into BoundDeconstructValuePlaceholder after inference --> <Node Name="OutDeconstructVarPendingInference" Base="BoundExpression"> <!-- Type is not significant for this node type; always null --> <Field Name="Type" Type="TypeSymbol" Override="true" Null="always"/> </Node> </Tree>