diff --git a/csharp/change-notes/2020-11-19-Relational-pattern.md b/csharp/change-notes/2020-11-19-Relational-pattern.md
new file mode 100644
index 000000000000..77179884d12d
--- /dev/null
+++ b/csharp/change-notes/2020-11-19-Relational-pattern.md
@@ -0,0 +1,3 @@
+lgtm,codescanning
+* The `RelationalPatternExpr` and its 4 sub class have been added to support C# 9
+relational `<`, `>`, `<=`, and `>=` patterns.
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs
index 7fe552ec8e92..3888ac00112b 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/Pattern.cs
@@ -42,6 +42,9 @@ internal static Expression Create(Context cx, PatternSyntax syntax, IExpressionP
case RecursivePatternSyntax recPattern:
return new RecursivePattern(cx, recPattern, parent, child);
+ case RelationalPatternSyntax relPattern:
+ return new RelationalPattern(cx, relPattern, parent, child);
+
case VarPatternSyntax varPattern:
switch (varPattern.Designation)
{
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs
index 997c622c8183..c6045f8cb140 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RecursivePattern.cs
@@ -15,7 +15,6 @@ internal class RecursivePattern : Expression
/// The syntax node of the recursive pattern.
/// The parent pattern/expression.
/// The child index of this pattern.
- /// If this pattern is in the top level of a case/is. In that case, the variable and type access are populated elsewhere.
public RecursivePattern(Context cx, RecursivePatternSyntax syntax, IExpressionParentEntity parent, int child) :
base(new ExpressionInfo(cx, Entities.NullType.Create(cx), cx.Create(syntax.GetLocation()), ExprKind.RECURSIVE_PATTERN, parent, child, false, null))
{
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs
new file mode 100644
index 000000000000..9dce7bf7c527
--- /dev/null
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Patterns/RelationalPattern.cs
@@ -0,0 +1,29 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.CSharp;
+using Semmle.Extraction.Kinds;
+using Semmle.Extraction.Entities;
+
+namespace Semmle.Extraction.CSharp.Entities.Expressions
+{
+ internal class RelationalPattern : Expression
+ {
+ public RelationalPattern(Context cx, RelationalPatternSyntax syntax, IExpressionParentEntity parent, int child) :
+ base(new ExpressionInfo(cx, NullType.Create(cx), cx.Create(syntax.GetLocation()), GetKind(syntax.OperatorToken), parent, child, false, null))
+ {
+ Expression.Create(cx, syntax.Expression, this, 0);
+ }
+
+ private static ExprKind GetKind(SyntaxToken operatorToken)
+ {
+ return operatorToken.Kind() switch
+ {
+ SyntaxKind.LessThanEqualsToken => ExprKind.LE_PATTERN,
+ SyntaxKind.GreaterThanEqualsToken => ExprKind.GE_PATTERN,
+ SyntaxKind.LessThanToken => ExprKind.LT_PATTERN,
+ SyntaxKind.GreaterThanToken => ExprKind.GT_PATTERN,
+ _ => throw new InternalError(operatorToken.Parent, $"Relation pattern with operator token '{operatorToken.Kind()}' is not supported."),
+ };
+ }
+ }
+}
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs
index f46ed47ff5f5..c7c22b6789da 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Kinds/ExprKind.cs
@@ -115,6 +115,10 @@ public enum ExprKind
SWITCH_CASE = 118,
ASSIGN_COALESCE = 119,
SUPPRESS_NULLABLE_WARNING = 120,
- NAMESPACE_ACCESS = 121
+ NAMESPACE_ACCESS = 121,
+ LT_PATTERN = 122,
+ GT_PATTERN = 123,
+ LE_PATTERN = 124,
+ GE_PATTERN = 125,
}
}
diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll
index b133b628732e..0f7dcb64a408 100644
--- a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll
+++ b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll
@@ -342,6 +342,45 @@ class ConstantPatternExpr extends PatternExpr {
override string getAPrimaryQlClass() { result = "ConstantPatternExpr" }
}
+/** A relational pattern, for example `>1` in `x is >1`. */
+class RelationalPatternExpr extends PatternExpr, @relational_pattern_expr {
+ /** Gets the name of the operator in this pattern. */
+ string getOperator() { none() }
+
+ /** Gets the expression of this relational pattern. */
+ Expr getExpr() { result = this.getChild(0) }
+
+ override string toString() { result = getOperator() + " ..." }
+}
+
+/** A less-than pattern, for example `< 10` in `x is < 10`. */
+class LTPattern extends RelationalPatternExpr, @lt_pattern_expr {
+ override string getOperator() { result = "<" }
+
+ override string getAPrimaryQlClass() { result = "LTPattern" }
+}
+
+/** A greater-than pattern, for example `> 10` in `x is > 10`. */
+class GTPattern extends RelationalPatternExpr, @gt_pattern_expr {
+ override string getOperator() { result = ">" }
+
+ override string getAPrimaryQlClass() { result = "GTPattern" }
+}
+
+/** A less-than or equals pattern, for example `<= 10` in `x is <= 10`. */
+class LEPattern extends RelationalPatternExpr, @le_pattern_expr {
+ override string getOperator() { result = "<=" }
+
+ override string getAPrimaryQlClass() { result = "LEPattern" }
+}
+
+/** A greater-than or equals pattern, for example `>= 10` in `x is >= 10` */
+class GEPattern extends RelationalPatternExpr, @ge_pattern_expr {
+ override string getOperator() { result = ">=" }
+
+ override string getAPrimaryQlClass() { result = "GEPattern" }
+}
+
/**
* A type pattern, for example `string` in `x is string`, `string s` in
* `x is string s`, or `string _` in `x is string _`.
diff --git a/csharp/ql/src/semmlecode.csharp.dbscheme b/csharp/ql/src/semmlecode.csharp.dbscheme
index eedef9359e1e..173895c0c823 100644
--- a/csharp/ql/src/semmlecode.csharp.dbscheme
+++ b/csharp/ql/src/semmlecode.csharp.dbscheme
@@ -998,11 +998,17 @@ case @expr.kind of
| 119 = @assign_coalesce_expr
| 120 = @suppress_nullable_warning_expr
| 121 = @namespace_access_expr
+/* C# 9.0 */
+| 122 = @lt_pattern_expr
+| 123 = @gt_pattern_expr
+| 124 = @le_pattern_expr
+| 125 = @ge_pattern_expr
;
@switch = @switch_stmt | @switch_expr;
@case = @case_stmt | @switch_case_expr;
@pattern_match = @case | @is_expr;
+@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr;
@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr;
@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr;
diff --git a/csharp/ql/test/library-tests/csharp9/PrintAst.expected b/csharp/ql/test/library-tests/csharp9/PrintAst.expected
index 42a0fad8d144..4eecbab929c8 100644
--- a/csharp/ql/test/library-tests/csharp9/PrintAst.expected
+++ b/csharp/ql/test/library-tests/csharp9/PrintAst.expected
@@ -335,6 +335,63 @@ ParenthesizedPattern.cs:
# 27| 0: [TypeAccessPatternExpr] access to type String
# 27| 0: [TypeMention] string
# 27| 2: [IntLiteral] 5
+RelationalPattern.cs:
+# 3| [Class] RelationalPattern
+# 5| 5: [Method] M1
+# 5| -1: [TypeMention] bool
+#-----| 2: (Parameters)
+# 5| 0: [Parameter] c
+# 5| -1: [TypeMention] char
+# 6| 4: [IsExpr] ... is ...
+# 6| 0: [ParameterAccess] access to parameter c
+# 6| 1: [GEPattern] >= ...
+# 6| 0: [CharLiteral] a
+# 7| 6: [Method] M2
+# 7| -1: [TypeMention] bool
+#-----| 2: (Parameters)
+# 7| 0: [Parameter] c
+# 7| -1: [TypeMention] char
+# 8| 4: [IsExpr] ... is ...
+# 8| 0: [ParameterAccess] access to parameter c
+# 8| 1: [GTPattern] > ...
+# 8| 0: [CharLiteral] a
+# 9| 7: [Method] M3
+# 9| -1: [TypeMention] bool
+#-----| 2: (Parameters)
+# 9| 0: [Parameter] c
+# 9| -1: [TypeMention] char
+# 10| 4: [IsExpr] ... is ...
+# 10| 0: [ParameterAccess] access to parameter c
+# 10| 1: [LEPattern] <= ...
+# 10| 0: [CharLiteral] a
+# 11| 8: [Method] M4
+# 11| -1: [TypeMention] bool
+#-----| 2: (Parameters)
+# 11| 0: [Parameter] c
+# 11| -1: [TypeMention] char
+# 12| 4: [IsExpr] ... is ...
+# 12| 0: [ParameterAccess] access to parameter c
+# 12| 1: [LTPattern] < ...
+# 12| 0: [CharLiteral] a
+# 14| 9: [Method] M5
+# 14| -1: [TypeMention] string
+#-----| 2: (Parameters)
+# 14| 0: [Parameter] i
+# 14| -1: [TypeMention] int
+# 15| 4: [BlockStmt] {...}
+# 16| 0: [ReturnStmt] return ...;
+# 16| 0: [SwitchExpr] ... switch { ... }
+# 16| -1: [ParameterAccess] access to parameter i
+# 18| 0: [SwitchCaseExpr] ... => ...
+# 18| 0: [ConstantPatternExpr,IntLiteral] 1
+# 18| 2: [StringLiteral] "1"
+# 19| 1: [SwitchCaseExpr] ... => ...
+# 19| 0: [GTPattern] > ...
+# 19| 0: [IntLiteral] 1
+# 19| 2: [StringLiteral] ">1"
+# 20| 2: [SwitchCaseExpr] ... => ...
+# 20| 0: [DiscardPatternExpr] _
+# 20| 2: [StringLiteral] "other"
TargetType.cs:
# 5| [Class] TargetType
# 7| 5: [Method] M2
diff --git a/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs b/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs
new file mode 100644
index 000000000000..d21f50445077
--- /dev/null
+++ b/csharp/ql/test/library-tests/csharp9/RelationalPattern.cs
@@ -0,0 +1,23 @@
+using System;
+
+public class RelationalPattern
+{
+ public static bool M1(char c) =>
+ c is >= 'a';
+ public static bool M2(char c) =>
+ c is > 'a';
+ public static bool M3(char c) =>
+ c is <= 'a';
+ public static bool M4(char c) =>
+ c is < 'a';
+
+ public static string M5(int i)
+ {
+ return i switch
+ {
+ 1 => "1",
+ >1 => ">1",
+ _ => "other"
+ };
+ }
+}
\ No newline at end of file
diff --git a/csharp/ql/test/library-tests/csharp9/relationalPattern.expected b/csharp/ql/test/library-tests/csharp9/relationalPattern.expected
new file mode 100644
index 000000000000..43dca825928d
--- /dev/null
+++ b/csharp/ql/test/library-tests/csharp9/relationalPattern.expected
@@ -0,0 +1,5 @@
+| RelationalPattern.cs:6:14:6:19 | >= ... | >= |
+| RelationalPattern.cs:8:14:8:18 | > ... | > |
+| RelationalPattern.cs:10:14:10:19 | <= ... | <= |
+| RelationalPattern.cs:12:14:12:18 | < ... | < |
+| RelationalPattern.cs:19:13:19:14 | > ... | > |
diff --git a/csharp/ql/test/library-tests/csharp9/relationalPattern.ql b/csharp/ql/test/library-tests/csharp9/relationalPattern.ql
new file mode 100644
index 000000000000..50618e5bb7d6
--- /dev/null
+++ b/csharp/ql/test/library-tests/csharp9/relationalPattern.ql
@@ -0,0 +1,4 @@
+import csharp
+
+from RelationalPatternExpr p
+select p, p.getOperator()
diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme
new file mode 100644
index 000000000000..eedef9359e1e
--- /dev/null
+++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/old.dbscheme
@@ -0,0 +1,1890 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | --compiler
+ * 1 | *path to compiler*
+ * 2 | --cil
+ * 3 | f1.cs
+ * 4 | f2.cs
+ * 5 | f3.cs
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.cs
+ * 1 | f2.cs
+ * 2 | f3.cs
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The references used by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | ref1.dll
+ * 1 | ref2.dll
+ * 2 | ref3.dll
+ */
+#keyset[id, num]
+compilation_referencing_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ unique int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+extractor_messages(
+ unique int id: @extractor_message,
+ int severity: int ref,
+ string origin : string ref,
+ string text : string ref,
+ string entity : string ref,
+ int location: @location_default ref,
+ string stack_trace : string ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalDefects(
+ unique int id: @externalDefect,
+ string queryPath: string ref,
+ int location: @location ref,
+ string message: string ref,
+ float severity: float ref);
+
+externalMetrics(
+ unique int id: @externalMetric,
+ string queryPath: string ref,
+ int location: @location ref,
+ float value: float ref);
+
+externalData(
+ int id: @externalDataElement,
+ string path: string ref,
+ int column: int ref,
+ string value: string ref);
+
+snapshotDate(
+ unique date snapshotDate: date ref);
+
+sourceLocationPrefix(
+ string prefix: string ref);
+
+/*
+ * Duplicate code
+ */
+
+duplicateCode(
+ unique int id: @duplication,
+ string relativePath: string ref,
+ int equivClass: int ref);
+
+similarCode(
+ unique int id: @similarity,
+ string relativePath: string ref,
+ int equivClass: int ref);
+
+@duplication_or_similarity = @duplication | @similarity
+
+tokens(
+ int id: @duplication_or_similarity ref,
+ int offset: int ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+/*
+ * C# dbscheme
+ */
+
+/** ELEMENTS **/
+
+@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration
+ | @using_directive | @type_parameter_constraints | @external_element
+ | @xmllocatable | @asp_element | @namespace;
+
+@declaration = @callable | @generic | @assignable | @namespace;
+
+@named_element = @namespace | @declaration;
+
+@declaration_with_accessors = @property | @indexer | @event;
+
+@assignable = @variable | @assignable_with_accessors | @event;
+
+@assignable_with_accessors = @property | @indexer;
+
+@external_element = @externalMetric | @externalDefect | @externalDataElement;
+
+@attributable = @assembly | @field | @parameter | @operator | @method | @constructor
+ | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors
+ | @local_function;
+
+/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/
+
+@location = @location_default | @assembly;
+
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+@sourceline = @file | @callable | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref);
+
+assemblies(
+ unique int id: @assembly,
+ int file: @file ref,
+ string fullname: string ref,
+ string name: string ref,
+ string version: string ref);
+
+/*
+ fromSource(0) = unknown,
+ fromSource(1) = from source,
+ fromSource(2) = from library
+*/
+files(
+ unique int id: @file,
+ string name: string ref,
+ string simple: string ref,
+ string ext: string ref,
+ int fromSource: int ref);
+
+folders(
+ unique int id: @folder,
+ string name: string ref,
+ string simple: string ref);
+
+@container = @folder | @file ;
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref);
+
+file_extraction_mode(
+ unique int file: @file ref,
+ int mode: int ref
+ /* 0 = normal, 1 = standalone extractor */
+ );
+
+/** NAMESPACES **/
+
+@type_container = @namespace | @type;
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref);
+
+namespace_declarations(
+ unique int id: @namespace_declaration,
+ int namespace_id: @namespace ref);
+
+namespace_declaration_location(
+ unique int id: @namespace_declaration ref,
+ int loc: @location ref);
+
+parent_namespace(
+ unique int child_id: @type_container ref,
+ int namespace_id: @namespace ref);
+
+@declaration_or_directive = @namespace_declaration | @type | @using_directive;
+
+parent_namespace_declaration(
+ int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes
+ int namespace_id: @namespace_declaration ref);
+
+@using_directive = @using_namespace_directive | @using_static_directive;
+
+using_namespace_directives(
+ unique int id: @using_namespace_directive,
+ int namespace_id: @namespace ref);
+
+using_static_directives(
+ unique int id: @using_static_directive,
+ int type_id: @type_or_ref ref);
+
+using_directive_location(
+ unique int id: @using_directive ref,
+ int loc: @location ref);
+
+/** TYPES **/
+
+types(
+ unique int id: @type,
+ int kind: int ref,
+ string name: string ref);
+
+case @type.kind of
+ 1 = @bool_type
+| 2 = @char_type
+| 3 = @decimal_type
+| 4 = @sbyte_type
+| 5 = @short_type
+| 6 = @int_type
+| 7 = @long_type
+| 8 = @byte_type
+| 9 = @ushort_type
+| 10 = @uint_type
+| 11 = @ulong_type
+| 12 = @float_type
+| 13 = @double_type
+| 14 = @enum_type
+| 15 = @struct_type
+| 17 = @class_type
+| 19 = @interface_type
+| 20 = @delegate_type
+| 21 = @null_type
+| 22 = @type_parameter
+| 23 = @pointer_type
+| 24 = @nullable_type
+| 25 = @array_type
+| 26 = @void_type
+| 27 = @int_ptr_type
+| 28 = @uint_ptr_type
+| 29 = @dynamic_type
+| 30 = @arglist_type
+| 31 = @unknown_type
+| 32 = @tuple_type
+ ;
+
+@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type;
+@integral_type = @signed_integral_type | @unsigned_integral_type;
+@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type;
+@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type;
+@floating_point_type = @float_type | @double_type;
+@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type
+ | @uint_ptr_type | @tuple_type;
+@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type
+ | @dynamic_type;
+@value_or_ref_type = @value_type | @ref_type;
+
+typerefs(
+ unique int id: @typeref,
+ string name: string ref);
+
+typeref_type(
+ int id: @typeref ref,
+ unique int typeId: @type ref);
+
+@type_or_ref = @type | @typeref;
+
+array_element_type(
+ unique int array: @array_type ref,
+ int dimension: int ref,
+ int rank: int ref,
+ int element: @type_or_ref ref);
+
+nullable_underlying_type(
+ unique int nullable: @nullable_type ref,
+ int underlying: @type_or_ref ref);
+
+pointer_referent_type(
+ unique int pointer: @pointer_type ref,
+ int referent: @type_or_ref ref);
+
+enum_underlying_type(
+ unique int enum_id: @enum_type ref,
+ int underlying_type_id: @type_or_ref ref);
+
+delegate_return_type(
+ unique int delegate_id: @delegate_type ref,
+ int return_type_id: @type_or_ref ref);
+
+extend(
+ unique int sub: @type ref,
+ int super: @type_or_ref ref);
+
+@interface_or_ref = @interface_type | @typeref;
+
+implement(
+ int sub: @type ref,
+ int super: @type_or_ref ref);
+
+type_location(
+ int id: @type ref,
+ int loc: @location ref);
+
+tuple_underlying_type(
+ unique int tuple: @tuple_type ref,
+ int struct: @type_or_ref ref);
+
+#keyset[tuple, index]
+tuple_element(
+ int tuple: @tuple_type ref,
+ int index: int ref,
+ unique int field: @field ref);
+
+attributes(
+ unique int id: @attribute,
+ int type_id: @type_or_ref ref,
+ int target: @attributable ref);
+
+attribute_location(
+ int id: @attribute ref,
+ int loc: @location ref);
+
+@type_mention_parent = @element | @type_mention;
+
+type_mention(
+ unique int id: @type_mention,
+ int type_id: @type_or_ref ref,
+ int parent: @type_mention_parent ref);
+
+type_mention_location(
+ unique int id: @type_mention ref,
+ int loc: @location ref);
+
+@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic;
+
+/**
+ * A direct annotation on an entity, for example `string? x;`.
+ *
+ * Annotations:
+ * 2 = reftype is not annotated "!"
+ * 3 = reftype is annotated "?"
+ * 4 = readonly ref type / in parameter
+ * 5 = ref type parameter, return or local variable
+ * 6 = out parameter
+ *
+ * Note that the annotation depends on the element it annotates.
+ * @assignable: The annotation is on the type of the assignable, for example the variable type.
+ * @type_parameter: The annotation is on the reftype constraint
+ * @callable: The annotation is on the return type
+ * @array_type: The annotation is on the element type
+ */
+type_annotation(int id: @has_type_annotation ref, int annotation: int ref);
+
+nullability(unique int nullability: @nullability, int kind: int ref);
+
+case @nullability.kind of
+ 0 = @oblivious
+| 1 = @not_annotated
+| 2 = @annotated
+;
+
+#keyset[parent, index]
+nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref)
+
+type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref);
+
+/**
+ * The nullable flow state of an expression, as determined by Roslyn.
+ * 0 = none (default, not populated)
+ * 1 = not null
+ * 2 = maybe null
+ */
+expr_flowstate(unique int id: @expr ref, int state: int ref);
+
+/** GENERICS **/
+
+@generic = @type | @method | @local_function;
+
+type_parameters(
+ unique int id: @type_parameter ref,
+ int index: int ref,
+ int generic_id: @generic ref,
+ int variance: int ref /* none = 0, out = 1, in = 2 */);
+
+#keyset[constructed_id, index]
+type_arguments(
+ int id: @type_or_ref ref,
+ int index: int ref,
+ int constructed_id: @generic_or_ref ref);
+
+@generic_or_ref = @generic | @typeref;
+
+constructed_generic(
+ unique int constructed: @generic ref,
+ int generic: @generic_or_ref ref);
+
+type_parameter_constraints(
+ unique int id: @type_parameter_constraints,
+ int param_id: @type_parameter ref);
+
+type_parameter_constraints_location(
+ int id: @type_parameter_constraints ref,
+ int loc: @location ref);
+
+general_type_parameter_constraints(
+ int id: @type_parameter_constraints ref,
+ int kind: int ref /* class = 1, struct = 2, new = 3 */);
+
+specific_type_parameter_constraints(
+ int id: @type_parameter_constraints ref,
+ int base_id: @type_or_ref ref);
+
+specific_type_parameter_nullability(
+ int id: @type_parameter_constraints ref,
+ int base_id: @type_or_ref ref,
+ int nullability: @nullability ref);
+
+/** MODIFIERS */
+
+@modifiable = @modifiable_direct | @event_accessor;
+
+@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr;
+
+modifiers(
+ unique int id: @modifier,
+ string name: string ref);
+
+has_modifiers(
+ int id: @modifiable_direct ref,
+ int mod_id: @modifier ref);
+
+compiler_generated(unique int id: @modifiable_direct ref);
+
+/** MEMBERS **/
+
+@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type;
+
+@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr;
+
+@virtualizable = @method | @property | @indexer | @event;
+
+exprorstmt_name(
+ unique int parent_id: @named_exprorstmt ref,
+ string name: string ref);
+
+nested_types(
+ unique int id: @type ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @type ref);
+
+properties(
+ unique int id: @property,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @property ref);
+
+property_location(
+ int id: @property ref,
+ int loc: @location ref);
+
+indexers(
+ unique int id: @indexer,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @indexer ref);
+
+indexer_location(
+ int id: @indexer ref,
+ int loc: @location ref);
+
+accessors(
+ unique int id: @accessor,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_member_id: @member ref,
+ int unbound_id: @accessor ref);
+
+case @accessor.kind of
+ 1 = @getter
+| 2 = @setter
+ ;
+
+accessor_location(
+ int id: @accessor ref,
+ int loc: @location ref);
+
+events(
+ unique int id: @event,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @event ref);
+
+event_location(
+ int id: @event ref,
+ int loc: @location ref);
+
+event_accessors(
+ unique int id: @event_accessor,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_event_id: @event ref,
+ int unbound_id: @event_accessor ref);
+
+case @event_accessor.kind of
+ 1 = @add_event_accessor
+| 2 = @remove_event_accessor
+ ;
+
+event_accessor_location(
+ int id: @event_accessor ref,
+ int loc: @location ref);
+
+operators(
+ unique int id: @operator,
+ string name: string ref,
+ string symbol: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @operator ref);
+
+operator_location(
+ int id: @operator ref,
+ int loc: @location ref);
+
+constant_value(
+ int id: @variable ref,
+ string value: string ref);
+
+/** CALLABLES **/
+
+@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function;
+
+@callable_accessor = @accessor | @event_accessor;
+
+methods(
+ unique int id: @method,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @method ref);
+
+method_location(
+ int id: @method ref,
+ int loc: @location ref);
+
+constructors(
+ unique int id: @constructor,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @constructor ref);
+
+constructor_location(
+ int id: @constructor ref,
+ int loc: @location ref);
+
+destructors(
+ unique int id: @destructor,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @destructor ref);
+
+destructor_location(
+ int id: @destructor ref,
+ int loc: @location ref);
+
+overrides(
+ int id: @callable ref,
+ int base_id: @callable ref);
+
+explicitly_implements(
+ int id: @member ref,
+ int interface_id: @interface_or_ref ref);
+
+local_functions(
+ unique int id: @local_function,
+ string name: string ref,
+ int return_type: @type ref,
+ int unbound_id: @local_function ref);
+
+local_function_stmts(
+ unique int fn: @local_function_stmt ref,
+ int stmt: @local_function ref);
+
+/** VARIABLES **/
+
+@variable = @local_scope_variable | @field;
+
+@local_scope_variable = @local_variable | @parameter;
+
+fields(
+ unique int id: @field,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @field ref);
+
+case @field.kind of
+ 1 = @addressable_field
+| 2 = @constant
+ ;
+
+field_location(
+ int id: @field ref,
+ int loc: @location ref);
+
+localvars(
+ unique int id: @local_variable,
+ int kind: int ref,
+ string name: string ref,
+ int implicitly_typed: int ref /* 0 = no, 1 = yes */,
+ int type_id: @type_or_ref ref,
+ int parent_id: @local_var_decl_expr ref);
+
+case @local_variable.kind of
+ 1 = @addressable_local_variable
+| 2 = @local_constant
+| 3 = @local_variable_ref
+ ;
+
+localvar_location(
+ unique int id: @local_variable ref,
+ int loc: @location ref);
+
+@parameterizable = @callable | @delegate_type | @indexer;
+
+#keyset[name, parent_id]
+#keyset[index, parent_id]
+params(
+ unique int id: @parameter,
+ string name: string ref,
+ int type_id: @type_or_ref ref,
+ int index: int ref,
+ int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */
+ int parent_id: @parameterizable ref,
+ int unbound_id: @parameter ref);
+
+param_location(
+ int id: @parameter ref,
+ int loc: @location ref);
+
+/** STATEMENTS **/
+
+@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent;
+
+statements(
+ unique int id: @stmt,
+ int kind: int ref);
+
+#keyset[index, parent]
+stmt_parent(
+ unique int stmt: @stmt ref,
+ int index: int ref,
+ int parent: @control_flow_element ref);
+
+@top_level_stmt_parent = @callable;
+
+// [index, parent] is not a keyset because the same parent may be compiled multiple times
+stmt_parent_top_level(
+ unique int stmt: @stmt ref,
+ int index: int ref,
+ int parent: @top_level_stmt_parent ref);
+
+case @stmt.kind of
+ 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @switch_stmt
+| 5 = @while_stmt
+| 6 = @do_stmt
+| 7 = @for_stmt
+| 8 = @foreach_stmt
+| 9 = @break_stmt
+| 10 = @continue_stmt
+| 11 = @goto_stmt
+| 12 = @goto_case_stmt
+| 13 = @goto_default_stmt
+| 14 = @throw_stmt
+| 15 = @return_stmt
+| 16 = @yield_stmt
+| 17 = @try_stmt
+| 18 = @checked_stmt
+| 19 = @unchecked_stmt
+| 20 = @lock_stmt
+| 21 = @using_block_stmt
+| 22 = @var_decl_stmt
+| 23 = @const_decl_stmt
+| 24 = @empty_stmt
+| 25 = @unsafe_stmt
+| 26 = @fixed_stmt
+| 27 = @label_stmt
+| 28 = @catch
+| 29 = @case_stmt
+| 30 = @local_function_stmt
+| 31 = @using_decl_stmt
+ ;
+
+@using_stmt = @using_block_stmt | @using_decl_stmt;
+
+@labeled_stmt = @label_stmt | @case;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt;
+
+@cond_stmt = @if_stmt | @switch_stmt;
+
+@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt;
+
+@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt
+ | @yield_stmt;
+
+@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt;
+
+
+stmt_location(
+ unique int id: @stmt ref,
+ int loc: @location ref);
+
+catch_type(
+ unique int catch_id: @catch ref,
+ int type_id: @type_or_ref ref,
+ int kind: int ref /* explicit = 1, implicit = 2 */);
+
+/** EXPRESSIONS **/
+
+expressions(
+ unique int id: @expr,
+ int kind: int ref,
+ int type_id: @type_or_ref ref);
+
+#keyset[index, parent]
+expr_parent(
+ unique int expr: @expr ref,
+ int index: int ref,
+ int parent: @control_flow_element ref);
+
+@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter;
+
+@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent;
+
+// [index, parent] is not a keyset because the same parent may be compiled multiple times
+expr_parent_top_level(
+ unique int expr: @expr ref,
+ int index: int ref,
+ int parent: @top_level_exprorstmt_parent ref);
+
+case @expr.kind of
+/* literal */
+ 1 = @bool_literal_expr
+| 2 = @char_literal_expr
+| 3 = @decimal_literal_expr
+| 4 = @int_literal_expr
+| 5 = @long_literal_expr
+| 6 = @uint_literal_expr
+| 7 = @ulong_literal_expr
+| 8 = @float_literal_expr
+| 9 = @double_literal_expr
+| 10 = @string_literal_expr
+| 11 = @null_literal_expr
+/* primary & unary */
+| 12 = @this_access_expr
+| 13 = @base_access_expr
+| 14 = @local_variable_access_expr
+| 15 = @parameter_access_expr
+| 16 = @field_access_expr
+| 17 = @property_access_expr
+| 18 = @method_access_expr
+| 19 = @event_access_expr
+| 20 = @indexer_access_expr
+| 21 = @array_access_expr
+| 22 = @type_access_expr
+| 23 = @typeof_expr
+| 24 = @method_invocation_expr
+| 25 = @delegate_invocation_expr
+| 26 = @operator_invocation_expr
+| 27 = @cast_expr
+| 28 = @object_creation_expr
+| 29 = @explicit_delegate_creation_expr
+| 30 = @implicit_delegate_creation_expr
+| 31 = @array_creation_expr
+| 32 = @default_expr
+| 33 = @plus_expr
+| 34 = @minus_expr
+| 35 = @bit_not_expr
+| 36 = @log_not_expr
+| 37 = @post_incr_expr
+| 38 = @post_decr_expr
+| 39 = @pre_incr_expr
+| 40 = @pre_decr_expr
+/* multiplicative */
+| 41 = @mul_expr
+| 42 = @div_expr
+| 43 = @rem_expr
+/* additive */
+| 44 = @add_expr
+| 45 = @sub_expr
+/* shift */
+| 46 = @lshift_expr
+| 47 = @rshift_expr
+/* relational */
+| 48 = @lt_expr
+| 49 = @gt_expr
+| 50 = @le_expr
+| 51 = @ge_expr
+/* equality */
+| 52 = @eq_expr
+| 53 = @ne_expr
+/* logical */
+| 54 = @bit_and_expr
+| 55 = @bit_xor_expr
+| 56 = @bit_or_expr
+| 57 = @log_and_expr
+| 58 = @log_or_expr
+/* type testing */
+| 59 = @is_expr
+| 60 = @as_expr
+/* null coalescing */
+| 61 = @null_coalescing_expr
+/* conditional */
+| 62 = @conditional_expr
+/* assignment */
+| 63 = @simple_assign_expr
+| 64 = @assign_add_expr
+| 65 = @assign_sub_expr
+| 66 = @assign_mul_expr
+| 67 = @assign_div_expr
+| 68 = @assign_rem_expr
+| 69 = @assign_and_expr
+| 70 = @assign_xor_expr
+| 71 = @assign_or_expr
+| 72 = @assign_lshift_expr
+| 73 = @assign_rshift_expr
+/* more */
+| 74 = @object_init_expr
+| 75 = @collection_init_expr
+| 76 = @array_init_expr
+| 77 = @checked_expr
+| 78 = @unchecked_expr
+| 79 = @constructor_init_expr
+| 80 = @add_event_expr
+| 81 = @remove_event_expr
+| 82 = @par_expr
+| 83 = @local_var_decl_expr
+| 84 = @lambda_expr
+| 85 = @anonymous_method_expr
+| 86 = @namespace_expr
+/* dynamic */
+| 92 = @dynamic_element_access_expr
+| 93 = @dynamic_member_access_expr
+/* unsafe */
+| 100 = @pointer_indirection_expr
+| 101 = @address_of_expr
+| 102 = @sizeof_expr
+/* async */
+| 103 = @await_expr
+/* C# 6.0 */
+| 104 = @nameof_expr
+| 105 = @interpolated_string_expr
+| 106 = @unknown_expr
+/* C# 7.0 */
+| 107 = @throw_expr
+| 108 = @tuple_expr
+| 109 = @local_function_invocation_expr
+| 110 = @ref_expr
+| 111 = @discard_expr
+/* C# 8.0 */
+| 112 = @range_expr
+| 113 = @index_expr
+| 114 = @switch_expr
+| 115 = @recursive_pattern_expr
+| 116 = @property_pattern_expr
+| 117 = @positional_pattern_expr
+| 118 = @switch_case_expr
+| 119 = @assign_coalesce_expr
+| 120 = @suppress_nullable_warning_expr
+| 121 = @namespace_access_expr
+;
+
+@switch = @switch_stmt | @switch_expr;
+@case = @case_stmt | @switch_case_expr;
+@pattern_match = @case | @is_expr;
+
+@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr;
+@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr;
+@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr
+ | @string_literal_expr | @null_literal_expr;
+
+@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr;
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr;
+@assign_event_expr = @add_event_expr | @remove_event_expr;
+
+@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr
+ | @assign_rem_expr
+@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr
+ | @assign_lshift_expr | @assign_rshift_expr;
+
+@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr
+ | @method_access_expr | @type_access_expr | @dynamic_member_access_expr;
+@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr;
+@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr;
+
+@local_variable_access = @local_variable_access_expr | @local_var_decl_expr;
+@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access;
+@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr;
+
+@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr
+ | @event_access_expr | @dynamic_member_access_expr;
+
+@objectorcollection_init_expr = @object_init_expr | @collection_init_expr;
+
+@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr;
+
+@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
+@incr_op_expr = @pre_incr_expr | @post_incr_expr;
+@decr_op_expr = @pre_decr_expr | @post_decr_expr;
+@mut_op_expr = @incr_op_expr | @decr_op_expr;
+@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr;
+@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr;
+
+@ternary_log_op_expr = @conditional_expr;
+@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr;
+@un_log_op_expr = @log_not_expr;
+@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
+
+@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
+ | @rshift_expr;
+@un_bit_op_expr = @bit_not_expr;
+@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;
+
+@equality_op_expr = @eq_expr | @ne_expr;
+@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr;
+@comp_expr = @equality_op_expr | @rel_op_expr;
+
+@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op;
+
+@ternary_op = @ternary_log_op_expr;
+@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr;
+@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr
+ | @pointer_indirection_expr | @address_of_expr;
+
+@anonymous_function_expr = @lambda_expr | @anonymous_method_expr;
+
+@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr
+ | @delegate_invocation_expr | @object_creation_expr | @call_access_expr
+ | @local_function_invocation_expr;
+
+@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr;
+
+@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr
+ | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr;
+
+@throw_element = @throw_expr | @throw_stmt;
+
+implicitly_typed_array_creation(
+ unique int id: @array_creation_expr ref);
+
+explicitly_sized_array_creation(
+ unique int id: @array_creation_expr ref);
+
+stackalloc_array_creation(
+ unique int id: @array_creation_expr ref);
+
+mutator_invocation_mode(
+ unique int id: @operator_invocation_expr ref,
+ int mode: int ref /* prefix = 1, postfix = 2*/);
+
+expr_compiler_generated(
+ unique int id: @expr ref);
+
+expr_value(
+ unique int id: @expr ref,
+ string value: string ref);
+
+expr_call(
+ unique int caller_id: @expr ref,
+ int target_id: @callable ref);
+
+expr_access(
+ unique int accesser_id: @access_expr ref,
+ int target_id: @accessible ref);
+
+@accessible = @method | @assignable | @local_function | @namespace;
+
+expr_location(
+ unique int id: @expr ref,
+ int loc: @location ref);
+
+dynamic_member_name(
+ unique int id: @late_bindable_expr ref,
+ string name: string ref);
+
+@qualifiable_expr = @member_access_expr
+ | @method_invocation_expr
+ | @element_access_expr;
+
+conditional_access(
+ unique int id: @qualifiable_expr ref);
+
+expr_argument(
+ unique int id: @expr ref,
+ int mode: int ref);
+ /* mode is the same as params: value = 0, ref = 1, out = 2 */
+
+expr_argument_name(
+ unique int id: @expr ref,
+ string name: string ref);
+
+/** CONTROL/DATA FLOW **/
+
+@control_flow_element = @stmt | @expr;
+
+/* XML Files */
+
+xmlEncoding (
+ unique int id: @file ref,
+ string encoding: string ref);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/* Comments */
+
+commentline(
+ unique int id: @commentline,
+ int kind: int ref,
+ string text: string ref,
+ string rawtext: string ref);
+
+case @commentline.kind of
+ 0 = @singlelinecomment
+| 1 = @xmldoccomment
+| 2 = @multilinecomment;
+
+commentline_location(
+ unique int id: @commentline ref,
+ int loc: @location ref);
+
+commentblock(
+ unique int id : @commentblock);
+
+commentblock_location(
+ unique int id: @commentblock ref,
+ int loc: @location ref);
+
+commentblock_binding(
+ int id: @commentblock ref,
+ int entity: @element ref,
+ int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */
+
+commentblock_child(
+ int id: @commentblock ref,
+ int commentline: @commentline ref,
+ int index: int ref);
+
+/* ASP.NET */
+
+case @asp_element.kind of
+ 0=@asp_close_tag
+| 1=@asp_code
+| 2=@asp_comment
+| 3=@asp_data_binding
+| 4=@asp_directive
+| 5=@asp_open_tag
+| 6=@asp_quoted_string
+| 7=@asp_text
+| 8=@asp_xml_directive;
+
+@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string;
+
+asp_elements(
+ unique int id: @asp_element,
+ int kind: int ref,
+ int loc: @location ref);
+
+asp_comment_server(unique int comment: @asp_comment ref);
+asp_code_inline(unique int code: @asp_code ref);
+asp_directive_attribute(
+ int directive: @asp_directive ref,
+ int index: int ref,
+ string name: string ref,
+ int value: @asp_quoted_string ref);
+asp_directive_name(
+ unique int directive: @asp_directive ref,
+ string name: string ref);
+asp_element_body(
+ unique int element: @asp_element ref,
+ string body: string ref);
+asp_tag_attribute(
+ int tag: @asp_open_tag ref,
+ int index: int ref,
+ string name: string ref,
+ int attribute: @asp_attribute ref);
+asp_tag_name(
+ unique int tag: @asp_open_tag ref,
+ string name: string ref);
+asp_tag_isempty(int tag: @asp_open_tag ref);
+
+/* Common Intermediate Language - CIL */
+
+case @cil_instruction.opcode of
+ 0 = @cil_nop
+| 1 = @cil_break
+| 2 = @cil_ldarg_0
+| 3 = @cil_ldarg_1
+| 4 = @cil_ldarg_2
+| 5 = @cil_ldarg_3
+| 6 = @cil_ldloc_0
+| 7 = @cil_ldloc_1
+| 8 = @cil_ldloc_2
+| 9 = @cil_ldloc_3
+| 10 = @cil_stloc_0
+| 11 = @cil_stloc_1
+| 12 = @cil_stloc_2
+| 13 = @cil_stloc_3
+| 14 = @cil_ldarg_s
+| 15 = @cil_ldarga_s
+| 16 = @cil_starg_s
+| 17 = @cil_ldloc_s
+| 18 = @cil_ldloca_s
+| 19 = @cil_stloc_s
+| 20 = @cil_ldnull
+| 21 = @cil_ldc_i4_m1
+| 22 = @cil_ldc_i4_0
+| 23 = @cil_ldc_i4_1
+| 24 = @cil_ldc_i4_2
+| 25 = @cil_ldc_i4_3
+| 26 = @cil_ldc_i4_4
+| 27 = @cil_ldc_i4_5
+| 28 = @cil_ldc_i4_6
+| 29 = @cil_ldc_i4_7
+| 30 = @cil_ldc_i4_8
+| 31 = @cil_ldc_i4_s
+| 32 = @cil_ldc_i4
+| 33 = @cil_ldc_i8
+| 34 = @cil_ldc_r4
+| 35 = @cil_ldc_r8
+| 37 = @cil_dup
+| 38 = @cil_pop
+| 39 = @cil_jmp
+| 40 = @cil_call
+| 41 = @cil_calli
+| 42 = @cil_ret
+| 43 = @cil_br_s
+| 44 = @cil_brfalse_s
+| 45 = @cil_brtrue_s
+| 46 = @cil_beq_s
+| 47 = @cil_bge_s
+| 48 = @cil_bgt_s
+| 49 = @cil_ble_s
+| 50 = @cil_blt_s
+| 51 = @cil_bne_un_s
+| 52 = @cil_bge_un_s
+| 53 = @cil_bgt_un_s
+| 54 = @cil_ble_un_s
+| 55 = @cil_blt_un_s
+| 56 = @cil_br
+| 57 = @cil_brfalse
+| 58 = @cil_brtrue
+| 59 = @cil_beq
+| 60 = @cil_bge
+| 61 = @cil_bgt
+| 62 = @cil_ble
+| 63 = @cil_blt
+| 64 = @cil_bne_un
+| 65 = @cil_bge_un
+| 66 = @cil_bgt_un
+| 67 = @cil_ble_un
+| 68 = @cil_blt_un
+| 69 = @cil_switch
+| 70 = @cil_ldind_i1
+| 71 = @cil_ldind_u1
+| 72 = @cil_ldind_i2
+| 73 = @cil_ldind_u2
+| 74 = @cil_ldind_i4
+| 75 = @cil_ldind_u4
+| 76 = @cil_ldind_i8
+| 77 = @cil_ldind_i
+| 78 = @cil_ldind_r4
+| 79 = @cil_ldind_r8
+| 80 = @cil_ldind_ref
+| 81 = @cil_stind_ref
+| 82 = @cil_stind_i1
+| 83 = @cil_stind_i2
+| 84 = @cil_stind_i4
+| 85 = @cil_stind_i8
+| 86 = @cil_stind_r4
+| 87 = @cil_stind_r8
+| 88 = @cil_add
+| 89 = @cil_sub
+| 90 = @cil_mul
+| 91 = @cil_div
+| 92 = @cil_div_un
+| 93 = @cil_rem
+| 94 = @cil_rem_un
+| 95 = @cil_and
+| 96 = @cil_or
+| 97 = @cil_xor
+| 98 = @cil_shl
+| 99 = @cil_shr
+| 100 = @cil_shr_un
+| 101 = @cil_neg
+| 102 = @cil_not
+| 103 = @cil_conv_i1
+| 104 = @cil_conv_i2
+| 105 = @cil_conv_i4
+| 106 = @cil_conv_i8
+| 107 = @cil_conv_r4
+| 108 = @cil_conv_r8
+| 109 = @cil_conv_u4
+| 110 = @cil_conv_u8
+| 111 = @cil_callvirt
+| 112 = @cil_cpobj
+| 113 = @cil_ldobj
+| 114 = @cil_ldstr
+| 115 = @cil_newobj
+| 116 = @cil_castclass
+| 117 = @cil_isinst
+| 118 = @cil_conv_r_un
+| 121 = @cil_unbox
+| 122 = @cil_throw
+| 123 = @cil_ldfld
+| 124 = @cil_ldflda
+| 125 = @cil_stfld
+| 126 = @cil_ldsfld
+| 127 = @cil_ldsflda
+| 128 = @cil_stsfld
+| 129 = @cil_stobj
+| 130 = @cil_conv_ovf_i1_un
+| 131 = @cil_conv_ovf_i2_un
+| 132 = @cil_conv_ovf_i4_un
+| 133 = @cil_conv_ovf_i8_un
+| 134 = @cil_conv_ovf_u1_un
+| 135 = @cil_conv_ovf_u2_un
+| 136 = @cil_conv_ovf_u4_un
+| 137 = @cil_conv_ovf_u8_un
+| 138 = @cil_conv_ovf_i_un
+| 139 = @cil_conv_ovf_u_un
+| 140 = @cil_box
+| 141 = @cil_newarr
+| 142 = @cil_ldlen
+| 143 = @cil_ldelema
+| 144 = @cil_ldelem_i1
+| 145 = @cil_ldelem_u1
+| 146 = @cil_ldelem_i2
+| 147 = @cil_ldelem_u2
+| 148 = @cil_ldelem_i4
+| 149 = @cil_ldelem_u4
+| 150 = @cil_ldelem_i8
+| 151 = @cil_ldelem_i
+| 152 = @cil_ldelem_r4
+| 153 = @cil_ldelem_r8
+| 154 = @cil_ldelem_ref
+| 155 = @cil_stelem_i
+| 156 = @cil_stelem_i1
+| 157 = @cil_stelem_i2
+| 158 = @cil_stelem_i4
+| 159 = @cil_stelem_i8
+| 160 = @cil_stelem_r4
+| 161 = @cil_stelem_r8
+| 162 = @cil_stelem_ref
+| 163 = @cil_ldelem
+| 164 = @cil_stelem
+| 165 = @cil_unbox_any
+| 179 = @cil_conv_ovf_i1
+| 180 = @cil_conv_ovf_u1
+| 181 = @cil_conv_ovf_i2
+| 182 = @cil_conv_ovf_u2
+| 183 = @cil_conv_ovf_i4
+| 184 = @cil_conv_ovf_u4
+| 185 = @cil_conv_ovf_i8
+| 186 = @cil_conv_ovf_u8
+| 194 = @cil_refanyval
+| 195 = @cil_ckinfinite
+| 198 = @cil_mkrefany
+| 208 = @cil_ldtoken
+| 209 = @cil_conv_u2
+| 210 = @cil_conv_u1
+| 211 = @cil_conv_i
+| 212 = @cil_conv_ovf_i
+| 213 = @cil_conv_ovf_u
+| 214 = @cil_add_ovf
+| 215 = @cil_add_ovf_un
+| 216 = @cil_mul_ovf
+| 217 = @cil_mul_ovf_un
+| 218 = @cil_sub_ovf
+| 219 = @cil_sub_ovf_un
+| 220 = @cil_endfinally
+| 221 = @cil_leave
+| 222 = @cil_leave_s
+| 223 = @cil_stind_i
+| 224 = @cil_conv_u
+| 65024 = @cil_arglist
+| 65025 = @cil_ceq
+| 65026 = @cil_cgt
+| 65027 = @cil_cgt_un
+| 65028 = @cil_clt
+| 65029 = @cil_clt_un
+| 65030 = @cil_ldftn
+| 65031 = @cil_ldvirtftn
+| 65033 = @cil_ldarg
+| 65034 = @cil_ldarga
+| 65035 = @cil_starg
+| 65036 = @cil_ldloc
+| 65037 = @cil_ldloca
+| 65038 = @cil_stloc
+| 65039 = @cil_localloc
+| 65041 = @cil_endfilter
+| 65042 = @cil_unaligned
+| 65043 = @cil_volatile
+| 65044 = @cil_tail
+| 65045 = @cil_initobj
+| 65046 = @cil_constrained
+| 65047 = @cil_cpblk
+| 65048 = @cil_initblk
+| 65050 = @cil_rethrow
+| 65052 = @cil_sizeof
+| 65053 = @cil_refanytype
+| 65054 = @cil_readonly
+;
+
+// CIL ignored instructions
+
+@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned;
+
+// CIL local/parameter/field access
+
+@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga;
+@cil_starg_any = @cil_starg | @cil_starg_s;
+
+@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca;
+@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc;
+
+@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda;
+@cil_stfld_any = @cil_stfld | @cil_stsfld;
+
+@cil_local_access = @cil_stloc_any | @cil_ldloc_any;
+@cil_arg_access = @cil_starg_any | @cil_ldarg_any;
+@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any;
+@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any;
+
+@cil_stack_access = @cil_local_access | @cil_arg_access;
+@cil_field_access = @cil_ldfld_any | @cil_stfld_any;
+
+@cil_access = @cil_read_access | @cil_write_access;
+
+// CIL constant/literal instructions
+
+@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8;
+
+@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 |
+ @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4;
+
+@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8;
+
+@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr;
+
+// Control flow
+
+@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump;
+@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s |
+ @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s |
+ @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt |
+ @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un;
+@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch;
+@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any;
+@cil_leave_any = @cil_leave | @cil_leave_s;
+@cil_jump = @cil_unconditional_jump | @cil_conditional_jump;
+
+// CIL call instructions
+
+@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj;
+
+// CIL expression instructions
+
+@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access |
+ @cil_newarr | @cil_ldtoken | @cil_sizeof |
+ @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup;
+
+@cil_unary_expr =
+ @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation|
+ @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any |
+ @cil_ldind | @cil_unbox;
+
+@cil_conversion_operation =
+ @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 |
+ @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 |
+ @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un |
+ @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un |
+ @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un |
+ @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un |
+ @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un |
+ @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un |
+ @cil_conv_i | @cil_conv_u | @cil_conv_r_un;
+
+@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 |
+ @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4;
+
+@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 |
+ @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref;
+
+@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation;
+
+@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl;
+
+@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un |
+ @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un |
+ @cil_sub_ovf | @cil_sub_ovf_un;
+
+@cil_unary_bitwise_operation = @cil_not;
+
+@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation;
+
+@cil_unary_arithmetic_operation = @cil_neg;
+
+@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un;
+
+// Elements that retrieve an address of something
+@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema;
+
+// CIL array instructions
+
+@cil_read_array =
+ @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i |
+ @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 |
+ @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4;
+
+@cil_write_array = @cil_stelem | @cil_stelem_ref |
+ @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 |
+ @cil_stelem_r4 | @cil_stelem_r8;
+
+@cil_throw_any = @cil_throw | @cil_rethrow;
+
+#keyset[impl, index]
+cil_instruction(
+ unique int id: @cil_instruction,
+ int opcode: int ref,
+ int index: int ref,
+ int impl: @cil_method_implementation ref);
+
+cil_jump(
+ unique int instruction: @cil_jump ref,
+ int target: @cil_instruction ref);
+
+cil_access(
+ unique int instruction: @cil_instruction ref,
+ int target: @cil_accessible ref);
+
+cil_value(
+ unique int instruction: @cil_literal ref,
+ string value: string ref);
+
+#keyset[instruction, index]
+cil_switch(
+ int instruction: @cil_switch ref,
+ int index: int ref,
+ int target: @cil_instruction ref);
+
+cil_instruction_location(
+ unique int id: @cil_instruction ref,
+ int loc: @location ref);
+
+cil_type_location(
+ int id: @cil_type ref,
+ int loc: @location ref);
+
+cil_method_location(
+ int id: @cil_method ref,
+ int loc: @location ref);
+
+@cil_namespace = @namespace;
+
+@cil_type_container = @cil_type | @cil_namespace | @cil_method;
+
+case @cil_type.kind of
+ 0 = @cil_valueorreftype
+| 1 = @cil_typeparameter
+| 2 = @cil_array_type
+| 3 = @cil_pointer_type
+;
+
+cil_type(
+ unique int id: @cil_type,
+ string name: string ref,
+ int kind: int ref,
+ int parent: @cil_type_container ref,
+ int sourceDecl: @cil_type ref);
+
+cil_pointer_type(
+ unique int id: @cil_pointer_type ref,
+ int pointee: @cil_type ref);
+
+cil_array_type(
+ unique int id: @cil_array_type ref,
+ int element_type: @cil_type ref,
+ int rank: int ref);
+
+cil_method(
+ unique int id: @cil_method,
+ string name: string ref,
+ int parent: @cil_type ref,
+ int return_type: @cil_type ref);
+
+cil_method_source_declaration(
+ unique int method: @cil_method ref,
+ int source: @cil_method ref);
+
+cil_method_implementation(
+ unique int id: @cil_method_implementation,
+ int method: @cil_method ref,
+ int location: @assembly ref);
+
+cil_implements(
+ int id: @cil_method ref,
+ int decl: @cil_method ref);
+
+#keyset[parent, name]
+cil_field(
+ unique int id: @cil_field,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int field_type: @cil_type ref);
+
+@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace;
+@cil_named_element = @cil_declaration | @cil_namespace;
+@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member;
+@cil_accessible = @cil_declaration;
+@cil_variable = @cil_field | @cil_stack_variable;
+@cil_stack_variable = @cil_local_variable | @cil_parameter;
+@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event;
+
+#keyset[method, index]
+cil_parameter(
+ unique int id: @cil_parameter,
+ int method: @cil_method ref,
+ int index: int ref,
+ int param_type: @cil_type ref);
+
+cil_parameter_in(unique int id: @cil_parameter ref);
+cil_parameter_out(unique int id: @cil_parameter ref);
+
+cil_setter(unique int prop: @cil_property ref,
+ int method: @cil_method ref);
+
+cil_getter(unique int prop: @cil_property ref,
+ int method: @cil_method ref);
+
+cil_adder(unique int event: @cil_event ref,
+ int method: @cil_method ref);
+
+cil_remover(unique int event: @cil_event ref, int method: @cil_method ref);
+
+cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref);
+
+cil_property(
+ unique int id: @cil_property,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int property_type: @cil_type ref);
+
+#keyset[parent, name]
+cil_event(unique int id: @cil_event,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int event_type: @cil_type ref);
+
+#keyset[impl, index]
+cil_local_variable(
+ unique int id: @cil_local_variable,
+ int impl: @cil_method_implementation ref,
+ int index: int ref,
+ int var_type: @cil_type ref);
+
+// CIL handlers (exception handlers etc).
+
+case @cil_handler.kind of
+ 0 = @cil_catch_handler
+| 1 = @cil_filter_handler
+| 2 = @cil_finally_handler
+| 4 = @cil_fault_handler
+;
+
+#keyset[impl, index]
+cil_handler(
+ unique int id: @cil_handler,
+ int impl: @cil_method_implementation ref,
+ int index: int ref,
+ int kind: int ref,
+ int try_start: @cil_instruction ref,
+ int try_end: @cil_instruction ref,
+ int handler_start: @cil_instruction ref);
+
+cil_handler_filter(
+ unique int id: @cil_handler ref,
+ int filter_start: @cil_instruction ref);
+
+cil_handler_type(
+ unique int id: @cil_handler ref,
+ int catch_type: @cil_type ref);
+
+@cil_controlflow_node = @cil_entry_point | @cil_instruction;
+
+@cil_entry_point = @cil_method_implementation | @cil_handler;
+
+@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method;
+
+cil_method_stack_size(
+ unique int method: @cil_method_implementation ref,
+ int size: int ref);
+
+// CIL modifiers
+
+cil_public(int id: @cil_member ref);
+cil_private(int id: @cil_member ref);
+cil_protected(int id: @cil_member ref);
+cil_internal(int id: @cil_member ref);
+cil_static(int id: @cil_member ref);
+cil_sealed(int id: @cil_member ref);
+cil_virtual(int id: @cil_method ref);
+cil_abstract(int id: @cil_member ref);
+cil_class(int id: @cil_type ref);
+cil_interface(int id: @cil_type ref);
+cil_security(int id: @cil_member ref);
+cil_requiresecobject(int id: @cil_method ref);
+cil_specialname(int id: @cil_method ref);
+cil_newslot(int id: @cil_method ref);
+
+cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref);
+cil_base_interface(int id: @cil_type ref, int base: @cil_type ref);
+
+#keyset[unbound, index]
+cil_type_parameter(
+ int unbound: @cil_member ref,
+ int index: int ref,
+ int param: @cil_typeparameter ref);
+
+#keyset[bound, index]
+cil_type_argument(
+ int bound: @cil_member ref,
+ int index: int ref,
+ int t: @cil_type ref);
+
+// CIL type parameter constraints
+
+cil_typeparam_covariant(int tp: @cil_typeparameter ref);
+cil_typeparam_contravariant(int tp: @cil_typeparameter ref);
+cil_typeparam_class(int tp: @cil_typeparameter ref);
+cil_typeparam_struct(int tp: @cil_typeparameter ref);
+cil_typeparam_new(int tp: @cil_typeparameter ref);
+cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref);
+
+// CIL attributes
+
+cil_attribute(
+ unique int attributeid: @cil_attribute,
+ int element: @cil_declaration ref,
+ int constructor: @cil_method ref);
+
+#keyset[attribute_id, param]
+cil_attribute_named_argument(
+ int attribute_id: @cil_attribute ref,
+ string param: string ref,
+ string value: string ref);
+
+#keyset[attribute_id, index]
+cil_attribute_positional_argument(
+ int attribute_id: @cil_attribute ref,
+ int index: int ref,
+ string value: string ref);
+
+
+// Common .Net data model covering both C# and CIL
+
+// Common elements
+@dotnet_element = @element | @cil_element;
+@dotnet_named_element = @named_element | @cil_named_element;
+@dotnet_callable = @callable | @cil_method;
+@dotnet_variable = @variable | @cil_variable;
+@dotnet_field = @field | @cil_field;
+@dotnet_parameter = @parameter | @cil_parameter;
+@dotnet_declaration = @declaration | @cil_declaration;
+@dotnet_member = @member | @cil_member;
+@dotnet_event = @event | @cil_event;
+@dotnet_property = @property | @cil_property | @indexer;
+
+// Common types
+@dotnet_type = @type | @cil_type;
+@dotnet_call = @call | @cil_call_any;
+@dotnet_throw = @throw_element | @cil_throw_any;
+@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type;
+@dotnet_typeparameter = @type_parameter | @cil_typeparameter;
+@dotnet_array_type = @array_type | @cil_array_type;
+@dotnet_pointer_type = @pointer_type | @cil_pointer_type;
+@dotnet_type_parameter = @type_parameter | @cil_typeparameter;
+@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable;
+
+// Attributes
+@dotnet_attribute = @attribute | @cil_attribute;
+
+// Expressions
+@dotnet_expr = @expr | @cil_expr;
+
+// Literals
+@dotnet_literal = @literal_expr | @cil_literal;
+@dotnet_string_literal = @string_literal_expr | @cil_ldstr;
+@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i;
+@dotnet_float_literal = @float_literal_expr | @cil_ldc_r;
+@dotnet_null_literal = @null_literal_expr | @cil_ldnull;
+
+@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property |
+ @callable | @value_or_ref_type | @void_type;
+
+#keyset[entity, location]
+metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref)
diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme
new file mode 100644
index 000000000000..173895c0c823
--- /dev/null
+++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/semmlecode.csharp.dbscheme
@@ -0,0 +1,1896 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ unique int id : @compilation,
+ string cwd : string ref
+);
+
+/**
+ * The arguments that were passed to the extractor for a compiler
+ * invocation. If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | --compiler
+ * 1 | *path to compiler*
+ * 2 | --cil
+ * 3 | f1.cs
+ * 4 | f2.cs
+ * 5 | f3.cs
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.cs
+ * 1 | f2.cs
+ * 2 | f3.cs
+ */
+#keyset[id, num]
+compilation_compiling_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The references used by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * csc f1.cs f2.cs f3.cs /r:ref1.dll /r:ref2.dll /r:ref3.dll
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | ref1.dll
+ * 1 | ref2.dll
+ * 2 | ref3.dll
+ */
+#keyset[id, num]
+compilation_referencing_files(
+ int id : @compilation ref,
+ int num : int ref,
+ int file : @file ref
+);
+
+/**
+ * The time taken by the extractor for a compiler invocation.
+ *
+ * For each file `num`, there will be rows for
+ *
+ * kind | seconds
+ * ---- | ---
+ * 1 | CPU seconds used by the extractor frontend
+ * 2 | Elapsed seconds during the extractor frontend
+ * 3 | CPU seconds used by the extractor backend
+ * 4 | Elapsed seconds during the extractor backend
+ */
+#keyset[id, num, kind]
+compilation_time(
+ int id : @compilation ref,
+ int num : int ref,
+ /* kind:
+ 1 = frontend_cpu_seconds
+ 2 = frontend_elapsed_seconds
+ 3 = extractor_cpu_seconds
+ 4 = extractor_elapsed_seconds
+ */
+ int kind : int ref,
+ float seconds : float ref
+);
+
+/**
+ * An error or warning generated by the extractor.
+ * The diagnostic message `diagnostic` was generated during compiler
+ * invocation `compilation`, and is the `file_number_diagnostic_number`th
+ * message generated while extracting the `file_number`th file of that
+ * invocation.
+ */
+#keyset[compilation, file_number, file_number_diagnostic_number]
+diagnostic_for(
+ unique int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int ref
+);
+
+diagnostics(
+ unique int id: @diagnostic,
+ int severity: int ref,
+ string error_tag: string ref,
+ string error_message: string ref,
+ string full_error_message: string ref,
+ int location: @location_default ref
+);
+
+extractor_messages(
+ unique int id: @extractor_message,
+ int severity: int ref,
+ string origin : string ref,
+ string text : string ref,
+ string entity : string ref,
+ int location: @location_default ref,
+ string stack_trace : string ref
+);
+
+/**
+ * If extraction was successful, then `cpu_seconds` and
+ * `elapsed_seconds` are the CPU time and elapsed time (respectively)
+ * that extraction took for compiler invocation `id`.
+ */
+compilation_finished(
+ unique int id : @compilation ref,
+ float cpu_seconds : float ref,
+ float elapsed_seconds : float ref
+);
+
+/*
+ * External artifacts
+ */
+
+externalDefects(
+ unique int id: @externalDefect,
+ string queryPath: string ref,
+ int location: @location ref,
+ string message: string ref,
+ float severity: float ref);
+
+externalMetrics(
+ unique int id: @externalMetric,
+ string queryPath: string ref,
+ int location: @location ref,
+ float value: float ref);
+
+externalData(
+ int id: @externalDataElement,
+ string path: string ref,
+ int column: int ref,
+ string value: string ref);
+
+snapshotDate(
+ unique date snapshotDate: date ref);
+
+sourceLocationPrefix(
+ string prefix: string ref);
+
+/*
+ * Duplicate code
+ */
+
+duplicateCode(
+ unique int id: @duplication,
+ string relativePath: string ref,
+ int equivClass: int ref);
+
+similarCode(
+ unique int id: @similarity,
+ string relativePath: string ref,
+ int equivClass: int ref);
+
+@duplication_or_similarity = @duplication | @similarity
+
+tokens(
+ int id: @duplication_or_similarity ref,
+ int offset: int ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+/*
+ * C# dbscheme
+ */
+
+/** ELEMENTS **/
+
+@element = @declaration | @stmt | @expr | @modifier | @attribute | @namespace_declaration
+ | @using_directive | @type_parameter_constraints | @external_element
+ | @xmllocatable | @asp_element | @namespace;
+
+@declaration = @callable | @generic | @assignable | @namespace;
+
+@named_element = @namespace | @declaration;
+
+@declaration_with_accessors = @property | @indexer | @event;
+
+@assignable = @variable | @assignable_with_accessors | @event;
+
+@assignable_with_accessors = @property | @indexer;
+
+@external_element = @externalMetric | @externalDefect | @externalDataElement;
+
+@attributable = @assembly | @field | @parameter | @operator | @method | @constructor
+ | @destructor | @callable_accessor | @value_or_ref_type | @declaration_with_accessors
+ | @local_function;
+
+/** LOCATIONS, ASEMMBLIES, MODULES, FILES and FOLDERS **/
+
+@location = @location_default | @assembly;
+
+locations_default(
+ unique int id: @location_default,
+ int file: @file ref,
+ int beginLine: int ref,
+ int beginColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref);
+
+@sourceline = @file | @callable | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: int ref);
+
+assemblies(
+ unique int id: @assembly,
+ int file: @file ref,
+ string fullname: string ref,
+ string name: string ref,
+ string version: string ref);
+
+/*
+ fromSource(0) = unknown,
+ fromSource(1) = from source,
+ fromSource(2) = from library
+*/
+files(
+ unique int id: @file,
+ string name: string ref,
+ string simple: string ref,
+ string ext: string ref,
+ int fromSource: int ref);
+
+folders(
+ unique int id: @folder,
+ string name: string ref,
+ string simple: string ref);
+
+@container = @folder | @file ;
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref);
+
+file_extraction_mode(
+ unique int file: @file ref,
+ int mode: int ref
+ /* 0 = normal, 1 = standalone extractor */
+ );
+
+/** NAMESPACES **/
+
+@type_container = @namespace | @type;
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref);
+
+namespace_declarations(
+ unique int id: @namespace_declaration,
+ int namespace_id: @namespace ref);
+
+namespace_declaration_location(
+ unique int id: @namespace_declaration ref,
+ int loc: @location ref);
+
+parent_namespace(
+ unique int child_id: @type_container ref,
+ int namespace_id: @namespace ref);
+
+@declaration_or_directive = @namespace_declaration | @type | @using_directive;
+
+parent_namespace_declaration(
+ int child_id: @declaration_or_directive ref, // cannot be unique because of partial classes
+ int namespace_id: @namespace_declaration ref);
+
+@using_directive = @using_namespace_directive | @using_static_directive;
+
+using_namespace_directives(
+ unique int id: @using_namespace_directive,
+ int namespace_id: @namespace ref);
+
+using_static_directives(
+ unique int id: @using_static_directive,
+ int type_id: @type_or_ref ref);
+
+using_directive_location(
+ unique int id: @using_directive ref,
+ int loc: @location ref);
+
+/** TYPES **/
+
+types(
+ unique int id: @type,
+ int kind: int ref,
+ string name: string ref);
+
+case @type.kind of
+ 1 = @bool_type
+| 2 = @char_type
+| 3 = @decimal_type
+| 4 = @sbyte_type
+| 5 = @short_type
+| 6 = @int_type
+| 7 = @long_type
+| 8 = @byte_type
+| 9 = @ushort_type
+| 10 = @uint_type
+| 11 = @ulong_type
+| 12 = @float_type
+| 13 = @double_type
+| 14 = @enum_type
+| 15 = @struct_type
+| 17 = @class_type
+| 19 = @interface_type
+| 20 = @delegate_type
+| 21 = @null_type
+| 22 = @type_parameter
+| 23 = @pointer_type
+| 24 = @nullable_type
+| 25 = @array_type
+| 26 = @void_type
+| 27 = @int_ptr_type
+| 28 = @uint_ptr_type
+| 29 = @dynamic_type
+| 30 = @arglist_type
+| 31 = @unknown_type
+| 32 = @tuple_type
+ ;
+
+@simple_type = @bool_type | @char_type | @integral_type | @floating_point_type | @decimal_type;
+@integral_type = @signed_integral_type | @unsigned_integral_type;
+@signed_integral_type = @sbyte_type | @short_type | @int_type | @long_type;
+@unsigned_integral_type = @byte_type | @ushort_type | @uint_type | @ulong_type;
+@floating_point_type = @float_type | @double_type;
+@value_type = @simple_type | @enum_type | @struct_type | @nullable_type | @int_ptr_type
+ | @uint_ptr_type | @tuple_type;
+@ref_type = @class_type | @interface_type | @array_type | @delegate_type | @null_type
+ | @dynamic_type;
+@value_or_ref_type = @value_type | @ref_type;
+
+typerefs(
+ unique int id: @typeref,
+ string name: string ref);
+
+typeref_type(
+ int id: @typeref ref,
+ unique int typeId: @type ref);
+
+@type_or_ref = @type | @typeref;
+
+array_element_type(
+ unique int array: @array_type ref,
+ int dimension: int ref,
+ int rank: int ref,
+ int element: @type_or_ref ref);
+
+nullable_underlying_type(
+ unique int nullable: @nullable_type ref,
+ int underlying: @type_or_ref ref);
+
+pointer_referent_type(
+ unique int pointer: @pointer_type ref,
+ int referent: @type_or_ref ref);
+
+enum_underlying_type(
+ unique int enum_id: @enum_type ref,
+ int underlying_type_id: @type_or_ref ref);
+
+delegate_return_type(
+ unique int delegate_id: @delegate_type ref,
+ int return_type_id: @type_or_ref ref);
+
+extend(
+ unique int sub: @type ref,
+ int super: @type_or_ref ref);
+
+@interface_or_ref = @interface_type | @typeref;
+
+implement(
+ int sub: @type ref,
+ int super: @type_or_ref ref);
+
+type_location(
+ int id: @type ref,
+ int loc: @location ref);
+
+tuple_underlying_type(
+ unique int tuple: @tuple_type ref,
+ int struct: @type_or_ref ref);
+
+#keyset[tuple, index]
+tuple_element(
+ int tuple: @tuple_type ref,
+ int index: int ref,
+ unique int field: @field ref);
+
+attributes(
+ unique int id: @attribute,
+ int type_id: @type_or_ref ref,
+ int target: @attributable ref);
+
+attribute_location(
+ int id: @attribute ref,
+ int loc: @location ref);
+
+@type_mention_parent = @element | @type_mention;
+
+type_mention(
+ unique int id: @type_mention,
+ int type_id: @type_or_ref ref,
+ int parent: @type_mention_parent ref);
+
+type_mention_location(
+ unique int id: @type_mention ref,
+ int loc: @location ref);
+
+@has_type_annotation = @assignable | @type_parameter | @callable | @expr | @delegate_type | @generic;
+
+/**
+ * A direct annotation on an entity, for example `string? x;`.
+ *
+ * Annotations:
+ * 2 = reftype is not annotated "!"
+ * 3 = reftype is annotated "?"
+ * 4 = readonly ref type / in parameter
+ * 5 = ref type parameter, return or local variable
+ * 6 = out parameter
+ *
+ * Note that the annotation depends on the element it annotates.
+ * @assignable: The annotation is on the type of the assignable, for example the variable type.
+ * @type_parameter: The annotation is on the reftype constraint
+ * @callable: The annotation is on the return type
+ * @array_type: The annotation is on the element type
+ */
+type_annotation(int id: @has_type_annotation ref, int annotation: int ref);
+
+nullability(unique int nullability: @nullability, int kind: int ref);
+
+case @nullability.kind of
+ 0 = @oblivious
+| 1 = @not_annotated
+| 2 = @annotated
+;
+
+#keyset[parent, index]
+nullability_parent(int nullability: @nullability ref, int index: int ref, int parent: @nullability ref)
+
+type_nullability(int id: @has_type_annotation ref, int nullability: @nullability ref);
+
+/**
+ * The nullable flow state of an expression, as determined by Roslyn.
+ * 0 = none (default, not populated)
+ * 1 = not null
+ * 2 = maybe null
+ */
+expr_flowstate(unique int id: @expr ref, int state: int ref);
+
+/** GENERICS **/
+
+@generic = @type | @method | @local_function;
+
+type_parameters(
+ unique int id: @type_parameter ref,
+ int index: int ref,
+ int generic_id: @generic ref,
+ int variance: int ref /* none = 0, out = 1, in = 2 */);
+
+#keyset[constructed_id, index]
+type_arguments(
+ int id: @type_or_ref ref,
+ int index: int ref,
+ int constructed_id: @generic_or_ref ref);
+
+@generic_or_ref = @generic | @typeref;
+
+constructed_generic(
+ unique int constructed: @generic ref,
+ int generic: @generic_or_ref ref);
+
+type_parameter_constraints(
+ unique int id: @type_parameter_constraints,
+ int param_id: @type_parameter ref);
+
+type_parameter_constraints_location(
+ int id: @type_parameter_constraints ref,
+ int loc: @location ref);
+
+general_type_parameter_constraints(
+ int id: @type_parameter_constraints ref,
+ int kind: int ref /* class = 1, struct = 2, new = 3 */);
+
+specific_type_parameter_constraints(
+ int id: @type_parameter_constraints ref,
+ int base_id: @type_or_ref ref);
+
+specific_type_parameter_nullability(
+ int id: @type_parameter_constraints ref,
+ int base_id: @type_or_ref ref,
+ int nullability: @nullability ref);
+
+/** MODIFIERS */
+
+@modifiable = @modifiable_direct | @event_accessor;
+
+@modifiable_direct = @member | @accessor | @local_function | @anonymous_function_expr;
+
+modifiers(
+ unique int id: @modifier,
+ string name: string ref);
+
+has_modifiers(
+ int id: @modifiable_direct ref,
+ int mod_id: @modifier ref);
+
+compiler_generated(unique int id: @modifiable_direct ref);
+
+/** MEMBERS **/
+
+@member = @method | @constructor | @destructor | @field | @property | @event | @operator | @indexer | @type;
+
+@named_exprorstmt = @goto_stmt | @labeled_stmt | @expr;
+
+@virtualizable = @method | @property | @indexer | @event;
+
+exprorstmt_name(
+ unique int parent_id: @named_exprorstmt ref,
+ string name: string ref);
+
+nested_types(
+ unique int id: @type ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @type ref);
+
+properties(
+ unique int id: @property,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @property ref);
+
+property_location(
+ int id: @property ref,
+ int loc: @location ref);
+
+indexers(
+ unique int id: @indexer,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @indexer ref);
+
+indexer_location(
+ int id: @indexer ref,
+ int loc: @location ref);
+
+accessors(
+ unique int id: @accessor,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_member_id: @member ref,
+ int unbound_id: @accessor ref);
+
+case @accessor.kind of
+ 1 = @getter
+| 2 = @setter
+ ;
+
+accessor_location(
+ int id: @accessor ref,
+ int loc: @location ref);
+
+events(
+ unique int id: @event,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @event ref);
+
+event_location(
+ int id: @event ref,
+ int loc: @location ref);
+
+event_accessors(
+ unique int id: @event_accessor,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_event_id: @event ref,
+ int unbound_id: @event_accessor ref);
+
+case @event_accessor.kind of
+ 1 = @add_event_accessor
+| 2 = @remove_event_accessor
+ ;
+
+event_accessor_location(
+ int id: @event_accessor ref,
+ int loc: @location ref);
+
+operators(
+ unique int id: @operator,
+ string name: string ref,
+ string symbol: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @operator ref);
+
+operator_location(
+ int id: @operator ref,
+ int loc: @location ref);
+
+constant_value(
+ int id: @variable ref,
+ string value: string ref);
+
+/** CALLABLES **/
+
+@callable = @method | @constructor | @destructor | @operator | @callable_accessor | @anonymous_function_expr | @local_function;
+
+@callable_accessor = @accessor | @event_accessor;
+
+methods(
+ unique int id: @method,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @method ref);
+
+method_location(
+ int id: @method ref,
+ int loc: @location ref);
+
+constructors(
+ unique int id: @constructor,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @constructor ref);
+
+constructor_location(
+ int id: @constructor ref,
+ int loc: @location ref);
+
+destructors(
+ unique int id: @destructor,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int unbound_id: @destructor ref);
+
+destructor_location(
+ int id: @destructor ref,
+ int loc: @location ref);
+
+overrides(
+ int id: @callable ref,
+ int base_id: @callable ref);
+
+explicitly_implements(
+ int id: @member ref,
+ int interface_id: @interface_or_ref ref);
+
+local_functions(
+ unique int id: @local_function,
+ string name: string ref,
+ int return_type: @type ref,
+ int unbound_id: @local_function ref);
+
+local_function_stmts(
+ unique int fn: @local_function_stmt ref,
+ int stmt: @local_function ref);
+
+/** VARIABLES **/
+
+@variable = @local_scope_variable | @field;
+
+@local_scope_variable = @local_variable | @parameter;
+
+fields(
+ unique int id: @field,
+ int kind: int ref,
+ string name: string ref,
+ int declaring_type_id: @type ref,
+ int type_id: @type_or_ref ref,
+ int unbound_id: @field ref);
+
+case @field.kind of
+ 1 = @addressable_field
+| 2 = @constant
+ ;
+
+field_location(
+ int id: @field ref,
+ int loc: @location ref);
+
+localvars(
+ unique int id: @local_variable,
+ int kind: int ref,
+ string name: string ref,
+ int implicitly_typed: int ref /* 0 = no, 1 = yes */,
+ int type_id: @type_or_ref ref,
+ int parent_id: @local_var_decl_expr ref);
+
+case @local_variable.kind of
+ 1 = @addressable_local_variable
+| 2 = @local_constant
+| 3 = @local_variable_ref
+ ;
+
+localvar_location(
+ unique int id: @local_variable ref,
+ int loc: @location ref);
+
+@parameterizable = @callable | @delegate_type | @indexer;
+
+#keyset[name, parent_id]
+#keyset[index, parent_id]
+params(
+ unique int id: @parameter,
+ string name: string ref,
+ int type_id: @type_or_ref ref,
+ int index: int ref,
+ int mode: int ref, /* value = 0, ref = 1, out = 2, array = 3, this = 4 */
+ int parent_id: @parameterizable ref,
+ int unbound_id: @parameter ref);
+
+param_location(
+ int id: @parameter ref,
+ int loc: @location ref);
+
+/** STATEMENTS **/
+
+@exprorstmt_parent = @control_flow_element | @top_level_exprorstmt_parent;
+
+statements(
+ unique int id: @stmt,
+ int kind: int ref);
+
+#keyset[index, parent]
+stmt_parent(
+ unique int stmt: @stmt ref,
+ int index: int ref,
+ int parent: @control_flow_element ref);
+
+@top_level_stmt_parent = @callable;
+
+// [index, parent] is not a keyset because the same parent may be compiled multiple times
+stmt_parent_top_level(
+ unique int stmt: @stmt ref,
+ int index: int ref,
+ int parent: @top_level_stmt_parent ref);
+
+case @stmt.kind of
+ 1 = @block_stmt
+| 2 = @expr_stmt
+| 3 = @if_stmt
+| 4 = @switch_stmt
+| 5 = @while_stmt
+| 6 = @do_stmt
+| 7 = @for_stmt
+| 8 = @foreach_stmt
+| 9 = @break_stmt
+| 10 = @continue_stmt
+| 11 = @goto_stmt
+| 12 = @goto_case_stmt
+| 13 = @goto_default_stmt
+| 14 = @throw_stmt
+| 15 = @return_stmt
+| 16 = @yield_stmt
+| 17 = @try_stmt
+| 18 = @checked_stmt
+| 19 = @unchecked_stmt
+| 20 = @lock_stmt
+| 21 = @using_block_stmt
+| 22 = @var_decl_stmt
+| 23 = @const_decl_stmt
+| 24 = @empty_stmt
+| 25 = @unsafe_stmt
+| 26 = @fixed_stmt
+| 27 = @label_stmt
+| 28 = @catch
+| 29 = @case_stmt
+| 30 = @local_function_stmt
+| 31 = @using_decl_stmt
+ ;
+
+@using_stmt = @using_block_stmt | @using_decl_stmt;
+
+@labeled_stmt = @label_stmt | @case;
+
+@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt;
+
+@cond_stmt = @if_stmt | @switch_stmt;
+
+@loop_stmt = @while_stmt | @do_stmt | @for_stmt | @foreach_stmt;
+
+@jump_stmt = @break_stmt | @goto_any_stmt | @continue_stmt | @throw_stmt | @return_stmt
+ | @yield_stmt;
+
+@goto_any_stmt = @goto_default_stmt | @goto_case_stmt | @goto_stmt;
+
+
+stmt_location(
+ unique int id: @stmt ref,
+ int loc: @location ref);
+
+catch_type(
+ unique int catch_id: @catch ref,
+ int type_id: @type_or_ref ref,
+ int kind: int ref /* explicit = 1, implicit = 2 */);
+
+/** EXPRESSIONS **/
+
+expressions(
+ unique int id: @expr,
+ int kind: int ref,
+ int type_id: @type_or_ref ref);
+
+#keyset[index, parent]
+expr_parent(
+ unique int expr: @expr ref,
+ int index: int ref,
+ int parent: @control_flow_element ref);
+
+@top_level_expr_parent = @attribute | @field | @property | @indexer | @parameter;
+
+@top_level_exprorstmt_parent = @top_level_expr_parent | @top_level_stmt_parent;
+
+// [index, parent] is not a keyset because the same parent may be compiled multiple times
+expr_parent_top_level(
+ unique int expr: @expr ref,
+ int index: int ref,
+ int parent: @top_level_exprorstmt_parent ref);
+
+case @expr.kind of
+/* literal */
+ 1 = @bool_literal_expr
+| 2 = @char_literal_expr
+| 3 = @decimal_literal_expr
+| 4 = @int_literal_expr
+| 5 = @long_literal_expr
+| 6 = @uint_literal_expr
+| 7 = @ulong_literal_expr
+| 8 = @float_literal_expr
+| 9 = @double_literal_expr
+| 10 = @string_literal_expr
+| 11 = @null_literal_expr
+/* primary & unary */
+| 12 = @this_access_expr
+| 13 = @base_access_expr
+| 14 = @local_variable_access_expr
+| 15 = @parameter_access_expr
+| 16 = @field_access_expr
+| 17 = @property_access_expr
+| 18 = @method_access_expr
+| 19 = @event_access_expr
+| 20 = @indexer_access_expr
+| 21 = @array_access_expr
+| 22 = @type_access_expr
+| 23 = @typeof_expr
+| 24 = @method_invocation_expr
+| 25 = @delegate_invocation_expr
+| 26 = @operator_invocation_expr
+| 27 = @cast_expr
+| 28 = @object_creation_expr
+| 29 = @explicit_delegate_creation_expr
+| 30 = @implicit_delegate_creation_expr
+| 31 = @array_creation_expr
+| 32 = @default_expr
+| 33 = @plus_expr
+| 34 = @minus_expr
+| 35 = @bit_not_expr
+| 36 = @log_not_expr
+| 37 = @post_incr_expr
+| 38 = @post_decr_expr
+| 39 = @pre_incr_expr
+| 40 = @pre_decr_expr
+/* multiplicative */
+| 41 = @mul_expr
+| 42 = @div_expr
+| 43 = @rem_expr
+/* additive */
+| 44 = @add_expr
+| 45 = @sub_expr
+/* shift */
+| 46 = @lshift_expr
+| 47 = @rshift_expr
+/* relational */
+| 48 = @lt_expr
+| 49 = @gt_expr
+| 50 = @le_expr
+| 51 = @ge_expr
+/* equality */
+| 52 = @eq_expr
+| 53 = @ne_expr
+/* logical */
+| 54 = @bit_and_expr
+| 55 = @bit_xor_expr
+| 56 = @bit_or_expr
+| 57 = @log_and_expr
+| 58 = @log_or_expr
+/* type testing */
+| 59 = @is_expr
+| 60 = @as_expr
+/* null coalescing */
+| 61 = @null_coalescing_expr
+/* conditional */
+| 62 = @conditional_expr
+/* assignment */
+| 63 = @simple_assign_expr
+| 64 = @assign_add_expr
+| 65 = @assign_sub_expr
+| 66 = @assign_mul_expr
+| 67 = @assign_div_expr
+| 68 = @assign_rem_expr
+| 69 = @assign_and_expr
+| 70 = @assign_xor_expr
+| 71 = @assign_or_expr
+| 72 = @assign_lshift_expr
+| 73 = @assign_rshift_expr
+/* more */
+| 74 = @object_init_expr
+| 75 = @collection_init_expr
+| 76 = @array_init_expr
+| 77 = @checked_expr
+| 78 = @unchecked_expr
+| 79 = @constructor_init_expr
+| 80 = @add_event_expr
+| 81 = @remove_event_expr
+| 82 = @par_expr
+| 83 = @local_var_decl_expr
+| 84 = @lambda_expr
+| 85 = @anonymous_method_expr
+| 86 = @namespace_expr
+/* dynamic */
+| 92 = @dynamic_element_access_expr
+| 93 = @dynamic_member_access_expr
+/* unsafe */
+| 100 = @pointer_indirection_expr
+| 101 = @address_of_expr
+| 102 = @sizeof_expr
+/* async */
+| 103 = @await_expr
+/* C# 6.0 */
+| 104 = @nameof_expr
+| 105 = @interpolated_string_expr
+| 106 = @unknown_expr
+/* C# 7.0 */
+| 107 = @throw_expr
+| 108 = @tuple_expr
+| 109 = @local_function_invocation_expr
+| 110 = @ref_expr
+| 111 = @discard_expr
+/* C# 8.0 */
+| 112 = @range_expr
+| 113 = @index_expr
+| 114 = @switch_expr
+| 115 = @recursive_pattern_expr
+| 116 = @property_pattern_expr
+| 117 = @positional_pattern_expr
+| 118 = @switch_case_expr
+| 119 = @assign_coalesce_expr
+| 120 = @suppress_nullable_warning_expr
+| 121 = @namespace_access_expr
+/* C# 9.0 */
+| 122 = @lt_pattern_expr
+| 123 = @gt_pattern_expr
+| 124 = @le_pattern_expr
+| 125 = @ge_pattern_expr
+;
+
+@switch = @switch_stmt | @switch_expr;
+@case = @case_stmt | @switch_case_expr;
+@pattern_match = @case | @is_expr;
+@relational_pattern_expr = @gt_pattern_expr | @lt_pattern_expr | @ge_pattern_expr | @le_pattern_expr;
+
+@integer_literal_expr = @int_literal_expr | @long_literal_expr | @uint_literal_expr | @ulong_literal_expr;
+@real_literal_expr = @float_literal_expr | @double_literal_expr | @decimal_literal_expr;
+@literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr
+ | @string_literal_expr | @null_literal_expr;
+
+@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr;
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr;
+@assign_event_expr = @add_event_expr | @remove_event_expr;
+
+@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr
+ | @assign_rem_expr
+@assign_bitwise_expr = @assign_and_expr | @assign_or_expr | @assign_xor_expr
+ | @assign_lshift_expr | @assign_rshift_expr;
+
+@member_access_expr = @field_access_expr | @property_access_expr | @indexer_access_expr | @event_access_expr
+ | @method_access_expr | @type_access_expr | @dynamic_member_access_expr;
+@access_expr = @member_access_expr | @this_access_expr | @base_access_expr | @assignable_access_expr | @namespace_access_expr;
+@element_access_expr = @indexer_access_expr | @array_access_expr | @dynamic_element_access_expr;
+
+@local_variable_access = @local_variable_access_expr | @local_var_decl_expr;
+@local_scope_variable_access_expr = @parameter_access_expr | @local_variable_access;
+@variable_access_expr = @local_scope_variable_access_expr | @field_access_expr;
+
+@assignable_access_expr = @variable_access_expr | @property_access_expr | @element_access_expr
+ | @event_access_expr | @dynamic_member_access_expr;
+
+@objectorcollection_init_expr = @object_init_expr | @collection_init_expr;
+
+@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr;
+
+@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
+@incr_op_expr = @pre_incr_expr | @post_incr_expr;
+@decr_op_expr = @pre_decr_expr | @post_decr_expr;
+@mut_op_expr = @incr_op_expr | @decr_op_expr;
+@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr;
+@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr;
+
+@ternary_log_op_expr = @conditional_expr;
+@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr;
+@un_log_op_expr = @log_not_expr;
+@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
+
+@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
+ | @rshift_expr;
+@un_bit_op_expr = @bit_not_expr;
+@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;
+
+@equality_op_expr = @eq_expr | @ne_expr;
+@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr;
+@comp_expr = @equality_op_expr | @rel_op_expr;
+
+@op_expr = @assign_expr | @un_op | @bin_op | @ternary_op;
+
+@ternary_op = @ternary_log_op_expr;
+@bin_op = @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr;
+@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr
+ | @pointer_indirection_expr | @address_of_expr;
+
+@anonymous_function_expr = @lambda_expr | @anonymous_method_expr;
+
+@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr
+ | @delegate_invocation_expr | @object_creation_expr | @call_access_expr
+ | @local_function_invocation_expr;
+
+@call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr;
+
+@late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr
+ | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr;
+
+@throw_element = @throw_expr | @throw_stmt;
+
+implicitly_typed_array_creation(
+ unique int id: @array_creation_expr ref);
+
+explicitly_sized_array_creation(
+ unique int id: @array_creation_expr ref);
+
+stackalloc_array_creation(
+ unique int id: @array_creation_expr ref);
+
+mutator_invocation_mode(
+ unique int id: @operator_invocation_expr ref,
+ int mode: int ref /* prefix = 1, postfix = 2*/);
+
+expr_compiler_generated(
+ unique int id: @expr ref);
+
+expr_value(
+ unique int id: @expr ref,
+ string value: string ref);
+
+expr_call(
+ unique int caller_id: @expr ref,
+ int target_id: @callable ref);
+
+expr_access(
+ unique int accesser_id: @access_expr ref,
+ int target_id: @accessible ref);
+
+@accessible = @method | @assignable | @local_function | @namespace;
+
+expr_location(
+ unique int id: @expr ref,
+ int loc: @location ref);
+
+dynamic_member_name(
+ unique int id: @late_bindable_expr ref,
+ string name: string ref);
+
+@qualifiable_expr = @member_access_expr
+ | @method_invocation_expr
+ | @element_access_expr;
+
+conditional_access(
+ unique int id: @qualifiable_expr ref);
+
+expr_argument(
+ unique int id: @expr ref,
+ int mode: int ref);
+ /* mode is the same as params: value = 0, ref = 1, out = 2 */
+
+expr_argument_name(
+ unique int id: @expr ref,
+ string name: string ref);
+
+/** CONTROL/DATA FLOW **/
+
+@control_flow_element = @stmt | @expr;
+
+/* XML Files */
+
+xmlEncoding (
+ unique int id: @file ref,
+ string encoding: string ref);
+
+xmlDTDs(
+ unique int id: @xmldtd,
+ string root: string ref,
+ string publicId: string ref,
+ string systemId: string ref,
+ int fileid: @file ref);
+
+xmlElements(
+ unique int id: @xmlelement,
+ string name: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int fileid: @file ref);
+
+xmlAttrs(
+ unique int id: @xmlattribute,
+ int elementid: @xmlelement ref,
+ string name: string ref,
+ string value: string ref,
+ int idx: int ref,
+ int fileid: @file ref);
+
+xmlNs(
+ int id: @xmlnamespace,
+ string prefixName: string ref,
+ string URI: string ref,
+ int fileid: @file ref);
+
+xmlHasNs(
+ int elementId: @xmlnamespaceable ref,
+ int nsId: @xmlnamespace ref,
+ int fileid: @file ref);
+
+xmlComments(
+ unique int id: @xmlcomment,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int fileid: @file ref);
+
+xmlChars(
+ unique int id: @xmlcharacters,
+ string text: string ref,
+ int parentid: @xmlparent ref,
+ int idx: int ref,
+ int isCDATA: int ref,
+ int fileid: @file ref);
+
+@xmlparent = @file | @xmlelement;
+@xmlnamespaceable = @xmlelement | @xmlattribute;
+
+xmllocations(
+ int xmlElement: @xmllocatable ref,
+ int location: @location_default ref);
+
+@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;
+
+/* Comments */
+
+commentline(
+ unique int id: @commentline,
+ int kind: int ref,
+ string text: string ref,
+ string rawtext: string ref);
+
+case @commentline.kind of
+ 0 = @singlelinecomment
+| 1 = @xmldoccomment
+| 2 = @multilinecomment;
+
+commentline_location(
+ unique int id: @commentline ref,
+ int loc: @location ref);
+
+commentblock(
+ unique int id : @commentblock);
+
+commentblock_location(
+ unique int id: @commentblock ref,
+ int loc: @location ref);
+
+commentblock_binding(
+ int id: @commentblock ref,
+ int entity: @element ref,
+ int bindtype: int ref); /* 0: Parent, 1: Best, 2: Before, 3: After */
+
+commentblock_child(
+ int id: @commentblock ref,
+ int commentline: @commentline ref,
+ int index: int ref);
+
+/* ASP.NET */
+
+case @asp_element.kind of
+ 0=@asp_close_tag
+| 1=@asp_code
+| 2=@asp_comment
+| 3=@asp_data_binding
+| 4=@asp_directive
+| 5=@asp_open_tag
+| 6=@asp_quoted_string
+| 7=@asp_text
+| 8=@asp_xml_directive;
+
+@asp_attribute = @asp_code | @asp_data_binding | @asp_quoted_string;
+
+asp_elements(
+ unique int id: @asp_element,
+ int kind: int ref,
+ int loc: @location ref);
+
+asp_comment_server(unique int comment: @asp_comment ref);
+asp_code_inline(unique int code: @asp_code ref);
+asp_directive_attribute(
+ int directive: @asp_directive ref,
+ int index: int ref,
+ string name: string ref,
+ int value: @asp_quoted_string ref);
+asp_directive_name(
+ unique int directive: @asp_directive ref,
+ string name: string ref);
+asp_element_body(
+ unique int element: @asp_element ref,
+ string body: string ref);
+asp_tag_attribute(
+ int tag: @asp_open_tag ref,
+ int index: int ref,
+ string name: string ref,
+ int attribute: @asp_attribute ref);
+asp_tag_name(
+ unique int tag: @asp_open_tag ref,
+ string name: string ref);
+asp_tag_isempty(int tag: @asp_open_tag ref);
+
+/* Common Intermediate Language - CIL */
+
+case @cil_instruction.opcode of
+ 0 = @cil_nop
+| 1 = @cil_break
+| 2 = @cil_ldarg_0
+| 3 = @cil_ldarg_1
+| 4 = @cil_ldarg_2
+| 5 = @cil_ldarg_3
+| 6 = @cil_ldloc_0
+| 7 = @cil_ldloc_1
+| 8 = @cil_ldloc_2
+| 9 = @cil_ldloc_3
+| 10 = @cil_stloc_0
+| 11 = @cil_stloc_1
+| 12 = @cil_stloc_2
+| 13 = @cil_stloc_3
+| 14 = @cil_ldarg_s
+| 15 = @cil_ldarga_s
+| 16 = @cil_starg_s
+| 17 = @cil_ldloc_s
+| 18 = @cil_ldloca_s
+| 19 = @cil_stloc_s
+| 20 = @cil_ldnull
+| 21 = @cil_ldc_i4_m1
+| 22 = @cil_ldc_i4_0
+| 23 = @cil_ldc_i4_1
+| 24 = @cil_ldc_i4_2
+| 25 = @cil_ldc_i4_3
+| 26 = @cil_ldc_i4_4
+| 27 = @cil_ldc_i4_5
+| 28 = @cil_ldc_i4_6
+| 29 = @cil_ldc_i4_7
+| 30 = @cil_ldc_i4_8
+| 31 = @cil_ldc_i4_s
+| 32 = @cil_ldc_i4
+| 33 = @cil_ldc_i8
+| 34 = @cil_ldc_r4
+| 35 = @cil_ldc_r8
+| 37 = @cil_dup
+| 38 = @cil_pop
+| 39 = @cil_jmp
+| 40 = @cil_call
+| 41 = @cil_calli
+| 42 = @cil_ret
+| 43 = @cil_br_s
+| 44 = @cil_brfalse_s
+| 45 = @cil_brtrue_s
+| 46 = @cil_beq_s
+| 47 = @cil_bge_s
+| 48 = @cil_bgt_s
+| 49 = @cil_ble_s
+| 50 = @cil_blt_s
+| 51 = @cil_bne_un_s
+| 52 = @cil_bge_un_s
+| 53 = @cil_bgt_un_s
+| 54 = @cil_ble_un_s
+| 55 = @cil_blt_un_s
+| 56 = @cil_br
+| 57 = @cil_brfalse
+| 58 = @cil_brtrue
+| 59 = @cil_beq
+| 60 = @cil_bge
+| 61 = @cil_bgt
+| 62 = @cil_ble
+| 63 = @cil_blt
+| 64 = @cil_bne_un
+| 65 = @cil_bge_un
+| 66 = @cil_bgt_un
+| 67 = @cil_ble_un
+| 68 = @cil_blt_un
+| 69 = @cil_switch
+| 70 = @cil_ldind_i1
+| 71 = @cil_ldind_u1
+| 72 = @cil_ldind_i2
+| 73 = @cil_ldind_u2
+| 74 = @cil_ldind_i4
+| 75 = @cil_ldind_u4
+| 76 = @cil_ldind_i8
+| 77 = @cil_ldind_i
+| 78 = @cil_ldind_r4
+| 79 = @cil_ldind_r8
+| 80 = @cil_ldind_ref
+| 81 = @cil_stind_ref
+| 82 = @cil_stind_i1
+| 83 = @cil_stind_i2
+| 84 = @cil_stind_i4
+| 85 = @cil_stind_i8
+| 86 = @cil_stind_r4
+| 87 = @cil_stind_r8
+| 88 = @cil_add
+| 89 = @cil_sub
+| 90 = @cil_mul
+| 91 = @cil_div
+| 92 = @cil_div_un
+| 93 = @cil_rem
+| 94 = @cil_rem_un
+| 95 = @cil_and
+| 96 = @cil_or
+| 97 = @cil_xor
+| 98 = @cil_shl
+| 99 = @cil_shr
+| 100 = @cil_shr_un
+| 101 = @cil_neg
+| 102 = @cil_not
+| 103 = @cil_conv_i1
+| 104 = @cil_conv_i2
+| 105 = @cil_conv_i4
+| 106 = @cil_conv_i8
+| 107 = @cil_conv_r4
+| 108 = @cil_conv_r8
+| 109 = @cil_conv_u4
+| 110 = @cil_conv_u8
+| 111 = @cil_callvirt
+| 112 = @cil_cpobj
+| 113 = @cil_ldobj
+| 114 = @cil_ldstr
+| 115 = @cil_newobj
+| 116 = @cil_castclass
+| 117 = @cil_isinst
+| 118 = @cil_conv_r_un
+| 121 = @cil_unbox
+| 122 = @cil_throw
+| 123 = @cil_ldfld
+| 124 = @cil_ldflda
+| 125 = @cil_stfld
+| 126 = @cil_ldsfld
+| 127 = @cil_ldsflda
+| 128 = @cil_stsfld
+| 129 = @cil_stobj
+| 130 = @cil_conv_ovf_i1_un
+| 131 = @cil_conv_ovf_i2_un
+| 132 = @cil_conv_ovf_i4_un
+| 133 = @cil_conv_ovf_i8_un
+| 134 = @cil_conv_ovf_u1_un
+| 135 = @cil_conv_ovf_u2_un
+| 136 = @cil_conv_ovf_u4_un
+| 137 = @cil_conv_ovf_u8_un
+| 138 = @cil_conv_ovf_i_un
+| 139 = @cil_conv_ovf_u_un
+| 140 = @cil_box
+| 141 = @cil_newarr
+| 142 = @cil_ldlen
+| 143 = @cil_ldelema
+| 144 = @cil_ldelem_i1
+| 145 = @cil_ldelem_u1
+| 146 = @cil_ldelem_i2
+| 147 = @cil_ldelem_u2
+| 148 = @cil_ldelem_i4
+| 149 = @cil_ldelem_u4
+| 150 = @cil_ldelem_i8
+| 151 = @cil_ldelem_i
+| 152 = @cil_ldelem_r4
+| 153 = @cil_ldelem_r8
+| 154 = @cil_ldelem_ref
+| 155 = @cil_stelem_i
+| 156 = @cil_stelem_i1
+| 157 = @cil_stelem_i2
+| 158 = @cil_stelem_i4
+| 159 = @cil_stelem_i8
+| 160 = @cil_stelem_r4
+| 161 = @cil_stelem_r8
+| 162 = @cil_stelem_ref
+| 163 = @cil_ldelem
+| 164 = @cil_stelem
+| 165 = @cil_unbox_any
+| 179 = @cil_conv_ovf_i1
+| 180 = @cil_conv_ovf_u1
+| 181 = @cil_conv_ovf_i2
+| 182 = @cil_conv_ovf_u2
+| 183 = @cil_conv_ovf_i4
+| 184 = @cil_conv_ovf_u4
+| 185 = @cil_conv_ovf_i8
+| 186 = @cil_conv_ovf_u8
+| 194 = @cil_refanyval
+| 195 = @cil_ckinfinite
+| 198 = @cil_mkrefany
+| 208 = @cil_ldtoken
+| 209 = @cil_conv_u2
+| 210 = @cil_conv_u1
+| 211 = @cil_conv_i
+| 212 = @cil_conv_ovf_i
+| 213 = @cil_conv_ovf_u
+| 214 = @cil_add_ovf
+| 215 = @cil_add_ovf_un
+| 216 = @cil_mul_ovf
+| 217 = @cil_mul_ovf_un
+| 218 = @cil_sub_ovf
+| 219 = @cil_sub_ovf_un
+| 220 = @cil_endfinally
+| 221 = @cil_leave
+| 222 = @cil_leave_s
+| 223 = @cil_stind_i
+| 224 = @cil_conv_u
+| 65024 = @cil_arglist
+| 65025 = @cil_ceq
+| 65026 = @cil_cgt
+| 65027 = @cil_cgt_un
+| 65028 = @cil_clt
+| 65029 = @cil_clt_un
+| 65030 = @cil_ldftn
+| 65031 = @cil_ldvirtftn
+| 65033 = @cil_ldarg
+| 65034 = @cil_ldarga
+| 65035 = @cil_starg
+| 65036 = @cil_ldloc
+| 65037 = @cil_ldloca
+| 65038 = @cil_stloc
+| 65039 = @cil_localloc
+| 65041 = @cil_endfilter
+| 65042 = @cil_unaligned
+| 65043 = @cil_volatile
+| 65044 = @cil_tail
+| 65045 = @cil_initobj
+| 65046 = @cil_constrained
+| 65047 = @cil_cpblk
+| 65048 = @cil_initblk
+| 65050 = @cil_rethrow
+| 65052 = @cil_sizeof
+| 65053 = @cil_refanytype
+| 65054 = @cil_readonly
+;
+
+// CIL ignored instructions
+
+@cil_ignore = @cil_nop | @cil_break | @cil_volatile | @cil_unaligned;
+
+// CIL local/parameter/field access
+
+@cil_ldarg_any = @cil_ldarg_0 | @cil_ldarg_1 | @cil_ldarg_2 | @cil_ldarg_3 | @cil_ldarg_s | @cil_ldarga_s | @cil_ldarg | @cil_ldarga;
+@cil_starg_any = @cil_starg | @cil_starg_s;
+
+@cil_ldloc_any = @cil_ldloc_0 | @cil_ldloc_1 | @cil_ldloc_2 | @cil_ldloc_3 | @cil_ldloc_s | @cil_ldloca_s | @cil_ldloc | @cil_ldloca;
+@cil_stloc_any = @cil_stloc_0 | @cil_stloc_1 | @cil_stloc_2 | @cil_stloc_3 | @cil_stloc_s | @cil_stloc;
+
+@cil_ldfld_any = @cil_ldfld | @cil_ldsfld | @cil_ldsflda | @cil_ldflda;
+@cil_stfld_any = @cil_stfld | @cil_stsfld;
+
+@cil_local_access = @cil_stloc_any | @cil_ldloc_any;
+@cil_arg_access = @cil_starg_any | @cil_ldarg_any;
+@cil_read_access = @cil_ldloc_any | @cil_ldarg_any | @cil_ldfld_any;
+@cil_write_access = @cil_stloc_any | @cil_starg_any | @cil_stfld_any;
+
+@cil_stack_access = @cil_local_access | @cil_arg_access;
+@cil_field_access = @cil_ldfld_any | @cil_stfld_any;
+
+@cil_access = @cil_read_access | @cil_write_access;
+
+// CIL constant/literal instructions
+
+@cil_ldc_i = @cil_ldc_i4_any | @cil_ldc_i8;
+
+@cil_ldc_i4_any = @cil_ldc_i4_m1 | @cil_ldc_i4_0 | @cil_ldc_i4_1 | @cil_ldc_i4_2 | @cil_ldc_i4_3 |
+ @cil_ldc_i4_4 | @cil_ldc_i4_5 | @cil_ldc_i4_6 | @cil_ldc_i4_7 | @cil_ldc_i4_8 | @cil_ldc_i4_s | @cil_ldc_i4;
+
+@cil_ldc_r = @cil_ldc_r4 | @cil_ldc_r8;
+
+@cil_literal = @cil_ldnull | @cil_ldc_i | @cil_ldc_r | @cil_ldstr;
+
+// Control flow
+
+@cil_conditional_jump = @cil_binary_jump | @cil_unary_jump;
+@cil_binary_jump = @cil_beq_s | @cil_bge_s | @cil_bgt_s | @cil_ble_s | @cil_blt_s |
+ @cil_bne_un_s | @cil_bge_un_s | @cil_bgt_un_s | @cil_ble_un_s | @cil_blt_un_s |
+ @cil_beq | @cil_bge | @cil_bgt | @cil_ble | @cil_blt |
+ @cil_bne_un | @cil_bge_un | @cil_bgt_un | @cil_ble_un | @cil_blt_un;
+@cil_unary_jump = @cil_brfalse_s | @cil_brtrue_s | @cil_brfalse | @cil_brtrue | @cil_switch;
+@cil_unconditional_jump = @cil_br | @cil_br_s | @cil_leave_any;
+@cil_leave_any = @cil_leave | @cil_leave_s;
+@cil_jump = @cil_unconditional_jump | @cil_conditional_jump;
+
+// CIL call instructions
+
+@cil_call_any = @cil_jmp | @cil_call | @cil_calli | @cil_tail | @cil_callvirt | @cil_newobj;
+
+// CIL expression instructions
+
+@cil_expr = @cil_literal | @cil_binary_expr | @cil_unary_expr | @cil_call_any | @cil_read_access |
+ @cil_newarr | @cil_ldtoken | @cil_sizeof |
+ @cil_ldftn | @cil_ldvirtftn | @cil_localloc | @cil_mkrefany | @cil_refanytype | @cil_arglist | @cil_dup;
+
+@cil_unary_expr =
+ @cil_conversion_operation | @cil_unary_arithmetic_operation | @cil_unary_bitwise_operation|
+ @cil_ldlen | @cil_isinst | @cil_box | @cil_ldobj | @cil_castclass | @cil_unbox_any |
+ @cil_ldind | @cil_unbox;
+
+@cil_conversion_operation =
+ @cil_conv_i1 | @cil_conv_i2 | @cil_conv_i4 | @cil_conv_i8 |
+ @cil_conv_u1 | @cil_conv_u2 | @cil_conv_u4 | @cil_conv_u8 |
+ @cil_conv_ovf_i | @cil_conv_ovf_i_un | @cil_conv_ovf_i1 | @cil_conv_ovf_i1_un |
+ @cil_conv_ovf_i2 | @cil_conv_ovf_i2_un | @cil_conv_ovf_i4 | @cil_conv_ovf_i4_un |
+ @cil_conv_ovf_i8 | @cil_conv_ovf_i8_un | @cil_conv_ovf_u | @cil_conv_ovf_u_un |
+ @cil_conv_ovf_u1 | @cil_conv_ovf_u1_un | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un |
+ @cil_conv_ovf_u4 | @cil_conv_ovf_u4_un | @cil_conv_ovf_u8 | @cil_conv_ovf_u8_un |
+ @cil_conv_r4 | @cil_conv_r8 | @cil_conv_ovf_u2 | @cil_conv_ovf_u2_un |
+ @cil_conv_i | @cil_conv_u | @cil_conv_r_un;
+
+@cil_ldind = @cil_ldind_i | @cil_ldind_i1 | @cil_ldind_i2 | @cil_ldind_i4 | @cil_ldind_i8 |
+ @cil_ldind_r4 | @cil_ldind_r8 | @cil_ldind_ref | @cil_ldind_u1 | @cil_ldind_u2 | @cil_ldind_u4;
+
+@cil_stind = @cil_stind_i | @cil_stind_i1 | @cil_stind_i2 | @cil_stind_i4 | @cil_stind_i8 |
+ @cil_stind_r4 | @cil_stind_r8 | @cil_stind_ref;
+
+@cil_bitwise_operation = @cil_binary_bitwise_operation | @cil_unary_bitwise_operation;
+
+@cil_binary_bitwise_operation = @cil_and | @cil_or | @cil_xor | @cil_shr | @cil_shr | @cil_shr_un | @cil_shl;
+
+@cil_binary_arithmetic_operation = @cil_add | @cil_sub | @cil_mul | @cil_div | @cil_div_un |
+ @cil_rem | @cil_rem_un | @cil_add_ovf | @cil_add_ovf_un | @cil_mul_ovf | @cil_mul_ovf_un |
+ @cil_sub_ovf | @cil_sub_ovf_un;
+
+@cil_unary_bitwise_operation = @cil_not;
+
+@cil_binary_expr = @cil_binary_arithmetic_operation | @cil_binary_bitwise_operation | @cil_read_array | @cil_comparison_operation;
+
+@cil_unary_arithmetic_operation = @cil_neg;
+
+@cil_comparison_operation = @cil_cgt_un | @cil_ceq | @cil_cgt | @cil_clt | @cil_clt_un;
+
+// Elements that retrieve an address of something
+@cil_read_ref = @cil_ldloca_s | @cil_ldarga_s | @cil_ldflda | @cil_ldsflda | @cil_ldelema;
+
+// CIL array instructions
+
+@cil_read_array =
+ @cil_ldelem | @cil_ldelema | @cil_ldelem_i1 | @cil_ldelem_ref | @cil_ldelem_i |
+ @cil_ldelem_i1 | @cil_ldelem_i2 | @cil_ldelem_i4 | @cil_ldelem_i8 | @cil_ldelem_r4 |
+ @cil_ldelem_r8 | @cil_ldelem_u1 | @cil_ldelem_u2 | @cil_ldelem_u4;
+
+@cil_write_array = @cil_stelem | @cil_stelem_ref |
+ @cil_stelem_i | @cil_stelem_i1 | @cil_stelem_i2 | @cil_stelem_i4 | @cil_stelem_i8 |
+ @cil_stelem_r4 | @cil_stelem_r8;
+
+@cil_throw_any = @cil_throw | @cil_rethrow;
+
+#keyset[impl, index]
+cil_instruction(
+ unique int id: @cil_instruction,
+ int opcode: int ref,
+ int index: int ref,
+ int impl: @cil_method_implementation ref);
+
+cil_jump(
+ unique int instruction: @cil_jump ref,
+ int target: @cil_instruction ref);
+
+cil_access(
+ unique int instruction: @cil_instruction ref,
+ int target: @cil_accessible ref);
+
+cil_value(
+ unique int instruction: @cil_literal ref,
+ string value: string ref);
+
+#keyset[instruction, index]
+cil_switch(
+ int instruction: @cil_switch ref,
+ int index: int ref,
+ int target: @cil_instruction ref);
+
+cil_instruction_location(
+ unique int id: @cil_instruction ref,
+ int loc: @location ref);
+
+cil_type_location(
+ int id: @cil_type ref,
+ int loc: @location ref);
+
+cil_method_location(
+ int id: @cil_method ref,
+ int loc: @location ref);
+
+@cil_namespace = @namespace;
+
+@cil_type_container = @cil_type | @cil_namespace | @cil_method;
+
+case @cil_type.kind of
+ 0 = @cil_valueorreftype
+| 1 = @cil_typeparameter
+| 2 = @cil_array_type
+| 3 = @cil_pointer_type
+;
+
+cil_type(
+ unique int id: @cil_type,
+ string name: string ref,
+ int kind: int ref,
+ int parent: @cil_type_container ref,
+ int sourceDecl: @cil_type ref);
+
+cil_pointer_type(
+ unique int id: @cil_pointer_type ref,
+ int pointee: @cil_type ref);
+
+cil_array_type(
+ unique int id: @cil_array_type ref,
+ int element_type: @cil_type ref,
+ int rank: int ref);
+
+cil_method(
+ unique int id: @cil_method,
+ string name: string ref,
+ int parent: @cil_type ref,
+ int return_type: @cil_type ref);
+
+cil_method_source_declaration(
+ unique int method: @cil_method ref,
+ int source: @cil_method ref);
+
+cil_method_implementation(
+ unique int id: @cil_method_implementation,
+ int method: @cil_method ref,
+ int location: @assembly ref);
+
+cil_implements(
+ int id: @cil_method ref,
+ int decl: @cil_method ref);
+
+#keyset[parent, name]
+cil_field(
+ unique int id: @cil_field,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int field_type: @cil_type ref);
+
+@cil_element = @cil_instruction | @cil_declaration | @cil_handler | @cil_attribute | @cil_namespace;
+@cil_named_element = @cil_declaration | @cil_namespace;
+@cil_declaration = @cil_variable | @cil_method | @cil_type | @cil_member;
+@cil_accessible = @cil_declaration;
+@cil_variable = @cil_field | @cil_stack_variable;
+@cil_stack_variable = @cil_local_variable | @cil_parameter;
+@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event;
+
+#keyset[method, index]
+cil_parameter(
+ unique int id: @cil_parameter,
+ int method: @cil_method ref,
+ int index: int ref,
+ int param_type: @cil_type ref);
+
+cil_parameter_in(unique int id: @cil_parameter ref);
+cil_parameter_out(unique int id: @cil_parameter ref);
+
+cil_setter(unique int prop: @cil_property ref,
+ int method: @cil_method ref);
+
+cil_getter(unique int prop: @cil_property ref,
+ int method: @cil_method ref);
+
+cil_adder(unique int event: @cil_event ref,
+ int method: @cil_method ref);
+
+cil_remover(unique int event: @cil_event ref, int method: @cil_method ref);
+
+cil_raiser(unique int event: @cil_event ref, int method: @cil_method ref);
+
+cil_property(
+ unique int id: @cil_property,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int property_type: @cil_type ref);
+
+#keyset[parent, name]
+cil_event(unique int id: @cil_event,
+ int parent: @cil_type ref,
+ string name: string ref,
+ int event_type: @cil_type ref);
+
+#keyset[impl, index]
+cil_local_variable(
+ unique int id: @cil_local_variable,
+ int impl: @cil_method_implementation ref,
+ int index: int ref,
+ int var_type: @cil_type ref);
+
+// CIL handlers (exception handlers etc).
+
+case @cil_handler.kind of
+ 0 = @cil_catch_handler
+| 1 = @cil_filter_handler
+| 2 = @cil_finally_handler
+| 4 = @cil_fault_handler
+;
+
+#keyset[impl, index]
+cil_handler(
+ unique int id: @cil_handler,
+ int impl: @cil_method_implementation ref,
+ int index: int ref,
+ int kind: int ref,
+ int try_start: @cil_instruction ref,
+ int try_end: @cil_instruction ref,
+ int handler_start: @cil_instruction ref);
+
+cil_handler_filter(
+ unique int id: @cil_handler ref,
+ int filter_start: @cil_instruction ref);
+
+cil_handler_type(
+ unique int id: @cil_handler ref,
+ int catch_type: @cil_type ref);
+
+@cil_controlflow_node = @cil_entry_point | @cil_instruction;
+
+@cil_entry_point = @cil_method_implementation | @cil_handler;
+
+@cil_dataflow_node = @cil_instruction | @cil_variable | @cil_method;
+
+cil_method_stack_size(
+ unique int method: @cil_method_implementation ref,
+ int size: int ref);
+
+// CIL modifiers
+
+cil_public(int id: @cil_member ref);
+cil_private(int id: @cil_member ref);
+cil_protected(int id: @cil_member ref);
+cil_internal(int id: @cil_member ref);
+cil_static(int id: @cil_member ref);
+cil_sealed(int id: @cil_member ref);
+cil_virtual(int id: @cil_method ref);
+cil_abstract(int id: @cil_member ref);
+cil_class(int id: @cil_type ref);
+cil_interface(int id: @cil_type ref);
+cil_security(int id: @cil_member ref);
+cil_requiresecobject(int id: @cil_method ref);
+cil_specialname(int id: @cil_method ref);
+cil_newslot(int id: @cil_method ref);
+
+cil_base_class(unique int id: @cil_type ref, int base: @cil_type ref);
+cil_base_interface(int id: @cil_type ref, int base: @cil_type ref);
+
+#keyset[unbound, index]
+cil_type_parameter(
+ int unbound: @cil_member ref,
+ int index: int ref,
+ int param: @cil_typeparameter ref);
+
+#keyset[bound, index]
+cil_type_argument(
+ int bound: @cil_member ref,
+ int index: int ref,
+ int t: @cil_type ref);
+
+// CIL type parameter constraints
+
+cil_typeparam_covariant(int tp: @cil_typeparameter ref);
+cil_typeparam_contravariant(int tp: @cil_typeparameter ref);
+cil_typeparam_class(int tp: @cil_typeparameter ref);
+cil_typeparam_struct(int tp: @cil_typeparameter ref);
+cil_typeparam_new(int tp: @cil_typeparameter ref);
+cil_typeparam_constraint(int tp: @cil_typeparameter ref, int supertype: @cil_type ref);
+
+// CIL attributes
+
+cil_attribute(
+ unique int attributeid: @cil_attribute,
+ int element: @cil_declaration ref,
+ int constructor: @cil_method ref);
+
+#keyset[attribute_id, param]
+cil_attribute_named_argument(
+ int attribute_id: @cil_attribute ref,
+ string param: string ref,
+ string value: string ref);
+
+#keyset[attribute_id, index]
+cil_attribute_positional_argument(
+ int attribute_id: @cil_attribute ref,
+ int index: int ref,
+ string value: string ref);
+
+
+// Common .Net data model covering both C# and CIL
+
+// Common elements
+@dotnet_element = @element | @cil_element;
+@dotnet_named_element = @named_element | @cil_named_element;
+@dotnet_callable = @callable | @cil_method;
+@dotnet_variable = @variable | @cil_variable;
+@dotnet_field = @field | @cil_field;
+@dotnet_parameter = @parameter | @cil_parameter;
+@dotnet_declaration = @declaration | @cil_declaration;
+@dotnet_member = @member | @cil_member;
+@dotnet_event = @event | @cil_event;
+@dotnet_property = @property | @cil_property | @indexer;
+
+// Common types
+@dotnet_type = @type | @cil_type;
+@dotnet_call = @call | @cil_call_any;
+@dotnet_throw = @throw_element | @cil_throw_any;
+@dotnet_valueorreftype = @cil_valueorreftype | @value_or_ref_type | @cil_array_type | @void_type;
+@dotnet_typeparameter = @type_parameter | @cil_typeparameter;
+@dotnet_array_type = @array_type | @cil_array_type;
+@dotnet_pointer_type = @pointer_type | @cil_pointer_type;
+@dotnet_type_parameter = @type_parameter | @cil_typeparameter;
+@dotnet_generic = @dotnet_valueorreftype | @dotnet_callable;
+
+// Attributes
+@dotnet_attribute = @attribute | @cil_attribute;
+
+// Expressions
+@dotnet_expr = @expr | @cil_expr;
+
+// Literals
+@dotnet_literal = @literal_expr | @cil_literal;
+@dotnet_string_literal = @string_literal_expr | @cil_ldstr;
+@dotnet_int_literal = @integer_literal_expr | @cil_ldc_i;
+@dotnet_float_literal = @float_literal_expr | @cil_ldc_r;
+@dotnet_null_literal = @null_literal_expr | @cil_ldnull;
+
+@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property |
+ @callable | @value_or_ref_type | @void_type;
+
+#keyset[entity, location]
+metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref)
diff --git a/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties
new file mode 100644
index 000000000000..ff3b5413d2c1
--- /dev/null
+++ b/csharp/upgrades/eedef9359e1e4e1ebcf2a1dc9d2ae75d4ea4d160/upgrade.properties
@@ -0,0 +1,2 @@
+description: Add 'relational_pattern_expr' and its four subtypes ('<', '>', '<=', '>=')
+compatibility: backwards