diff --git a/.github/workflows/codegen.yml b/.github/workflows/python-tooling.yml
similarity index 76%
rename from .github/workflows/codegen.yml
rename to .github/workflows/python-tooling.yml
index 24422eba10f8..75fdd75299d4 100644
--- a/.github/workflows/codegen.yml
+++ b/.github/workflows/python-tooling.yml
@@ -1,10 +1,11 @@
-name: Codegen
+name: Python tooling
on:
pull_request:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
+ - "misc/scripts/models-as-data/bulk_generate_mad.py"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml
@@ -17,17 +18,14 @@ permissions:
contents: read
jobs:
- codegen:
+ check-python-tooling:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - uses: actions/setup-python@v4
- with:
- python-version-file: 'misc/codegen/.python-version'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
- extra_args: autopep8 --all-files
+ extra_args: black --all-files
- name: Run codegen tests
shell: bash
run: |
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 42333e91289e..bc07fb789873 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -14,11 +14,11 @@ repos:
hooks:
- id: clang-format
- - repo: https://github.com/pre-commit/mirrors-autopep8
- rev: v2.0.4
+ - repo: https://github.com/psf/black
+ rev: 25.1.0
hooks:
- - id: autopep8
- files: ^misc/codegen/.*\.py
+ - id: black
+ files: ^(misc/codegen/.*|misc/scripts/models-as-data/bulk_generate_mad)\.py$
- repo: local
hooks:
diff --git a/actions/ql/lib/change-notes/2025-06-09-bash-parsing-performance.md b/actions/ql/lib/change-notes/2025-06-09-bash-parsing-performance.md
new file mode 100644
index 000000000000..5ee29557c85e
--- /dev/null
+++ b/actions/ql/lib/change-notes/2025-06-09-bash-parsing-performance.md
@@ -0,0 +1,6 @@
+---
+category: minorAnalysis
+---
+* Fixed performance issues in the parsing of Bash scripts in workflow files,
+ which led to out-of-disk errors when analysing certain workflow files with
+ complex interpolations of shell commands or quoted strings.
\ No newline at end of file
diff --git a/actions/ql/lib/codeql/actions/Bash.qll b/actions/ql/lib/codeql/actions/Bash.qll
index 4519a8949d7c..4975ce6f4cc5 100644
--- a/actions/ql/lib/codeql/actions/Bash.qll
+++ b/actions/ql/lib/codeql/actions/Bash.qll
@@ -8,35 +8,64 @@ class BashShellScript extends ShellScript {
)
}
- private string lineProducer(int i) {
- result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
- }
-
- private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
- exists(string line | line = this.lineProducer(k) |
- exists(int i, int j |
- cmdSubs =
- // $() cmd substitution
- line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
- .regexpReplaceAll("^\\$\\(", "")
- .regexpReplaceAll("\\)$", "") and
- id = "cmdsubs:" + k + ":" + i + ":" + j
- )
- or
- exists(int i, int j |
- // `...` cmd substitution
- cmdSubs =
- line.regexpFind("\\`[^\\`]+\\`", i, j)
- .regexpReplaceAll("^\\`", "")
- .regexpReplaceAll("\\`$", "") and
- id = "cmd:" + k + ":" + i + ":" + j
- )
+ /**
+ * Gets the line at 0-based index `lineIndex` within this shell script,
+ * assuming newlines as separators.
+ */
+ private string lineProducer(int lineIndex) {
+ result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", lineIndex)
+ }
+
+ private predicate cmdSubstitutionReplacement(string command, string id, int lineIndex) {
+ this.commandInSubstitution(lineIndex, command, id)
+ or
+ this.commandInBackticks(lineIndex, command, id)
+ }
+
+ /**
+ * Holds if there is a command substitution `$(command)` in
+ * the line at `lineIndex` in the shell script,
+ * and `id` is a unique identifier for this command.
+ */
+ private predicate commandInSubstitution(int lineIndex, string command, string id) {
+ exists(int occurrenceIndex, int occurrenceOffset |
+ command =
+ // Look for the command inside a $(...) command substitution
+ this.lineProducer(lineIndex)
+ .regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", occurrenceIndex,
+ occurrenceOffset)
+ // trim starting $( - TODO do this in first regex
+ .regexpReplaceAll("^\\$\\(", "")
+ // trim ending ) - TODO do this in first regex
+ .regexpReplaceAll("\\)$", "") and
+ id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
)
}
- private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
- old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
- this.cmdSubstitutionReplacement(old, new, _)
+ /**
+ * Holds if `command` is a command in backticks `` `...` `` in
+ * the line at `lineIndex` in the shell script,
+ * and `id` is a unique identifier for this command.
+ */
+ private predicate commandInBackticks(int lineIndex, string command, string id) {
+ exists(int occurrenceIndex, int occurrenceOffset |
+ command =
+ this.lineProducer(lineIndex)
+ .regexpFind("\\`[^\\`]+\\`", occurrenceIndex, occurrenceOffset)
+ // trim leading backtick - TODO do this in first regex
+ .regexpReplaceAll("^\\`", "")
+ // trim trailing backtick - TODO do this in first regex
+ .regexpReplaceAll("\\`$", "") and
+ id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
+ )
+ }
+
+ private predicate rankedCmdSubstitutionReplacements(int i, string command, string commandId) {
+ // rank commands by their unique IDs
+ commandId = rank[i](string c, string id | this.cmdSubstitutionReplacement(c, id, _) | id) and
+ // since we cannot output (command, ID) tuples from the rank operation,
+ // we need to work out the specific command associated with the resulting ID
+ this.cmdSubstitutionReplacement(command, commandId, _)
}
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
@@ -64,31 +93,56 @@ class BashShellScript extends ShellScript {
this.cmdSubstitutionReplacement(result, _, i)
}
+ /**
+ * Holds if `quotedStr` is a string in double quotes in
+ * the line at `lineIndex` in the shell script,
+ * and `id` is a unique identifier for this quoted string.
+ */
+ private predicate doubleQuotedString(int lineIndex, string quotedStr, string id) {
+ exists(int occurrenceIndex, int occurrenceOffset |
+ // double quoted string
+ quotedStr =
+ this.cmdSubstitutedLineProducer(lineIndex)
+ .regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", occurrenceIndex, occurrenceOffset) and
+ id =
+ "qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
+ quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
+ )
+ }
+
+ /**
+ * Holds if `quotedStr` is a string in single quotes in
+ * the line at `lineIndex` in the shell script,
+ * and `id` is a unique identifier for this quoted string.
+ */
+ private predicate singleQuotedString(int lineIndex, string quotedStr, string id) {
+ exists(int occurrenceIndex, int occurrenceOffset |
+ // single quoted string
+ quotedStr =
+ this.cmdSubstitutedLineProducer(lineIndex)
+ .regexpFind("'((?:\\\\.|[^'\\\\])*)'", occurrenceIndex, occurrenceOffset) and
+ id =
+ "qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
+ quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
+ )
+ }
+
private predicate quotedStringReplacement(string quotedStr, string id) {
- exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
- exists(int i, int j |
- // double quoted string
- quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
- id =
- "qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
- quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
- )
+ exists(int lineIndex |
+ this.doubleQuotedString(lineIndex, quotedStr, id)
or
- exists(int i, int j |
- // single quoted string
- quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
- id =
- "qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
- quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
- )
+ this.singleQuotedString(lineIndex, quotedStr, id)
) and
// Only do this for strings that might otherwise disrupt subsequent parsing
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
}
- private predicate rankedQuotedStringReplacements(int i, string old, string new) {
- old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
- this.quotedStringReplacement(old, new)
+ private predicate rankedQuotedStringReplacements(int i, string quotedString, string quotedStringId) {
+ // rank quoted strings by their nearly-unique IDs
+ quotedStringId = rank[i](string s, string id | this.quotedStringReplacement(s, id) | id) and
+ // since we cannot output (string, ID) tuples from the rank operation,
+ // we need to work out the specific string associated with the resulting ID
+ this.quotedStringReplacement(quotedString, quotedStringId)
}
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {
diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml
index 5919efe3b678..596bf4a14f0a 100644
--- a/actions/ql/lib/qlpack.yml
+++ b/actions/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/actions-all
-version: 0.4.11
+version: 0.4.12-dev
library: true
warnOnImplicitThis: true
dependencies:
diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml
index 9e45e764edef..99c4fd8d02c1 100644
--- a/actions/ql/src/qlpack.yml
+++ b/actions/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/actions-queries
-version: 0.6.3
+version: 0.6.4-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]
diff --git a/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/interpolation.yml b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/interpolation.yml
new file mode 100644
index 000000000000..2b719a3a38ab
--- /dev/null
+++ b/actions/ql/test/query-tests/Security/CWE-094/.github/workflows/interpolation.yml
@@ -0,0 +1,81 @@
+name: Workflow with complex interpolation
+on:
+ workflow_dispatch:
+ inputs:
+ choice-a:
+ required: true
+ type: choice
+ description: choice-a
+ default: a1
+ options:
+ - a1
+ - a2
+ - a3
+ string-b:
+ required: false
+ type: string
+ description: string-b
+ string-c:
+ required: false
+ type: string
+ description: string-c
+ list-d:
+ required: true
+ type: string
+ default: d1 d2
+ description: list-d whitespace separated
+ list-e:
+ required: false
+ type: string
+ description: list-e whitespace separated
+ choice-f:
+ required: true
+ type: choice
+ description: choice-f
+ options:
+ - false
+ - true
+
+env:
+ DRY_TEST: false
+ B: ${{ github.event.inputs.string-b }}
+
+jobs:
+ job:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Produce values
+ id: produce-values
+ run: |
+ echo "region=region" >> $GITHUB_OUTPUT
+ echo "zone=zone" >> $GITHUB_OUTPUT
+
+ - name: Step with complex interpolation
+ id: complex
+ env:
+ CHOICE_A: ${{ github.event.inputs.choice-a }}
+ STRING_B: ${{ github.event.inputs.string-b }}
+ STRING_C: ${{ github.event.inputs.string-c }}
+ LIST_D: ${{ github.event.inputs.list-d }}
+ LIST_E: ${{ github.event.inputs.list-e }}
+ CHOICE_F: ${{ github.event.inputs.choice-f }}
+ REGION: ${{ steps.produce-values.outputs.region }}
+ ZONE: ${{ steps.produce-values.outputs.zone }}
+ DRY_TEST_JSON: ${{ fromJSON(env.DRY_TEST) }}
+ FUNCTION_NAME: my-function
+ USER_EMAIL: 'example@example.com'
+ TYPE: type
+ RANGE: '0-100'
+
+ run: |
+ comma_separated_list_d=$(echo "${LIST_D}" | sed "s/ /\",\"/g")
+ comma_separated_list_e=$(echo "${LIST_E}" | sed "s/ /\",\"/g")
+ c1=$(echo "${STRING_C}" | cut -d "-" -f 1)
+ c2=$(echo "${STRING_C}" | cut -d "-" -f 2)
+ # Similar commands that use JSON payloads with string interpolation.
+ response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
+ response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
+ response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
+ response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
+ response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":["'"${comma_separated_list_e}"'"],"dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
+ shell: bash
diff --git a/cpp/bulk_generation_targets.yml b/cpp/bulk_generation_targets.yml
new file mode 100644
index 000000000000..0e42eac3765e
--- /dev/null
+++ b/cpp/bulk_generation_targets.yml
@@ -0,0 +1,10 @@
+language: cpp
+strategy: dca
+destination: cpp/ql/lib/ext/generated
+targets:
+- name: openssl
+ with-sinks: false
+ with-sources: false
+- name: sqlite
+ with-sinks: false
+ with-sources: false
diff --git a/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/lambdas.ql b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/lambdas.ql
new file mode 100644
index 000000000000..cb35a2cc5329
--- /dev/null
+++ b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/lambdas.ql
@@ -0,0 +1,7 @@
+class LambdaExpr extends @lambdaexpr {
+ string toString() { none() }
+}
+
+from LambdaExpr lambda, string default_capture, boolean has_explicit_return_type
+where lambdas(lambda, default_capture, has_explicit_return_type, _)
+select lambda, default_capture, has_explicit_return_type
diff --git a/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
new file mode 100644
index 000000000000..3c45f8b9e71e
--- /dev/null
+++ b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
@@ -0,0 +1,2493 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..af887e83a815
--- /dev/null
+++ b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme
@@ -0,0 +1,2492 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties
new file mode 100644
index 000000000000..9299dcb085a6
--- /dev/null
+++ b/cpp/downgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties
@@ -0,0 +1,3 @@
+description: capture whether a lambda has an explicitly specified parameter list.
+compatibility: full
+lambdas.rel: run lambdas.qlo
diff --git a/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/old.dbscheme b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/old.dbscheme
new file mode 100644
index 000000000000..a8c2176e9a5c
--- /dev/null
+++ b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/old.dbscheme
@@ -0,0 +1,2494 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/semmlecode.cpp.dbscheme b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..3c45f8b9e71e
--- /dev/null
+++ b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/semmlecode.cpp.dbscheme
@@ -0,0 +1,2493 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/stmts.ql b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/stmts.ql
new file mode 100644
index 000000000000..41c2ac1b7704
--- /dev/null
+++ b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/stmts.ql
@@ -0,0 +1,13 @@
+class Stmt extends @stmt {
+ string toString() { none() }
+}
+
+class Location extends @location_stmt {
+ string toString() { none() }
+}
+
+from Stmt id, int kind, Location loc, int new_kind
+where
+ stmts(id, kind, loc) and
+ if kind = 40 then new_kind = 4 else new_kind = kind
+select id, new_kind, loc
diff --git a/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/upgrade.properties b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/upgrade.properties
new file mode 100644
index 000000000000..beabef86257c
--- /dev/null
+++ b/cpp/downgrades/a8c2176e9a5cf9be8d17053a4c8e7e56b5aced6d/upgrade.properties
@@ -0,0 +1,3 @@
+description: Support `__leave` statement
+compatibility: full
+stmts.rel: run stmts.qlo
diff --git a/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/builtintypes.ql b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/builtintypes.ql
new file mode 100644
index 000000000000..73b715fd71f0
--- /dev/null
+++ b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/builtintypes.ql
@@ -0,0 +1,9 @@
+class BuiltinType extends @builtintype {
+ string toString() { none() }
+}
+
+from BuiltinType id, string name, int kind, int new_kind, int size, int sign, int alignment
+where
+ builtintypes(id, name, kind, size, sign, alignment) and
+ if kind = 62 then new_kind = 1 else new_kind = kind
+select id, name, new_kind, size, sign, alignment
diff --git a/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
new file mode 100644
index 000000000000..af887e83a815
--- /dev/null
+++ b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
@@ -0,0 +1,2492 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..9a7c3c14c107
--- /dev/null
+++ b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme
@@ -0,0 +1,2491 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties
new file mode 100644
index 000000000000..bc85f01c52e3
--- /dev/null
+++ b/cpp/downgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties
@@ -0,0 +1,3 @@
+description: Support __mfp8 type
+compatibility: backwards
+builtintypes.rel: run builtintypes.qlo
diff --git a/cpp/misc/bulk_generation_targets.json b/cpp/misc/bulk_generation_targets.json
deleted file mode 100644
index 4cddef005b2f..000000000000
--- a/cpp/misc/bulk_generation_targets.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "strategy": "dca",
- "language": "cpp",
- "targets": [
- { "name": "openssl", "with-sources": false, "with-sinks": false },
- { "name": "sqlite", "with-sources": false, "with-sinks": false }
- ],
- "destination": "cpp/ql/lib/ext/generated"
-}
\ No newline at end of file
diff --git a/cpp/ql/lib/change-notes/2025-06-06-lambda-parameters.md b/cpp/ql/lib/change-notes/2025-06-06-lambda-parameters.md
new file mode 100644
index 000000000000..44f9b12968d9
--- /dev/null
+++ b/cpp/ql/lib/change-notes/2025-06-06-lambda-parameters.md
@@ -0,0 +1,4 @@
+---
+category: feature
+---
+* Added a predicate `hasParameterList` to `LambdaExpression` to capture whether a lambda has an explicitly specified parameter list.
diff --git a/cpp/ql/lib/change-notes/2025-06-11-leave-stmt.md b/cpp/ql/lib/change-notes/2025-06-11-leave-stmt.md
new file mode 100644
index 000000000000..d06be5b77a9c
--- /dev/null
+++ b/cpp/ql/lib/change-notes/2025-06-11-leave-stmt.md
@@ -0,0 +1,5 @@
+---
+category: feature
+---
+* The Microsoft-specific `__leave` statement is now supported.
+* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.
\ No newline at end of file
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index 5d1966180cc4..c0dd5d2ae2a5 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-all
-version: 5.1.0
+version: 5.1.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
diff --git a/cpp/ql/lib/semmle/code/cpp/Type.qll b/cpp/ql/lib/semmle/code/cpp/Type.qll
index aa3fa54835cd..fef978b198d6 100644
--- a/cpp/ql/lib/semmle/code/cpp/Type.qll
+++ b/cpp/ql/lib/semmle/code/cpp/Type.qll
@@ -839,6 +839,9 @@ private predicate floatingPointTypeMapping(
or
// _Complex _Float128
kind = 61 and base = 2 and domain = TComplexDomain() and realKind = 49 and extended = false
+ or
+ // __mfp8
+ kind = 62 and base = 2 and domain = TRealDomain() and realKind = 62 and extended = false
}
/**
diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
index 313875d1325d..d1836f0ff4dd 100644
--- a/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
+++ b/cpp/ql/lib/semmle/code/cpp/exprs/Lambda.qll
@@ -41,12 +41,17 @@ class LambdaExpression extends Expr, @lambdaexpr {
* - "&" if capture-by-reference is the default for implicit captures.
* - "=" if capture-by-value is the default for implicit captures.
*/
- string getDefaultCaptureMode() { lambdas(underlyingElement(this), result, _) }
+ string getDefaultCaptureMode() { lambdas(underlyingElement(this), result, _, _) }
/**
* Holds if the return type (of the call operator of the resulting object) was explicitly specified.
*/
- predicate returnTypeIsExplicit() { lambdas(underlyingElement(this), _, true) }
+ predicate returnTypeIsExplicit() { lambdas(underlyingElement(this), _, true, _) }
+
+ /**
+ * Holds if the lambda has an explicitly specified parameter list, even when empty.
+ */
+ predicate hasParameterList() { lambdas(underlyingElement(this), _, _, true) }
/**
* Gets the function which will be invoked when the resulting object is called.
diff --git a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
index aa6a585ea4b3..5305c8ca58f6 100644
--- a/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
+++ b/cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
@@ -841,6 +841,41 @@ private Stmt getEnclosingBreakable(Stmt s) {
else result = getEnclosingBreakable(s.getParent().getEnclosingStmt())
}
+/**
+ * A Microsoft C/C++ `__leave` statement.
+ *
+ * For example, the `__leave` statement in the following code:
+ * ```
+ * __try {
+ * if (err) __leave;
+ * ...
+ * }
+ * __finally {
+ *
+ * }
+ * ```
+ */
+class LeaveStmt extends JumpStmt, @stmt_leave {
+ override string getAPrimaryQlClass() { result = "LeaveStmt" }
+
+ override string toString() { result = "__leave;" }
+
+ override predicate mayBeImpure() { none() }
+
+ override predicate mayBeGloballyImpure() { none() }
+
+ /**
+ * Gets the `__try` statement that this `__leave` exits.
+ */
+ MicrosoftTryStmt getEnclosingTry() { result = getEnclosingTry(this) }
+}
+
+private MicrosoftTryStmt getEnclosingTry(Stmt s) {
+ if s.getParent().getEnclosingStmt() instanceof MicrosoftTryStmt
+ then result = s.getParent().getEnclosingStmt()
+ else result = getEnclosingTry(s.getParent().getEnclosingStmt())
+}
+
/**
* A C/C++ 'label' statement.
*
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme
index 9a7c3c14c107..a8c2176e9a5c 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme
@@ -691,6 +691,7 @@ case @builtintype.kind of
| 59 = @complex_std_float64 // _Complex _Float64
| 60 = @complex_float64x // _Complex _Float64x
| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
;
builtintypes(
@@ -2138,7 +2139,8 @@ code_block(
lambdas(
unique int expr: @lambdaexpr ref,
string default_capture: string ref,
- boolean has_explicit_return_type: boolean ref
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
);
lambda_capture(
@@ -2211,6 +2213,7 @@ case @stmt.kind of
| 37 = @stmt_co_return
| 38 = @stmt_consteval_if
| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
;
type_vla(
@@ -2347,7 +2350,7 @@ blockscope(
int enclosing: @parameterized_element ref
);
-@jump = @stmt_goto | @stmt_break | @stmt_continue;
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
@jumporlabel = @jump | @stmt_label | @literal;
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
index bca58ed2f5b1..089d69c641cc 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
@@ -2,7 +2,7 @@
@compilation
- 16142
+ 15785@externalDataElement
@@ -18,15 +18,15 @@
@location_default
- 36226754
+ 36090723@location_stmt
- 5202209
+ 5203175@location_expr
- 17956521
+ 17959858@diagnostic
@@ -34,47 +34,47 @@
@file
- 83260
+ 81417@folder
- 15818
+ 15468@macro_expansion
- 40121869
+ 39234203@other_macro_reference
- 312756
+ 312446@function
- 4015439
+ 4000085@fun_decl
- 4154519
+ 4138135@var_decl
- 9247204
+ 9237636@type_decl
- 1882105
+ 1840533@namespace_decl
- 430914
+ 429821@using_declaration
- 341862
+ 334532@using_directive
- 8125
+ 8117@using_enum_declaration
@@ -82,283 +82,287 @@
@static_assert
- 183493
+ 183028@parameter
- 6965639
+ 6939004@membervariable
- 1489139
+ 1489415@globalvariable
- 466518
+ 486788@localvariable
- 734804
+ 727548@enumconstant
- 343781
+ 343845@errortype
- 125
+ 124@unknowntype
- 125
+ 124@void
- 125
+ 124@boolean
- 125
+ 124@char
- 125
+ 124@unsigned_char
- 125
+ 124@signed_char
- 125
+ 124@short
- 125
+ 124@unsigned_short
- 125
+ 124@signed_short
- 125
+ 124@int
- 125
+ 124@unsigned_int
- 125
+ 124@signed_int
- 125
+ 124@long
- 125
+ 124@unsigned_long
- 125
+ 124@signed_long
- 125
+ 124@long_long
- 125
+ 124@unsigned_long_long
- 125
+ 124@signed_long_long
- 125
+ 124@float
- 125
+ 124@double
- 125
+ 124@long_double
- 125
+ 124@complex_float
- 125
+ 124@complex_double
- 125
+ 124@complex_long_double
- 125
+ 124@imaginary_float
- 125
+ 124@imaginary_double
- 125
+ 124@imaginary_long_double
- 125
+ 124@wchar_t
- 125
+ 124@decltype_nullptr
- 125
+ 124@int128
- 125
+ 124@unsigned_int128
- 125
+ 124@signed_int128
- 125
+ 124@float128
- 125
+ 124@complex_float128
- 125
+ 124@decimal32
- 125
+ 124@decimal64
- 125
+ 124@decimal128
- 125
+ 124@char16_t
- 125
+ 124@char32_t
- 125
+ 124@std_float32
- 125
+ 124@float32x
- 125
+ 124@std_float64
- 125
+ 124@float64x
- 125
+ 124@std_float128
- 125
+ 124@char8_t
- 125
+ 124@float16
- 125
+ 124@complex_float16
- 125
+ 124@fp16
- 125
+ 124@std_bfloat16
- 125
+ 124@std_float16
- 125
+ 124@complex_std_float32
- 125
+ 124@complex_float32x
- 125
+ 124@complex_std_float64
- 125
+ 124@complex_float64x
- 125
+ 124@complex_std_float128
- 125
+ 124
+
+
+ @mfp8
+ 124@pointer
- 470652
+ 470186@type_with_specifiers
- 696526
+ 693863@array
- 98431
+ 98055@routineptr
- 858764
+ 857913@reference
- 970559
+ 966848@gnu_vector
- 863
+ 843@routinereference
- 470
+ 469@rvalue_reference
- 291793
+ 290677@block
@@ -366,7 +370,7 @@
@decltype
- 102057
+ 102076@type_operator
@@ -374,15 +378,15 @@
@usertype
- 4962767
+ 4863363@mangledname
- 6329773
+ 6313668@type_mention
- 5812069
+ 5813149@concept_template
@@ -390,15 +394,15 @@
@routinetype
- 758603
+ 757852@ptrtomember
- 12029
+ 12026@specifier
- 7754
+ 7724@gnuattribute
@@ -406,11 +410,11 @@
@stdattribute
- 350577
+ 349236@declspec
- 328789
+ 328850@msattribute
@@ -418,19 +422,19 @@
@alignas
- 2192
+ 2171@attribute_arg_token
- 20955
+ 20935@attribute_arg_constant_expr
- 88857
+ 86916@attribute_arg_expr
- 1793
+ 1753@attribute_arg_empty
@@ -442,39 +446,39 @@
@attribute_arg_type
- 466
+ 461@derivation
- 597157
+ 598061@frienddecl
- 879292
+ 878379@comment
- 11233849
+ 11190894@namespace
- 11044
+ 10800@specialnamequalifyingelement
- 125
+ 124@namequalifier
- 3254040
+ 3255226@value
- 13436143
+ 13438640@initialiser
- 2338659
+ 2334426@address_of
@@ -482,131 +486,131 @@
@indirect
- 403000
+ 403075@array_to_pointer
- 1948290
+ 1948652@parexpr
- 4901469
+ 4902380@arithnegexpr
- 584894
+ 585003@unaryplusexpr
- 4122
+ 4081@complementexpr
- 38090
+ 38098@notexpr
- 357805
+ 357277@postincrexpr
- 84356
+ 84372@postdecrexpr
- 57234
+ 57244@preincrexpr
- 96438
+ 96455@predecrexpr
- 35718
+ 35725@conditionalexpr
- 895370
+ 895536@addexpr
- 569921
+ 570027@subexpr
- 465494
+ 465581@mulexpr
- 434549
+ 434630@divexpr
- 60159
+ 58999@remexpr
- 20100
+ 20080@paddexpr
- 118331
+ 118353@psubexpr
- 67843
+ 67856@pdiffexpr
- 43900
+ 43732@lshiftexpr
- 550121
+ 550224@rshiftexpr
- 199982
+ 200019@andexpr
- 479844
+ 479933@orexpr
- 193501
+ 193537@xorexpr
- 73764
+ 73778@eqexpr
- 641535
+ 641655@neexpr
- 410719
+ 410795@gtexpr
- 110832
+ 110852@ltexpr
- 139031
+ 139057@geexpr
- 81151
+ 81166@leexpr
- 291203
+ 291256@assignexpr
- 1277487
+ 1277725@assignaddexpr
@@ -614,23 +618,23 @@
@assignsubexpr
- 15263
+ 15266@assignmulexpr
- 14065
+ 13754@assigndivexpr
- 6789
+ 6791@assignremexpr
- 875
+ 872@assignlshiftexpr
- 3693
+ 3694@assignrshiftexpr
@@ -638,19 +642,19 @@
@assignandexpr
- 6509
+ 6510@assignorexpr
- 19550
+ 19554@assignxorexpr
- 29824
+ 29829@assignpaddexpr
- 18574
+ 18578@assignpsubexpr
@@ -658,31 +662,31 @@
@andlogicalexpr
- 345599
+ 345664@orlogicalexpr
- 1100373
+ 1100577@commaexpr
- 169097
+ 168450@subscriptexpr
- 433900
+ 433981@callexpr
- 300995
+ 300697@vastartexpr
- 5084
+ 5071@vaargexpr
- 1299
+ 1300@vaendexpr
@@ -690,43 +694,43 @@
@vacopyexpr
- 171
+ 170@varaccess
- 8231069
+ 8232599@runtime_sizeof
- 400899
+ 400974@runtime_alignof
- 62611
+ 62549@expr_stmt
- 147941
+ 147968@routineexpr
- 6134772
+ 6134317@type_operand
- 1401351
+ 1401612@offsetofexpr
- 148598
+ 148626@typescompexpr
- 699930
+ 700060@literal
- 6101485
+ 6102027@aggregateliteral
@@ -734,31 +738,31 @@
@c_style_cast
- 6025595
+ 6026988@temp_init
- 1075277
+ 1073608@errorexpr
- 57350
+ 57293@reference_to
- 2184503
+ 2182339@ref_indirect
- 2645319
+ 2642699@vacuous_destructor_call
- 9836
+ 9826@assume
- 4394
+ 4383@conjugation
@@ -766,11 +770,11 @@
@realpartexpr
- 94
+ 92@imagpartexpr
- 94
+ 92@jmulexpr
@@ -810,35 +814,35 @@
@thisaccess
- 1518451
+ 1514601@new_expr
- 57992
+ 57934@delete_expr
- 14412
+ 14398@throw_expr
- 26141
+ 26079@condition_decl
- 437622
+ 437589@braced_init_list
- 2331
+ 2328@type_id
- 60130
+ 60071@sizeof_pack
- 2181
+ 2178@hasassignexpr
@@ -866,7 +870,7 @@
@hastrivialconstr
- 3
+ 7@hastrivialcopy
@@ -890,23 +894,23 @@
@isclassexpr
- 2538
+ 2531@isconvtoexpr
- 250
+ 249@isemptyexpr
- 8880
+ 8846@isenumexpr
- 2376
+ 2990@ispodexpr
- 1065
+ 1041@ispolyexpr
@@ -922,75 +926,75 @@
@hastrivialdestructor
- 555
+ 3503@uuidof
- 28057
+ 27985@delete_array_expr
- 1591
+ 1556@new_array_expr
- 6932
+ 6914@foldexpr
- 1368
+ 1367@ctordirectinit
- 141602
+ 141461@ctorvirtualinit
- 5046
+ 5041@ctorfieldinit
- 258185
+ 257929@ctordelegatinginit
- 3627
+ 3613@dtordirectdestruct
- 49481
+ 49432@dtorvirtualdestruct
- 5003
+ 4998@dtorfielddestruct
- 49994
+ 49945@static_cast
- 389474
+ 387985@reinterpret_cast
- 41835
+ 41729@const_cast
- 30706
+ 30676@dynamic_cast
- 1011
+ 989@lambdaexpr
- 17748
+ 17730@param_ref
- 177835
+ 177449@noopexpr
@@ -998,7 +1002,7 @@
@istriviallyconstructibleexpr
- 2376
+ 3737@isdestructibleexpr
@@ -1010,19 +1014,19 @@
@istriviallydestructibleexpr
- 1000
+ 996@istriviallyassignableexpr
- 2376
+ 3737@isnothrowassignableexpr
- 5127
+ 5108@istrivialexpr
- 1375
+ 3644@isstandardlayoutexpr
@@ -1030,7 +1034,7 @@
@istriviallycopyableexpr
- 598
+ 1538@isliteraltypeexpr
@@ -1050,11 +1054,11 @@
@isconstructibleexpr
- 3627
+ 3613@isnothrowconstructibleexpr
- 20761
+ 20682@hasfinalizerexpr
@@ -1090,11 +1094,11 @@
@isfinalexpr
- 11803
+ 11792@noexceptexpr
- 30854
+ 30678@builtinshufflevector
@@ -1102,11 +1106,11 @@
@builtinchooseexpr
- 20642
+ 20646@builtinaddressof
- 16294
+ 16278@vec_fill
@@ -1146,11 +1150,11 @@
@builtinbitcast
- 250
+ 249@builtinshuffle
- 782
+ 764@blockassignexpr
@@ -1266,7 +1270,7 @@
@reuseexpr
- 906491
+ 906424@istriviallycopyassignable
@@ -1362,11 +1366,11 @@
@c11_generic
- 30031
+ 30036@requires_expr
- 17661
+ 17660@nested_requirement
@@ -1374,87 +1378,87 @@
@compound_requirement
- 11720
+ 11719@concept_id
- 96781
+ 96774@lambdacapture
- 28523
+ 28450@stmt_expr
- 2025815
+ 2026191@stmt_if
- 987388
+ 987571@stmt_while
- 39534
+ 39542@stmt_goto
- 151155
+ 151183@stmt_label
- 72498
+ 72512@stmt_return
- 1508953
+ 1507458@stmt_block
- 1846814
+ 1839752@stmt_end_test_while
- 232974
+ 233017@stmt_for
- 84148
+ 84163@stmt_switch_case
- 894840
+ 894774@stmt_switch
- 440777
+ 440744@stmt_asm
- 64015
+ 64027@stmt_decl
- 768980
+ 767031@stmt_empty
- 459543
+ 459509@stmt_continue
- 28011
+ 28016@stmt_break
- 140276
+ 139921@stmt_try_block
- 28918
+ 28885@stmt_microsoft_try
- 224
+ 223@stmt_set_vla_size
@@ -1466,19 +1470,19 @@
@stmt_assigned_goto
- 12391
+ 12393@stmt_range_based_for
- 7398
+ 7391@stmt_handler
- 47389
+ 47330@stmt_constexpr_if
- 103934
+ 103537@stmt_co_return
@@ -1492,45 +1496,49 @@
@stmt_not_consteval_if3
+
+ @stmt_leave
+ 3
+ @ppd_if
- 589589
+ 587335@ppd_ifdef
- 213751
+ 213791@ppd_ifndef
- 157794
+ 157824@ppd_elif
- 27982
+ 27363@ppd_else
- 236511
+ 235606@ppd_endif
- 886636
+ 883245@ppd_plain_include
- 406728
+ 397725@ppd_define
- 2749584
+ 2739070@ppd_undef
- 101058
+ 100671@ppd_pragma
- 407234
+ 405677@ppd_include_next
@@ -1538,11 +1546,11 @@
@ppd_line
- 19055
+ 18866@ppd_error
- 125
+ 124@ppd_objc_import
@@ -1566,7 +1574,7 @@
@link_target
- 943
+ 923@xmldtd
@@ -1596,11 +1604,11 @@
compilations
- 16142
+ 15785id
- 16142
+ 15785cwd
@@ -1618,7 +1626,7 @@
12
- 16142
+ 15785
@@ -1644,19 +1652,19 @@
compilation_args
- 1292348
+ 1263740id
- 16142
+ 15785num
- 1874
+ 1833arg
- 37368
+ 36541
@@ -1670,77 +1678,77 @@
3642
- 1281
+ 12524243
- 1402
+ 13714344
- 917
+ 8964445
- 647
+ 6324551
- 1213
+ 11865170
- 620
+ 6067172
- 903
+ 8837290
- 1146
+ 11209496
- 498
+ 4879899
- 1712
+ 1674100102
- 121
+ 118103104
- 2548
+ 2492104119
- 1362
+ 1331120138
- 1186
+ 1160139140
- 579
+ 567
@@ -1756,67 +1764,67 @@
3438
- 755
+ 7383839
- 1914
+ 18723940
- 1254
+ 12264042
- 1389
+ 13584253
- 768
+ 7515354
- 903
+ 8835463
- 1146
+ 11206467
- 512
+ 5016768
- 1793
+ 17536870
- 1240
+ 12137071
- 1793
+ 17537379
- 1213
+ 11867989
- 1442
+ 141189
@@ -1837,57 +1845,57 @@
4390
- 80
+ 7990108
- 148
+ 145108183
- 134
+ 131198422
- 148
+ 145422595
- 161
+ 158595605
- 161
+ 158605749
- 148
+ 145750778
- 148
+ 145781883
- 148
+ 1459301190
- 107
+ 10511971198
- 485
+ 474
@@ -1903,67 +1911,67 @@
15
- 161
+ 15857
- 148
+ 145912
- 94
+ 921215
- 148
+ 1451518
- 121
+ 1181822
- 148
+ 1452227
- 161
+ 1582729
- 107
+ 1052934
- 148
+ 1453444
- 161
+ 1584563
- 148
+ 1456794
- 148
+ 14594164
- 148
+ 145171
@@ -1984,22 +1992,22 @@
12
- 17113
+ 1673423
- 16196
+ 158373103
- 2805
+ 27421041198
- 1254
+ 1226
@@ -2015,17 +2023,17 @@
12
- 24746
+ 2419823
- 11139
+ 10892362
- 1483
+ 1450
@@ -2035,11 +2043,11 @@
compilation_build_mode
- 16142
+ 15785id
- 16142
+ 15785mode
@@ -2057,7 +2065,7 @@
12
- 16142
+ 15785
@@ -2083,11 +2091,11 @@
compilation_compiling_files
- 16142
+ 15785id
- 16142
+ 15785num
@@ -2095,7 +2103,7 @@
file
- 7390
+ 7226
@@ -2109,7 +2117,7 @@
12
- 16142
+ 15785
@@ -2125,7 +2133,7 @@
12
- 16142
+ 15785
@@ -2173,12 +2181,12 @@
12
- 175
+ 17123
- 7187
+ 702828
@@ -2199,7 +2207,7 @@
12
- 7390
+ 7226
@@ -2209,11 +2217,11 @@
compilation_time
- 64299
+ 62876id
- 16074
+ 15719num
@@ -2221,11 +2229,11 @@
kind
- 53
+ 52seconds
- 17801
+ 17473
@@ -2239,7 +2247,7 @@
12
- 16074
+ 15719
@@ -2255,7 +2263,7 @@
45
- 16074
+ 15719
@@ -2271,17 +2279,17 @@
23
- 107
+ 14534
- 7821
+ 781945
- 8145
+ 7754
@@ -2327,8 +2335,8 @@
12
- 1320
- 1321
+ 1325
+ 132613
@@ -2345,7 +2353,7 @@
11921193
- 53
+ 52
@@ -2361,7 +2369,7 @@
12
- 53
+ 52
@@ -2385,13 +2393,13 @@
13
- 718
- 719
+ 705
+ 70613
- 792
- 793
+ 795
+ 79613
@@ -2408,27 +2416,22 @@
12
- 11233
+ 1119523
- 3910
+ 362634
- 1200
+ 13844
- 24
- 1335
-
-
- 24
- 696
- 121
+ 703
+ 1265
@@ -2444,7 +2447,7 @@
12
- 17801
+ 17473
@@ -2460,17 +2463,17 @@
12
- 14969
+ 1491423
- 2818
+ 253134
- 13
+ 26
@@ -2480,7 +2483,7 @@
diagnostic_for
- 4444
+ 4443diagnostic
@@ -2726,19 +2729,19 @@
compilation_finished
- 16142
+ 15785id
- 16142
+ 15785cpu_seconds
- 12164
+ 11894elapsed_seconds
- 256
+ 224
@@ -2752,7 +2755,7 @@
12
- 16142
+ 15785
@@ -2768,7 +2771,7 @@
12
- 16142
+ 15785
@@ -2784,17 +2787,17 @@
12
- 10168
+ 1007523
- 1402
+ 13453
- 24
- 593
+ 36
+ 474
@@ -2810,12 +2813,12 @@
12
- 11368
+ 1098423
- 795
+ 909
@@ -2828,15 +2831,10 @@
12
-
- 1
- 2
- 40
- 23
- 26
+ 523
@@ -2844,13 +2842,8 @@
13
- 4
- 5
- 13
-
-
- 6
- 7
+ 5
+ 613
@@ -2859,53 +2852,48 @@
13
- 9
- 10
- 13
-
-
- 10
- 11
+ 12
+ 1313
- 15
- 16
+ 13
+ 1413
- 18
- 19
- 13
+ 17
+ 18
+ 26
- 32
- 33
+ 30
+ 3113
- 48
- 49
+ 52
+ 5313
- 157
- 158
+ 145
+ 14613
- 249
- 250
+ 261
+ 26213
- 309
- 310
+ 303
+ 30413
- 323
- 324
+ 324
+ 32513
@@ -2919,15 +2907,10 @@
12
-
- 1
- 2
- 40
- 23
- 26
+ 523
@@ -2935,13 +2918,8 @@
13
- 4
- 5
- 13
-
-
- 6
- 7
+ 5
+ 613
@@ -2950,53 +2928,48 @@
13
- 8
- 9
- 13
-
-
- 10
- 11
+ 12
+ 1313
- 15
- 16
+ 13
+ 1413
- 18
- 19
- 13
+ 17
+ 18
+ 26
- 32
- 33
+ 30
+ 3113
- 48
- 49
+ 49
+ 5013
- 147
- 148
+ 141
+ 14213
- 170
- 171
+ 174
+ 17513
- 222
- 223
+ 239
+ 24013
- 264
- 265
+ 256
+ 25713
@@ -3223,11 +3196,11 @@
sourceLocationPrefix
- 125
+ 124prefix
- 125
+ 124
@@ -4721,15 +4694,15 @@
extractor_version
- 125
+ 124codeql_version
- 125
+ 124frontend_version
- 125
+ 124
@@ -4743,7 +4716,7 @@
12
- 125
+ 124
@@ -4759,7 +4732,7 @@
12
- 125
+ 124
@@ -4769,31 +4742,31 @@
locations_default
- 36226754
+ 36090723id
- 36226754
+ 36090723container
- 41023
+ 40866startLine
- 7495820
+ 7467157startColumn
- 21262
+ 21180endLine
- 7497821
+ 7469151endColumn
- 53530
+ 53326
@@ -4807,7 +4780,7 @@
12
- 36226754
+ 36090723
@@ -4823,7 +4796,7 @@
12
- 36226754
+ 36090723
@@ -4839,7 +4812,7 @@
12
- 36226754
+ 36090723
@@ -4855,7 +4828,7 @@
12
- 36226754
+ 36090723
@@ -4871,7 +4844,7 @@
12
- 36226754
+ 36090723
@@ -4887,67 +4860,67 @@
115
- 3126
+ 31141541
- 3126
+ 31144266
- 3376
+ 33646795
- 3126
+ 311498124
- 3251
+ 3239124174
- 3376
+ 3364175228
- 3126
+ 3114230303
- 3126
+ 3114305406
- 3126
+ 3114408596
- 3251
+ 3239598943
- 3126
+ 31149862568
- 3251
+ 3114
- 2725
+ 258757658
- 2626
+ 2741
@@ -4963,67 +4936,67 @@
113
- 3502
+ 34881329
- 3251
+ 32392942
- 3126
+ 31144258
- 3376
+ 33645876
- 3126
+ 311477102
- 3251
+ 3239102134
- 3126
+ 3114134173
- 3126
+ 3114173242
- 3126
+ 3114243348
- 3126
+ 3114348489
- 3126
+ 31144931269
- 3126
+ 3114133757597
- 2626
+ 2616
@@ -5039,67 +5012,67 @@
14
- 2251
+ 224247
- 3126
+ 3114712
- 3502
+ 34881216
- 3126
+ 31141622
- 3376
+ 33642228
- 3126
+ 31142833
- 3251
+ 32393339
- 3376
+ 33643948
- 3376
+ 33644860
- 3376
+ 33646082
- 3376
+ 33648398
- 3251
+ 323998141
- 2501
+ 2491
@@ -5115,67 +5088,67 @@
113
- 3502
+ 34881329
- 3251
+ 32392942
- 3126
+ 31144258
- 3376
+ 33645876
- 3126
+ 311477102
- 3251
+ 3239102134
- 3126
+ 3114134173
- 3251
+ 3239174244
- 3126
+ 3114246348
- 3126
+ 3114348494
- 3126
+ 31145131349
- 3126
+ 3114140757597
- 2501
+ 2491
@@ -5191,67 +5164,67 @@
112
- 3376
+ 33641324
- 3251
+ 32392533
- 3251
+ 32393339
- 3376
+ 33643945
- 3627
+ 36134554
- 3126
+ 31145462
- 3627
+ 36136271
- 3376
+ 33647183
- 3502
+ 34888399
- 3126
+ 311499114
- 3126
+ 3114114
- 136
- 3126
+ 143
+ 3114147363
- 1125
+ 1121
@@ -5267,32 +5240,32 @@
12
- 4960358
+ 494139123
- 800711
+ 79764934
- 566326
+ 564160412
- 593091
+ 59082312210
- 562324
+ 560173210534
- 13007
+ 12957
@@ -5308,27 +5281,27 @@
12
- 5018642
+ 499945223
- 1234586
+ 122986536
- 664132
+ 6615936106
- 562324
+ 560173107329
- 16134
+ 16072
@@ -5344,27 +5317,27 @@
12
- 5655509
+ 563388423
- 532682
+ 53064537
- 579333
+ 577118724
- 571454
+ 5692692472
- 156840
+ 156240
@@ -5380,12 +5353,12 @@
12
- 7320969
+ 7292975281
- 174850
+ 174182
@@ -5401,27 +5374,27 @@
12
- 5027272
+ 500804923
- 767567
+ 76463234
- 559822
+ 557682412
- 604348
+ 60203712235
- 536809
+ 534756
@@ -5437,67 +5410,67 @@
12
- 1500
+ 149524
- 1876
+ 186849
- 1625
+ 1619919
- 1751
+ 17442074
- 1625
+ 161981173
- 1625
+ 1619173435
- 1625
+ 1619468904
- 1625
+ 16199451309
- 1625
+ 161913281510
- 1625
+ 161915311774
- 1625
+ 161918342887
- 1625
+ 16193491119749
- 1500
+ 1495
@@ -5513,67 +5486,67 @@
12
- 1876
+ 186824
- 1751
+ 174446
- 1500
+ 1495611
- 1751
+ 17441133
- 1625
+ 16193445
- 1625
+ 16195075
- 1751
+ 17447898
- 1751
+ 1744101131
- 1625
+ 1619131147
- 1876
+ 1868149161
- 1625
+ 1619162198
- 1625
+ 1619202329
- 875
+ 872
@@ -5589,67 +5562,67 @@
12
- 1625
+ 161924
- 1876
+ 186849
- 1625
+ 1619919
- 1751
+ 17442074
- 1625
+ 161980169
- 1625
+ 1619171432
- 1625
+ 1619467822
- 1625
+ 16198611001
- 1625
+ 161910021190
- 1625
+ 161912011338
- 1625
+ 161913471920
- 1625
+ 1619221059360
- 1375
+ 1370
@@ -5665,67 +5638,67 @@
12
- 1625
+ 161924
- 1876
+ 186849
- 1625
+ 1619919
- 1751
+ 17442074
- 1625
+ 161980169
- 1625
+ 1619171432
- 1625
+ 1619467822
- 1625
+ 16198611003
- 1625
+ 161910031198
- 1625
+ 161912011338
- 1625
+ 161913471920
- 1625
+ 1619222059375
- 1375
+ 1370
@@ -5741,67 +5714,67 @@
12
- 1876
+ 186824
- 1751
+ 174447
- 1876
+ 1868713
- 1751
+ 17441321
- 1751
+ 17442129
- 1625
+ 16192937
- 1500
+ 14953750
- 1625
+ 16195058
- 1625
+ 16196167
- 1751
+ 17446776
- 1751
+ 161976
- 140
- 1625
+ 137
+ 1619
- 144
+ 139299
- 750
+ 872
@@ -5817,32 +5790,32 @@
12
- 4959983
+ 494101723
- 807965
+ 80487634
- 561448
+ 559301412
- 593467
+ 59119712214
- 562449
+ 560298214530
- 12507
+ 12459
@@ -5858,27 +5831,27 @@
12
- 5017141
+ 499795723
- 1237713
+ 123298036
- 664507
+ 6619676107
- 562449
+ 560298107329
- 16009
+ 15948
@@ -5894,12 +5867,12 @@
12
- 7316466
+ 728849027
- 181354
+ 180661
@@ -5915,27 +5888,27 @@
12
- 5658136
+ 563650023
- 531306
+ 52927437
- 580209
+ 577990724
- 571079
+ 5688952472
- 157090
+ 156489
@@ -5951,27 +5924,27 @@
12
- 5027147
+ 500792423
- 774196
+ 77123534
- 555194
+ 553072412
- 605348
+ 60303412235
- 535933
+ 533884
@@ -5987,52 +5960,52 @@
12
- 15759
+ 1569823
- 5628
+ 56063
- 6
- 4127
+ 7
+ 4485
- 6
- 16
- 4252
+ 7
+ 17
+ 4111
- 16
- 29
- 4127
+ 17
+ 32
+ 4236
- 30
- 97
- 4127
+ 35
+ 103
+ 4111
- 97
- 518
- 4127
+ 147
+ 635
+ 4111
- 523
- 1928
- 4127
+ 651
+ 2069
+ 4111
- 1990
- 3352
- 4127
+ 2137
+ 3404
+ 4111
- 3386
+ 343033692
- 3126
+ 2741
@@ -6048,52 +6021,52 @@
12
- 18760
+ 1856423
- 5628
+ 560635
- 4127
+ 423657
- 3376
+ 3364715
- 4752
+ 460915
- 79
- 4127
+ 78
+ 4111
- 80
+ 78143
- 4127
+ 4236150202
- 4127
+ 4111203263
- 4127
+ 4111266329
- 375
+ 373
@@ -6109,52 +6082,52 @@
12
- 16009
+ 1594823
- 6128
+ 59803
- 8
- 4127
+ 7
+ 4111
- 8
+ 717
- 4127
+ 42361735
- 4127
+ 411135140
- 4127
+ 4111157601
- 4127
+ 4111610
- 1713
- 4127
+ 1714
+ 411117492382
- 4127
+ 4111242130689
- 2501
+ 2491
@@ -6170,52 +6143,52 @@
12
- 17385
+ 1731823
- 6378
+ 635434
- 3502
+ 311446
- 3502
+ 3862611
- 4627
+ 46091122
- 4127
+ 41112240
- 4252
+ 42364260
- 4877
+ 48596068
- 4127
+ 41116873
- 750
+ 747
@@ -6231,52 +6204,52 @@
12
- 16009
+ 1594823
- 6128
+ 59803
- 8
- 4127
+ 7
+ 4111
- 8
+ 717
- 4252
+ 43601736
- 4252
+ 423636170
- 4127
+ 4111173
- 619
- 4127
+ 620
+ 41116221824
- 4127
+ 411118432449
- 4127
+ 4111246030688
- 2251
+ 2242
@@ -6286,19 +6259,19 @@
locations_stmt
- 5202209
+ 5203175id
- 5202209
+ 5203175container
- 4152
+ 4153startLine
- 272815
+ 272866startColumn
@@ -6306,11 +6279,11 @@
endLine
- 264987
+ 265036endColumn
- 3226
+ 3227
@@ -6324,7 +6297,7 @@
12
- 5202209
+ 5203175
@@ -6340,7 +6313,7 @@
12
- 5202209
+ 5203175
@@ -6356,7 +6329,7 @@
12
- 5202209
+ 5203175
@@ -6372,7 +6345,7 @@
12
- 5202209
+ 5203175
@@ -6388,7 +6361,7 @@
12
- 5202209
+ 5203175
@@ -6789,67 +6762,67 @@
12
- 29405
+ 2941123
- 20875
+ 2087934
- 17031
+ 1703446
- 19725
+ 1972868
- 17087
+ 17090811
- 22811
+ 228161116
- 23569
+ 235731622
- 20931
+ 209352229
- 23232
+ 232362937
- 23681
+ 236863745
- 20623
+ 206274556
- 22138
+ 221425673
- 11700
+ 11702
@@ -6865,67 +6838,67 @@
12
- 30443
+ 3044923
- 21464
+ 2146834
- 17312
+ 1731546
- 19641
+ 1964468
- 17368
+ 17371811
- 23990
+ 239941116
- 22334
+ 223381622
- 22138
+ 221422229
- 23148
+ 231522936
- 21857
+ 218613644
- 22306
+ 223104454
- 21661
+ 216655468
- 9147
+ 9148
@@ -6941,57 +6914,57 @@
12
- 36616
+ 3662323
- 28451
+ 2845634
- 22952
+ 2295645
- 21970
+ 2197456
- 23793
+ 2379867
- 27104
+ 2710978
- 31061
+ 3106689
- 27890
+ 27895910
- 20426
+ 204301012
- 22699
+ 227031218
- 9848
+ 9850
@@ -7007,67 +6980,67 @@
12
- 47222
+ 4723123
- 35213
+ 3522034
- 25168
+ 2517345
- 22110
+ 2211456
- 17452
+ 1745567
- 16470
+ 1647378
- 13917
+ 1391989
- 15067
+ 15070910
- 14730
+ 147331011
- 14394
+ 143961112
- 13861
+ 138631214
- 21577
+ 215811424
- 15628
+ 15631
@@ -7083,62 +7056,62 @@
12
- 30219
+ 3022423
- 22110
+ 2211434
- 17677
+ 1768046
- 21941
+ 2194668
- 20062
+ 20065810
- 18013
+ 180171014
- 24944
+ 249481418
- 23232
+ 232361822
- 24074
+ 240782226
- 25224
+ 252292630
- 22531
+ 225353036
- 20679
+ 2068336
@@ -7529,67 +7502,67 @@
12
- 23765
+ 2377023
- 19669
+ 1967234
- 15684
+ 1568746
- 21296
+ 2130068
- 17059
+ 17062811
- 21100
+ 211041115
- 20005
+ 200091521
- 21941
+ 219462127
- 21072
+ 210762734
- 20370
+ 203743442
- 21549
+ 215534251
- 19921
+ 199255168
- 20258
+ 2026268
@@ -7610,62 +7583,62 @@
12
- 34063
+ 3406923
- 22026
+ 2203034
- 17424
+ 1742746
- 21380
+ 2138468
- 20482
+ 20486811
- 21689
+ 216931116
- 23793
+ 237981620
- 19921
+ 199252026
- 23429
+ 234332632
- 22222
+ 222263239
- 20454
+ 204583958
- 18097
+ 18101
@@ -7681,62 +7654,62 @@
12
- 44332
+ 4434123
- 32407
+ 3241334
- 25196
+ 2520145
- 20791
+ 2079556
- 18855
+ 1885967
- 15853
+ 1585678
- 16246
+ 1624989
- 14927
+ 14930910
- 13917
+ 139191012
- 24439
+ 244431215
- 24186
+ 2419115100
- 13832
+ 13835
@@ -7752,57 +7725,57 @@
12
- 34063
+ 3406923
- 27834
+ 2783934
- 22980
+ 2298445
- 24326
+ 2433156
- 25337
+ 2534167
- 27946
+ 2795178
- 30612
+ 3061789
- 25589
+ 25594910
- 17620
+ 176241012
- 20454
+ 204581218
- 8221
+ 8222
@@ -7818,67 +7791,67 @@
12
- 33726
+ 3373223
- 22699
+ 2270334
- 17115
+ 1711946
- 24326
+ 2433168
- 20931
+ 20935810
- 17480
+ 174831013
- 19697
+ 197001316
- 20510
+ 205141619
- 20062
+ 200651922
- 18967
+ 189712226
- 23681
+ 236862631
- 20959
+ 209633139
- 4826
+ 4827
@@ -8278,19 +8251,19 @@
locations_expr
- 17956521
+ 17959858id
- 17956521
+ 17959858container
- 6341
+ 6342startLine
- 261984
+ 262033startColumn
@@ -8298,11 +8271,11 @@
endLine
- 261956
+ 262005endColumn
- 3815
+ 3816
@@ -8316,7 +8289,7 @@
12
- 17956521
+ 17959858
@@ -8332,7 +8305,7 @@
12
- 17956521
+ 17959858
@@ -8348,7 +8321,7 @@
12
- 17956521
+ 17959858
@@ -8364,7 +8337,7 @@
12
- 17956521
+ 17959858
@@ -8380,7 +8353,7 @@
12
- 17956521
+ 17959858
@@ -8401,12 +8374,12 @@
26
- 476
+ 477611
- 476
+ 47712
@@ -8416,47 +8389,47 @@
2787
- 476
+ 47795514
- 476
+ 4775251401
- 476
+ 47715262343
- 476
+ 47724043615
- 476
+ 47736685162
- 476
+ 47753417345
- 476
+ 47773999307
- 476
+ 477938216759
- 476
+ 47718811
@@ -8482,7 +8455,7 @@
24
- 476
+ 4774
@@ -8497,42 +8470,42 @@
2066
- 476
+ 47767162
- 476
+ 477166362
- 476
+ 477376591
- 476
+ 477593929
- 476
+ 4779601269
- 476
+ 47712911782
- 476
+ 47718512492
- 476
+ 4772594
@@ -8568,7 +8541,7 @@
716
- 476
+ 47716
@@ -8578,7 +8551,7 @@
3659
- 476
+ 47759
@@ -8644,7 +8617,7 @@
24
- 476
+ 4774
@@ -8659,42 +8632,42 @@
2068
- 476
+ 47768163
- 476
+ 477166362
- 476
+ 477376592
- 476
+ 477593931
- 476
+ 4779601273
- 476
+ 47712921786
- 476
+ 47718552501
- 476
+ 4772593
@@ -8720,7 +8693,7 @@
24
- 476
+ 4774
@@ -8730,17 +8703,17 @@
715
- 476
+ 4771536
- 476
+ 4773662
- 476
+ 47762
@@ -8755,7 +8728,7 @@
7375
- 448
+ 44975
@@ -8770,12 +8743,12 @@
7779
- 476
+ 4777984
- 476
+ 47784
@@ -8796,67 +8769,67 @@
15
- 21998
+ 2200259
- 22503
+ 22507915
- 21885
+ 218891523
- 20623
+ 206272332
- 20679
+ 206833244
- 20482
+ 204864460
- 20146
+ 201496080
- 20286
+ 2029080103
- 19949
+ 19953103130
- 20090
+ 20093130159
- 19893
+ 19897159194
- 19949
+ 19953194297
- 13496
+ 13498
@@ -8872,62 +8845,62 @@
12
- 32099
+ 3210523
- 21324
+ 2132834
- 15488
+ 1549146
- 22334
+ 2233868
- 18602
+ 18606811
- 22418
+ 224231116
- 23681
+ 236861621
- 22503
+ 225072128
- 22671
+ 226752835
- 21633
+ 216373543
- 21773
+ 217774361
- 17452
+ 17455
@@ -8943,62 +8916,62 @@
14
- 21801
+ 2180547
- 23934
+ 23938711
- 22783
+ 227871116
- 23765
+ 237701621
- 23906
+ 239102126
- 20567
+ 205702631
- 22082
+ 220863136
- 24102
+ 241063640
- 21464
+ 214684044
- 22615
+ 226194449
- 22755
+ 227594963
- 12205
+ 12207
@@ -9014,27 +8987,27 @@
12
- 138947
+ 13897223
- 61112
+ 6112334
- 37682
+ 3768946
- 19977
+ 19981623
- 4264
+ 4265
@@ -9050,62 +9023,62 @@
14
- 23148
+ 2315247
- 22727
+ 22731711
- 22418
+ 224231116
- 22138
+ 221421621
- 22447
+ 224512127
- 22867
+ 228722733
- 22475
+ 224793338
- 19753
+ 197573843
- 21296
+ 213004347
- 19949
+ 199534752
- 23036
+ 230405266
- 19669
+ 1967268
@@ -9202,7 +9175,7 @@
12
- 448
+ 4492
@@ -9430,7 +9403,7 @@
12
- 448
+ 4492
@@ -9506,67 +9479,67 @@
15
- 22026
+ 2203059
- 22503
+ 22507915
- 21577
+ 215811523
- 20595
+ 205982332
- 21352
+ 213563244
- 20118
+ 201214460
- 19781
+ 197856080
- 20875
+ 2087980103
- 19809
+ 19813103130
- 20005
+ 20009130159
- 19949
+ 19953159193
- 19669
+ 19672193296
- 13692
+ 13695
@@ -9582,67 +9555,67 @@
12
- 32099
+ 3210523
- 21240
+ 2124434
- 15488
+ 1549146
- 21913
+ 2191768
- 18406
+ 18409811
- 22503
+ 225071115
- 19781
+ 197851520
- 22811
+ 228162026
- 20454
+ 204582633
- 21913
+ 219173340
- 19893
+ 198974049
- 20033
+ 200374961
- 5415
+ 5416
@@ -9658,22 +9631,22 @@
12
- 130248
+ 13027323
- 68210
+ 6822334
- 40152
+ 4015946
- 21380
+ 213846
@@ -9694,62 +9667,62 @@
14
- 21605
+ 2160947
- 23821
+ 23826711
- 22503
+ 225071116
- 23681
+ 236861621
- 23625
+ 236292126
- 20679
+ 206832631
- 22278
+ 222823136
- 24074
+ 240783640
- 20875
+ 208794044
- 22587
+ 225914449
- 23148
+ 231524963
- 13075
+ 13077
@@ -9765,62 +9738,62 @@
14
- 23457
+ 2346147
- 22924
+ 22928711
- 22418
+ 224231116
- 23036
+ 230401621
- 21857
+ 218612126
- 19809
+ 198132632
- 22054
+ 220583238
- 23878
+ 238823843
- 22110
+ 221144347
- 19781
+ 197854752
- 22755
+ 227595269
- 17873
+ 17876
@@ -9912,7 +9885,7 @@
12
- 448
+ 4492
@@ -10205,23 +10178,23 @@
numlines
- 809466
+ 806371element_id
- 808340
+ 805249num_lines
- 39522
+ 39371num_code
- 34019
+ 33889num_comment
- 18385
+ 18315
@@ -10235,12 +10208,12 @@
12
- 807215
+ 80412823
- 1125
+ 1121
@@ -10256,12 +10229,12 @@
12
- 807215
+ 80412823
- 1125
+ 1121
@@ -10277,12 +10250,12 @@
12
- 808090
+ 80500023
- 250
+ 249
@@ -10298,27 +10271,27 @@
12
- 26765
+ 2666323
- 3752
+ 373735
- 3376
+ 3364537
- 3126
+ 3114411978
- 2501
+ 2491
@@ -10334,27 +10307,27 @@
12
- 27265
+ 2716123
- 4127
+ 411134
- 2501
+ 249147
- 3502
+ 3488712
- 2126
+ 2118
@@ -10370,27 +10343,27 @@
12
- 26890
+ 2678723
- 4127
+ 411134
- 2501
+ 249146
- 3126
+ 3114611
- 2876
+ 2865
@@ -10406,32 +10379,32 @@
12
- 21637
+ 2155423
- 3752
+ 373734
- 2376
+ 2367413
- 2876
+ 286514197
- 2626
+ 26162052101
- 750
+ 747
@@ -10447,32 +10420,32 @@
12
- 22012
+ 2192823
- 3752
+ 373734
- 2126
+ 211846
- 1876
+ 186869
- 2751
+ 2741913
- 1500
+ 1495
@@ -10488,27 +10461,27 @@
12
- 21762
+ 2167923
- 4377
+ 436035
- 2876
+ 286558
- 3126
+ 3114812
- 1876
+ 1868
@@ -10524,32 +10497,32 @@
12
- 11381
+ 1133823
- 1751
+ 174434
- 1500
+ 149547
- 1375
+ 1370822
- 1500
+ 1495423650
- 875
+ 872
@@ -10565,32 +10538,32 @@
12
- 11381
+ 1133823
- 1751
+ 174434
- 1500
+ 149547
- 1500
+ 1495827
- 1500
+ 14953048
- 750
+ 747
@@ -10606,32 +10579,32 @@
12
- 11381
+ 1133823
- 1751
+ 174434
- 1751
+ 174449
- 1500
+ 14951036
- 1625
+ 16193643
- 375
+ 373
@@ -11198,15 +11171,15 @@
files
- 83260
+ 81417id
- 83260
+ 81417name
- 83260
+ 81417
@@ -11220,7 +11193,7 @@
12
- 83260
+ 81417
@@ -11236,7 +11209,7 @@
12
- 83260
+ 81417
@@ -11246,15 +11219,15 @@
folders
- 15818
+ 15468id
- 15818
+ 15468name
- 15818
+ 15468
@@ -11268,7 +11241,7 @@
12
- 15818
+ 15468
@@ -11284,7 +11257,7 @@
12
- 15818
+ 15468
@@ -11294,15 +11267,15 @@
containerparent
- 99052
+ 96859parent
- 15818
+ 15468child
- 99052
+ 96859
@@ -11316,42 +11289,42 @@
12
- 7700
+ 752923
- 1941
+ 189834
- 849
+ 83046
- 1281
+ 1252610
- 1240
+ 12131016
- 1281
+ 12521644
- 1186
+ 116044151
- 337
+ 329
@@ -11367,7 +11340,7 @@
12
- 99052
+ 96859
@@ -11377,11 +11350,11 @@
fileannotations
- 5363077
+ 5244354id
- 7363
+ 7200kind
@@ -11389,11 +11362,11 @@
name
- 74967
+ 73307value
- 50450
+ 49333
@@ -11407,12 +11380,12 @@
12
- 256
+ 25023
- 7106
+ 6949
@@ -11428,62 +11401,62 @@
186
- 552
+ 54088206
- 552
+ 540212291
- 566
+ 553291359
- 552
+ 540362401
- 552
+ 540402479
- 552
+ 540480549
- 323
+ 316550551
- 1699
+ 1661553628
- 552
+ 540631753
- 579
+ 5677531231
- 566
+ 55312342155
- 310
+ 303
@@ -11499,62 +11472,62 @@
198
- 552
+ 540102244
- 552
+ 540244351
- 552
+ 540352434
- 566
+ 553434490
- 566
+ 553490628
- 552
+ 540632702
- 80
+ 79706707
- 1699
+ 1661710939
- 552
+ 5409391038
- 552
+ 54010661853
- 552
+ 54018533292
- 552
+ 5403423
@@ -11638,62 +11611,62 @@
12
- 14079
+ 1376723
- 5569
+ 544635
- 6459
+ 631657
- 5232
+ 511679
- 5866
+ 5736916
- 5529
+ 54061619
- 6243
+ 61051927
- 5434
+ 53142747
- 6176
+ 603947128
- 6284
+ 6145128459
- 5906
+ 5775459546
- 2184
+ 2136
@@ -11709,7 +11682,7 @@
12
- 74967
+ 73307
@@ -11725,57 +11698,57 @@
12
- 14793
+ 1446623
- 9817
+ 960034
- 5232
+ 511646
- 5191
+ 507768
- 4369
+ 4272811
- 6055
+ 59211117
- 6891
+ 67381723
- 6001
+ 58682341
- 5974
+ 58414195
- 5704
+ 5578951726
- 4935
+ 4826
@@ -11791,72 +11764,72 @@
12
- 4288
+ 419324
- 2090
+ 204445
- 4072
+ 398258
- 3142
+ 3072814
- 3789
+ 37051417
- 2467
+ 24131724
- 3883
+ 37972451
- 4517
+ 44175158
- 3870
+ 37845880
- 3802
+ 371881151
- 3937
+ 3850151334
- 3802
+ 3718334473
- 3829
+ 3745473547
- 2953
+ 2887
@@ -11872,7 +11845,7 @@
12
- 50436
+ 493202
@@ -11893,72 +11866,72 @@
12
- 4342
+ 424624
- 2440
+ 238645
- 3897
+ 381158
- 3169
+ 3098814
- 4450
+ 43511418
- 4409
+ 43121828
- 4086
+ 39952834
- 4018
+ 39293441
- 4086
+ 39954166
- 3816
+ 37316692
- 3924
+ 383792113
- 3816
+ 3731113145
- 3870
+ 3784145172
- 121
+ 118
@@ -11968,15 +11941,15 @@
inmacroexpansion
- 149575195
+ 149602994id
- 24600427
+ 24604999inv
- 3693421
+ 3694108
@@ -11990,37 +11963,37 @@
13
- 2201734
+ 220214335
- 1470855
+ 147112856
- 1615840
+ 161614067
- 6564145
+ 656536578
- 8694629
+ 869624589
- 3547106
+ 3547765922
- 506116
+ 506210
@@ -12036,57 +12009,57 @@
12
- 528682
+ 52878023
- 741131
+ 74126834
- 480166
+ 48025547
- 274533
+ 27458478
- 281364
+ 28141689
- 329323
+ 329385910
- 3037
+ 30381011
- 443407
+ 44348911337
- 306938
+ 306995339423
- 280967
+ 2810204237616
- 23868
+ 23872
@@ -12096,15 +12069,15 @@
affectedbymacroexpansion
- 48599612
+ 48608644id
- 7025049
+ 7026354inv
- 3792491
+ 3793196
@@ -12118,37 +12091,37 @@
12
- 3835957
+ 383667023
- 764163
+ 76430534
- 360830
+ 36089745
- 770576
+ 770719512
- 533664
+ 5337631250
- 554712
+ 554815509900
- 205144
+ 205182
@@ -12164,67 +12137,67 @@
14
- 312373
+ 31243147
- 315722
+ 31578179
- 300246
+ 300302912
- 341980
+ 3420431213
- 454730
+ 4548141314
- 225467
+ 2255091415
- 406898
+ 4069731516
- 165963
+ 1659941617
- 376622
+ 3766921718
- 200076
+ 2001131820
- 343293
+ 3433572025
- 284595
+ 28464825207
- 64521
+ 64533
@@ -12234,19 +12207,19 @@
macroinvocations
- 40422573
+ 39528251id
- 40422573
+ 39528251macro_id
- 109396
+ 106974location
- 1065236
+ 1041654kind
@@ -12264,7 +12237,7 @@
12
- 40422573
+ 39528251
@@ -12280,7 +12253,7 @@
12
- 40422573
+ 39528251
@@ -12296,7 +12269,7 @@
12
- 40422573
+ 39528251
@@ -12312,52 +12285,52 @@
12
- 23235
+ 2272123
- 20471
+ 2001834
- 7484
+ 731846
- 10019
+ 9798611
- 9413
+ 92041121
- 9048
+ 88482148
- 8334
+ 814948145
- 8280
+ 8096145955
- 8212
+ 8030955175302
- 4895
+ 4786
@@ -12373,37 +12346,37 @@
12
- 59970
+ 5864323
- 13580
+ 1327934
- 6850
+ 669946
- 8684
+ 8492613
- 9399
+ 91911367
- 8253
+ 8070674815
- 2656
+ 2597
@@ -12419,12 +12392,12 @@
12
- 100980
+ 9874523
- 8415
+ 8228
@@ -12440,37 +12413,37 @@
12
- 424327
+ 41492123
- 251670
+ 24609934
- 112794
+ 11033746
- 77246
+ 75496611
- 81763
+ 799671141
- 80374
+ 7859541226300
- 37058
+ 36238
@@ -12486,12 +12459,12 @@
12
- 1005062
+ 9828132367
- 60173
+ 58841
@@ -12507,7 +12480,7 @@
12
- 1065236
+ 1041654
@@ -12526,8 +12499,8 @@
13
- 2975140
- 2975141
+ 2975179
+ 297518013
@@ -12580,15 +12553,15 @@
macroparent
- 35648322
+ 34859187id
- 35648322
+ 34859187parent_id
- 27932475
+ 27314145
@@ -12602,7 +12575,7 @@
12
- 35648322
+ 34859187
@@ -12618,17 +12591,17 @@
12
- 21758475
+ 2127681923
- 5150852
+ 5036827391
- 1023147
+ 1000497
@@ -12638,15 +12611,15 @@
macrolocationbind
- 5543583
+ 5544606id
- 3882063
+ 3882779location
- 2758591
+ 2759101
@@ -12660,22 +12633,22 @@
12
- 3056719
+ 305728323
- 469858
+ 46994437
- 314935
+ 314994757
- 40549
+ 40556
@@ -12691,22 +12664,22 @@
12
- 2198268
+ 219867423
- 240004
+ 24004838
- 216571
+ 2166118723
- 103748
+ 103767
@@ -12716,19 +12689,19 @@
macro_argument_unexpanded
- 102782052
+ 100507893invocation
- 31085973
+ 30398388argument_index
- 890
+ 870text
- 438272
+ 428569
@@ -12742,22 +12715,22 @@
12
- 9939829
+ 971983023
- 12443923
+ 1216893934
- 6366751
+ 6225849467
- 2335468
+ 2283768
@@ -12773,22 +12746,22 @@
12
- 10173011
+ 994785023
- 12465325
+ 1218986734
- 6167729
+ 6031233467
- 2279907
+ 2229436
@@ -12804,17 +12777,17 @@
4645746458
- 782
+ 76446659173182
- 67
+ 65
- 645292
- 2305106
- 40
+ 645295
+ 2305149
+ 39
@@ -12830,17 +12803,17 @@
23
- 782
+ 764131115
- 67
+ 65770222873
- 40
+ 39
@@ -12856,57 +12829,57 @@
12
- 51717
+ 5055923
- 79633
+ 7788334
- 29533
+ 2887945
- 44314
+ 4331956
- 49964
+ 4884569
- 36465
+ 35684915
- 36654
+ 358291527
- 33377
+ 326512757
- 33970
+ 3320557517
- 33093
+ 32374518485092
- 9547
+ 9336
@@ -12922,17 +12895,17 @@
12
- 310481
+ 30360823
- 114749
+ 11220939
- 13040
+ 12751
@@ -12942,19 +12915,19 @@
macro_argument_expanded
- 102782052
+ 100507893invocation
- 31085973
+ 30398388argument_index
- 890
+ 870text
- 265479
+ 259602
@@ -12968,22 +12941,22 @@
12
- 9939829
+ 971983023
- 12443923
+ 1216893934
- 6366751
+ 6225849467
- 2335468
+ 2283768
@@ -12999,22 +12972,22 @@
12
- 13706388
+ 1340300823
- 10736336
+ 1049915334
- 5379705
+ 526065349
- 1263543
+ 1235572
@@ -13030,17 +13003,17 @@
4645746458
- 782
+ 76446659173182
- 67
+ 65
- 645292
- 2305106
- 40
+ 645295
+ 2305149
+ 39
@@ -13056,17 +13029,17 @@
12
- 768
+ 751296
- 67
+ 6595016176
- 53
+ 52
@@ -13082,57 +13055,57 @@
12
- 28171
+ 2753423
- 34927
+ 3416734
- 58231
+ 5694245
- 20538
+ 2007056
- 3964
+ 386367
- 23235
+ 22734710
- 21590
+ 211121019
- 22939
+ 224441951
- 19931
+ 1947751253
- 20053
+ 19622254990275
- 11894
+ 11631
@@ -13148,17 +13121,17 @@
12
- 134169
+ 13119923
- 113522
+ 111009366
- 17787
+ 17393
@@ -13168,19 +13141,19 @@
functions
- 4015439
+ 4000085id
- 4015439
+ 4000085name
- 1650451
+ 1644140kind
- 1000
+ 996
@@ -13194,7 +13167,7 @@
12
- 4015439
+ 4000085
@@ -13210,7 +13183,7 @@
12
- 4015439
+ 4000085
@@ -13226,17 +13199,17 @@
12
- 1403934
+ 139856524
- 139330
+ 13879743162
- 107186
+ 106776
@@ -13252,12 +13225,12 @@
12
- 1647574
+ 164127423
- 2876
+ 2865
@@ -13273,42 +13246,42 @@
89
- 125
+ 1241314
- 125
+ 1244748
- 125
+ 1248384
- 125
+ 124690691
- 125
+ 12444504451
- 125
+ 12452305231
- 125
+ 1242158421585
- 125
+ 124
@@ -13324,42 +13297,42 @@
23
- 125
+ 1241314
- 125
+ 1241819
- 125
+ 1244142
- 125
+ 1244344
- 125
+ 124302303
- 125
+ 124504505
- 125
+ 1241229612297
- 125
+ 124
@@ -13369,15 +13342,15 @@
function_entry_point
- 1432100
+ 1430682id
- 1427396
+ 1425982entry_point
- 1432100
+ 1430682
@@ -13391,12 +13364,12 @@
12
- 1423376
+ 1421966217
- 4020
+ 4016
@@ -13412,7 +13385,7 @@
12
- 1432100
+ 1430682
@@ -13422,15 +13395,15 @@
function_return_type
- 4032949
+ 4017528id
- 4015439
+ 4000085return_type
- 623609
+ 621224
@@ -13444,12 +13417,12 @@
12
- 3997929
+ 398264223
- 17510
+ 17443
@@ -13465,27 +13438,27 @@
12
- 313305
+ 31210723
- 213748
+ 21293035
- 48527
+ 483425354
- 46776
+ 465983589897
- 1250
+ 1245
@@ -13765,59 +13738,59 @@
purefunctions
- 138705
+ 138354id
- 138705
+ 138354function_deleted
- 94271
+ 94264id
- 94271
+ 94264function_defaulted
- 55310
+ 55306id
- 55310
+ 55306function_prototyped
- 4013938
+ 3998590id
- 4013938
+ 3998590deduction_guide_for_class
- 5878
+ 5855id
- 5878
+ 5855class_template
- 2251
+ 2242
@@ -13831,7 +13804,7 @@
12
- 5878
+ 5855
@@ -13847,32 +13820,32 @@
12
- 1125
+ 112123
- 375
+ 37334
- 125
+ 12445
- 250
+ 24956
- 125
+ 12489
- 250
+ 249
@@ -13882,15 +13855,15 @@
member_function_this_type
- 841186
+ 840354id
- 841186
+ 840354this_type
- 239923
+ 239686
@@ -13904,7 +13877,7 @@
12
- 841186
+ 840354
@@ -13920,37 +13893,37 @@
12
- 73730
+ 7365723
- 70223
+ 7015434
- 33743
+ 3370945
- 15396
+ 1538057
- 21854
+ 21832713
- 18903
+ 1888413530
- 6072
+ 6066
@@ -13960,27 +13933,27 @@
fun_decls
- 4160522
+ 4144115id
- 4154519
+ 4138135function
- 3990925
+ 3975664type_id
- 615604
+ 613250name
- 1648950
+ 1642645location
- 2773098
+ 2762494
@@ -13994,7 +13967,7 @@
12
- 4154519
+ 4138135
@@ -14010,12 +13983,12 @@
12
- 4148516
+ 413215423
- 6003
+ 5980
@@ -14031,7 +14004,7 @@
12
- 4154519
+ 4138135
@@ -14047,7 +14020,7 @@
12
- 4154519
+ 4138135
@@ -14063,12 +14036,12 @@
12
- 3840713
+ 382652524
- 150211
+ 149138
@@ -14084,12 +14057,12 @@
12
- 3972414
+ 395722423
- 18510
+ 18439
@@ -14105,7 +14078,7 @@
12
- 3990925
+ 3975664
@@ -14121,12 +14094,12 @@
12
- 3847467
+ 383275524
- 143457
+ 142909
@@ -14142,27 +14115,27 @@
12
- 298547
+ 29740523
- 220627
+ 21978335
- 48903
+ 487165354
- 46276
+ 46099358
- 10246
- 1250
+ 10242
+ 1245
@@ -14178,27 +14151,27 @@
12
- 308677
+ 30749723
- 211872
+ 21106135
- 48527
+ 4834251033
- 46276
+ 4609914839847
- 250
+ 249
@@ -14214,22 +14187,22 @@
12
- 495160
+ 49326723
- 52780
+ 5257837
- 51154
+ 5095872211
- 16509
+ 16446
@@ -14245,22 +14218,22 @@
12
- 458514
+ 45676123
- 69540
+ 6927436
- 55907
+ 5569364728
- 31643
+ 31522
@@ -14276,22 +14249,22 @@
12
- 1299248
+ 129452923
- 184106
+ 183152310
- 125697
+ 125341103169
- 39897
+ 39620
@@ -14307,17 +14280,17 @@
12
- 1403433
+ 139806724
- 139705
+ 13917143162
- 105810
+ 105406
@@ -14333,12 +14306,12 @@
12
- 1558773
+ 155281321596
- 90176
+ 89832
@@ -14354,17 +14327,17 @@
12
- 1323637
+ 131857623
- 208745
+ 20794731592
- 116567
+ 116121
@@ -14380,17 +14353,17 @@
12
- 2392879
+ 238372923
- 238012
+ 2371023211
- 142206
+ 141663
@@ -14406,17 +14379,17 @@
12
- 2396631
+ 238746723
- 234760
+ 2338623211
- 141706
+ 141164
@@ -14432,12 +14405,12 @@
12
- 2657656
+ 26474942211
- 115441
+ 115000
@@ -14453,12 +14426,12 @@
12
- 2733825
+ 272337228
- 39272
+ 39122
@@ -14468,22 +14441,22 @@
fun_def
- 1584950
+ 1583380id
- 1584950
+ 1583380fun_specialized
- 8434
+ 8413id
- 8434
+ 8413
@@ -14501,15 +14474,15 @@
fun_decl_specifiers
- 4106992
+ 4091287id
- 1690224
+ 1683761name
- 1375
+ 1370
@@ -14523,22 +14496,22 @@
12
- 361958
+ 36057423
- 262776
+ 26177134
- 1042475
+ 103848945
- 23013
+ 22925
@@ -14554,57 +14527,57 @@
1516
- 125
+ 1241920
- 125
+ 124224225
- 125
+ 124261262
- 125
+ 124546547
- 125
+ 124826827
- 125
+ 12410321033
- 125
+ 12410891090
- 125
+ 12476687669
- 125
+ 1241054310544
- 125
+ 1241061410615
- 125
+ 124
@@ -14735,26 +14708,26 @@
fun_decl_empty_throws
- 436983
+ 435875fun_decl
- 436983
+ 435875fun_decl_noexcept
- 178039
+ 177863fun_decl
- 178039
+ 177863constant
- 177440
+ 177265
@@ -14768,7 +14741,7 @@
12
- 178039
+ 177863
@@ -14784,7 +14757,7 @@
12
- 176884
+ 1767092
@@ -14799,26 +14772,26 @@
fun_decl_empty_noexcept
- 1165171
+ 1160716fun_decl
- 1165171
+ 1160716fun_decl_typedef_type
- 2796
+ 2769fun_decl
- 2796
+ 2769typedeftype_id
- 125
+ 124
@@ -14832,7 +14805,7 @@
12
- 2796
+ 2769
@@ -14908,11 +14881,11 @@
fun_requires
- 31155
+ 31152id
- 10822
+ 10821kind
@@ -14920,7 +14893,7 @@
constraint
- 30901
+ 30899
@@ -14934,7 +14907,7 @@
12
- 10753
+ 107522
@@ -14955,7 +14928,7 @@
12
- 7783
+ 77822
@@ -14965,7 +14938,7 @@
36
- 921
+ 9206
@@ -15038,7 +15011,7 @@
12
- 30648
+ 306452
@@ -15059,7 +15032,7 @@
12
- 30901
+ 30899
@@ -15069,19 +15042,19 @@
param_decl_bind
- 7198273
+ 7170500id
- 7198273
+ 7170500index
- 8004
+ 7974fun_decl
- 3482131
+ 3468567
@@ -15095,7 +15068,7 @@
12
- 7198273
+ 7170500
@@ -15111,7 +15084,7 @@
12
- 7198273
+ 7170500
@@ -15127,32 +15100,32 @@
23
- 4002
+ 398767
- 2001
+ 19931620
- 625
+ 62225143
- 625
+ 62233215841
- 625
+ 622
- 27841
- 27842
- 125
+ 27839
+ 27840
+ 124
@@ -15168,32 +15141,32 @@
23
- 4002
+ 398767
- 2001
+ 19931620
- 625
+ 62225143
- 625
+ 62233215841
- 625
+ 622
- 27841
- 27842
- 125
+ 27839
+ 27840
+ 124
@@ -15209,27 +15182,27 @@
12
- 1500990
+ 149500123
- 957927
+ 95426434
- 580584
+ 57836445
- 283413
+ 282329565
- 159216
+ 158607
@@ -15245,27 +15218,27 @@
12
- 1500990
+ 149500123
- 957927
+ 95426434
- 580584
+ 57836445
- 283413
+ 282329565
- 159216
+ 158607
@@ -15275,27 +15248,27 @@
var_decls
- 9254083
+ 9244489id
- 9247204
+ 9237636variable
- 8956662
+ 8948454type_id
- 1464093
+ 1458495name
- 853366
+ 850103location
- 6211705
+ 6187953
@@ -15309,7 +15282,7 @@
12
- 9247204
+ 9237636
@@ -15325,12 +15298,12 @@
12
- 9240325
+ 923078323
- 6878
+ 6852
@@ -15346,7 +15319,7 @@
12
- 9247204
+ 9237636
@@ -15362,7 +15335,7 @@
12
- 9247204
+ 9237636
@@ -15378,12 +15351,12 @@
12
- 8679127
+ 867222924
- 277534
+ 276224
@@ -15399,12 +15372,12 @@
12
- 8917889
+ 890983023
- 38772
+ 38624
@@ -15420,12 +15393,12 @@
12
- 8850851
+ 884304724
- 105810
+ 105406
@@ -15441,12 +15414,12 @@
12
- 8704516
+ 869727224
- 252145
+ 251181
@@ -15462,27 +15435,27 @@
12
- 855743
+ 85247123
- 285289
+ 28419835
- 128198
+ 127708511
- 113065
+ 11263211
- 2767
- 81797
+ 2944
+ 81484
@@ -15498,27 +15471,27 @@
12
- 876129
+ 87277923
- 270781
+ 26974535
- 123571
+ 123098511
- 113065
+ 11263211
- 2682
- 80546
+ 2859
+ 80238
@@ -15534,22 +15507,22 @@
12
- 1126274
+ 112196723
- 193361
+ 19262237
- 115316
+ 11487571038
- 29141
+ 29030
@@ -15565,27 +15538,27 @@
12
- 992071
+ 98827823
- 219376
+ 21853736
- 134202
+ 133689695
- 109938
+ 109517972570
- 8504
+ 8472
@@ -15601,32 +15574,32 @@
12
- 466393
+ 46461023
- 165970
+ 16533634
- 60159
+ 5992947
- 66038
+ 657857
- 25
- 64537
+ 26
+ 64165
- 25
- 26622
- 30267
+ 26
+ 26620
+ 30276
@@ -15642,32 +15615,32 @@
12
- 479276
+ 47744323
- 165220
+ 16458834
- 55031
+ 5482148
- 71916
+ 716418
- 45
- 64036
+ 46
+ 63792
- 45
+ 4626187
- 17885
+ 17816
@@ -15683,22 +15656,22 @@
12
- 655627
+ 65312023
- 110563
+ 110140311
- 65412
+ 65162113460
- 21762
+ 21679
@@ -15714,27 +15687,27 @@
12
- 493659
+ 49177123
- 183480
+ 18277934
- 52405
+ 5220448
- 65287
+ 65037822104
- 58533
+ 58309
@@ -15750,12 +15723,12 @@
12
- 5763571
+ 57415332
- 2943
- 448133
+ 2941
+ 446419
@@ -15771,12 +15744,12 @@
12
- 5787585
+ 576545522935
- 424119
+ 422497
@@ -15792,12 +15765,12 @@
12
- 5927416
+ 590475122555
- 284288
+ 283201
@@ -15813,12 +15786,12 @@
12
- 6199197
+ 617549325
- 12507
+ 12459
@@ -15828,11 +15801,11 @@
var_def
- 3714015
+ 3721867id
- 3714015
+ 3721867
@@ -15850,15 +15823,15 @@
var_decl_specifiers
- 489532
+ 487660id
- 489532
+ 487660name
- 500
+ 498
@@ -15872,7 +15845,7 @@
12
- 489532
+ 487660
@@ -15888,22 +15861,22 @@
1617
- 125
+ 1247778
- 125
+ 124651652
- 125
+ 12431703171
- 125
+ 124
@@ -15982,19 +15955,19 @@
type_decls
- 1882105
+ 1840533id
- 1882105
+ 1840533type_id
- 1840893
+ 1800233location
- 1478788
+ 1446052
@@ -16008,7 +15981,7 @@
12
- 1882105
+ 1840533
@@ -16024,7 +15997,7 @@
12
- 1882105
+ 1840533
@@ -16040,12 +16013,12 @@
12
- 1811238
+ 1771235224
- 29655
+ 28998
@@ -16061,12 +16034,12 @@
12
- 1812560
+ 1772527224
- 28333
+ 27706
@@ -16082,12 +16055,12 @@
12
- 1402608
+ 13715582651
- 76180
+ 74494
@@ -16103,12 +16076,12 @@
12
- 1403943
+ 13728632651
- 74845
+ 73188
@@ -16118,29 +16091,29 @@
type_def
- 1291458
+ 1262896id
- 1291458
+ 1262896type_decl_top
- 670615
+ 670739type_decl
- 670615
+ 670739type_requires
- 8220
+ 8219id
@@ -16148,7 +16121,7 @@
constraint
- 8197
+ 8196
@@ -16198,7 +16171,7 @@
12
- 8174
+ 81732
@@ -16213,23 +16186,23 @@
namespace_decls
- 430914
+ 429821id
- 430914
+ 429821namespace_id
- 1959
+ 1954location
- 430914
+ 429821bodylocation
- 430914
+ 429821
@@ -16243,7 +16216,7 @@
12
- 430914
+ 429821
@@ -16259,7 +16232,7 @@
12
- 430914
+ 429821
@@ -16275,7 +16248,7 @@
12
- 430914
+ 429821
@@ -16291,7 +16264,7 @@
12
- 414
+ 4132
@@ -16301,42 +16274,42 @@
36
- 181
+ 180615
- 164
+ 1631534
- 155
+ 1543562
- 164
+ 1636387
- 155
+ 15490142
- 155
+ 154143219
- 155
+ 1542631505
- 155
+ 1541854
@@ -16357,7 +16330,7 @@
12
- 414
+ 4132
@@ -16367,42 +16340,42 @@
36
- 181
+ 180615
- 164
+ 1631534
- 155
+ 1543562
- 164
+ 1636387
- 155
+ 15490142
- 155
+ 154143219
- 155
+ 1542631505
- 155
+ 1541854
@@ -16423,7 +16396,7 @@
12
- 414
+ 4132
@@ -16433,42 +16406,42 @@
36
- 181
+ 180615
- 164
+ 1631534
- 155
+ 1543562
- 164
+ 1636387
- 155
+ 15490142
- 155
+ 154143219
- 155
+ 1542631505
- 155
+ 1541854
@@ -16489,7 +16462,7 @@
12
- 430914
+ 429821
@@ -16505,7 +16478,7 @@
12
- 430914
+ 429821
@@ -16521,7 +16494,7 @@
12
- 430914
+ 429821
@@ -16537,7 +16510,7 @@
12
- 430914
+ 429821
@@ -16553,7 +16526,7 @@
12
- 430914
+ 429821
@@ -16569,7 +16542,7 @@
12
- 430914
+ 429821
@@ -16579,19 +16552,19 @@
usings
- 347162
+ 339714id
- 347162
+ 339714element_id
- 75169
+ 73742location
- 34280
+ 33521kind
@@ -16609,7 +16582,7 @@
12
- 347162
+ 339714
@@ -16625,7 +16598,7 @@
12
- 347162
+ 339714
@@ -16641,7 +16614,7 @@
12
- 347162
+ 339714
@@ -16657,17 +16630,17 @@
12
- 65297
+ 6408925
- 6877
+ 67255134
- 2993
+ 2927
@@ -16683,17 +16656,17 @@
12
- 65297
+ 6408925
- 6877
+ 67255134
- 2993
+ 2927
@@ -16709,7 +16682,7 @@
12
- 75169
+ 73742
@@ -16725,22 +16698,22 @@
12
- 27038
+ 2644024
- 2926
+ 28614132
- 2494
+ 2439145
- 365
- 1820
+ 367
+ 1780
@@ -16756,22 +16729,22 @@
12
- 27038
+ 2644024
- 2926
+ 28614132
- 2494
+ 2439145
- 365
- 1820
+ 367
+ 1780
@@ -16787,7 +16760,7 @@
12
- 34280
+ 33521
@@ -16806,8 +16779,8 @@
13
- 25350
- 25351
+ 25368
+ 2536913
@@ -16827,8 +16800,8 @@
13
- 5360
- 5361
+ 5378
+ 537913
@@ -16860,15 +16833,15 @@
using_container
- 738908
+ 722789parent
- 27038
+ 26479child
- 347162
+ 339714
@@ -16882,42 +16855,42 @@
12
- 12528
+ 1225023
- 1995
+ 195136
- 2292
+ 224167
- 2885
+ 2861727
- 2063
+ 201727136
- 1051
+ 1028145146
- 3344
+ 3270146437
- 876
+ 857
@@ -16933,27 +16906,27 @@
12
- 123785
+ 12128223
- 153561
+ 15016234
- 25123
+ 2456745
- 34078
+ 33323565
- 10613
+ 10378
@@ -16963,27 +16936,27 @@
static_asserts
- 183493
+ 183028id
- 183493
+ 183028condition
- 183493
+ 183028message
- 41092
+ 40988location
- 23921
+ 23861enclosing
- 6647
+ 6630
@@ -16997,7 +16970,7 @@
12
- 183493
+ 183028
@@ -17013,7 +16986,7 @@
12
- 183493
+ 183028
@@ -17029,7 +17002,7 @@
12
- 183493
+ 183028
@@ -17045,7 +17018,7 @@
12
- 183493
+ 183028
@@ -17061,7 +17034,7 @@
12
- 183493
+ 183028
@@ -17077,7 +17050,7 @@
12
- 183493
+ 183028
@@ -17093,7 +17066,7 @@
12
- 183493
+ 183028
@@ -17109,7 +17082,7 @@
12
- 183493
+ 183028
@@ -17125,32 +17098,32 @@
12
- 30232
+ 3015523
- 673
+ 67134
- 3876
+ 3866412
- 2184
+ 21781217
- 3315
+ 330617513
- 811
+ 809
@@ -17166,32 +17139,32 @@
12
- 30232
+ 3015523
- 673
+ 67134
- 3876
+ 3866412
- 2184
+ 21781217
- 3315
+ 330617513
- 811
+ 809
@@ -17207,12 +17180,12 @@
12
- 38079
+ 37983233
- 3012
+ 3005
@@ -17228,7 +17201,7 @@
12
- 32166
+ 320842
@@ -17238,17 +17211,17 @@
34
- 3625
+ 3616412
- 1985
+ 19801243
- 2961
+ 2953
@@ -17264,37 +17237,37 @@
12
- 4489
+ 447723
- 3893
+ 388334
- 1873
+ 186845
- 112
+ 11156
- 5024
+ 5011613
- 457
+ 4561415
- 2814
+ 280716
@@ -17304,12 +17277,12 @@
1718
- 4670
+ 46581952
- 526
+ 525
@@ -17325,37 +17298,37 @@
12
- 4489
+ 447723
- 3893
+ 388334
- 1873
+ 186845
- 112
+ 11156
- 5024
+ 5011613
- 457
+ 4561415
- 2814
+ 280716
@@ -17365,12 +17338,12 @@
1718
- 4670
+ 46581952
- 526
+ 525
@@ -17386,22 +17359,22 @@
12
- 7243
+ 722423
- 8158
+ 813734
- 8270
+ 824947
- 250
+ 249
@@ -17417,32 +17390,32 @@
12
- 5326
+ 531323
- 8537
+ 851634
- 1597
+ 159345
- 5041
+ 5028513
- 517
+ 5161314
- 2814
+ 280716
@@ -17463,17 +17436,17 @@
12
- 5481
+ 546823
- 561
+ 5593210
- 500
+ 499223
@@ -17494,17 +17467,17 @@
12
- 5481
+ 546823
- 561
+ 5593210
- 500
+ 499223
@@ -17525,17 +17498,17 @@
12
- 5645
+ 563123
- 552
+ 55132936
- 448
+ 447
@@ -17551,17 +17524,17 @@
12
- 5628
+ 561423
- 569
+ 56831929
- 448
+ 447
@@ -17571,23 +17544,23 @@
params
- 6992280
+ 6965543id
- 6965639
+ 6939004function
- 3369817
+ 3356931index
- 8004
+ 7974type_id
- 1226832
+ 1222140
@@ -17601,7 +17574,7 @@
12
- 6965639
+ 6939004
@@ -17617,7 +17590,7 @@
12
- 6965639
+ 6939004
@@ -17633,12 +17606,12 @@
12
- 6938999
+ 691246623
- 26640
+ 26538
@@ -17654,27 +17627,27 @@
12
- 1464594
+ 145899323
- 909774
+ 90629534
- 561823
+ 55967545
- 277660
+ 276598565
- 155964
+ 155368
@@ -17690,27 +17663,27 @@
12
- 1464594
+ 145899323
- 909774
+ 90629534
- 561823
+ 55967545
- 277660
+ 276598565
- 155964
+ 155368
@@ -17726,22 +17699,22 @@
12
- 1765517
+ 175876623
- 1009581
+ 100572134
- 437502
+ 435829411
- 157215
+ 156614
@@ -17757,32 +17730,32 @@
23
- 4002
+ 398767
- 2001
+ 19931418
- 625
+ 62223138
- 625
+ 62232315234
- 625
+ 6222694326944
- 125
+ 124
@@ -17798,32 +17771,32 @@
23
- 4002
+ 398767
- 2001
+ 19931418
- 625
+ 62223138
- 625
+ 62232315234
- 625
+ 6222694326944
- 125
+ 124
@@ -17839,32 +17812,32 @@
12
- 4002
+ 398723
- 2001
+ 199347
- 625
+ 622954
- 625
+ 6221152700
- 625
+ 62275287529
- 125
+ 124
@@ -17880,27 +17853,27 @@
12
- 741677
+ 73884123
- 242264
+ 24133835
- 93929
+ 93569513
- 93804
+ 93445132570
- 55156
+ 54945
@@ -17916,27 +17889,27 @@
12
- 824099
+ 82094823
- 181354
+ 18066136
- 106686
+ 106278627
- 92553
+ 92199272558
- 22137
+ 22053
@@ -17952,17 +17925,17 @@
12
- 1001202
+ 99737323
- 167221
+ 166581365
- 58408
+ 58185
@@ -17972,15 +17945,15 @@
overrides
- 169801
+ 169371new
- 160547
+ 160140old
- 19122
+ 19073
@@ -17994,12 +17967,12 @@
12
- 151301
+ 15091724
- 9245
+ 9222
@@ -18015,32 +17988,32 @@
12
- 10463
+ 1043623
- 2589
+ 258334
- 1735
+ 173046
- 1579
+ 1575618
- 1441
+ 143818230
- 1312
+ 1308
@@ -18050,19 +18023,19 @@
membervariables
- 1491583
+ 1491860id
- 1489139
+ 1489415type_id
- 453830
+ 453914name
- 638893
+ 639011
@@ -18076,12 +18049,12 @@
12
- 1486803
+ 148707924
- 2335
+ 2336
@@ -18097,7 +18070,7 @@
12
- 1489139
+ 1489415
@@ -18113,22 +18086,22 @@
12
- 336774
+ 33683623
- 71917
+ 71930310
- 35035
+ 35041104422
- 10103
+ 10105
@@ -18144,22 +18117,22 @@
12
- 354264
+ 35433023
- 63932
+ 63944349
- 34111
+ 34118562175
- 1520
+ 1521
@@ -18175,22 +18148,22 @@
12
- 419772
+ 41985023
- 121781
+ 12180435
- 57305
+ 573165654
- 40032
+ 40040
@@ -18206,17 +18179,17 @@
12
- 522217
+ 52231423
- 72297
+ 723113658
- 44378
+ 44386
@@ -18226,19 +18199,19 @@
globalvariables
- 466518
+ 486788id
- 466518
+ 486788type_id
- 10380
+ 10341name
- 112564
+ 112134
@@ -18252,7 +18225,7 @@
12
- 466518
+ 486788
@@ -18268,7 +18241,7 @@
12
- 466518
+ 486788
@@ -18284,32 +18257,32 @@
12
- 7004
+ 697723
- 375
+ 37335
- 750
+ 747520
- 875
+ 8722074
- 875
+ 872152
- 2037
- 500
+ 2214
+ 498
@@ -18325,32 +18298,32 @@
12
- 7129
+ 710123
- 375
+ 37335
- 750
+ 747520
- 750
+ 7472074
- 875
+ 872124226
- 500
+ 498
@@ -18366,17 +18339,17 @@
12
- 95430
+ 9506527
- 8755
+ 87217
- 500
- 8379
+ 604
+ 8347
@@ -18392,17 +18365,17 @@
12
- 97055
+ 9668423
- 15258
+ 1520034
- 250
+ 249
@@ -18412,19 +18385,19 @@
localvariables
- 734804
+ 727548id
- 734804
+ 727548type_id
- 54064
+ 53530name
- 102754
+ 101739
@@ -18438,7 +18411,7 @@
12
- 734804
+ 727548
@@ -18454,7 +18427,7 @@
12
- 734804
+ 727548
@@ -18470,37 +18443,37 @@
12
- 29233
+ 2894423
- 7920
+ 784234
- 4073
+ 403346
- 4098
+ 4057612
- 4199
+ 415712166
- 4057
+ 401716819320
- 482
+ 477
@@ -18516,22 +18489,22 @@
12
- 38827
+ 3844423
- 6781
+ 671435
- 4519
+ 447453502
- 3935
+ 3897
@@ -18547,32 +18520,32 @@
12
- 63217
+ 6259223
- 16238
+ 1607734
- 6611
+ 654548
- 8228
+ 81478135
- 7709
+ 76331357544
- 749
+ 742
@@ -18588,22 +18561,22 @@
12
- 85502
+ 8465823
- 8520
+ 8436315
- 7766
+ 7689151509
- 964
+ 955
@@ -18613,15 +18586,15 @@
autoderivation
- 229507
+ 228629var
- 229507
+ 228629derivation_type
- 625
+ 622
@@ -18635,7 +18608,7 @@
12
- 229507
+ 228629
@@ -18651,27 +18624,27 @@
3839
- 125
+ 1247980
- 125
+ 124454455
- 125
+ 124530531
- 125
+ 124734735
- 125
+ 124
@@ -18681,15 +18654,15 @@
orphaned_variables
- 55640
+ 55584var
- 55640
+ 55584function
- 51534
+ 51483
@@ -18703,7 +18676,7 @@
12
- 55640
+ 55584
@@ -18719,12 +18692,12 @@
12
- 50465
+ 50415247
- 1069
+ 1068
@@ -18734,19 +18707,19 @@
enumconstants
- 343781
+ 343845id
- 343781
+ 343845parent
- 41173
+ 41181index
- 13905
+ 13908type_id
@@ -18754,11 +18727,11 @@
name
- 343400
+ 343464location
- 316459
+ 316517
@@ -18772,7 +18745,7 @@
12
- 343781
+ 343845
@@ -18788,7 +18761,7 @@
12
- 343781
+ 343845
@@ -18804,7 +18777,7 @@
12
- 343781
+ 343845
@@ -18820,7 +18793,7 @@
12
- 343781
+ 343845
@@ -18836,7 +18809,7 @@
12
- 343781
+ 343845
@@ -18852,22 +18825,22 @@
12
- 1520
+ 152123
- 5703
+ 570434
- 8690
+ 869245
- 5486
+ 54875
@@ -18877,7 +18850,7 @@
67
- 2661
+ 26627
@@ -18892,7 +18865,7 @@
1117
- 3150
+ 315117
@@ -18918,22 +18891,22 @@
12
- 1520
+ 152123
- 5703
+ 570434
- 8690
+ 869245
- 5486
+ 54875
@@ -18943,7 +18916,7 @@
67
- 2661
+ 26627
@@ -18958,7 +18931,7 @@
1117
- 3150
+ 315117
@@ -18984,7 +18957,7 @@
12
- 41173
+ 41181
@@ -19000,22 +18973,22 @@
12
- 1520
+ 152123
- 5703
+ 570434
- 8690
+ 869245
- 5486
+ 54875
@@ -19025,7 +18998,7 @@
67
- 2661
+ 26627
@@ -19040,7 +19013,7 @@
1117
- 3150
+ 315117
@@ -19071,17 +19044,17 @@
23
- 5920
+ 592134
- 8745
+ 874645
- 5431
+ 54325
@@ -19096,12 +19069,12 @@
78
- 1846
+ 1847811
- 3693
+ 369411
@@ -19239,7 +19212,7 @@
12
- 13905
+ 13908
@@ -19447,7 +19420,7 @@
12
- 343020
+ 3430842
@@ -19468,7 +19441,7 @@
12
- 343020
+ 3430842
@@ -19489,7 +19462,7 @@
12
- 343400
+ 343464
@@ -19505,7 +19478,7 @@
12
- 343400
+ 343464
@@ -19521,7 +19494,7 @@
12
- 343020
+ 3430842
@@ -19542,7 +19515,7 @@
12
- 315427
+ 3154852
@@ -19563,7 +19536,7 @@
12
- 316459
+ 316517
@@ -19579,7 +19552,7 @@
12
- 315427
+ 3154852
@@ -19600,7 +19573,7 @@
12
- 316459
+ 316517
@@ -19616,7 +19589,7 @@
12
- 315427
+ 3154852
@@ -19631,31 +19604,31 @@
builtintypes
- 7004
+ 7101id
- 7004
+ 7101name
- 7004
+ 7101kind
- 7004
+ 7101size
- 875
+ 872sign
- 375
+ 373alignment
- 625
+ 622
@@ -19669,7 +19642,7 @@
12
- 7004
+ 7101
@@ -19685,7 +19658,7 @@
12
- 7004
+ 7101
@@ -19701,7 +19674,7 @@
12
- 7004
+ 7101
@@ -19717,7 +19690,7 @@
12
- 7004
+ 7101
@@ -19733,7 +19706,7 @@
12
- 7004
+ 7101
@@ -19749,7 +19722,7 @@
12
- 7004
+ 7101
@@ -19765,7 +19738,7 @@
12
- 7004
+ 7101
@@ -19781,7 +19754,7 @@
12
- 7004
+ 7101
@@ -19797,7 +19770,7 @@
12
- 7004
+ 7101
@@ -19813,7 +19786,7 @@
12
- 7004
+ 7101
@@ -19829,7 +19802,7 @@
12
- 7004
+ 7101
@@ -19845,7 +19818,7 @@
12
- 7004
+ 7101
@@ -19861,7 +19834,7 @@
12
- 7004
+ 7101
@@ -19877,7 +19850,7 @@
12
- 7004
+ 7101
@@ -19893,7 +19866,7 @@
12
- 7004
+ 7101
@@ -19909,37 +19882,37 @@
12
- 125
+ 12423
- 125
+ 124
- 7
- 8
- 125
+ 8
+ 9
+ 124910
- 125
+ 1241112
- 125
+ 1241213
- 125
+ 1241415
- 125
+ 124
@@ -19955,37 +19928,37 @@
12
- 125
+ 12423
- 125
+ 124
- 7
- 8
- 125
+ 8
+ 9
+ 124910
- 125
+ 1241112
- 125
+ 1241213
- 125
+ 1241415
- 125
+ 124
@@ -20001,37 +19974,37 @@
12
- 125
+ 12423
- 125
+ 124
- 7
- 8
- 125
+ 8
+ 9
+ 124910
- 125
+ 1241112
- 125
+ 1241213
- 125
+ 1241415
- 125
+ 124
@@ -20047,12 +20020,12 @@
12
- 250
+ 24934
- 625
+ 622
@@ -20068,12 +20041,12 @@
12
- 500
+ 49823
- 375
+ 373
@@ -20089,17 +20062,17 @@
67
- 125
+ 1241213
- 125
+ 124
- 38
- 39
- 125
+ 39
+ 40
+ 124
@@ -20115,17 +20088,17 @@
67
- 125
+ 1241213
- 125
+ 124
- 38
- 39
- 125
+ 39
+ 40
+ 124
@@ -20141,17 +20114,17 @@
67
- 125
+ 1241213
- 125
+ 124
- 38
- 39
- 125
+ 39
+ 40
+ 124
@@ -20167,12 +20140,12 @@
56
- 250
+ 24978
- 125
+ 124
@@ -20188,7 +20161,7 @@
56
- 375
+ 373
@@ -20204,22 +20177,27 @@
89
- 250
+ 124
+
+
+ 9
+ 10
+ 1241011
- 125
+ 1241314
- 125
+ 1241718
- 125
+ 124
@@ -20235,22 +20213,27 @@
89
- 250
+ 124
+
+
+ 9
+ 10
+ 1241011
- 125
+ 1241314
- 125
+ 1241718
- 125
+ 124
@@ -20266,22 +20249,27 @@
89
- 250
+ 124
+
+
+ 9
+ 10
+ 1241011
- 125
+ 1241314
- 125
+ 1241718
- 125
+ 124
@@ -20297,7 +20285,7 @@
23
- 625
+ 622
@@ -20313,7 +20301,7 @@
34
- 625
+ 622
@@ -20323,23 +20311,23 @@
derivedtypes
- 3047881
+ 3036227id
- 3047881
+ 3036227name
- 1475975
+ 1470331kind
- 750
+ 747type_id
- 1949998
+ 1942542
@@ -20353,7 +20341,7 @@
12
- 3047881
+ 3036227
@@ -20369,7 +20357,7 @@
12
- 3047881
+ 3036227
@@ -20385,7 +20373,7 @@
12
- 3047881
+ 3036227
@@ -20401,17 +20389,17 @@
12
- 1358908
+ 1353712230
- 110938
+ 110514304274
- 6128
+ 6105
@@ -20427,7 +20415,7 @@
12
- 1475975
+ 1470331
@@ -20443,17 +20431,17 @@
12
- 1359033
+ 1353836230
- 110813
+ 110390304274
- 6128
+ 6105
@@ -20469,32 +20457,32 @@
787788
- 125
+ 12423332334
- 125
+ 12436473648
- 125
+ 12442734274
- 125
+ 12455695570
- 125
+ 12477607761
- 125
+ 124
@@ -20510,32 +20498,32 @@
12
- 125
+ 124733734
- 125
+ 12416131614
- 125
+ 12424332434
- 125
+ 12426782679
- 125
+ 12443434344
- 125
+ 124
@@ -20551,32 +20539,32 @@
208209
- 125
+ 12423332334
- 125
+ 12436433644
- 125
+ 12442734274
- 125
+ 12455025503
- 125
+ 12477607761
- 125
+ 124
@@ -20592,22 +20580,22 @@
12
- 1317134
+ 131209723
- 378593
+ 37714534
- 122945
+ 1224754135
- 131325
+ 130823
@@ -20623,22 +20611,22 @@
12
- 1318635
+ 131359223
- 378593
+ 37714534
- 121444
+ 1209804135
- 131325
+ 130823
@@ -20654,22 +20642,22 @@
12
- 1319010
+ 131396623
- 379468
+ 37801734
- 122945
+ 12247546
- 128574
+ 128082
@@ -20679,19 +20667,19 @@
pointerishsize
- 2252923
+ 2244308id
- 2252923
+ 2244308size
- 250
+ 249alignment
- 250
+ 249
@@ -20705,7 +20693,7 @@
12
- 2252923
+ 2244308
@@ -20721,7 +20709,7 @@
12
- 2252923
+ 2244308
@@ -20737,12 +20725,12 @@
34
- 125
+ 1241801018011
- 125
+ 124
@@ -20758,7 +20746,7 @@
12
- 250
+ 249
@@ -20774,12 +20762,12 @@
34
- 125
+ 1241801018011
- 125
+ 124
@@ -20795,7 +20783,7 @@
12
- 250
+ 249
@@ -20805,23 +20793,23 @@
arraysizes
- 88676
+ 88337id
- 88676
+ 88337num_elements
- 18510
+ 18439bytesize
- 22888
+ 22800alignment
- 625
+ 622
@@ -20835,7 +20823,7 @@
12
- 88676
+ 88337
@@ -20851,7 +20839,7 @@
12
- 88676
+ 88337
@@ -20867,7 +20855,7 @@
12
- 88676
+ 88337
@@ -20883,37 +20871,37 @@
12
- 250
+ 24923
- 8880
+ 884634
- 250
+ 24945
- 5628
+ 560667
- 1625
+ 1619827
- 1500
+ 14953457
- 375
+ 373
@@ -20929,22 +20917,22 @@
12
- 9505
+ 946923
- 6628
+ 660335
- 1250
+ 1245511
- 1125
+ 1121
@@ -20960,22 +20948,22 @@
12
- 9505
+ 946923
- 6628
+ 660334
- 1000
+ 99646
- 1375
+ 1370
@@ -20991,37 +20979,37 @@
12
- 625
+ 62223
- 14758
+ 1470234
- 375
+ 37345
- 3251
+ 323957
- 1500
+ 1495717
- 1751
+ 17441745
- 625
+ 622
@@ -21037,22 +21025,22 @@
12
- 16509
+ 1644623
- 4002
+ 398735
- 1751
+ 174457
- 625
+ 622
@@ -21068,22 +21056,22 @@
12
- 16634
+ 1657023
- 4002
+ 398735
- 1876
+ 186856
- 375
+ 373
@@ -21099,27 +21087,27 @@
1011
- 125
+ 1248687
- 125
+ 1249192
- 125
+ 124187188
- 125
+ 124335336
- 125
+ 124
@@ -21135,22 +21123,22 @@
45
- 125
+ 1241617
- 250
+ 2498081
- 125
+ 124137138
- 125
+ 124
@@ -21166,27 +21154,27 @@
45
- 125
+ 1241920
- 125
+ 1242021
- 125
+ 1248081
- 125
+ 124138139
- 125
+ 124
@@ -21196,15 +21184,15 @@
typedefbase
- 2164787
+ 2162643id
- 2164787
+ 2162643type_id
- 901360
+ 900467
@@ -21218,7 +21206,7 @@
12
- 2164787
+ 2162643
@@ -21234,22 +21222,22 @@
12
- 727340
+ 72662023
- 81343
+ 8126236
- 69667
+ 6959862848
- 23008
+ 22985
@@ -21259,15 +21247,15 @@
decltypes
- 812151
+ 812302id
- 27485
+ 27490expr
- 812151
+ 812302kind
@@ -21275,7 +21263,7 @@
base_type
- 3331
+ 3332parentheses_would_change_meaning
@@ -21293,27 +21281,27 @@
12
- 9709
+ 971123
- 3638
+ 363945
- 3616
+ 361769
- 547
+ 5482324
- 3243
+ 324429
@@ -21328,7 +21316,7 @@
171172
- 3068
+ 3069173
@@ -21349,7 +21337,7 @@
12
- 27485
+ 27490
@@ -21365,7 +21353,7 @@
12
- 27485
+ 27490
@@ -21381,7 +21369,7 @@
12
- 27485
+ 27490
@@ -21397,7 +21385,7 @@
12
- 812151
+ 812302
@@ -21413,7 +21401,7 @@
12
- 812151
+ 812302
@@ -21429,7 +21417,7 @@
12
- 812151
+ 812302
@@ -21445,7 +21433,7 @@
12
- 812151
+ 812302
@@ -21617,7 +21605,7 @@
12
- 3331
+ 3332
@@ -21633,7 +21621,7 @@
12
- 3331
+ 3332
@@ -22003,7 +21991,7 @@
12
- 4375
+ 43742
@@ -22023,19 +22011,19 @@
usertypes
- 4962767
+ 4863363id
- 4962767
+ 4863363name
- 1069983
+ 1051136kind
- 161
+ 158
@@ -22049,7 +22037,7 @@
12
- 4962767
+ 4863363
@@ -22065,7 +22053,7 @@
12
- 4962767
+ 4863363
@@ -22081,22 +22069,22 @@
12
- 740028
+ 72765523
- 195960
+ 19244037
- 85634
+ 837387
- 30188
- 48359
+ 30282
+ 47302
@@ -22112,12 +22100,12 @@
12
- 1003916
+ 986532210
- 66066
+ 64603
@@ -22151,8 +22139,8 @@
13
- 1426
- 1427
+ 1563
+ 156413
@@ -22166,13 +22154,13 @@
13
- 19665
- 19666
+ 19666
+ 1966713
- 20058
- 20059
+ 20075
+ 2007613
@@ -22181,13 +22169,13 @@
13
- 85546
- 85547
+ 86007
+ 8600813
- 151042
- 151043
+ 151219
+ 15122013
@@ -22247,8 +22235,8 @@
13
- 10827
- 10828
+ 10838
+ 1083913
@@ -22257,8 +22245,8 @@
13
- 51351
- 51352
+ 51707
+ 5170813
@@ -22269,19 +22257,19 @@
usertypesize
- 1624097
+ 1595582id
- 1624097
+ 1595582size
- 1887
+ 1846alignment
- 107
+ 105
@@ -22295,7 +22283,7 @@
12
- 1624097
+ 1595582
@@ -22311,7 +22299,7 @@
12
- 1624097
+ 1595582
@@ -22327,52 +22315,52 @@
12
- 593
+ 58023
- 256
+ 25034
- 107
+ 10546
- 121
+ 11868
- 148
+ 145814
- 148
+ 1451426
- 148
+ 1452686
- 148
+ 14596
- 1588
- 148
+ 1592
+ 1451733
- 92740
- 67
+ 93158
+ 65
@@ -22388,17 +22376,17 @@
12
- 1550
+ 151623
- 215
+ 21036
- 121
+ 118
@@ -22437,18 +22425,18 @@
13
- 1909
- 1910
+ 2046
+ 204713
- 10475
- 10476
+ 10484
+ 1048513
- 107926
- 107927
+ 108344
+ 10834513
@@ -22505,26 +22493,26 @@
usertype_final
- 11506
+ 11462id
- 11506
+ 11462usertype_uuid
- 50407
+ 50280id
- 50407
+ 50280uuid
- 49898
+ 49771
@@ -22538,7 +22526,7 @@
12
- 50407
+ 50280
@@ -22554,12 +22542,12 @@
12
- 49389
+ 4926323
- 509
+ 508
@@ -22569,11 +22557,11 @@
usertype_alias_kind
- 2164830
+ 2162686id
- 2164787
+ 2162643alias_kind
@@ -22591,7 +22579,7 @@
12
- 2164744
+ 21626002
@@ -22627,26 +22615,26 @@
nontype_template_parameters
- 961918
+ 960966id
- 961918
+ 960966type_template_type_constraint
- 29059
+ 29057id
- 14322
+ 14321constraint
- 27839
+ 27836
@@ -22660,7 +22648,7 @@
12
- 10937
+ 109362
@@ -22696,7 +22684,7 @@
12
- 26618
+ 266162
@@ -22711,19 +22699,19 @@
mangled_name
- 7827011
+ 7805181id
- 7827011
+ 7805181mangled_name
- 6329773
+ 6313668is_complete
- 250
+ 249
@@ -22737,7 +22725,7 @@
12
- 7827011
+ 7805181
@@ -22753,7 +22741,7 @@
12
- 7827011
+ 7805181
@@ -22769,12 +22757,12 @@
12
- 6000083
+ 598498921127
- 329690
+ 328678
@@ -22790,7 +22778,7 @@
12
- 6329773
+ 6313668
@@ -22806,12 +22794,12 @@
67
- 125
+ 124
- 62574
- 62575
- 125
+ 62639
+ 62640
+ 124
@@ -22827,12 +22815,12 @@
67
- 125
+ 124
- 50603
- 50604
- 125
+ 50668
+ 50669
+ 124
@@ -22842,59 +22830,59 @@
is_pod_class
- 742865
+ 744607id
- 742865
+ 744607is_standard_layout_class
- 1338834
+ 1314787id
- 1338834
+ 1314787is_complete
- 1604003
+ 1574126id
- 1604003
+ 1574126is_class_template
- 290846
+ 284420id
- 290846
+ 284420class_instantiation
- 1320911
+ 1297973to
- 1317027
+ 1294176from
- 91190
+ 89303
@@ -22908,12 +22896,12 @@
12
- 1314303
+ 129151228
- 2724
+ 2663
@@ -22929,47 +22917,47 @@
12
- 26607
+ 2595223
- 16533
+ 1615434
- 9021
+ 883545
- 5974
+ 584157
- 7700
+ 7529710
- 6904
+ 68301017
- 7336
+ 72261753
- 6904
+ 6765534219
- 4207
+ 4167
@@ -22979,19 +22967,19 @@
class_template_argument
- 3486149
+ 3419922type_id
- 1623773
+ 1594052index
- 1510
+ 1476arg_type
- 1029795
+ 1008977
@@ -23005,27 +22993,27 @@
12
- 675431
+ 66340723
- 488142
+ 47923534
- 307433
+ 30201247
- 123542
+ 1208207113
- 29223
+ 28576
@@ -23041,22 +23029,22 @@
12
- 709847
+ 69765423
- 503407
+ 49364834
- 305505
+ 3000474113
- 105013
+ 102701
@@ -23077,32 +23065,32 @@
45
- 957
+ 936530
- 121
+ 1183390
- 121
+ 11895453
- 121
+ 118643
- 6818
- 121
+ 6819
+ 118
- 11328
- 120405
- 53
+ 11329
+ 120877
+ 52
@@ -23123,32 +23111,32 @@
45
- 957
+ 936516
- 134
+ 1311635
- 121
+ 11837155
- 121
+ 1181963251
- 121
+ 118
- 10040
- 43709
- 40
+ 10075
+ 43772
+ 39
@@ -23164,27 +23152,27 @@
12
- 646113
+ 63305023
- 211415
+ 20695934
- 61737
+ 60608411
- 78284
+ 7676211
- 11552
- 32244
+ 11634
+ 31596
@@ -23200,17 +23188,17 @@
12
- 908181
+ 88944823
- 98486
+ 96886322
- 23127
+ 22642
@@ -23220,11 +23208,11 @@
class_template_argument_value
- 640309
+ 639675type_id
- 258356
+ 258100index
@@ -23232,7 +23220,7 @@
arg_value
- 640138
+ 639504
@@ -23246,17 +23234,17 @@
12
- 195574
+ 19538023
- 54442
+ 5438838
- 8339
+ 8331
@@ -23272,22 +23260,22 @@
12
- 185694
+ 18551123
- 50807
+ 50757345
- 19501
+ 1948245154
- 2352
+ 2349
@@ -23415,12 +23403,12 @@
12
- 639967
+ 63933323
- 171
+ 170
@@ -23436,7 +23424,7 @@
12
- 640138
+ 639504
@@ -23446,15 +23434,15 @@
is_proxy_class_for
- 61845
+ 60476id
- 61845
+ 60476templ_param_id
- 58433
+ 57140
@@ -23468,7 +23456,7 @@
12
- 61845
+ 60476
@@ -23484,12 +23472,12 @@
12
- 57516
+ 56243279
- 917
+ 896
@@ -23499,19 +23487,19 @@
type_mentions
- 5812069
+ 5813149id
- 5812069
+ 5813149type_id
- 275231
+ 275282location
- 5766496
+ 5767568kind
@@ -23529,7 +23517,7 @@
12
- 5812069
+ 5813149
@@ -23545,7 +23533,7 @@
12
- 5812069
+ 5813149
@@ -23561,7 +23549,7 @@
12
- 5812069
+ 5813149
@@ -23577,42 +23565,42 @@
12
- 136121
+ 13614723
- 30907
+ 3091234
- 11135
+ 1113745
- 14665
+ 1466857
- 19934
+ 19938712
- 21781
+ 217851228
- 21021
+ 21025288907
- 19663
+ 19666
@@ -23628,42 +23616,42 @@
12
- 136121
+ 13614723
- 30907
+ 3091234
- 11135
+ 1113745
- 14665
+ 1466857
- 19934
+ 19938712
- 21781
+ 217851228
- 21021
+ 21025288907
- 19663
+ 19666
@@ -23679,7 +23667,7 @@
12
- 275231
+ 275282
@@ -23695,12 +23683,12 @@
12
- 5720923
+ 572198623
- 45573
+ 45581
@@ -23716,12 +23704,12 @@
12
- 5720923
+ 572198623
- 45573
+ 45581
@@ -23737,7 +23725,7 @@
12
- 5766496
+ 5767568
@@ -23795,26 +23783,26 @@
is_function_template
- 1383517
+ 1382147id
- 1383517
+ 1382147function_instantiation
- 1221386
+ 1220177to
- 1221386
+ 1220177from
- 229146
+ 228919
@@ -23828,7 +23816,7 @@
12
- 1221386
+ 1220177
@@ -23844,27 +23832,27 @@
12
- 139378
+ 13924023
- 53031
+ 5297839
- 18047
+ 180299103
- 17192
+ 171751031532
- 1496
+ 1495
@@ -23874,11 +23862,11 @@
function_template_argument
- 3119179
+ 3116090function_id
- 1824318
+ 1822511index
@@ -23886,7 +23874,7 @@
arg_type
- 374084
+ 373713
@@ -23900,22 +23888,22 @@
12
- 982917
+ 98194323
- 518637
+ 51812334
- 215674
+ 215461415
- 107088
+ 106982
@@ -23931,22 +23919,22 @@
12
- 1006952
+ 100595523
- 516242
+ 51573134
- 212937
+ 21272649
- 88185
+ 88098
@@ -24084,37 +24072,37 @@
12
- 219395
+ 21917823
- 33059
+ 3302634
- 25104
+ 2507946
- 28440
+ 28411611
- 29167
+ 291381176
- 29338
+ 29309792452
- 9579
+ 9570
@@ -24130,17 +24118,17 @@
12
- 322378
+ 32205923
- 40329
+ 40289315
- 11376
+ 11364
@@ -24150,11 +24138,11 @@
function_template_argument_value
- 568375
+ 567812function_id
- 247023
+ 246778index
@@ -24162,7 +24150,7 @@
arg_value
- 564996
+ 564437
@@ -24176,17 +24164,17 @@
12
- 190057
+ 18986823
- 53843
+ 5379038
- 3122
+ 3118
@@ -24202,22 +24190,22 @@
12
- 181375
+ 18119523
- 46060
+ 46014354
- 18646
+ 1862854113
- 940
+ 939
@@ -24355,12 +24343,12 @@
12
- 561618
+ 56106223
- 3378
+ 3375
@@ -24376,7 +24364,7 @@
12
- 564996
+ 564437
@@ -24386,26 +24374,26 @@
is_variable_template
- 58783
+ 58559id
- 58783
+ 58559variable_instantiation
- 395853
+ 420379to
- 395853
+ 420379from
- 35145
+ 35010
@@ -24419,7 +24407,7 @@
12
- 395853
+ 420379
@@ -24435,47 +24423,47 @@
12
- 15383
+ 1507523
- 3752
+ 398734
- 2251
+ 224246
- 2876
+ 286568
- 2251
+ 2242811
- 2751
+ 274111
- 25
- 2876
+ 30
+ 2741
- 26
- 181
- 2751
+ 30
+ 105
+ 2741
- 388
- 447
- 250
+ 180
+ 546
+ 373
@@ -24485,19 +24473,19 @@
variable_template_argument
- 719414
+ 766875variable_id
- 379093
+ 399697index
- 2001
+ 1993arg_type
- 255397
+ 256164
@@ -24511,22 +24499,22 @@
12
- 151962
+ 15549323
- 173725
+ 18963134
- 36521
+ 36381417
- 16884
+ 18190
@@ -24542,22 +24530,22 @@
12
- 165470
+ 17044423
- 165345
+ 17978834
- 33769
+ 33640417
- 14508
+ 15823
@@ -24571,44 +24559,44 @@
12
- 23
- 24
- 875
+ 28
+ 29
+ 872
- 29
- 30
- 375
+ 34
+ 35
+ 373
- 32
- 33
- 125
+ 37
+ 38
+ 124
- 61
- 62
- 125
+ 66
+ 67
+ 124
- 135
- 136
- 125
+ 146
+ 147
+ 124
- 427
- 428
- 125
+ 438
+ 439
+ 124
- 1816
- 1817
- 125
+ 1960
+ 1961
+ 124
- 3031
- 3032
- 125
+ 3208
+ 3209
+ 124
@@ -24624,42 +24612,42 @@
12
- 875
+ 87223
- 375
+ 37356
- 125
+ 1242829
- 125
+ 1245455
- 125
+ 124161162
- 125
+ 124
- 731
- 732
- 125
+ 748
+ 749
+ 124
- 1321
- 1322
- 125
+ 1326
+ 1327
+ 124
@@ -24675,22 +24663,22 @@
12
- 176226
+ 17555223
- 44150
+ 4460436
- 21137
+ 216796
- 190
- 13883
+ 206
+ 14328
@@ -24706,17 +24694,17 @@
12
- 227756
+ 22775723
- 24138
+ 2479437
- 3502
+ 3613
@@ -24726,19 +24714,19 @@
variable_template_argument_value
- 20011
+ 19935variable_id
- 14883
+ 14826index
- 500
+ 498arg_value
- 20011
+ 19935
@@ -24752,12 +24740,12 @@
12
- 13382
+ 1333123
- 1500
+ 1495
@@ -24773,17 +24761,17 @@
12
- 10506
+ 1046523
- 4002
+ 398745
- 375
+ 373
@@ -24799,22 +24787,22 @@
1718
- 125
+ 1242728
- 125
+ 1244142
- 125
+ 1244647
- 125
+ 124
@@ -24830,22 +24818,22 @@
2223
- 125
+ 1242930
- 125
+ 1245051
- 125
+ 1245960
- 125
+ 124
@@ -24861,7 +24849,7 @@
12
- 20011
+ 19935
@@ -24877,7 +24865,7 @@
12
- 20011
+ 19935
@@ -24887,15 +24875,15 @@
template_template_instantiation
- 7403
+ 7239to
- 6945
+ 6791from
- 4908
+ 4800
@@ -24909,12 +24897,12 @@
12
- 6796
+ 6646215
- 148
+ 145
@@ -24930,17 +24918,17 @@
12
- 3209
+ 313823
- 1523
+ 1490320
- 175
+ 171
@@ -24950,19 +24938,19 @@
template_template_argument
- 12352
+ 12079type_id
- 7808
+ 7635index
- 134
+ 131arg_type
- 11597
+ 11340
@@ -24976,22 +24964,22 @@
12
- 6405
+ 626323
- 539
+ 52738
- 647
+ 632811
- 215
+ 210
@@ -25007,22 +24995,22 @@
12
- 6432
+ 629024
- 714
+ 698410
- 593
+ 5801011
- 67
+ 65
@@ -25160,12 +25148,12 @@
12
- 11557
+ 11301343
- 40
+ 39
@@ -25181,7 +25169,7 @@
12
- 11570
+ 113142
@@ -25196,11 +25184,11 @@
template_template_argument_value
- 795
+ 778type_id
- 674
+ 659index
@@ -25208,7 +25196,7 @@
arg_value
- 795
+ 778
@@ -25222,7 +25210,7 @@
12
- 674
+ 659
@@ -25238,12 +25226,12 @@
12
- 579
+ 56723
- 67
+ 653
@@ -25306,7 +25294,7 @@
12
- 795
+ 778
@@ -25322,7 +25310,7 @@
12
- 795
+ 778
@@ -25448,15 +25436,15 @@
concept_instantiation
- 96781
+ 96774to
- 96781
+ 96774from
- 3684
+ 3683
@@ -25470,7 +25458,7 @@
12
- 96781
+ 96774
@@ -25566,22 +25554,22 @@
is_type_constraint
- 39490
+ 39487concept_id
- 39490
+ 39487concept_template_argument
- 120982
+ 120973concept_id
- 81744
+ 81738index
@@ -25589,7 +25577,7 @@
arg_type
- 22934
+ 22932
@@ -25603,12 +25591,12 @@
12
- 49737
+ 4973323
- 26411
+ 264093
@@ -25629,12 +25617,12 @@
12
- 53606
+ 5360223
- 23947
+ 239453
@@ -25762,7 +25750,7 @@
69
- 1727
+ 17269
@@ -25788,12 +25776,12 @@
12
- 19296
+ 1929423
- 3500
+ 34993
@@ -25939,15 +25927,15 @@
routinetypes
- 758603
+ 757852id
- 758603
+ 757852return_type
- 356335
+ 355982
@@ -25961,7 +25949,7 @@
12
- 758603
+ 757852
@@ -25977,17 +25965,17 @@
12
- 294024
+ 29373223
- 44050
+ 4400634676
- 18261
+ 18243
@@ -25997,11 +25985,11 @@
routinetypeargs
- 1165836
+ 1166052routine
- 412059
+ 412136index
@@ -26009,7 +25997,7 @@
type_id
- 111081
+ 111101
@@ -26023,32 +26011,32 @@
12
- 82129
+ 8214423
- 125475
+ 12549834
- 106844
+ 10686445
- 48614
+ 4862457
- 32482
+ 32488719
- 16512
+ 16515
@@ -26064,27 +26052,27 @@
12
- 88104
+ 8812023
- 138023
+ 13804834
- 113525
+ 11354645
- 40141
+ 40148510
- 32156
+ 3216210
@@ -26282,47 +26270,47 @@
12
- 33188
+ 3319423
- 14991
+ 1499434
- 13199
+ 1320145
- 9831
+ 983356
- 6355
+ 635668
- 9505
+ 9507813
- 9451
+ 94531326
- 8745
+ 874626916
- 5812
+ 5813
@@ -26338,22 +26326,22 @@
12
- 78490
+ 7850423
- 17544
+ 1754835
- 9451
+ 9453517
- 5594
+ 5595
@@ -26363,15 +26351,15 @@
ptrtomembers
- 12029
+ 12026id
- 12029
+ 12026type_id
- 10114
+ 9890class_id
@@ -26389,7 +26377,7 @@
12
- 12029
+ 12026
@@ -26405,7 +26393,7 @@
12
- 12029
+ 12026
@@ -26421,12 +26409,12 @@
12
- 9831
+ 96132
- 74
- 283
+ 84
+ 276
@@ -26442,12 +26430,12 @@
12
- 9831
+ 96132
- 74
- 283
+ 84
+ 276
@@ -26463,22 +26451,22 @@
12
- 4854
+ 474723
- 539
+ 65989
- 512
+ 5011065
- 53
+ 52
@@ -26494,22 +26482,22 @@
12
- 4854
+ 474723
- 539
+ 65989
- 512
+ 5011065
- 53
+ 52
@@ -26519,15 +26507,15 @@
specifiers
- 7754
+ 7724id
- 7754
+ 7724str
- 7754
+ 7724
@@ -26541,7 +26529,7 @@
12
- 7754
+ 7724
@@ -26557,7 +26545,7 @@
12
- 7754
+ 7724
@@ -26567,15 +26555,15 @@
typespecifiers
- 985913
+ 969178type_id
- 979359
+ 962756spec_id
- 107
+ 118
@@ -26589,12 +26577,12 @@
12
- 972805
+ 95633323
- 6554
+ 6422
@@ -26612,19 +26600,24 @@
16513
+
+ 215
+ 216
+ 13
+ 22422513
- 529
- 530
+ 532
+ 53313
- 820
- 821
+ 821
+ 82213
@@ -26633,18 +26626,18 @@
13
- 4147
- 4148
+ 4150
+ 415113
- 17356
- 17357
+ 17496
+ 1749713
- 48300
- 48301
+ 48324
+ 4832513
@@ -26655,15 +26648,15 @@
funspecifiers
- 9699590
+ 9674560func_id
- 3974790
+ 3322023spec_id
- 2376
+ 811
@@ -26677,27 +26670,32 @@
12
- 1485356
+ 43545123
- 507167
+ 67355634
- 1039223
+ 141628445
- 697026
+ 4569415
+ 6
+ 223835
+
+
+ 68
- 246016
+ 115955
@@ -26711,99 +26709,94 @@
12
- 17
- 18
- 125
-
-
- 18
- 19
- 125
+ 2
+ 3
+ 85
- 53
- 54
- 125
+ 106
+ 107
+ 42
- 114
- 115
- 125
+ 214
+ 215
+ 42
- 206
- 207
- 125
+ 301
+ 302
+ 42
- 272
- 273
- 125
+ 308
+ 309
+ 42
- 354
- 355
- 125
+ 562
+ 563
+ 42
- 653
- 654
- 125
+ 1589
+ 1590
+ 42
- 766
- 767
- 125
+ 1631
+ 1632
+ 42
- 823
- 824
- 125
+ 3749
+ 3750
+ 42
- 1075
- 1076
- 125
+ 3881
+ 3882
+ 42
- 1258
- 1259
- 125
+ 6569
+ 6570
+ 42
- 1662
- 1663
- 125
+ 6803
+ 6804
+ 42
- 3340
- 3341
- 125
+ 12221
+ 12222
+ 42
- 3351
- 3352
- 125
+ 14693
+ 14694
+ 42
- 6166
- 6167
- 125
+ 15715
+ 15716
+ 42
- 15136
- 15137
- 125
+ 42406
+ 42407
+ 42
- 19863
- 19864
- 125
+ 51943
+ 51944
+ 42
- 22425
- 22426
- 125
+ 63744
+ 63745
+ 42
@@ -26813,15 +26806,15 @@
varspecifiers
- 2999353
+ 3064883var_id
- 2281064
+ 2308848spec_id
- 1125
+ 1121
@@ -26835,17 +26828,17 @@
12
- 1661582
+ 165522923
- 521175
+ 55170135
- 98306
+ 101917
@@ -26858,50 +26851,50 @@
12
-
- 67
- 68
- 125
- 9798
- 125
+ 124
+
+
+ 240
+ 241
+ 12410911092
- 125
+ 12413251326
- 125
+ 12422362237
- 125
+ 124
- 2557
- 2558
- 125
+ 2761
+ 2762
+ 124
- 3227
- 3228
- 125
+ 3436
+ 3437
+ 12449314932
- 125
+ 124
- 8450
- 8451
- 125
+ 8482
+ 8483
+ 124
@@ -26911,15 +26904,15 @@
explicit_specifier_exprs
- 41398
+ 41240func_id
- 41398
+ 41240constant
- 41398
+ 41240
@@ -26933,7 +26926,7 @@
12
- 41398
+ 41240
@@ -26949,7 +26942,7 @@
12
- 41398
+ 41240
@@ -26959,27 +26952,27 @@
attributes
- 651875
+ 649383id
- 651875
+ 649383kind
- 375
+ 373name
- 2126
+ 2118name_space
- 250
+ 249location
- 645747
+ 643277
@@ -26993,7 +26986,7 @@
12
- 651875
+ 649383
@@ -27009,7 +27002,7 @@
12
- 651875
+ 649383
@@ -27025,7 +27018,7 @@
12
- 651875
+ 649383
@@ -27041,7 +27034,7 @@
12
- 651875
+ 649383
@@ -27057,17 +27050,17 @@
78
- 125
+ 12424022403
- 125
+ 12428032804
- 125
+ 124
@@ -27083,17 +27076,17 @@
12
- 125
+ 12467
- 125
+ 1241213
- 125
+ 124
@@ -27109,12 +27102,12 @@
12
- 250
+ 24923
- 125
+ 124
@@ -27130,17 +27123,17 @@
45
- 125
+ 12423562357
- 125
+ 12428032804
- 125
+ 124
@@ -27156,77 +27149,77 @@
12
- 250
+ 24934
- 125
+ 12467
- 125
+ 12478
- 125
+ 12489
- 125
+ 1241011
- 250
+ 2491415
- 125
+ 1241819
- 125
+ 1242425
- 125
+ 1245556
- 125
+ 1246263
- 125
+ 1247273
- 125
+ 124340341
- 125
+ 12419771978
- 125
+ 12426042605
- 125
+ 124
@@ -27242,12 +27235,12 @@
12
- 1876
+ 186823
- 250
+ 249
@@ -27263,7 +27256,7 @@
12
- 2126
+ 2118
@@ -27279,77 +27272,77 @@
12
- 250
+ 24934
- 125
+ 12445
- 125
+ 12467
- 125
+ 12489
- 125
+ 1241011
- 250
+ 2491415
- 125
+ 1241819
- 125
+ 1242425
- 125
+ 1245556
- 125
+ 1246263
- 125
+ 1247273
- 125
+ 124335336
- 125
+ 12419771978
- 125
+ 12426042605
- 125
+ 124
@@ -27365,12 +27358,12 @@
1112
- 125
+ 12452015202
- 125
+ 124
@@ -27386,12 +27379,12 @@
12
- 125
+ 12434
- 125
+ 124
@@ -27407,12 +27400,12 @@
23
- 125
+ 1241516
- 125
+ 124
@@ -27428,12 +27421,12 @@
1112
- 125
+ 12451525153
- 125
+ 124
@@ -27449,12 +27442,12 @@
12
- 639868
+ 63742225
- 5878
+ 5855
@@ -27470,7 +27463,7 @@
12
- 645747
+ 643277
@@ -27486,12 +27479,12 @@
12
- 640619
+ 63816923
- 5127
+ 5108
@@ -27507,7 +27500,7 @@
12
- 645747
+ 643277
@@ -27517,27 +27510,27 @@
attribute_args
- 98337
+ 96187id
- 98337
+ 96187kind
- 53
+ 52attribute
- 84946
+ 83066index
- 67
+ 65location
- 91527
+ 89501
@@ -27551,7 +27544,7 @@
12
- 98337
+ 96187
@@ -27567,7 +27560,7 @@
12
- 98337
+ 96187
@@ -27583,7 +27576,7 @@
12
- 98337
+ 96187
@@ -27599,7 +27592,7 @@
12
- 98337
+ 96187
@@ -27628,8 +27621,8 @@
13
- 6589
- 6590
+ 6591
+ 659213
@@ -27734,17 +27727,17 @@
12
- 77165
+ 7543024
- 6432
+ 6316418
- 1348
+ 1318
@@ -27760,12 +27753,12 @@
12
- 82653
+ 8082423
- 2292
+ 2241
@@ -27781,12 +27774,12 @@
12
- 78689
+ 7694726
- 6257
+ 6118
@@ -27802,12 +27795,12 @@
12
- 80293
+ 7851626
- 4652
+ 4549
@@ -27841,8 +27834,8 @@
13
- 6472
- 6473
+ 6474
+ 647513
@@ -27864,7 +27857,7 @@
23
- 40
+ 394
@@ -27957,12 +27950,12 @@
12
- 89261
+ 87259223
- 2265
+ 2241
@@ -27978,12 +27971,12 @@
12
- 91311
+ 8929023
- 215
+ 210
@@ -27999,12 +27992,12 @@
12
- 91122
+ 89105218
- 404
+ 395
@@ -28020,12 +28013,12 @@
12
- 90974
+ 8896023
- 552
+ 540
@@ -28035,15 +28028,15 @@
attribute_arg_value
- 20955
+ 20935arg
- 20955
+ 20935value
- 641
+ 640
@@ -28057,7 +28050,7 @@
12
- 20955
+ 20935
@@ -28128,15 +28121,15 @@
attribute_arg_type
- 466
+ 461arg
- 466
+ 461type_id
- 85
+ 84
@@ -28150,7 +28143,7 @@
12
- 466
+ 461
@@ -28191,15 +28184,15 @@
attribute_arg_constant
- 88857
+ 86916arg
- 88857
+ 86916constant
- 88857
+ 86916
@@ -28213,7 +28206,7 @@
12
- 88857
+ 86916
@@ -28229,7 +28222,7 @@
12
- 88857
+ 86916
@@ -28239,15 +28232,15 @@
attribute_arg_expr
- 1793
+ 1753arg
- 1793
+ 1753expr
- 1793
+ 1753
@@ -28261,7 +28254,7 @@
12
- 1793
+ 1753
@@ -28277,7 +28270,7 @@
12
- 1793
+ 1753
@@ -28340,15 +28333,15 @@
typeattributes
- 92303
+ 91950type_id
- 90677
+ 90330spec_id
- 29266
+ 29154
@@ -28362,12 +28355,12 @@
12
- 89051
+ 8871023
- 1625
+ 1619
@@ -28383,17 +28376,17 @@
12
- 24764
+ 2466927
- 2251
+ 2242758
- 2251
+ 2242
@@ -28403,15 +28396,15 @@
funcattributes
- 845862
+ 842628func_id
- 800961
+ 797898spec_id
- 617856
+ 615493
@@ -28425,12 +28418,12 @@
12
- 760563
+ 75765527
- 40398
+ 40243
@@ -28446,12 +28439,12 @@
12
- 572079
+ 5698922213
- 45776
+ 45601
@@ -28592,15 +28585,15 @@
unspecifiedtype
- 8313750
+ 8145638type_id
- 8313750
+ 8145638unspecified_type_id
- 4783555
+ 4690387
@@ -28614,7 +28607,7 @@
12
- 8313750
+ 8145638
@@ -28630,17 +28623,17 @@
12
- 3189801
+ 313093823
- 1303717
+ 127556836277
- 290037
+ 283880
@@ -28650,19 +28643,19 @@
member
- 4663372
+ 4659651parent
- 558581
+ 559011index
- 10691
+ 10681child
- 4546703
+ 4543098
@@ -28676,52 +28669,52 @@
12
- 232140
+ 23289223
- 24548
+ 2452434
- 29295
+ 2926645
- 37592
+ 3755557
- 47642
+ 47595711
- 43152
+ 431091114
- 41569
+ 415281419
- 45162
+ 451171953
- 42125
+ 4208353251
- 15353
+ 15338
@@ -28737,52 +28730,52 @@
12
- 232011
+ 23276423
- 24676
+ 2465234
- 29338
+ 2930945
- 37677
+ 3764057
- 47428
+ 47381711
- 43579
+ 435361114
- 41484
+ 414431419
- 44948
+ 449031953
- 42125
+ 4208353255
- 15310
+ 15295
@@ -28798,57 +28791,57 @@
12
- 2822
+ 281924
- 812
+ 811422
- 812
+ 8112231
- 812
+ 8113153
- 855
+ 85453108
- 812
+ 811110218
- 812
+ 811223328
- 812
+ 811328581
- 812
+ 8116532518
- 812
+ 8112899
- 12712
- 513
+ 12735
+ 512
@@ -28864,61 +28857,61 @@
12
- 1753
+ 175123
- 1368
+ 136738
- 812
+ 811831
- 855
+ 8543141
- 855
+ 8544197
- 812
+ 81197161
- 812
+ 811164314
- 855
+ 854318386
- 812
+ 8114351127
- 812
+ 81111456168
- 812
+ 8116496
- 12724
+ 12747128
@@ -28935,7 +28928,7 @@
12
- 4546703
+ 4543098
@@ -28951,12 +28944,12 @@
12
- 4459244
+ 4455726213
- 87458
+ 87372
@@ -28966,15 +28959,15 @@
enclosingfunction
- 144125
+ 143982child
- 144125
+ 143982parent
- 89554
+ 89465
@@ -28988,7 +28981,7 @@
12
- 144125
+ 143982
@@ -29004,22 +28997,22 @@
12
- 61926
+ 6186523
- 5816
+ 581034
- 19287
+ 19268437
- 2523
+ 2520
@@ -29029,15 +29022,15 @@
derivations
- 597157
+ 598061derivation
- 597157
+ 598061sub
- 569872
+ 570803index
@@ -29045,11 +29038,11 @@
super
- 294708
+ 295399location
- 44435
+ 44391
@@ -29063,7 +29056,7 @@
12
- 597157
+ 598061
@@ -29079,7 +29072,7 @@
12
- 597157
+ 598061
@@ -29095,7 +29088,7 @@
12
- 597157
+ 598061
@@ -29111,7 +29104,7 @@
12
- 597157
+ 598061
@@ -29127,12 +29120,12 @@
12
- 549130
+ 55008129
- 20742
+ 20721
@@ -29148,12 +29141,12 @@
12
- 549130
+ 55008128
- 20742
+ 20721
@@ -29169,12 +29162,12 @@
12
- 549130
+ 55008129
- 20742
+ 20721
@@ -29190,12 +29183,12 @@
12
- 549130
+ 55008128
- 20742
+ 20721
@@ -29229,8 +29222,8 @@
42
- 13325
- 13326
+ 13360
+ 1336142
@@ -29247,7 +29240,7 @@
2526
- 171
+ 17052
@@ -29260,8 +29253,8 @@
42
- 13325
- 13326
+ 13360
+ 1336142
@@ -29301,8 +29294,8 @@
42
- 6487
- 6488
+ 6510
+ 651142
@@ -29319,7 +29312,7 @@
12
- 171
+ 1707
@@ -29350,12 +29343,12 @@
12
- 282648
+ 28309421655
- 12060
+ 12304
@@ -29371,12 +29364,12 @@
12
- 282648
+ 28309421655
- 12060
+ 12304
@@ -29392,7 +29385,7 @@
12
- 294152
+ 2948432
@@ -29413,12 +29406,12 @@
12
- 288207
+ 288691281
- 6500
+ 6707
@@ -29434,22 +29427,22 @@
12
- 33358
+ 3323925
- 3977
+ 3930522
- 3378
+ 3460
- 23
+ 22383
- 3335
+ 3375388
@@ -29470,22 +29463,22 @@
12
- 33358
+ 3323925
- 3977
+ 3930522
- 3378
+ 3460
- 23
+ 22383
- 3335
+ 3375388
@@ -29506,7 +29499,7 @@
12
- 44435
+ 44391
@@ -29522,22 +29515,22 @@
12
- 36138
+ 3601724
- 3293
+ 3289426
- 3464
+ 354626928
- 1539
+ 1538
@@ -29547,15 +29540,15 @@
derspecifiers
- 599381
+ 600283der_id
- 596601
+ 597506spec_id
- 171
+ 170
@@ -29569,12 +29562,12 @@
12
- 593821
+ 59472923
- 2779
+ 2777
@@ -29603,8 +29596,8 @@
42
- 12754
- 12755
+ 12789
+ 1279042
@@ -29615,15 +29608,15 @@
direct_base_offsets
- 563371
+ 564309der_id
- 563371
+ 564309offset
- 641
+ 640
@@ -29637,7 +29630,7 @@
12
- 563371
+ 564309
@@ -29658,7 +29651,7 @@
23
- 171
+ 1703
@@ -29686,8 +29679,8 @@
42
- 13023
- 13024
+ 13058
+ 1305942
@@ -29698,11 +29691,11 @@
virtual_base_offsets
- 7313
+ 7305sub
- 7313
+ 7305super
@@ -29724,7 +29717,7 @@
12
- 7313
+ 7305
@@ -29740,7 +29733,7 @@
12
- 7313
+ 7305
@@ -29834,23 +29827,23 @@
frienddecls
- 879292
+ 878379id
- 879292
+ 878379type_id
- 53245
+ 53192decl_id
- 97594
+ 97626location
- 7655
+ 7647
@@ -29864,7 +29857,7 @@
12
- 879292
+ 878379
@@ -29880,7 +29873,7 @@
12
- 879292
+ 878379
@@ -29896,7 +29889,7 @@
12
- 879292
+ 878379
@@ -29912,47 +29905,47 @@
12
- 7740
+ 777523
- 17534
+ 1747437
- 4490
+ 4486712
- 4319
+ 43151220
- 4576
+ 45712032
- 4148
+ 41443350
- 4747
+ 47425080
- 4747
+ 4742101120
- 940
+ 939
@@ -29968,47 +29961,47 @@
12
- 7740
+ 777523
- 17534
+ 1747437
- 4490
+ 4486712
- 4319
+ 43151220
- 4576
+ 45712032
- 4148
+ 41443350
- 4747
+ 47425080
- 4747
+ 4742101120
- 940
+ 939
@@ -30024,12 +30017,12 @@
12
- 51534
+ 51483213
- 1710
+ 1708
@@ -30045,32 +30038,32 @@
12
- 60087
+ 6032723
- 7612
+ 743438
- 7527
+ 7519815
- 7612
+ 76051540
- 7612
+ 760540164
- 7142
+ 7135
@@ -30086,32 +30079,32 @@
12
- 60087
+ 6032723
- 7612
+ 743438
- 7527
+ 7519815
- 7612
+ 76051540
- 7612
+ 760540164
- 7142
+ 7135
@@ -30127,12 +30120,12 @@
12
- 96739
+ 9677125
- 855
+ 854
@@ -30148,12 +30141,12 @@
12
- 7184
+ 71772
- 20371
- 470
+ 20370
+ 469
@@ -30169,12 +30162,12 @@
12
- 7484
+ 747621148
- 171
+ 170
@@ -30190,11 +30183,11 @@
12
- 7227
+ 72202
- 2129
+ 2132427
@@ -30205,19 +30198,19 @@
comments
- 11233849
+ 11190894id
- 11233849
+ 11190894contents
- 4296351
+ 4279922location
- 11233849
+ 11190894
@@ -30231,7 +30224,7 @@
12
- 11233849
+ 11190894
@@ -30247,7 +30240,7 @@
12
- 11233849
+ 11190894
@@ -30263,17 +30256,17 @@
12
- 3921885
+ 390688926
- 322310
+ 321078634359
- 52155
+ 51955
@@ -30289,17 +30282,17 @@
12
- 3921885
+ 390688926
- 322310
+ 321078634359
- 52155
+ 51955
@@ -30315,7 +30308,7 @@
12
- 11233849
+ 11190894
@@ -30331,7 +30324,7 @@
12
- 11233849
+ 11190894
@@ -30341,15 +30334,15 @@
commentbinding
- 3842839
+ 3828145id
- 3355433
+ 3342603element
- 3676619
+ 3662560
@@ -30363,12 +30356,12 @@
12
- 3299151
+ 328653621706
- 56282
+ 56067
@@ -30384,12 +30377,12 @@
12
- 3510398
+ 349697523
- 166220
+ 165585
@@ -30399,15 +30392,15 @@
exprconv
- 9606161
+ 9607946converted
- 9606056
+ 9607841conversion
- 9606161
+ 9607946
@@ -30421,7 +30414,7 @@
12
- 9605951
+ 96077362
@@ -30442,7 +30435,7 @@
12
- 9606161
+ 9607946
@@ -30452,22 +30445,22 @@
compgenerated
- 10707572
+ 10701538id
- 10707572
+ 10701538synthetic_destructor_call
- 1789036
+ 1788903element
- 1332347
+ 1332248i
@@ -30475,7 +30468,7 @@
destructor_call
- 1789036
+ 1788903
@@ -30489,17 +30482,17 @@
12
- 886850
+ 88678423
- 438221
+ 438188319
- 7276
+ 7275
@@ -30515,17 +30508,17 @@
12
- 886850
+ 88678423
- 438221
+ 438188319
- 7276
+ 7275
@@ -30673,7 +30666,7 @@
12
- 1789036
+ 1788903
@@ -30689,7 +30682,7 @@
12
- 1789036
+ 1788903
@@ -30699,15 +30692,15 @@
namespaces
- 11044
+ 10800id
- 11044
+ 10800name
- 5839
+ 5710
@@ -30721,7 +30714,7 @@
12
- 11044
+ 10800
@@ -30737,17 +30730,17 @@
12
- 4773
+ 466823
- 674
+ 6593149
- 391
+ 382
@@ -30757,26 +30750,26 @@
namespace_inline
- 500
+ 498id
- 500
+ 498namespacembrs
- 2018038
+ 2036610parentid
- 4002
+ 3987memberid
- 2018038
+ 2036610
@@ -30790,67 +30783,67 @@
12
- 500
+ 49823
- 250
+ 24934
- 500
+ 49845
- 625
+ 622510
- 250
+ 2491012
- 250
+ 2491218
- 250
+ 2491921
- 250
+ 2492324
- 250
+ 2492529
- 250
+ 2497083
- 250
+ 249165170
- 250
+ 249
- 15407
- 15408
- 125
+ 15618
+ 15619
+ 124
@@ -30866,7 +30859,7 @@
12
- 2018038
+ 2036610
@@ -30876,19 +30869,19 @@
exprparents
- 19398686
+ 19402291expr_id
- 19398686
+ 19402291child_index
- 19977
+ 19981parent_id
- 12903052
+ 12905450
@@ -30902,7 +30895,7 @@
12
- 19398686
+ 19402291
@@ -30918,7 +30911,7 @@
12
- 19398686
+ 19402291
@@ -30949,7 +30942,7 @@
45
- 8950
+ 89525
@@ -31000,7 +30993,7 @@
45
- 8950
+ 89525
@@ -31036,17 +31029,17 @@
12
- 7373649
+ 737502023
- 5068172
+ 50691143712
- 461230
+ 461315
@@ -31062,17 +31055,17 @@
12
- 7373649
+ 737502023
- 5068172
+ 50691143712
- 461230
+ 461315
@@ -31082,22 +31075,22 @@
expr_isload
- 6822557
+ 6834844expr_id
- 6822557
+ 6834844conversionkinds
- 6049042
+ 6050435expr_id
- 6049042
+ 6050435kind
@@ -31115,7 +31108,7 @@
12
- 6049042
+ 6050435
@@ -31154,13 +31147,13 @@
1
- 93175
- 93176
+ 93247
+ 932481
- 5830215
- 5830216
+ 5831536
+ 58315371
@@ -31171,11 +31164,11 @@
iscall
- 6210093
+ 6209631caller
- 6210093
+ 6209631kind
@@ -31193,7 +31186,7 @@
12
- 6210093
+ 6209631
@@ -31229,11 +31222,11 @@
numtemplatearguments
- 720113
+ 719400expr_id
- 720113
+ 719400num
@@ -31251,7 +31244,7 @@
12
- 720113
+ 719400
@@ -31312,15 +31305,15 @@
specialnamequalifyingelements
- 125
+ 124id
- 125
+ 124name
- 125
+ 124
@@ -31334,7 +31327,7 @@
12
- 125
+ 124
@@ -31350,7 +31343,7 @@
12
- 125
+ 124
@@ -31360,23 +31353,23 @@
namequalifiers
- 3254040
+ 3255226id
- 3254040
+ 3255226qualifiableelement
- 3254040
+ 3255226qualifyingelement
- 50221
+ 50816location
- 590842
+ 591189
@@ -31390,7 +31383,7 @@
12
- 3254040
+ 3255226
@@ -31406,7 +31399,7 @@
12
- 3254040
+ 3255226
@@ -31422,7 +31415,7 @@
12
- 3254040
+ 3255226
@@ -31438,7 +31431,7 @@
12
- 3254040
+ 3255226
@@ -31454,7 +31447,7 @@
12
- 3254040
+ 3255226
@@ -31470,7 +31463,7 @@
12
- 3254040
+ 3255226
@@ -31486,27 +31479,27 @@
12
- 33757
+ 3375423
- 8220
+ 874935
- 4352
+ 43975
- 1601
- 3776
+ 6810
+ 3822
- 6806
+ 1901841956
- 115
+ 92
@@ -31522,27 +31515,27 @@
12
- 33757
+ 3375423
- 8220
+ 874935
- 4352
+ 43975
- 1601
- 3776
+ 6810
+ 3822
- 6806
+ 1901841956
- 115
+ 92
@@ -31558,17 +31551,17 @@
12
- 36474
+ 3681623
- 7644
+ 787436
- 3799
+ 38226
@@ -31589,22 +31582,22 @@
12
- 84761
+ 8470826
- 40365
+ 4075467
- 427076
+ 4269757192
- 38638
+ 38751
@@ -31620,22 +31613,22 @@
12
- 84761
+ 8470826
- 40365
+ 4075467
- 427076
+ 4269757192
- 38638
+ 38751
@@ -31651,22 +31644,22 @@
12
- 119071
+ 11936124
- 14184
+ 1422945
- 444530
+ 444428533
- 13056
+ 13170
@@ -31676,15 +31669,15 @@
varbind
- 8231069
+ 8232599expr
- 8231069
+ 8232599var
- 1047377
+ 1047572
@@ -31698,7 +31691,7 @@
12
- 8231069
+ 8232599
@@ -31714,52 +31707,52 @@
12
- 171046
+ 17107823
- 188162
+ 18819734
- 145232
+ 14525945
- 116303
+ 11632556
- 82913
+ 8292967
- 65629
+ 6564179
- 80584
+ 80599913
- 81342
+ 813571327
- 78901
+ 78915275137
- 37262
+ 37268
@@ -31769,15 +31762,15 @@
funbind
- 6220501
+ 6220039expr
- 6217853
+ 6217391fun
- 295317
+ 295295
@@ -31791,12 +31784,12 @@
12
- 6215204
+ 621474323
- 2648
+ 2647
@@ -31812,27 +31805,27 @@
12
- 194184
+ 19416923
- 41563
+ 4156034
- 18398
+ 1839648
- 24339
+ 24337837798
- 16832
+ 16831
@@ -31842,11 +31835,11 @@
expr_allocator
- 56794
+ 56738expr
- 56794
+ 56738func
@@ -31868,7 +31861,7 @@
12
- 56794
+ 56738
@@ -31884,7 +31877,7 @@
12
- 56794
+ 56738
@@ -31968,11 +31961,11 @@
expr_deallocator
- 67572
+ 67505expr
- 67572
+ 67505func
@@ -31994,7 +31987,7 @@
12
- 67572
+ 67505
@@ -32010,7 +32003,7 @@
12
- 67572
+ 67505
@@ -32115,15 +32108,15 @@
expr_cond_guard
- 895370
+ 895536cond
- 895370
+ 895536guard
- 895370
+ 895536
@@ -32137,7 +32130,7 @@
12
- 895370
+ 895536
@@ -32153,7 +32146,7 @@
12
- 895370
+ 895536
@@ -32163,15 +32156,15 @@
expr_cond_true
- 895366
+ 895533cond
- 895366
+ 895533true
- 895366
+ 895533
@@ -32185,7 +32178,7 @@
12
- 895366
+ 895533
@@ -32201,7 +32194,7 @@
12
- 895366
+ 895533
@@ -32211,15 +32204,15 @@
expr_cond_false
- 895370
+ 895536cond
- 895370
+ 895536false
- 895370
+ 895536
@@ -32233,7 +32226,7 @@
12
- 895370
+ 895536
@@ -32249,7 +32242,7 @@
12
- 895370
+ 895536
@@ -32259,15 +32252,15 @@
values
- 13436143
+ 13438640id
- 13436143
+ 13438640str
- 114239
+ 114260
@@ -32281,7 +32274,7 @@
12
- 13436143
+ 13438640
@@ -32297,27 +32290,27 @@
12
- 78079
+ 7809323
- 15258
+ 1526036
- 8869
+ 8871652
- 8604
+ 860552674264
- 3427
+ 3428
@@ -32327,15 +32320,15 @@
valuetext
- 6643521
+ 6647587id
- 6643521
+ 6647587text
- 1095396
+ 1095411
@@ -32349,7 +32342,7 @@
12
- 6643521
+ 6647587
@@ -32365,22 +32358,22 @@
12
- 833981
+ 83398523
- 146939
+ 14694037
- 86534
+ 865367
- 593537
- 27942
+ 593553
+ 27950
@@ -32390,15 +32383,15 @@
valuebind
- 13544416
+ 13546933val
- 13436143
+ 13438640expr
- 13544416
+ 13546933
@@ -32412,12 +32405,12 @@
12
- 13345847
+ 1334832726
- 90296
+ 90313
@@ -32433,7 +32426,7 @@
12
- 13544416
+ 13546933
@@ -32443,15 +32436,15 @@
fieldoffsets
- 1489139
+ 1489415id
- 1489139
+ 1489415byteoffset
- 31287
+ 31293bitoffset
@@ -32469,7 +32462,7 @@
12
- 1489139
+ 1489415
@@ -32485,7 +32478,7 @@
12
- 1489139
+ 1489415
@@ -32501,7 +32494,7 @@
12
- 17653
+ 176562
@@ -32511,7 +32504,7 @@
35
- 2661
+ 26625
@@ -32547,7 +32540,7 @@
12
- 30309
+ 303152
@@ -32644,19 +32637,19 @@
bitfield
- 30392
+ 30276id
- 30392
+ 30276bits
- 3502
+ 3488declared_bits
- 3502
+ 3488
@@ -32670,7 +32663,7 @@
12
- 30392
+ 30276
@@ -32686,7 +32679,7 @@
12
- 30392
+ 30276
@@ -32702,42 +32695,42 @@
12
- 1000
+ 99623
- 750
+ 74734
- 250
+ 24945
- 500
+ 49857
- 250
+ 24989
- 250
+ 249911
- 250
+ 24913143
- 250
+ 249
@@ -32753,7 +32746,7 @@
12
- 3502
+ 3488
@@ -32769,42 +32762,42 @@
12
- 1000
+ 99623
- 750
+ 74734
- 250
+ 24945
- 500
+ 49857
- 250
+ 24989
- 250
+ 249911
- 250
+ 24913143
- 250
+ 249
@@ -32820,7 +32813,7 @@
12
- 3502
+ 3488
@@ -32830,23 +32823,23 @@
initialisers
- 2338659
+ 2334426init
- 2338659
+ 2334426var
- 989337
+ 988525expr
- 2338659
+ 2334426location
- 539154
+ 537813
@@ -32860,7 +32853,7 @@
12
- 2338659
+ 2334426
@@ -32876,7 +32869,7 @@
12
- 2338659
+ 2334426
@@ -32892,7 +32885,7 @@
12
- 2338659
+ 2334426
@@ -32908,17 +32901,17 @@
12
- 872291
+ 871776215
- 39495
+ 393951625
- 77549
+ 77353
@@ -32934,17 +32927,17 @@
12
- 872291
+ 871776215
- 39495
+ 393951625
- 77549
+ 77353
@@ -32960,7 +32953,7 @@
12
- 989328
+ 9885162
@@ -32981,7 +32974,7 @@
12
- 2338659
+ 2334426
@@ -32997,7 +32990,7 @@
12
- 2338659
+ 2334426
@@ -33013,7 +33006,7 @@
12
- 2338659
+ 2334426
@@ -33029,22 +33022,22 @@
12
- 439236
+ 43812223
- 33072
+ 32980315
- 42172
+ 4209915111796
- 24672
+ 24610
@@ -33060,17 +33053,17 @@
12
- 470366
+ 46917424
- 49613
+ 49479412163
- 19173
+ 19159
@@ -33086,22 +33079,22 @@
12
- 439236
+ 43812223
- 33072
+ 32980315
- 42172
+ 4209915111796
- 24672
+ 24610
@@ -33111,26 +33104,26 @@
braced_initialisers
- 74182
+ 74076init
- 74182
+ 74076expr_ancestor
- 1795437
+ 1795304exp
- 1795437
+ 1795304ancestor
- 898593
+ 898527
@@ -33144,7 +33137,7 @@
12
- 1795437
+ 1795304
@@ -33160,17 +33153,17 @@
12
- 18283
+ 1828123
- 869534
+ 869469319
- 10776
+ 10775
@@ -33180,19 +33173,19 @@
exprs
- 25138614
+ 25143286id
- 25138614
+ 25143286kind
- 1456
+ 1446location
- 5896962
+ 10554424
@@ -33206,7 +33199,7 @@
12
- 25138614
+ 25143286
@@ -33222,7 +33215,7 @@
12
- 25138614
+ 25143286
@@ -33237,63 +33230,73 @@
1
- 13
- 121
+ 10
+ 109
- 13
- 46
- 121
+ 12
+ 18
+ 109
- 53
- 76
- 121
+ 26
+ 100
+ 109
- 79
- 245
- 121
+ 105
+ 305
+ 109
- 302
- 524
- 121
+ 323
+ 467
+ 109
- 530
- 969
- 121
+ 607
+ 893
+ 109
- 1043
- 2109
- 121
+ 906
+ 1658
+ 109
+
+
+ 1781
+ 2386
+ 109
+
+
+ 3390
+ 4336
+ 109
- 2204
- 3636
- 121
+ 4809
+ 5185
+ 109
- 4328
- 7013
- 121
+ 5187
+ 22128
+ 109
- 7403
- 8498
- 121
+ 26432
+ 50205
+ 109
- 9709
- 32322
- 121
+ 63936
+ 144106
+ 109
- 33490
- 447645
- 121
+ 313148
+ 313149
+ 21
@@ -33308,68 +33311,73 @@
1
- 3
- 107
+ 9
+ 109
- 4
+ 915
- 121
+ 10917
- 26
- 121
+ 96
+ 109
- 28
- 40
- 121
+ 99
+ 222
+ 109
- 47
- 105
- 121
+ 260
+ 383
+ 109
- 133
- 276
- 121
+ 408
+ 594
+ 109
- 305
- 552
- 121
+ 599
+ 749
+ 109
- 620
- 1425
- 121
+ 864
+ 1774
+ 109
- 1437
- 1711
- 121
+ 1812
+ 2545
+ 109
- 1929
- 3215
- 121
+ 2623
+ 2919
+ 109
- 3232
- 8454
- 121
+ 3419
+ 4913
+ 109
- 11521
- 87503
- 121
+ 5473
+ 21165
+ 109
- 155156
- 155157
- 13
+ 26254
+ 76840
+ 109
+
+
+ 224080
+ 224081
+ 21
@@ -33385,32 +33393,22 @@
12
- 2750855
+ 887694423
- 1390969
+ 8184183
- 4
- 522854
-
-
- 4
- 6
- 539333
-
-
- 6
- 13
- 455210
+ 16
+ 795071
- 13
- 144777
- 237739
+ 16
+ 71733
+ 63990
@@ -33426,17 +33424,17 @@
12
- 4271139
+ 901597423
- 1230098
+ 7722063
- 30
- 395724
+ 32
+ 766243
@@ -33446,15 +33444,15 @@
expr_reuse
- 906491
+ 906424reuse
- 906491
+ 906424original
- 906491
+ 906424value_category
@@ -33472,7 +33470,7 @@
12
- 906491
+ 906424
@@ -33488,7 +33486,7 @@
12
- 906491
+ 906424
@@ -33504,7 +33502,7 @@
12
- 906491
+ 906424
@@ -33520,7 +33518,7 @@
12
- 906491
+ 906424
@@ -33572,19 +33570,19 @@
expr_types
- 25138614
+ 25143286id
- 25138614
+ 25143286typeid
- 120596
+ 213631value_category
- 56
+ 43
@@ -33598,7 +33596,7 @@
12
- 25138614
+ 25143286
@@ -33614,7 +33612,7 @@
12
- 25138614
+ 25143286
@@ -33630,57 +33628,52 @@
12
- 17845
+ 5237123
- 19220
+ 3509734
- 10269
+ 1446845
- 8080
+ 144905
- 7
- 10690
-
-
- 7
- 11
- 11111
+ 8
+ 17515
- 11
- 18
- 10157
+ 8
+ 14
+ 17340
- 18
- 33
- 9483
+ 14
+ 24
+ 16397
- 33
- 70
- 9119
+ 24
+ 49
+ 16025
- 70
- 233
- 9062
+ 49
+ 134
+ 16134
- 233
- 379496
- 5555
+ 134
+ 441505
+ 13789
@@ -33696,12 +33689,12 @@
12
- 100590
+ 18541723
- 20005
+ 28213
@@ -33715,14 +33708,14 @@
12
- 118902
- 118903
- 28
+ 153745
+ 153746
+ 21
- 777025
- 777026
- 28
+ 993192
+ 993193
+ 21
@@ -33736,14 +33729,14 @@
12
- 1298
- 1299
- 28
+ 2282
+ 2283
+ 21
- 3713
- 3714
- 28
+ 8750
+ 8751
+ 21
@@ -33764,15 +33757,15 @@
new_allocated_type
- 57992
+ 57934expr
- 57992
+ 57934type_id
- 34384
+ 34350
@@ -33786,7 +33779,7 @@
12
- 57992
+ 57934
@@ -33802,17 +33795,17 @@
12
- 14455
+ 1444023
- 18176
+ 18158319
- 1753
+ 1751
@@ -33822,15 +33815,15 @@
new_array_allocated_type
- 6932
+ 6914expr
- 6932
+ 6914type_id
- 2978
+ 2970
@@ -33844,7 +33837,7 @@
12
- 6932
+ 6914
@@ -33865,12 +33858,12 @@
23
- 2633
+ 262635
- 224
+ 2236
@@ -35221,15 +35214,15 @@
condition_decl_bind
- 437622
+ 437589expr
- 437622
+ 437589decl
- 437622
+ 437589
@@ -35243,7 +35236,7 @@
12
- 437622
+ 437589
@@ -35259,7 +35252,7 @@
12
- 437622
+ 437589
@@ -35269,15 +35262,15 @@
typeid_bind
- 60130
+ 60071expr
- 60130
+ 60071type_id
- 20015
+ 19995
@@ -35291,7 +35284,7 @@
12
- 60130
+ 60071
@@ -35307,17 +35300,17 @@
12
- 3720
+ 371723
- 15781
+ 157653328
- 513
+ 512
@@ -35327,15 +35320,15 @@
uuidof_bind
- 28057
+ 27985expr
- 28057
+ 27985type_id
- 27789
+ 27719
@@ -35349,7 +35342,7 @@
12
- 28057
+ 27985
@@ -35365,12 +35358,12 @@
12
- 27565
+ 2749524
- 224
+ 223
@@ -35380,15 +35373,15 @@
sizeof_bind
- 241336
+ 241381expr
- 241336
+ 241381type_id
- 11178
+ 11180
@@ -35402,7 +35395,7 @@
12
- 241336
+ 241381
@@ -35418,12 +35411,12 @@
12
- 3866
+ 386723
- 2775
+ 27763
@@ -35433,7 +35426,7 @@
45
- 1136
+ 11375
@@ -35443,7 +35436,7 @@
67
- 1061
+ 10627
@@ -35511,11 +35504,11 @@
lambdas
- 17748
+ 17730expr
- 17748
+ 17730default_capture
@@ -35525,6 +35518,10 @@
has_explicit_return_type85
+
+ has_explicit_parameter_list
+ 85
+
@@ -35537,7 +35534,7 @@
12
- 17748
+ 17730
@@ -35553,7 +35550,23 @@
12
- 17748
+ 17730
+
+
+
+
+
+
+ expr
+ has_explicit_parameter_list
+
+
+ 12
+
+
+ 1
+ 2
+ 17730
@@ -35606,6 +35619,27 @@
+
+ default_capture
+ has_explicit_parameter_list
+
+
+ 12
+
+
+ 1
+ 2
+ 42
+
+
+ 2
+ 3
+ 85
+
+
+
+
+ has_explicit_return_typeexpr
@@ -35648,19 +35682,103 @@
+
+ has_explicit_return_type
+ has_explicit_parameter_list
+
+
+ 12
+
+
+ 1
+ 2
+ 42
+
+
+ 2
+ 3
+ 42
+
+
+
+
+
+
+ has_explicit_parameter_list
+ expr
+
+
+ 12
+
+
+ 45
+ 46
+ 42
+
+
+ 370
+ 371
+ 42
+
+
+
+
+
+
+ has_explicit_parameter_list
+ default_capture
+
+
+ 12
+
+
+ 2
+ 3
+ 42
+
+
+ 3
+ 4
+ 42
+
+
+
+
+
+
+ has_explicit_parameter_list
+ has_explicit_return_type
+
+
+ 12
+
+
+ 1
+ 2
+ 42
+
+
+ 2
+ 3
+ 42
+
+
+
+
+ lambda_capture
- 28523
+ 28450id
- 28523
+ 28450lambda
- 13294
+ 13261index
@@ -35668,7 +35786,7 @@
field
- 28523
+ 28450captured_by_reference
@@ -35680,7 +35798,7 @@
location
- 18396
+ 18350
@@ -35694,7 +35812,7 @@
12
- 28523
+ 28450
@@ -35710,7 +35828,7 @@
12
- 28523
+ 28450
@@ -35726,7 +35844,7 @@
12
- 28523
+ 28450
@@ -35742,7 +35860,7 @@
12
- 28523
+ 28450
@@ -35758,7 +35876,7 @@
12
- 28523
+ 28450
@@ -35774,7 +35892,7 @@
12
- 28523
+ 28450
@@ -35790,27 +35908,27 @@
12
- 6673
+ 665623
- 3081
+ 307434
- 1614
+ 161046
- 1225
+ 1222618
- 699
+ 697
@@ -35826,27 +35944,27 @@
12
- 6673
+ 665623
- 3081
+ 307434
- 1614
+ 161046
- 1225
+ 1222618
- 699
+ 697
@@ -35862,27 +35980,27 @@
12
- 6673
+ 665623
- 3081
+ 307434
- 1614
+ 161046
- 1225
+ 1222618
- 699
+ 697
@@ -35898,12 +36016,12 @@
12
- 12724
+ 1269223
- 569
+ 568
@@ -35919,7 +36037,7 @@
12
- 13268
+ 132352
@@ -35940,27 +36058,27 @@
12
- 7303
+ 728423
- 3245
+ 323734
- 1329
+ 132647
- 1087
+ 1084718
- 328
+ 327
@@ -36269,7 +36387,7 @@
23
- 112
+ 111
@@ -36402,7 +36520,7 @@
12
- 28523
+ 28450
@@ -36418,7 +36536,7 @@
12
- 28523
+ 28450
@@ -36434,7 +36552,7 @@
12
- 28523
+ 28450
@@ -36450,7 +36568,7 @@
12
- 28523
+ 28450
@@ -36466,7 +36584,7 @@
12
- 28523
+ 28450
@@ -36482,7 +36600,7 @@
12
- 28523
+ 28450
@@ -36740,17 +36858,17 @@
12
- 16566
+ 1652426
- 1398
+ 1394668
- 431
+ 430
@@ -36766,12 +36884,12 @@
12
- 17179
+ 17136268
- 1217
+ 1214
@@ -36787,12 +36905,12 @@
12
- 17663
+ 1761828
- 733
+ 731
@@ -36808,17 +36926,17 @@
12
- 16566
+ 1652426
- 1398
+ 1394668
- 431
+ 430
@@ -36834,7 +36952,7 @@
12
- 18370
+ 183242
@@ -36855,7 +36973,7 @@
12
- 18396
+ 18350
@@ -36865,11 +36983,11 @@
fold
- 1368
+ 1367expr
- 1368
+ 1367operator
@@ -36891,7 +37009,7 @@
12
- 1368
+ 1367
@@ -36907,7 +37025,7 @@
12
- 1368
+ 1367
@@ -36986,11 +37104,11 @@
stmts
- 6258938
+ 6243069id
- 6258938
+ 6243069kind
@@ -36998,7 +37116,7 @@
location
- 2754699
+ 2747715
@@ -37012,7 +37130,7 @@
12
- 6258938
+ 6243069
@@ -37028,7 +37146,7 @@
12
- 6258938
+ 6243069
@@ -37266,17 +37384,17 @@
12
- 2352912
+ 234694724
- 239081
+ 23847541581
- 162705
+ 162292
@@ -37292,12 +37410,12 @@
12
- 2667989
+ 2661225210
- 86709
+ 86489
@@ -37414,15 +37532,15 @@
if_initialization
- 375
+ 373if_stmt
- 375
+ 373init_id
- 375
+ 373
@@ -37436,7 +37554,7 @@
12
- 375
+ 373
@@ -37452,7 +37570,7 @@
12
- 375
+ 373
@@ -37462,15 +37580,15 @@
if_then
- 987388
+ 987571if_stmt
- 987388
+ 987571then_id
- 987388
+ 987571
@@ -37484,7 +37602,7 @@
12
- 987388
+ 987571
@@ -37500,7 +37618,7 @@
12
- 987388
+ 987571
@@ -37510,15 +37628,15 @@
if_else
- 467787
+ 467752if_stmt
- 467787
+ 467752else_id
- 467787
+ 467752
@@ -37532,7 +37650,7 @@
12
- 467787
+ 467752
@@ -37548,7 +37666,7 @@
12
- 467787
+ 467752
@@ -37606,15 +37724,15 @@
constexpr_if_then
- 103934
+ 103537constexpr_if_stmt
- 103934
+ 103537then_id
- 103934
+ 103537
@@ -37628,7 +37746,7 @@
12
- 103934
+ 103537
@@ -37644,7 +37762,7 @@
12
- 103934
+ 103537
@@ -37654,15 +37772,15 @@
constexpr_if_else
- 74042
+ 73759constexpr_if_stmt
- 74042
+ 73759else_id
- 74042
+ 73759
@@ -37676,7 +37794,7 @@
12
- 74042
+ 73759
@@ -37692,7 +37810,7 @@
12
- 74042
+ 73759
@@ -37798,15 +37916,15 @@
while_body
- 39534
+ 39542while_stmt
- 39534
+ 39542body_id
- 39534
+ 39542
@@ -37820,7 +37938,7 @@
12
- 39534
+ 39542
@@ -37836,7 +37954,7 @@
12
- 39534
+ 39542
@@ -37846,15 +37964,15 @@
do_body
- 232974
+ 233017do_stmt
- 232974
+ 233017body_id
- 232974
+ 233017
@@ -37868,7 +37986,7 @@
12
- 232974
+ 233017
@@ -37884,7 +38002,7 @@
12
- 232974
+ 233017
@@ -37942,11 +38060,11 @@
switch_case
- 894840
+ 894774switch_stmt
- 440777
+ 440744index
@@ -37954,7 +38072,7 @@
case_id
- 894840
+ 894774
@@ -37973,7 +38091,7 @@
23
- 437691
+ 4376583
@@ -37999,7 +38117,7 @@
23
- 437691
+ 4376583
@@ -38162,7 +38280,7 @@
12
- 894840
+ 894774
@@ -38178,7 +38296,7 @@
12
- 894840
+ 894774
@@ -38188,15 +38306,15 @@
switch_body
- 440777
+ 440744switch_stmt
- 440777
+ 440744body_id
- 440777
+ 440744
@@ -38210,7 +38328,7 @@
12
- 440777
+ 440744
@@ -38226,7 +38344,7 @@
12
- 440777
+ 440744
@@ -38236,15 +38354,15 @@
for_initialization
- 73036
+ 73050for_stmt
- 73036
+ 73050init_id
- 73036
+ 73050
@@ -38258,7 +38376,7 @@
12
- 73036
+ 73050
@@ -38274,7 +38392,7 @@
12
- 73036
+ 73050
@@ -38284,15 +38402,15 @@
for_condition
- 76123
+ 76137for_stmt
- 76123
+ 76137condition_id
- 76123
+ 76137
@@ -38306,7 +38424,7 @@
12
- 76123
+ 76137
@@ -38322,7 +38440,7 @@
12
- 76123
+ 76137
@@ -38332,15 +38450,15 @@
for_update
- 73177
+ 73190for_stmt
- 73177
+ 73190update_id
- 73177
+ 73190
@@ -38354,7 +38472,7 @@
12
- 73177
+ 73190
@@ -38370,7 +38488,7 @@
12
- 73177
+ 73190
@@ -38380,15 +38498,15 @@
for_body
- 84148
+ 84163for_stmt
- 84148
+ 84163body_id
- 84148
+ 84163
@@ -38402,7 +38520,7 @@
12
- 84148
+ 84163
@@ -38418,7 +38536,7 @@
12
- 84148
+ 84163
@@ -38428,19 +38546,19 @@
stmtparents
- 5523824
+ 5509819id
- 5523824
+ 5509819index
- 16765
+ 16722parent
- 2342363
+ 2336424
@@ -38454,7 +38572,7 @@
12
- 5523824
+ 5509819
@@ -38470,7 +38588,7 @@
12
- 5523824
+ 5509819
@@ -38486,52 +38604,52 @@
12
- 5507
+ 549323
- 1372
+ 136934
- 302
+ 30145
- 2132
+ 212678
- 1398
+ 1394812
- 1087
+ 10841229
- 1476
+ 14722938
- 1260
+ 12574177
- 1269
+ 126577195079
- 958
+ 955
@@ -38547,52 +38665,52 @@
12
- 5507
+ 549323
- 1372
+ 136934
- 302
+ 30145
- 2132
+ 212678
- 1398
+ 1394812
- 1087
+ 10841229
- 1476
+ 14722938
- 1260
+ 12574177
- 1269
+ 126577195079
- 958
+ 955
@@ -38608,32 +38726,32 @@
12
- 1344445
+ 134103623
- 507773
+ 50648534
- 144118
+ 14375346
- 151422
+ 151038616
- 175775
+ 175330161943
- 18828
+ 18780
@@ -38649,32 +38767,32 @@
12
- 1344445
+ 134103623
- 507773
+ 50648534
- 144118
+ 14375346
- 151422
+ 151038616
- 175775
+ 175330161943
- 18828
+ 18780
@@ -38684,30 +38802,30 @@
ishandler
- 47389
+ 47330block
- 47389
+ 47330stmt_decl_bind
- 730244
+ 723033stmt
- 689803
+ 682991num
- 125
+ 124decl
- 730175
+ 722964
@@ -38721,12 +38839,12 @@
12
- 667590
+ 660998232
- 22212
+ 21993
@@ -38742,12 +38860,12 @@
12
- 667590
+ 660998232
- 22212
+ 21993
@@ -38885,7 +39003,7 @@
12
- 730151
+ 7229402
@@ -38906,7 +39024,7 @@
12
- 730175
+ 722964
@@ -38916,19 +39034,19 @@
stmt_decl_entry_bind
- 730244
+ 723033stmt
- 689803
+ 682991num
- 125
+ 124decl_entry
- 730244
+ 723033
@@ -38942,12 +39060,12 @@
12
- 667590
+ 660998232
- 22212
+ 21993
@@ -38963,12 +39081,12 @@
12
- 667590
+ 660998232
- 22212
+ 21993
@@ -39106,7 +39224,7 @@
12
- 730244
+ 723033
@@ -39122,7 +39240,7 @@
12
- 730244
+ 723033
@@ -39132,15 +39250,15 @@
blockscope
- 1764517
+ 1757769block
- 1764517
+ 1757769enclosing
- 1509119
+ 1503349
@@ -39154,7 +39272,7 @@
12
- 1764517
+ 1757769
@@ -39170,17 +39288,17 @@
12
- 1337771
+ 133265523
- 128699
+ 128207328
- 42649
+ 42486
@@ -39190,19 +39308,19 @@
jumpinfo
- 347327
+ 347391id
- 347327
+ 347391str
- 28866
+ 28871target
- 72498
+ 72512
@@ -39216,7 +39334,7 @@
12
- 347327
+ 347391
@@ -39232,7 +39350,7 @@
12
- 347327
+ 347391
@@ -39248,12 +39366,12 @@
23
- 13558
+ 1356034
- 6041
+ 60424
@@ -39268,7 +39386,7 @@
610
- 2191
+ 219210
@@ -39278,7 +39396,7 @@
2513711
- 999
+ 1000
@@ -39294,17 +39412,17 @@
12
- 23124
+ 2312823
- 3616
+ 361733321
- 2124
+ 2125
@@ -39325,27 +39443,27 @@
23
- 36107
+ 3611434
- 17583
+ 1758645
- 7358
+ 735958
- 6399
+ 640182124
- 5016
+ 5017
@@ -39361,7 +39479,7 @@
12
- 72498
+ 72512
@@ -39371,19 +39489,19 @@
preprocdirects
- 5407616
+ 5386939id
- 5407616
+ 5386939kind
- 1375
+ 1370location
- 5404364
+ 5383699
@@ -39397,7 +39515,7 @@
12
- 5407616
+ 5386939
@@ -39413,7 +39531,7 @@
12
- 5407616
+ 5386939
@@ -39429,57 +39547,57 @@
12
- 125
+ 124145146
- 125
+ 124808809
- 125
+ 124866867
- 125
+ 124973974
- 125
+ 12415091510
- 125
+ 12418911892
- 125
+ 12432563257
- 125
+ 12447144715
- 125
+ 12470897090
- 125
+ 1242198421985
- 125
+ 124
@@ -39495,57 +39613,57 @@
12
- 125
+ 124145146
- 125
+ 124808809
- 125
+ 124866867
- 125
+ 124973974
- 125
+ 12415091510
- 125
+ 12418911892
- 125
+ 12432563257
- 125
+ 12447144715
- 125
+ 12470897090
- 125
+ 1242195821959
- 125
+ 124
@@ -39561,12 +39679,12 @@
12
- 5404239
+ 53835752728
- 125
+ 124
@@ -39582,7 +39700,7 @@
12
- 5404364
+ 5383699
@@ -39592,15 +39710,15 @@
preprocpair
- 1141282
+ 1136918begin
- 886636
+ 883245elseelifend
- 1141282
+ 1136918
@@ -39614,17 +39732,17 @@
12
- 645622
+ 64315323
- 231383
+ 23049839
- 9630
+ 9593
@@ -39640,7 +39758,7 @@
12
- 1141282
+ 1136918
@@ -39650,41 +39768,41 @@
preproctrue
- 437752
+ 436078branch
- 437752
+ 436078preprocfalse
- 284664
+ 283575branch
- 284664
+ 283575preproctext
- 4352508
+ 4335865id
- 4352508
+ 4335865head
- 2954828
+ 2943529body
- 1681344
+ 1674914
@@ -39698,7 +39816,7 @@
12
- 4352508
+ 4335865
@@ -39714,7 +39832,7 @@
12
- 4352508
+ 4335865
@@ -39730,12 +39848,12 @@
12
- 2758089
+ 27475432798
- 196738
+ 195986
@@ -39751,12 +39869,12 @@
12
- 2875157
+ 286416325
- 79670
+ 79366
@@ -39772,17 +39890,17 @@
12
- 1532758
+ 1526897210
- 127698
+ 1272101013579
- 20887
+ 20807
@@ -39798,17 +39916,17 @@
12
- 1537010
+ 1531133212
- 127323
+ 126836123231
- 17009
+ 16944
@@ -39818,15 +39936,15 @@
includes
- 406823
+ 397817id
- 406823
+ 397817included
- 74940
+ 73281
@@ -39840,7 +39958,7 @@
12
- 406823
+ 397817
@@ -39856,37 +39974,37 @@
12
- 37085
+ 3626423
- 12056
+ 1178934
- 6324
+ 618446
- 6837
+ 6685611
- 5771
+ 56441147
- 5623
+ 549947793
- 1240
+ 1213
@@ -39896,15 +40014,15 @@
link_targets
- 943
+ 923id
- 943
+ 923binary
- 943
+ 923
@@ -39918,7 +40036,7 @@
12
- 943
+ 923
@@ -39934,7 +40052,7 @@
12
- 943
+ 923
@@ -39944,11 +40062,11 @@
link_parent
- 38129861
+ 38113722element
- 4849837
+ 4847512link_target
@@ -39966,17 +40084,17 @@
12
- 665798
+ 66522529
- 33828
+ 33795910
- 4150209
+ 4148492
@@ -39995,48 +40113,48 @@
42
- 97300
- 97301
+ 97356
+ 9735742
- 97419
- 97420
+ 97475
+ 9747642
- 97472
- 97473
+ 97528
+ 9752942
- 97499
- 97500
+ 97555
+ 9755642
- 97521
- 97522
+ 97577
+ 9757842
- 97553
- 97554
+ 97609
+ 9761042
- 99560
- 99561
+ 99616
+ 9961742
- 102940
- 102941
+ 102996
+ 10299742
- 104302
- 104303
+ 104360
+ 10436142
diff --git a/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
new file mode 100644
index 000000000000..3c45f8b9e71e
--- /dev/null
+++ b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/old.dbscheme
@@ -0,0 +1,2493 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..a8c2176e9a5c
--- /dev/null
+++ b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/semmlecode.cpp.dbscheme
@@ -0,0 +1,2494 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+| 40 = @stmt_leave
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue | @stmt_leave;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties
new file mode 100644
index 000000000000..bd639edb8f24
--- /dev/null
+++ b/cpp/ql/lib/upgrades/3c45f8b9e71ec723bf50c40581e1f18f4f25e290/upgrade.properties
@@ -0,0 +1,2 @@
+description: Support `__leave` statement
+compatibility: partial
diff --git a/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/old.dbscheme b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/old.dbscheme
new file mode 100644
index 000000000000..9a7c3c14c107
--- /dev/null
+++ b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/old.dbscheme
@@ -0,0 +1,2491 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..af887e83a815
--- /dev/null
+++ b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/semmlecode.cpp.dbscheme
@@ -0,0 +1,2492 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/upgrade.properties b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/upgrade.properties
new file mode 100644
index 000000000000..3fdb0aa5a823
--- /dev/null
+++ b/cpp/ql/lib/upgrades/9a7c3c14c1076f64b871719117a558733d987b48/upgrade.properties
@@ -0,0 +1,2 @@
+description: Support __mfp8 type
+compatibility: full
diff --git a/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/lambdas.ql b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/lambdas.ql
new file mode 100644
index 000000000000..f3891442a864
--- /dev/null
+++ b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/lambdas.ql
@@ -0,0 +1,7 @@
+class LambdaExpr extends @lambdaexpr {
+ string toString() { none() }
+}
+
+from LambdaExpr lambda, string default_capture, boolean has_explicit_return_type
+where lambdas(lambda, default_capture, has_explicit_return_type)
+select lambda, default_capture, has_explicit_return_type, true
diff --git a/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
new file mode 100644
index 000000000000..af887e83a815
--- /dev/null
+++ b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/old.dbscheme
@@ -0,0 +1,2492 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..3c45f8b9e71e
--- /dev/null
+++ b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/semmlecode.cpp.dbscheme
@@ -0,0 +1,2493 @@
+
+/**
+ * An invocation of the compiler. Note that more than one file may be
+ * compiled per invocation. For example, this command compiles three
+ * source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * The `id` simply identifies the invocation, while `cwd` is the working
+ * directory from which the compiler was invoked.
+ */
+compilations(
+ /**
+ * An invocation of the compiler. Note that more than one file may
+ * be compiled per invocation. For example, this command compiles
+ * three source files:
+ *
+ * gcc -c f1.c f2.c f3.c
+ */
+ 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
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then typically there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | *path to extractor*
+ * 1 | `--mimic`
+ * 2 | `/usr/bin/gcc`
+ * 3 | `-c`
+ * 4 | f1.c
+ * 5 | f2.c
+ * 6 | f3.c
+ */
+#keyset[id, num]
+compilation_args(
+ int id : @compilation ref,
+ int num : int ref,
+ string arg : string ref
+);
+
+/**
+ * Optionally, record the build mode for each compilation.
+ */
+compilation_build_mode(
+ unique int id : @compilation ref,
+ int mode : int ref
+);
+
+/*
+case @compilation_build_mode.mode of
+ 0 = @build_mode_none
+| 1 = @build_mode_manual
+| 2 = @build_mode_auto
+;
+*/
+
+/**
+ * The source files that are compiled by a compiler invocation.
+ * If `id` is for the compiler invocation
+ *
+ * gcc -c f1.c f2.c f3.c
+ *
+ * then there will be rows for
+ *
+ * num | arg
+ * --- | ---
+ * 0 | f1.c
+ * 1 | f2.c
+ * 2 | f3.c
+ *
+ * Note that even if those files `#include` headers, those headers
+ * do not appear as rows.
+ */
+#keyset[id, num]
+compilation_compiling_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(
+ int diagnostic : @diagnostic ref,
+ int compilation : @compilation ref,
+ int file_number : int ref,
+ int file_number_diagnostic_number : int 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 data, loaded from CSV files during snapshot creation. See
+ * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data)
+ * for more information.
+ */
+externalData(
+ int id : @externalDataElement,
+ string path : string ref,
+ int column: int ref,
+ string value : string ref
+);
+
+/**
+ * The source location of the snapshot.
+ */
+sourceLocationPrefix(string prefix : string ref);
+
+/**
+ * Information about packages that provide code used during compilation.
+ * The `id` is just a unique identifier.
+ * The `namespace` is typically the name of the package manager that
+ * provided the package (e.g. "dpkg" or "yum").
+ * The `package_name` is the name of the package, and `version` is its
+ * version (as a string).
+ */
+external_packages(
+ unique int id: @external_package,
+ string namespace : string ref,
+ string package_name : string ref,
+ string version : string ref
+);
+
+/**
+ * Holds if File `fileid` was provided by package `package`.
+ */
+header_to_external_package(
+ int fileid : @file ref,
+ int package : @external_package ref
+);
+
+/*
+ * Version history
+ */
+
+svnentries(
+ unique int id : @svnentry,
+ string revision : string ref,
+ string author : string ref,
+ date revisionDate : date ref,
+ int changeSize : int ref
+)
+
+svnaffectedfiles(
+ int id : @svnentry ref,
+ int file : @file ref,
+ string action : string ref
+)
+
+svnentrymsg(
+ unique int id : @svnentry ref,
+ string message : string ref
+)
+
+svnchurn(
+ int commit : @svnentry ref,
+ int file : @file ref,
+ int addedLines : int ref,
+ int deletedLines : int ref
+)
+
+/*
+ * C++ dbscheme
+ */
+
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
+@location = @location_stmt | @location_expr | @location_default ;
+
+/**
+ * The location of an element that is not an expression or a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_default(
+ /** The location of an element that is not an expression or a statement. */
+ unique int id: @location_default,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of a statement.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_stmt(
+ /** The location of a statement. */
+ unique int id: @location_stmt,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/**
+ * The location of an expression.
+ * The location spans column `startcolumn` of line `startline` to
+ * column `endcolumn` of line `endline` in file `file`.
+ * For more information, see
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
+ */
+locations_expr(
+ /** The location of an expression. */
+ unique int id: @location_expr,
+ int container: @container ref,
+ int startLine: int ref,
+ int startColumn: int ref,
+ int endLine: int ref,
+ int endColumn: int ref
+);
+
+/** An element for which line-count information is available. */
+@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable;
+
+numlines(
+ int element_id: @sourceline ref,
+ int num_lines: int ref,
+ int num_code: int ref,
+ int num_comment: 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
+);
+
+files(
+ unique int id: @file,
+ string name: string ref
+);
+
+folders(
+ unique int id: @folder,
+ string name: string ref
+);
+
+@container = @folder | @file
+
+containerparent(
+ int parent: @container ref,
+ unique int child: @container ref
+);
+
+fileannotations(
+ int id: @file ref,
+ int kind: int ref,
+ string name: string ref,
+ string value: string ref
+);
+
+inmacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+affectedbymacroexpansion(
+ int id: @element ref,
+ int inv: @macroinvocation ref
+);
+
+case @macroinvocation.kind of
+ 1 = @macro_expansion
+| 2 = @other_macro_reference
+;
+
+macroinvocations(
+ unique int id: @macroinvocation,
+ int macro_id: @ppd_define ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+macroparent(
+ unique int id: @macroinvocation ref,
+ int parent_id: @macroinvocation ref
+);
+
+// a macroinvocation may be part of another location
+// the way to find a constant expression that uses a macro
+// is thus to find a constant expression that has a location
+// to which a macro invocation is bound
+macrolocationbind(
+ int id: @macroinvocation ref,
+ int location: @location ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_unexpanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+#keyset[invocation, argument_index]
+macro_argument_expanded(
+ int invocation: @macroinvocation ref,
+ int argument_index: int ref,
+ string text: string ref
+);
+
+/*
+case @function.kind of
+ 1 = @normal_function
+| 2 = @constructor
+| 3 = @destructor
+| 4 = @conversion_function
+| 5 = @operator
+| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
+| 7 = @user_defined_literal
+| 8 = @deduction_guide
+;
+*/
+
+functions(
+ unique int id: @function,
+ string name: string ref,
+ int kind: int ref
+);
+
+function_entry_point(
+ int id: @function ref,
+ unique int entry_point: @stmt ref
+);
+
+function_return_type(
+ int id: @function ref,
+ int return_type: @type ref
+);
+
+/**
+ * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits`
+ * instance associated with it, and the variables representing the `handle` and `promise`
+ * for it.
+ */
+coroutine(
+ unique int function: @function ref,
+ int traits: @type ref
+);
+
+/*
+case @coroutine_placeholder_variable.kind of
+ 1 = @handle
+| 2 = @promise
+| 3 = @init_await_resume
+;
+*/
+
+coroutine_placeholder_variable(
+ unique int placeholder_variable: @variable ref,
+ int kind: int ref,
+ int function: @function ref
+)
+
+/** The `new` function used for allocating the coroutine state, if any. */
+coroutine_new(
+ unique int function: @function ref,
+ int new: @function ref
+);
+
+/** The `delete` function used for deallocating the coroutine state, if any. */
+coroutine_delete(
+ unique int function: @function ref,
+ int delete: @function ref
+);
+
+purefunctions(unique int id: @function ref);
+
+function_deleted(unique int id: @function ref);
+
+function_defaulted(unique int id: @function ref);
+
+function_prototyped(unique int id: @function ref)
+
+deduction_guide_for_class(
+ int id: @function ref,
+ int class_template: @usertype ref
+)
+
+member_function_this_type(
+ unique int id: @function ref,
+ int this_type: @type ref
+);
+
+#keyset[id, type_id]
+fun_decls(
+ int id: @fun_decl,
+ int function: @function ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+fun_def(unique int id: @fun_decl ref);
+fun_specialized(unique int id: @fun_decl ref);
+fun_implicit(unique int id: @fun_decl ref);
+fun_decl_specifiers(
+ int id: @fun_decl ref,
+ string name: string ref
+)
+#keyset[fun_decl, index]
+fun_decl_throws(
+ int fun_decl: @fun_decl ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+/* an empty throw specification is different from none */
+fun_decl_empty_throws(unique int fun_decl: @fun_decl ref);
+fun_decl_noexcept(
+ int fun_decl: @fun_decl ref,
+ int constant: @expr ref
+);
+fun_decl_empty_noexcept(int fun_decl: @fun_decl ref);
+fun_decl_typedef_type(
+ unique int fun_decl: @fun_decl ref,
+ int typedeftype_id: @usertype ref
+);
+
+/*
+case @fun_requires.kind of
+ 1 = @template_attached
+| 2 = @function_attached
+;
+*/
+
+fun_requires(
+ int id: @fun_decl ref,
+ int kind: int ref,
+ int constraint: @expr ref
+);
+
+param_decl_bind(
+ unique int id: @var_decl ref,
+ int index: int ref,
+ int fun_decl: @fun_decl ref
+);
+
+#keyset[id, type_id]
+var_decls(
+ int id: @var_decl,
+ int variable: @variable ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+var_def(unique int id: @var_decl ref);
+var_specialized(int id: @var_decl ref);
+var_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable ref);
+var_requires(
+ int id: @var_decl ref,
+ int constraint: @expr ref
+);
+
+type_decls(
+ unique int id: @type_decl,
+ int type_id: @type ref,
+ int location: @location_default ref
+);
+type_def(unique int id: @type_decl ref);
+type_decl_top(
+ unique int type_decl: @type_decl ref
+);
+type_requires(
+ int id: @type_decl ref,
+ int constraint: @expr ref
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+case @using.kind of
+ 1 = @using_declaration
+| 2 = @using_directive
+| 3 = @using_enum_declaration
+;
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default ref,
+ int kind: int ref
+);
+
+/** The element which contains the `using` declaration. */
+using_container(
+ int parent: @element ref,
+ int child: @using ref
+);
+
+static_asserts(
+ unique int id: @static_assert,
+ int condition : @expr ref,
+ string message : string ref,
+ int location: @location_default ref,
+ int enclosing : @element ref
+);
+
+// each function has an ordered list of parameters
+#keyset[id, type_id]
+#keyset[function, index, type_id]
+params(
+ int id: @parameter,
+ int function: @parameterized_element ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+overrides(
+ int new: @function ref,
+ int old: @function ref
+);
+
+#keyset[id, type_id]
+membervariables(
+ int id: @membervariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+globalvariables(
+ int id: @globalvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+#keyset[id, type_id]
+localvariables(
+ int id: @localvariable,
+ int type_id: @type ref,
+ string name: string ref
+);
+
+autoderivation(
+ unique int var: @variable ref,
+ int derivation_type: @type ref
+);
+
+orphaned_variables(
+ int var: @localvariable ref,
+ int function: @function ref
+)
+
+enumconstants(
+ unique int id: @enumconstant,
+ int parent: @usertype ref,
+ int index: int ref,
+ int type_id: @type ref,
+ string name: string ref,
+ int location: @location_default ref
+);
+
+@variable = @localscopevariable | @globalvariable | @membervariable;
+
+@localscopevariable = @localvariable | @parameter;
+
+/**
+ * Built-in types are the fundamental types, e.g., integral, floating, and void.
+ */
+case @builtintype.kind of
+ 1 = @errortype
+| 2 = @unknowntype
+| 3 = @void
+| 4 = @boolean
+| 5 = @char
+| 6 = @unsigned_char
+| 7 = @signed_char
+| 8 = @short
+| 9 = @unsigned_short
+| 10 = @signed_short
+| 11 = @int
+| 12 = @unsigned_int
+| 13 = @signed_int
+| 14 = @long
+| 15 = @unsigned_long
+| 16 = @signed_long
+| 17 = @long_long
+| 18 = @unsigned_long_long
+| 19 = @signed_long_long
+// ... 20 Microsoft-specific __int8
+// ... 21 Microsoft-specific __int16
+// ... 22 Microsoft-specific __int32
+// ... 23 Microsoft-specific __int64
+| 24 = @float
+| 25 = @double
+| 26 = @long_double
+| 27 = @complex_float // C99-specific _Complex float
+| 28 = @complex_double // C99-specific _Complex double
+| 29 = @complex_long_double // C99-specific _Complex long double
+| 30 = @imaginary_float // C99-specific _Imaginary float
+| 31 = @imaginary_double // C99-specific _Imaginary double
+| 32 = @imaginary_long_double // C99-specific _Imaginary long double
+| 33 = @wchar_t // Microsoft-specific
+| 34 = @decltype_nullptr // C++11
+| 35 = @int128 // __int128
+| 36 = @unsigned_int128 // unsigned __int128
+| 37 = @signed_int128 // signed __int128
+| 38 = @float128 // __float128
+| 39 = @complex_float128 // _Complex __float128
+| 40 = @decimal32 // _Decimal32
+| 41 = @decimal64 // _Decimal64
+| 42 = @decimal128 // _Decimal128
+| 43 = @char16_t
+| 44 = @char32_t
+| 45 = @std_float32 // _Float32
+| 46 = @float32x // _Float32x
+| 47 = @std_float64 // _Float64
+| 48 = @float64x // _Float64x
+| 49 = @std_float128 // _Float128
+// ... 50 _Float128x
+| 51 = @char8_t
+| 52 = @float16 // _Float16
+| 53 = @complex_float16 // _Complex _Float16
+| 54 = @fp16 // __fp16
+| 55 = @std_bfloat16 // __bf16
+| 56 = @std_float16 // std::float16_t
+| 57 = @complex_std_float32 // _Complex _Float32
+| 58 = @complex_float32x // _Complex _Float32x
+| 59 = @complex_std_float64 // _Complex _Float64
+| 60 = @complex_float64x // _Complex _Float64x
+| 61 = @complex_std_float128 // _Complex _Float128
+| 62 = @mfp8 // __mfp8
+;
+
+builtintypes(
+ unique int id: @builtintype,
+ string name: string ref,
+ int kind: int ref,
+ int size: int ref,
+ int sign: int ref,
+ int alignment: int ref
+);
+
+/**
+ * Derived types are types that are directly derived from existing types and
+ * point to, refer to, transform type data to return a new type.
+ */
+case @derivedtype.kind of
+ 1 = @pointer
+| 2 = @reference
+| 3 = @type_with_specifiers
+| 4 = @array
+| 5 = @gnu_vector
+| 6 = @routineptr
+| 7 = @routinereference
+| 8 = @rvalue_reference // C++11
+// ... 9 type_conforming_to_protocols deprecated
+| 10 = @block
+;
+
+derivedtypes(
+ unique int id: @derivedtype,
+ string name: string ref,
+ int kind: int ref,
+ int type_id: @type ref
+);
+
+pointerishsize(unique int id: @derivedtype ref,
+ int size: int ref,
+ int alignment: int ref);
+
+arraysizes(
+ unique int id: @derivedtype ref,
+ int num_elements: int ref,
+ int bytesize: int ref,
+ int alignment: int ref
+);
+
+typedefbase(
+ unique int id: @usertype ref,
+ int type_id: @type ref
+);
+
+/**
+ * An instance of the C++11 `decltype` operator or C23 `typeof`/`typeof_unqual`
+ * operator taking an expression as its argument. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * typeof(1+a) c;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * changes the semantics of the decltype, e.g.
+ * ```
+ * struct A { double x; };
+ * const A* a = new A();
+ * decltype( a->x ); // type is double
+ * decltype((a->x)); // type is const double&
+ * ```
+ * (Please consult the C++11 standard for more details).
+ * `parentheses_would_change_meaning` is `true` iff that is the case.
+ */
+
+/*
+case @decltype.kind of
+| 0 = @decltype
+| 1 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+;
+*/
+
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int kind: int ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @type_operator.kind of
+| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
+| 1 = @underlying_type
+| 2 = @bases
+| 3 = @direct_bases
+| 4 = @add_lvalue_reference
+| 5 = @add_pointer
+| 6 = @add_rvalue_reference
+| 7 = @decay
+| 8 = @make_signed
+| 9 = @make_unsigned
+| 10 = @remove_all_extents
+| 11 = @remove_const
+| 12 = @remove_cv
+| 13 = @remove_cvref
+| 14 = @remove_extent
+| 15 = @remove_pointer
+| 16 = @remove_reference_t
+| 17 = @remove_restrict
+| 18 = @remove_volatile
+| 19 = @remove_reference
+;
+*/
+
+type_operators(
+ unique int id: @type_operator,
+ int arg_type: @type ref,
+ int kind: int ref,
+ int base_type: @type ref
+)
+
+/*
+case @usertype.kind of
+| 0 = @unknown_usertype
+| 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+// ... 5 = @typedef deprecated // classic C: typedef typedef type name
+// ... 6 = @template deprecated
+| 7 = @template_parameter
+| 8 = @template_template_parameter
+| 9 = @proxy_class // a proxy class associated with a template parameter
+// ... 10 objc_class deprecated
+// ... 11 objc_protocol deprecated
+// ... 12 objc_category deprecated
+| 13 = @scoped_enum
+// ... 14 = @using_alias deprecated // a using name = type style typedef
+| 15 = @template_struct
+| 16 = @template_class
+| 17 = @template_union
+| 18 = @alias
+;
+*/
+
+usertypes(
+ unique int id: @usertype,
+ string name: string ref,
+ int kind: int ref
+);
+
+usertypesize(
+ unique int id: @usertype ref,
+ int size: int ref,
+ int alignment: int ref
+);
+
+usertype_final(unique int id: @usertype ref);
+
+usertype_uuid(
+ unique int id: @usertype ref,
+ string uuid: string ref
+);
+
+/*
+case @usertype.alias_kind of
+| 0 = @typedef
+| 1 = @alias
+*/
+
+usertype_alias_kind(
+ int id: @usertype ref,
+ int alias_kind: int ref
+)
+
+nontype_template_parameters(
+ int id: @expr ref
+);
+
+type_template_type_constraint(
+ int id: @usertype ref,
+ int constraint: @expr ref
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname,
+ boolean is_complete: boolean ref
+);
+
+is_pod_class(unique int id: @usertype ref);
+is_standard_layout_class(unique int id: @usertype ref);
+
+is_complete(unique int id: @usertype ref);
+
+is_class_template(unique int id: @usertype ref);
+class_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+class_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+class_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@user_or_decltype = @usertype | @decltype;
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ int templ_param_id: @user_or_decltype ref
+);
+
+type_mentions(
+ unique int id: @type_mention,
+ int type_id: @type ref,
+ int location: @location ref,
+ // a_symbol_reference_kind from the frontend.
+ int kind: int ref
+);
+
+is_function_template(unique int id: @function ref);
+function_instantiation(
+ unique int to: @function ref,
+ int from: @function ref
+);
+function_template_argument(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+function_template_argument_value(
+ int function_id: @function ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+is_variable_template(unique int id: @variable ref);
+variable_instantiation(
+ unique int to: @variable ref,
+ int from: @variable ref
+);
+variable_template_argument(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+variable_template_argument_value(
+ int variable_id: @variable ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+template_template_instantiation(
+ int to: @usertype ref,
+ int from: @usertype ref
+);
+template_template_argument(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+template_template_argument_value(
+ int type_id: @usertype ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+@concept = @concept_template | @concept_id;
+
+concept_templates(
+ unique int concept_id: @concept_template,
+ string name: string ref,
+ int location: @location_default ref
+);
+concept_instantiation(
+ unique int to: @concept_id ref,
+ int from: @concept_template ref
+);
+is_type_constraint(int concept_id: @concept_id ref);
+concept_template_argument(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_type: @type ref
+);
+concept_template_argument_value(
+ int concept_id: @concept ref,
+ int index: int ref,
+ int arg_value: @expr ref
+);
+
+routinetypes(
+ unique int id: @routinetype,
+ int return_type: @type ref
+);
+
+routinetypeargs(
+ int routine: @routinetype ref,
+ int index: int ref,
+ int type_id: @type ref
+);
+
+ptrtomembers(
+ unique int id: @ptrtomember,
+ int type_id: @type ref,
+ int class_id: @type ref
+);
+
+/*
+ specifiers for types, functions, and variables
+
+ "public",
+ "protected",
+ "private",
+
+ "const",
+ "volatile",
+ "static",
+
+ "pure",
+ "virtual",
+ "sealed", // Microsoft
+ "__interface", // Microsoft
+ "inline",
+ "explicit",
+
+ "near", // near far extension
+ "far", // near far extension
+ "__ptr32", // Microsoft
+ "__ptr64", // Microsoft
+ "__sptr", // Microsoft
+ "__uptr", // Microsoft
+ "dllimport", // Microsoft
+ "dllexport", // Microsoft
+ "thread", // Microsoft
+ "naked", // Microsoft
+ "microsoft_inline", // Microsoft
+ "forceinline", // Microsoft
+ "selectany", // Microsoft
+ "nothrow", // Microsoft
+ "novtable", // Microsoft
+ "noreturn", // Microsoft
+ "noinline", // Microsoft
+ "noalias", // Microsoft
+ "restrict", // Microsoft
+*/
+
+specifiers(
+ unique int id: @specifier,
+ unique string str: string ref
+);
+
+typespecifiers(
+ int type_id: @type ref,
+ int spec_id: @specifier ref
+);
+
+funspecifiers(
+ int func_id: @function ref,
+ int spec_id: @specifier ref
+);
+
+varspecifiers(
+ int var_id: @accessible ref,
+ int spec_id: @specifier ref
+);
+
+explicit_specifier_exprs(
+ unique int func_id: @function ref,
+ int constant: @expr ref
+)
+
+attributes(
+ unique int id: @attribute,
+ int kind: int ref,
+ string name: string ref,
+ string name_space: string ref,
+ int location: @location_default ref
+);
+
+case @attribute.kind of
+ 0 = @gnuattribute
+| 1 = @stdattribute
+| 2 = @declspec
+| 3 = @msattribute
+| 4 = @alignas
+// ... 5 @objc_propertyattribute deprecated
+;
+
+attribute_args(
+ unique int id: @attribute_arg,
+ int kind: int ref,
+ int attribute: @attribute ref,
+ int index: int ref,
+ int location: @location_default ref
+);
+
+case @attribute_arg.kind of
+ 0 = @attribute_arg_empty
+| 1 = @attribute_arg_token
+| 2 = @attribute_arg_constant
+| 3 = @attribute_arg_type
+| 4 = @attribute_arg_constant_expr
+| 5 = @attribute_arg_expr
+;
+
+attribute_arg_value(
+ unique int arg: @attribute_arg ref,
+ string value: string ref
+);
+attribute_arg_type(
+ unique int arg: @attribute_arg ref,
+ int type_id: @type ref
+);
+attribute_arg_constant(
+ unique int arg: @attribute_arg ref,
+ int constant: @expr ref
+)
+attribute_arg_expr(
+ unique int arg: @attribute_arg ref,
+ int expr: @expr ref
+)
+attribute_arg_name(
+ unique int arg: @attribute_arg ref,
+ string name: string ref
+);
+
+typeattributes(
+ int type_id: @type ref,
+ int spec_id: @attribute ref
+);
+
+funcattributes(
+ int func_id: @function ref,
+ int spec_id: @attribute ref
+);
+
+varattributes(
+ int var_id: @accessible ref,
+ int spec_id: @attribute ref
+);
+
+stmtattributes(
+ int stmt_id: @stmt ref,
+ int spec_id: @attribute ref
+);
+
+@type = @builtintype
+ | @derivedtype
+ | @usertype
+ | @routinetype
+ | @ptrtomember
+ | @decltype
+ | @type_operator;
+
+unspecifiedtype(
+ unique int type_id: @type ref,
+ int unspecified_type_id: @type ref
+);
+
+member(
+ int parent: @type ref,
+ int index: int ref,
+ int child: @member ref
+);
+
+@enclosingfunction_child = @usertype | @variable | @namespace
+
+enclosingfunction(
+ unique int child: @enclosingfunction_child ref,
+ int parent: @function ref
+);
+
+derivations(
+ unique int derivation: @derivation,
+ int sub: @type ref,
+ int index: int ref,
+ int super: @type ref,
+ int location: @location_default ref
+);
+
+derspecifiers(
+ int der_id: @derivation ref,
+ int spec_id: @specifier ref
+);
+
+/**
+ * Contains the byte offset of the base class subobject within the derived
+ * class. Only holds for non-virtual base classes, but see table
+ * `virtual_base_offsets` for offsets of virtual base class subobjects.
+ */
+direct_base_offsets(
+ unique int der_id: @derivation ref,
+ int offset: int ref
+);
+
+/**
+ * Contains the byte offset of the virtual base class subobject for class
+ * `super` within a most-derived object of class `sub`. `super` can be either a
+ * direct or indirect base class.
+ */
+#keyset[sub, super]
+virtual_base_offsets(
+ int sub: @usertype ref,
+ int super: @usertype ref,
+ int offset: int ref
+);
+
+frienddecls(
+ unique int id: @frienddecl,
+ int type_id: @type ref,
+ int decl_id: @declaration ref,
+ int location: @location_default ref
+);
+
+@declaredtype = @usertype ;
+
+@declaration = @function
+ | @declaredtype
+ | @variable
+ | @enumconstant
+ | @frienddecl
+ | @concept_template;
+
+@member = @membervariable
+ | @function
+ | @declaredtype
+ | @enumconstant;
+
+@locatable = @diagnostic
+ | @declaration
+ | @ppd_include
+ | @ppd_define
+ | @macroinvocation
+ /*| @funcall*/
+ | @xmllocatable
+ | @attribute
+ | @attribute_arg;
+
+@namedscope = @namespace | @usertype;
+
+@element = @locatable
+ | @file
+ | @folder
+ | @specifier
+ | @type
+ | @expr
+ | @namespace
+ | @initialiser
+ | @stmt
+ | @derivation
+ | @comment
+ | @preprocdirect
+ | @fun_decl
+ | @var_decl
+ | @type_decl
+ | @namespace_decl
+ | @using
+ | @namequalifier
+ | @specialnamequalifyingelement
+ | @static_assert
+ | @type_mention
+ | @lambdacapture;
+
+@exprparent = @element;
+
+comments(
+ unique int id: @comment,
+ string contents: string ref,
+ int location: @location_default ref
+);
+
+commentbinding(
+ int id: @comment ref,
+ int element: @element ref
+);
+
+exprconv(
+ int converted: @expr ref,
+ unique int conversion: @expr ref
+);
+
+compgenerated(unique int id: @element ref);
+
+/**
+ * `destructor_call` destructs the `i`'th entity that should be
+ * destructed following `element`. Note that entities should be
+ * destructed in reverse construction order, so for a given `element`
+ * these should be called from highest to lowest `i`.
+ */
+#keyset[element, destructor_call]
+#keyset[element, i]
+synthetic_destructor_call(
+ int element: @element ref,
+ int i: int ref,
+ int destructor_call: @routineexpr ref
+);
+
+namespaces(
+ unique int id: @namespace,
+ string name: string ref
+);
+
+namespace_inline(
+ unique int id: @namespace ref
+);
+
+namespacembrs(
+ int parentid: @namespace ref,
+ unique int memberid: @namespacembr ref
+);
+
+@namespacembr = @declaration | @namespace;
+
+exprparents(
+ int expr_id: @expr ref,
+ int child_index: int ref,
+ int parent_id: @exprparent ref
+);
+
+expr_isload(unique int expr_id: @expr ref);
+
+@cast = @c_style_cast
+ | @const_cast
+ | @dynamic_cast
+ | @reinterpret_cast
+ | @static_cast
+ ;
+
+/*
+case @conversion.kind of
+ 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast
+| 1 = @bool_conversion // conversion to 'bool'
+| 2 = @base_class_conversion // a derived-to-base conversion
+| 3 = @derived_class_conversion // a base-to-derived conversion
+| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member
+| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member
+| 6 = @glvalue_adjust // an adjustment of the type of a glvalue
+| 7 = @prvalue_adjust // an adjustment of the type of a prvalue
+;
+*/
+/**
+ * Describes the semantics represented by a cast expression. This is largely
+ * independent of the source syntax of the cast, so it is separate from the
+ * regular expression kind.
+ */
+conversionkinds(
+ unique int expr_id: @cast ref,
+ int kind: int ref
+);
+
+@conversion = @cast
+ | @array_to_pointer
+ | @parexpr
+ | @reference_to
+ | @ref_indirect
+ | @temp_init
+ | @c11_generic
+ ;
+
+/*
+case @funbindexpr.kind of
+ 0 = @normal_call // a normal call
+| 1 = @virtual_call // a virtual call
+| 2 = @adl_call // a call whose target is only found by ADL
+;
+*/
+iscall(
+ unique int caller: @funbindexpr ref,
+ int kind: int ref
+);
+
+numtemplatearguments(
+ unique int expr_id: @expr ref,
+ int num: int ref
+);
+
+specialnamequalifyingelements(
+ unique int id: @specialnamequalifyingelement,
+ unique string name: string ref
+);
+
+@namequalifiableelement = @expr | @namequalifier;
+@namequalifyingelement = @namespace
+ | @specialnamequalifyingelement
+ | @usertype;
+
+namequalifiers(
+ unique int id: @namequalifier,
+ unique int qualifiableelement: @namequalifiableelement ref,
+ int qualifyingelement: @namequalifyingelement ref,
+ int location: @location_default ref
+);
+
+varbind(
+ int expr: @varbindexpr ref,
+ int var: @accessible ref
+);
+
+funbind(
+ int expr: @funbindexpr ref,
+ int fun: @function ref
+);
+
+@any_new_expr = @new_expr
+ | @new_array_expr;
+
+@new_or_delete_expr = @any_new_expr
+ | @delete_expr
+ | @delete_array_expr;
+
+@prefix_crement_expr = @preincrexpr | @predecrexpr;
+
+@postfix_crement_expr = @postincrexpr | @postdecrexpr;
+
+@increment_expr = @preincrexpr | @postincrexpr;
+
+@decrement_expr = @predecrexpr | @postdecrexpr;
+
+@crement_expr = @increment_expr | @decrement_expr;
+
+@un_arith_op_expr = @arithnegexpr
+ | @unaryplusexpr
+ | @conjugation
+ | @realpartexpr
+ | @imagpartexpr
+ | @crement_expr
+ ;
+
+@un_bitwise_op_expr = @complementexpr;
+
+@un_log_op_expr = @notexpr;
+
+@un_op_expr = @address_of
+ | @indirect
+ | @un_arith_op_expr
+ | @un_bitwise_op_expr
+ | @builtinaddressof
+ | @vec_fill
+ | @un_log_op_expr
+ | @co_await
+ | @co_yield
+ ;
+
+@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr;
+
+@cmp_op_expr = @eq_op_expr | @rel_op_expr;
+
+@eq_op_expr = @eqexpr | @neexpr;
+
+@rel_op_expr = @gtexpr
+ | @ltexpr
+ | @geexpr
+ | @leexpr
+ | @spaceshipexpr
+ ;
+
+@bin_bitwise_op_expr = @lshiftexpr
+ | @rshiftexpr
+ | @andexpr
+ | @orexpr
+ | @xorexpr
+ ;
+
+@p_arith_op_expr = @paddexpr
+ | @psubexpr
+ | @pdiffexpr
+ ;
+
+@bin_arith_op_expr = @addexpr
+ | @subexpr
+ | @mulexpr
+ | @divexpr
+ | @remexpr
+ | @jmulexpr
+ | @jdivexpr
+ | @fjaddexpr
+ | @jfaddexpr
+ | @fjsubexpr
+ | @jfsubexpr
+ | @minexpr
+ | @maxexpr
+ | @p_arith_op_expr
+ ;
+
+@bin_op_expr = @bin_arith_op_expr
+ | @bin_bitwise_op_expr
+ | @cmp_op_expr
+ | @bin_log_op_expr
+ ;
+
+@op_expr = @un_op_expr
+ | @bin_op_expr
+ | @assign_expr
+ | @conditionalexpr
+ ;
+
+@assign_arith_expr = @assignaddexpr
+ | @assignsubexpr
+ | @assignmulexpr
+ | @assigndivexpr
+ | @assignremexpr
+ ;
+
+@assign_bitwise_expr = @assignandexpr
+ | @assignorexpr
+ | @assignxorexpr
+ | @assignlshiftexpr
+ | @assignrshiftexpr
+ ;
+
+@assign_pointer_expr = @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr
+ | @assign_bitwise_expr
+ | @assign_pointer_expr
+ ;
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ Binary encoding of the allocator form.
+
+ case @allocator.form of
+ 0 = plain
+ | 1 = alignment
+ ;
+*/
+
+/**
+ * The allocator function associated with a `new` or `new[]` expression.
+ * The `form` column specified whether the allocation call contains an alignment
+ * argument.
+ */
+expr_allocator(
+ unique int expr: @any_new_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/*
+ Binary encoding of the deallocator form.
+
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 4 = destroying_delete
+ ;
+*/
+
+/**
+ * The deallocator function associated with a `delete`, `delete[]`, `new`, or
+ * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the
+ * one used to free memory if the initialization throws an exception.
+ * The `form` column specifies whether the deallocation call contains a size
+ * argument, and alignment argument, or both.
+ */
+expr_deallocator(
+ unique int expr: @new_or_delete_expr ref,
+ int func: @function ref,
+ int form: int ref
+);
+
+/**
+ * Holds if the `@conditionalexpr` is of the two operand form
+ * `guard ? : false`.
+ */
+expr_cond_two_operand(
+ unique int cond: @conditionalexpr ref
+);
+
+/**
+ * The guard of `@conditionalexpr` `guard ? true : false`
+ */
+expr_cond_guard(
+ unique int cond: @conditionalexpr ref,
+ int guard: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` holds. For the two operand form
+ * `guard ?: false` consider using `expr_cond_guard` instead.
+ */
+expr_cond_true(
+ unique int cond: @conditionalexpr ref,
+ int true: @expr ref
+);
+
+/**
+ * The expression used when the guard of `@conditionalexpr`
+ * `guard ? true : false` does not hold.
+ */
+expr_cond_false(
+ unique int cond: @conditionalexpr ref,
+ int false: @expr ref
+);
+
+/** A string representation of the value. */
+values(
+ unique int id: @value,
+ string str: string ref
+);
+
+/** The actual text in the source code for the value, if any. */
+valuetext(
+ unique int id: @value ref,
+ string text: string ref
+);
+
+valuebind(
+ int val: @value ref,
+ unique int expr: @expr ref
+);
+
+fieldoffsets(
+ unique int id: @variable ref,
+ int byteoffset: int ref,
+ int bitoffset: int ref
+);
+
+bitfield(
+ unique int id: @variable ref,
+ int bits: int ref,
+ int declared_bits: int ref
+);
+
+/* TODO
+memberprefix(
+ int member: @expr ref,
+ int prefix: @expr ref
+);
+*/
+
+/*
+ kind(1) = mbrcallexpr
+ kind(2) = mbrptrcallexpr
+ kind(3) = mbrptrmbrcallexpr
+ kind(4) = ptrmbrptrmbrcallexpr
+ kind(5) = mbrreadexpr // x.y
+ kind(6) = mbrptrreadexpr // p->y
+ kind(7) = mbrptrmbrreadexpr // x.*pm
+ kind(8) = mbrptrmbrptrreadexpr // x->*pm
+ kind(9) = staticmbrreadexpr // static x.y
+ kind(10) = staticmbrptrreadexpr // static p->y
+*/
+/* TODO
+memberaccess(
+ int member: @expr ref,
+ int kind: int ref
+);
+*/
+
+initialisers(
+ unique int init: @initialiser,
+ int var: @accessible ref,
+ unique int expr: @expr ref,
+ int location: @location_expr ref
+);
+
+braced_initialisers(
+ int init: @initialiser ref
+);
+
+/**
+ * An ancestor for the expression, for cases in which we cannot
+ * otherwise find the expression's parent.
+ */
+expr_ancestor(
+ int exp: @expr ref,
+ int ancestor: @element ref
+);
+
+exprs(
+ unique int id: @expr,
+ int kind: int ref,
+ int location: @location_expr ref
+);
+
+expr_reuse(
+ int reuse: @expr ref,
+ int original: @expr ref,
+ int value_category: int ref
+)
+
+/*
+ case @value.category of
+ 1 = prval
+ | 2 = xval
+ | 3 = lval
+ ;
+*/
+expr_types(
+ int id: @expr ref,
+ int typeid: @type ref,
+ int value_category: int ref
+);
+
+case @expr.kind of
+ 1 = @errorexpr
+| 2 = @address_of // & AddressOfExpr
+| 3 = @reference_to // ReferenceToExpr (implicit?)
+| 4 = @indirect // * PointerDereferenceExpr
+| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?)
+// ...
+| 8 = @array_to_pointer // (???)
+| 9 = @vacuous_destructor_call // VacuousDestructorCall
+// ...
+| 11 = @assume // Microsoft
+| 12 = @parexpr
+| 13 = @arithnegexpr
+| 14 = @unaryplusexpr
+| 15 = @complementexpr
+| 16 = @notexpr
+| 17 = @conjugation // GNU ~ operator
+| 18 = @realpartexpr // GNU __real
+| 19 = @imagpartexpr // GNU __imag
+| 20 = @postincrexpr
+| 21 = @postdecrexpr
+| 22 = @preincrexpr
+| 23 = @predecrexpr
+| 24 = @conditionalexpr
+| 25 = @addexpr
+| 26 = @subexpr
+| 27 = @mulexpr
+| 28 = @divexpr
+| 29 = @remexpr
+| 30 = @jmulexpr // C99 mul imaginary
+| 31 = @jdivexpr // C99 div imaginary
+| 32 = @fjaddexpr // C99 add real + imaginary
+| 33 = @jfaddexpr // C99 add imaginary + real
+| 34 = @fjsubexpr // C99 sub real - imaginary
+| 35 = @jfsubexpr // C99 sub imaginary - real
+| 36 = @paddexpr // pointer add (pointer + int or int + pointer)
+| 37 = @psubexpr // pointer sub (pointer - integer)
+| 38 = @pdiffexpr // difference between two pointers
+| 39 = @lshiftexpr
+| 40 = @rshiftexpr
+| 41 = @andexpr
+| 42 = @orexpr
+| 43 = @xorexpr
+| 44 = @eqexpr
+| 45 = @neexpr
+| 46 = @gtexpr
+| 47 = @ltexpr
+| 48 = @geexpr
+| 49 = @leexpr
+| 50 = @minexpr // GNU minimum
+| 51 = @maxexpr // GNU maximum
+| 52 = @assignexpr
+| 53 = @assignaddexpr
+| 54 = @assignsubexpr
+| 55 = @assignmulexpr
+| 56 = @assigndivexpr
+| 57 = @assignremexpr
+| 58 = @assignlshiftexpr
+| 59 = @assignrshiftexpr
+| 60 = @assignandexpr
+| 61 = @assignorexpr
+| 62 = @assignxorexpr
+| 63 = @assignpaddexpr // assign pointer add
+| 64 = @assignpsubexpr // assign pointer sub
+| 65 = @andlogicalexpr
+| 66 = @orlogicalexpr
+| 67 = @commaexpr
+| 68 = @subscriptexpr // access to member of an array, e.g., a[5]
+// ... 69 @objc_subscriptexpr deprecated
+// ... 70 @cmdaccess deprecated
+// ...
+| 73 = @virtfunptrexpr
+| 74 = @callexpr
+// ... 75 @msgexpr_normal deprecated
+// ... 76 @msgexpr_super deprecated
+// ... 77 @atselectorexpr deprecated
+// ... 78 @atprotocolexpr deprecated
+| 79 = @vastartexpr
+| 80 = @vaargexpr
+| 81 = @vaendexpr
+| 82 = @vacopyexpr
+// ... 83 @atencodeexpr deprecated
+| 84 = @varaccess
+| 85 = @thisaccess
+// ... 86 @objc_box_expr deprecated
+| 87 = @new_expr
+| 88 = @delete_expr
+| 89 = @throw_expr
+| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2)
+| 91 = @braced_init_list
+| 92 = @type_id
+| 93 = @runtime_sizeof
+| 94 = @runtime_alignof
+| 95 = @sizeof_pack
+| 96 = @expr_stmt // GNU extension
+| 97 = @routineexpr
+| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....)
+| 99 = @offsetofexpr // offsetof ::= type and field
+| 100 = @hasassignexpr // __has_assign ::= type
+| 101 = @hascopyexpr // __has_copy ::= type
+| 102 = @hasnothrowassign // __has_nothrow_assign ::= type
+| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type
+| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type
+| 105 = @hastrivialassign // __has_trivial_assign ::= type
+| 106 = @hastrivialconstr // __has_trivial_constructor ::= type
+| 107 = @hastrivialcopy // __has_trivial_copy ::= type
+| 108 = @hasuserdestr // __has_user_destructor ::= type
+| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type
+| 110 = @isabstractexpr // __is_abstract ::= type
+| 111 = @isbaseofexpr // __is_base_of ::= type type
+| 112 = @isclassexpr // __is_class ::= type
+| 113 = @isconvtoexpr // __is_convertible_to ::= type type
+| 114 = @isemptyexpr // __is_empty ::= type
+| 115 = @isenumexpr // __is_enum ::= type
+| 116 = @ispodexpr // __is_pod ::= type
+| 117 = @ispolyexpr // __is_polymorphic ::= type
+| 118 = @isunionexpr // __is_union ::= type
+| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type
+| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof
+// ...
+| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type
+| 123 = @literal
+| 124 = @uuidof
+| 127 = @aggregateliteral
+| 128 = @delete_array_expr
+| 129 = @new_array_expr
+// ... 130 @objc_array_literal deprecated
+// ... 131 @objc_dictionary_literal deprecated
+| 132 = @foldexpr
+// ...
+| 200 = @ctordirectinit
+| 201 = @ctorvirtualinit
+| 202 = @ctorfieldinit
+| 203 = @ctordelegatinginit
+| 204 = @dtordirectdestruct
+| 205 = @dtorvirtualdestruct
+| 206 = @dtorfielddestruct
+// ...
+| 210 = @static_cast
+| 211 = @reinterpret_cast
+| 212 = @const_cast
+| 213 = @dynamic_cast
+| 214 = @c_style_cast
+| 215 = @lambdaexpr
+| 216 = @param_ref
+| 217 = @noopexpr
+// ...
+| 294 = @istriviallyconstructibleexpr
+| 295 = @isdestructibleexpr
+| 296 = @isnothrowdestructibleexpr
+| 297 = @istriviallydestructibleexpr
+| 298 = @istriviallyassignableexpr
+| 299 = @isnothrowassignableexpr
+| 300 = @istrivialexpr
+| 301 = @isstandardlayoutexpr
+| 302 = @istriviallycopyableexpr
+| 303 = @isliteraltypeexpr
+| 304 = @hastrivialmoveconstructorexpr
+| 305 = @hastrivialmoveassignexpr
+| 306 = @hasnothrowmoveassignexpr
+| 307 = @isconstructibleexpr
+| 308 = @isnothrowconstructibleexpr
+| 309 = @hasfinalizerexpr
+| 310 = @isdelegateexpr
+| 311 = @isinterfaceclassexpr
+| 312 = @isrefarrayexpr
+| 313 = @isrefclassexpr
+| 314 = @issealedexpr
+| 315 = @issimplevalueclassexpr
+| 316 = @isvalueclassexpr
+| 317 = @isfinalexpr
+| 319 = @noexceptexpr
+| 320 = @builtinshufflevector
+| 321 = @builtinchooseexpr
+| 322 = @builtinaddressof
+| 323 = @vec_fill
+| 324 = @builtinconvertvector
+| 325 = @builtincomplex
+| 326 = @spaceshipexpr
+| 327 = @co_await
+| 328 = @co_yield
+| 329 = @temp_init
+| 330 = @isassignable
+| 331 = @isaggregate
+| 332 = @hasuniqueobjectrepresentations
+| 333 = @builtinbitcast
+| 334 = @builtinshuffle
+| 335 = @blockassignexpr
+| 336 = @issame
+| 337 = @isfunction
+| 338 = @islayoutcompatible
+| 339 = @ispointerinterconvertiblebaseof
+| 340 = @isarray
+| 341 = @arrayrank
+| 342 = @arrayextent
+| 343 = @isarithmetic
+| 344 = @iscompletetype
+| 345 = @iscompound
+| 346 = @isconst
+| 347 = @isfloatingpoint
+| 348 = @isfundamental
+| 349 = @isintegral
+| 350 = @islvaluereference
+| 351 = @ismemberfunctionpointer
+| 352 = @ismemberobjectpointer
+| 353 = @ismemberpointer
+| 354 = @isobject
+| 355 = @ispointer
+| 356 = @isreference
+| 357 = @isrvaluereference
+| 358 = @isscalar
+| 359 = @issigned
+| 360 = @isunsigned
+| 361 = @isvoid
+| 362 = @isvolatile
+| 363 = @reuseexpr
+| 364 = @istriviallycopyassignable
+| 365 = @isassignablenopreconditioncheck
+| 366 = @referencebindstotemporary
+| 367 = @issameas
+| 368 = @builtinhasattribute
+| 369 = @ispointerinterconvertiblewithclass
+| 370 = @builtinispointerinterconvertiblewithclass
+| 371 = @iscorrespondingmember
+| 372 = @builtiniscorrespondingmember
+| 373 = @isboundedarray
+| 374 = @isunboundedarray
+| 375 = @isreferenceable
+| 378 = @isnothrowconvertible
+| 379 = @referenceconstructsfromtemporary
+| 380 = @referenceconvertsfromtemporary
+| 381 = @isconvertible
+| 382 = @isvalidwinrttype
+| 383 = @iswinclass
+| 384 = @iswininterface
+| 385 = @istriviallyequalitycomparable
+| 386 = @isscopedenum
+| 387 = @istriviallyrelocatable
+| 388 = @datasizeof
+| 389 = @c11_generic
+| 390 = @requires_expr
+| 391 = @nested_requirement
+| 392 = @compound_requirement
+| 393 = @concept_id
+;
+
+@var_args_expr = @vastartexpr
+ | @vaendexpr
+ | @vaargexpr
+ | @vacopyexpr
+ ;
+
+@builtin_op = @var_args_expr
+ | @noopexpr
+ | @offsetofexpr
+ | @intaddrexpr
+ | @hasassignexpr
+ | @hascopyexpr
+ | @hasnothrowassign
+ | @hasnothrowconstr
+ | @hasnothrowcopy
+ | @hastrivialassign
+ | @hastrivialconstr
+ | @hastrivialcopy
+ | @hastrivialdestructor
+ | @hasuserdestr
+ | @hasvirtualdestr
+ | @isabstractexpr
+ | @isbaseofexpr
+ | @isclassexpr
+ | @isconvtoexpr
+ | @isemptyexpr
+ | @isenumexpr
+ | @ispodexpr
+ | @ispolyexpr
+ | @isunionexpr
+ | @typescompexpr
+ | @builtinshufflevector
+ | @builtinconvertvector
+ | @builtinaddressof
+ | @istriviallyconstructibleexpr
+ | @isdestructibleexpr
+ | @isnothrowdestructibleexpr
+ | @istriviallydestructibleexpr
+ | @istriviallyassignableexpr
+ | @isnothrowassignableexpr
+ | @istrivialexpr
+ | @isstandardlayoutexpr
+ | @istriviallycopyableexpr
+ | @isliteraltypeexpr
+ | @hastrivialmoveconstructorexpr
+ | @hastrivialmoveassignexpr
+ | @hasnothrowmoveassignexpr
+ | @isconstructibleexpr
+ | @isnothrowconstructibleexpr
+ | @hasfinalizerexpr
+ | @isdelegateexpr
+ | @isinterfaceclassexpr
+ | @isrefarrayexpr
+ | @isrefclassexpr
+ | @issealedexpr
+ | @issimplevalueclassexpr
+ | @isvalueclassexpr
+ | @isfinalexpr
+ | @builtinchooseexpr
+ | @builtincomplex
+ | @isassignable
+ | @isaggregate
+ | @hasuniqueobjectrepresentations
+ | @builtinbitcast
+ | @builtinshuffle
+ | @issame
+ | @isfunction
+ | @islayoutcompatible
+ | @ispointerinterconvertiblebaseof
+ | @isarray
+ | @arrayrank
+ | @arrayextent
+ | @isarithmetic
+ | @iscompletetype
+ | @iscompound
+ | @isconst
+ | @isfloatingpoint
+ | @isfundamental
+ | @isintegral
+ | @islvaluereference
+ | @ismemberfunctionpointer
+ | @ismemberobjectpointer
+ | @ismemberpointer
+ | @isobject
+ | @ispointer
+ | @isreference
+ | @isrvaluereference
+ | @isscalar
+ | @issigned
+ | @isunsigned
+ | @isvoid
+ | @isvolatile
+ | @istriviallycopyassignable
+ | @isassignablenopreconditioncheck
+ | @referencebindstotemporary
+ | @issameas
+ | @builtinhasattribute
+ | @ispointerinterconvertiblewithclass
+ | @builtinispointerinterconvertiblewithclass
+ | @iscorrespondingmember
+ | @builtiniscorrespondingmember
+ | @isboundedarray
+ | @isunboundedarray
+ | @isreferenceable
+ | @isnothrowconvertible
+ | @referenceconstructsfromtemporary
+ | @referenceconvertsfromtemporary
+ | @isconvertible
+ | @isvalidwinrttype
+ | @iswinclass
+ | @iswininterface
+ | @istriviallyequalitycomparable
+ | @isscopedenum
+ | @istriviallyrelocatable
+ ;
+
+compound_requirement_is_noexcept(
+ int expr: @compound_requirement ref
+);
+
+new_allocated_type(
+ unique int expr: @new_expr ref,
+ int type_id: @type ref
+);
+
+new_array_allocated_type(
+ unique int expr: @new_array_expr ref,
+ int type_id: @type ref
+);
+
+/**
+ * The field being initialized by an initializer expression within an aggregate
+ * initializer for a class/struct/union. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_field_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int field: @membervariable ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+/**
+ * The index of the element being initialized by an initializer expression
+ * within an aggregate initializer for an array. Position is used to sort repeated initializers.
+ */
+#keyset[aggregate, position]
+aggregate_array_init(
+ int aggregate: @aggregateliteral ref,
+ int initializer: @expr ref,
+ int element_index: int ref,
+ int position: int ref,
+ boolean is_designated: boolean ref
+);
+
+@ctorinit = @ctordirectinit
+ | @ctorvirtualinit
+ | @ctorfieldinit
+ | @ctordelegatinginit;
+@dtordestruct = @dtordirectdestruct
+ | @dtorvirtualdestruct
+ | @dtorfielddestruct;
+
+
+condition_decl_bind(
+ unique int expr: @condition_decl ref,
+ unique int decl: @declaration ref
+);
+
+typeid_bind(
+ unique int expr: @type_id ref,
+ int type_id: @type ref
+);
+
+uuidof_bind(
+ unique int expr: @uuidof ref,
+ int type_id: @type ref
+);
+
+@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;
+
+sizeof_bind(
+ unique int expr: @sizeof_or_alignof ref,
+ int type_id: @type ref
+);
+
+code_block(
+ unique int block: @literal ref,
+ unique int routine: @function ref
+);
+
+lambdas(
+ unique int expr: @lambdaexpr ref,
+ string default_capture: string ref,
+ boolean has_explicit_return_type: boolean ref,
+ boolean has_explicit_parameter_list: boolean ref
+);
+
+lambda_capture(
+ unique int id: @lambdacapture,
+ int lambda: @lambdaexpr ref,
+ int index: int ref,
+ int field: @membervariable ref,
+ boolean captured_by_reference: boolean ref,
+ boolean is_implicit: boolean ref,
+ int location: @location_default ref
+);
+
+@funbindexpr = @routineexpr
+ | @new_expr
+ | @delete_expr
+ | @delete_array_expr
+ | @ctordirectinit
+ | @ctorvirtualinit
+ | @ctordelegatinginit
+ | @dtordirectdestruct
+ | @dtorvirtualdestruct;
+
+@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct;
+@addressable = @function | @variable ;
+@accessible = @addressable | @enumconstant ;
+
+@access = @varaccess | @routineexpr ;
+
+fold(
+ int expr: @foldexpr ref,
+ string operator: string ref,
+ boolean is_left_fold: boolean ref
+);
+
+stmts(
+ unique int id: @stmt,
+ int kind: int ref,
+ int location: @location_stmt ref
+);
+
+case @stmt.kind of
+ 1 = @stmt_expr
+| 2 = @stmt_if
+| 3 = @stmt_while
+| 4 = @stmt_goto
+| 5 = @stmt_label
+| 6 = @stmt_return
+| 7 = @stmt_block
+| 8 = @stmt_end_test_while // do { ... } while ( ... )
+| 9 = @stmt_for
+| 10 = @stmt_switch_case
+| 11 = @stmt_switch
+| 13 = @stmt_asm // "asm" statement or the body of an asm function
+| 15 = @stmt_try_block
+| 16 = @stmt_microsoft_try // Microsoft
+| 17 = @stmt_decl
+| 18 = @stmt_set_vla_size // C99
+| 19 = @stmt_vla_decl // C99
+| 25 = @stmt_assigned_goto // GNU
+| 26 = @stmt_empty
+| 27 = @stmt_continue
+| 28 = @stmt_break
+| 29 = @stmt_range_based_for // C++11
+// ... 30 @stmt_at_autoreleasepool_block deprecated
+// ... 31 @stmt_objc_for_in deprecated
+// ... 32 @stmt_at_synchronized deprecated
+| 33 = @stmt_handler
+// ... 34 @stmt_finally_end deprecated
+| 35 = @stmt_constexpr_if
+| 37 = @stmt_co_return
+| 38 = @stmt_consteval_if
+| 39 = @stmt_not_consteval_if
+;
+
+type_vla(
+ int type_id: @type ref,
+ int decl: @stmt_vla_decl ref
+);
+
+variable_vla(
+ int var: @variable ref,
+ int decl: @stmt_vla_decl ref
+);
+
+type_is_vla(unique int type_id: @derivedtype ref)
+
+if_initialization(
+ unique int if_stmt: @stmt_if ref,
+ int init_id: @stmt ref
+);
+
+if_then(
+ unique int if_stmt: @stmt_if ref,
+ int then_id: @stmt ref
+);
+
+if_else(
+ unique int if_stmt: @stmt_if ref,
+ int else_id: @stmt ref
+);
+
+constexpr_if_initialization(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int init_id: @stmt ref
+);
+
+constexpr_if_then(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int then_id: @stmt ref
+);
+
+constexpr_if_else(
+ unique int constexpr_if_stmt: @stmt_constexpr_if ref,
+ int else_id: @stmt ref
+);
+
+@stmt_consteval_or_not_consteval_if = @stmt_consteval_if | @stmt_not_consteval_if;
+
+consteval_if_then(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int then_id: @stmt ref
+);
+
+consteval_if_else(
+ unique int constexpr_if_stmt: @stmt_consteval_or_not_consteval_if ref,
+ int else_id: @stmt ref
+);
+
+while_body(
+ unique int while_stmt: @stmt_while ref,
+ int body_id: @stmt ref
+);
+
+do_body(
+ unique int do_stmt: @stmt_end_test_while ref,
+ int body_id: @stmt ref
+);
+
+switch_initialization(
+ unique int switch_stmt: @stmt_switch ref,
+ int init_id: @stmt ref
+);
+
+#keyset[switch_stmt, index]
+switch_case(
+ int switch_stmt: @stmt_switch ref,
+ int index: int ref,
+ int case_id: @stmt_switch_case ref
+);
+
+switch_body(
+ unique int switch_stmt: @stmt_switch ref,
+ int body_id: @stmt ref
+);
+
+@stmt_for_or_range_based_for = @stmt_for
+ | @stmt_range_based_for;
+
+for_initialization(
+ unique int for_stmt: @stmt_for_or_range_based_for ref,
+ int init_id: @stmt ref
+);
+
+for_condition(
+ unique int for_stmt: @stmt_for ref,
+ int condition_id: @expr ref
+);
+
+for_update(
+ unique int for_stmt: @stmt_for ref,
+ int update_id: @expr ref
+);
+
+for_body(
+ unique int for_stmt: @stmt_for ref,
+ int body_id: @stmt ref
+);
+
+@stmtparent = @stmt | @expr_stmt ;
+stmtparents(
+ unique int id: @stmt ref,
+ int index: int ref,
+ int parent: @stmtparent ref
+);
+
+ishandler(unique int block: @stmt_block ref);
+
+@cfgnode = @stmt | @expr | @function | @initialiser ;
+
+stmt_decl_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl: @declaration ref
+);
+
+stmt_decl_entry_bind(
+ int stmt: @stmt_decl ref,
+ int num: int ref,
+ int decl_entry: @element ref
+);
+
+@parameterized_element = @function | @stmt_block | @requires_expr;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @parameterized_element ref
+);
+
+@jump = @stmt_goto | @stmt_break | @stmt_continue;
+
+@jumporlabel = @jump | @stmt_label | @literal;
+
+jumpinfo(
+ unique int id: @jumporlabel ref,
+ string str: string ref,
+ int target: @stmt ref
+);
+
+preprocdirects(
+ unique int id: @preprocdirect,
+ int kind: int ref,
+ int location: @location_default ref
+);
+case @preprocdirect.kind of
+ 0 = @ppd_if
+| 1 = @ppd_ifdef
+| 2 = @ppd_ifndef
+| 3 = @ppd_elif
+| 4 = @ppd_else
+| 5 = @ppd_endif
+| 6 = @ppd_plain_include
+| 7 = @ppd_define
+| 8 = @ppd_undef
+| 9 = @ppd_line
+| 10 = @ppd_error
+| 11 = @ppd_pragma
+| 12 = @ppd_objc_import
+| 13 = @ppd_include_next
+| 14 = @ppd_ms_import
+| 15 = @ppd_elifdef
+| 16 = @ppd_elifndef
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
+
+preprocpair(
+ int begin : @ppd_branch ref,
+ int elseelifend : @preprocdirect ref
+);
+
+preproctrue(int branch : @ppd_branch ref);
+preprocfalse(int branch : @ppd_branch ref);
+
+preproctext(
+ unique int id: @preprocdirect ref,
+ string head: string ref,
+ string body: string ref
+);
+
+includes(
+ unique int id: @ppd_include ref,
+ int included: @file ref
+);
+
+link_targets(
+ int id: @link_target,
+ int binary: @file ref
+);
+
+link_parent(
+ int element : @element ref,
+ int link_target : @link_target ref
+);
+
+/* 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;
diff --git a/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties
new file mode 100644
index 000000000000..9dc80bb35fcb
--- /dev/null
+++ b/cpp/ql/lib/upgrades/af887e83a815a9cefe774ffa80e2493a1365b9e2/upgrade.properties
@@ -0,0 +1,3 @@
+description: capture whether a lambda has an explicitly specified parameter list.
+compatibility: backwards
+lambdas.rel: run lambdas.qlo
diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml
index 52f0f08a4c55..290c18cb815b 100644
--- a/cpp/ql/src/qlpack.yml
+++ b/cpp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/cpp-queries
-version: 1.4.2
+version: 1.4.3-dev
groups:
- cpp
- queries
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index 0b825a0a855b..b9ffaf71656b 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -58,6 +58,77 @@
#-----| Type = [LongType] unsigned long
#-----| getParameter(1): [Parameter] (unnamed parameter 1)
#-----| Type = [ScopedEnum] align_val_t
+arm.cpp:
+# 6| [TopLevelFunction] uint8x8_t vadd_u8(uint8x8_t, uint8x8_t)
+# 6| :
+# 6| getParameter(0): [Parameter] a
+# 6| Type = [CTypedefType] uint8x8_t
+# 6| getParameter(1): [Parameter] b
+# 6| Type = [CTypedefType] uint8x8_t
+# 6| getEntryPoint(): [BlockStmt] { ... }
+# 7| getStmt(0): [ReturnStmt] return ...
+# 7| getExpr(): [AddExpr] ... + ...
+# 7| Type = [GNUVectorType] __attribute((neon_vector_type(8))) unsigned char
+# 7| ValueCategory = prvalue
+# 7| getLeftOperand(): [VariableAccess] a
+# 7| Type = [CTypedefType] uint8x8_t
+# 7| ValueCategory = prvalue(load)
+# 7| getRightOperand(): [VariableAccess] b
+# 7| Type = [CTypedefType] uint8x8_t
+# 7| ValueCategory = prvalue(load)
+# 12| [TopLevelFunction] uint16x8_t __builtin_aarch64_uaddlv8qi_uuu(uint8x8_t, uint8x8_t)
+# 12| :
+# 12| getParameter(0): [Parameter] (unnamed parameter 0)
+# 12| Type = [CTypedefType] uint8x8_t
+# 12| getParameter(1): [Parameter] (unnamed parameter 1)
+# 12| Type = [CTypedefType] uint8x8_t
+# 14| [TopLevelFunction] uint16x8_t vaddl_u8(uint8x8_t, uint8x8_t)
+# 14| :
+# 14| getParameter(0): [Parameter] a
+# 14| Type = [CTypedefType] uint8x8_t
+# 14| getParameter(1): [Parameter] b
+# 14| Type = [CTypedefType] uint8x8_t
+# 14| getEntryPoint(): [BlockStmt] { ... }
+# 15| getStmt(0): [ReturnStmt] return ...
+# 15| getExpr(): [FunctionCall] call to __builtin_aarch64_uaddlv8qi_uuu
+# 15| Type = [CTypedefType] uint16x8_t
+# 15| ValueCategory = prvalue
+# 15| getArgument(0): [VariableAccess] a
+# 15| Type = [CTypedefType] uint8x8_t
+# 15| ValueCategory = prvalue(load)
+# 15| getArgument(1): [VariableAccess] b
+# 15| Type = [CTypedefType] uint8x8_t
+# 15| ValueCategory = prvalue(load)
+# 18| [TopLevelFunction] uint16x8_t arm_add(uint8x8_t, uint8x8_t)
+# 18| :
+# 18| getParameter(0): [Parameter] a
+# 18| Type = [CTypedefType] uint8x8_t
+# 18| getParameter(1): [Parameter] b
+# 18| Type = [CTypedefType] uint8x8_t
+# 18| getEntryPoint(): [BlockStmt] { ... }
+# 19| getStmt(0): [DeclStmt] declaration
+# 19| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
+# 19| Type = [CTypedefType] uint8x8_t
+# 19| getVariable().getInitializer(): [Initializer] initializer for c
+# 19| getExpr(): [FunctionCall] call to vadd_u8
+# 19| Type = [CTypedefType] uint8x8_t
+# 19| ValueCategory = prvalue
+# 19| getArgument(0): [VariableAccess] a
+# 19| Type = [CTypedefType] uint8x8_t
+# 19| ValueCategory = prvalue(load)
+# 19| getArgument(1): [VariableAccess] b
+# 19| Type = [CTypedefType] uint8x8_t
+# 19| ValueCategory = prvalue(load)
+# 20| getStmt(1): [ReturnStmt] return ...
+# 20| getExpr(): [FunctionCall] call to vaddl_u8
+# 20| Type = [CTypedefType] uint16x8_t
+# 20| ValueCategory = prvalue
+# 20| getArgument(0): [VariableAccess] a
+# 20| Type = [CTypedefType] uint8x8_t
+# 20| ValueCategory = prvalue(load)
+# 20| getArgument(1): [VariableAccess] c
+# 20| Type = [CTypedefType] uint8x8_t
+# 20| ValueCategory = prvalue(load)
bad_asts.cpp:
# 5| [CopyAssignmentOperator] Bad::S& Bad::S::operator=(Bad::S const&)
# 5| :
diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
index 20d593e2379a..fbd0db5e7966 100644
--- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
@@ -1,3 +1,86 @@
+arm.cpp:
+# 6| uint8x8_t vadd_u8(uint8x8_t, uint8x8_t)
+# 6| Block 0
+# 6| v6_1(void) = EnterFunction :
+# 6| m6_2(unknown) = AliasedDefinition :
+# 6| m6_3(unknown) = InitializeNonLocal :
+# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3
+# 6| r6_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 6| m6_6(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r6_5
+# 6| r6_7(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 6| m6_8(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r6_7
+# 7| r7_1(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[#return] :
+# 7| r7_2(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 7| r7_3(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r7_2, m6_6
+# 7| r7_4(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 7| r7_5(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r7_4, m6_8
+# 7| r7_6(__attribute((neon_vector_type(8))) unsigned char) = Add : r7_3, r7_5
+# 7| m7_7(__attribute((neon_vector_type(8))) unsigned char) = Store[#return] : &:r7_1, r7_6
+# 6| r6_9(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[#return] :
+# 6| v6_10(void) = ReturnValue : &:r6_9, m7_7
+# 6| v6_11(void) = AliasedUse : m6_3
+# 6| v6_12(void) = ExitFunction :
+
+# 14| uint16x8_t vaddl_u8(uint8x8_t, uint8x8_t)
+# 14| Block 0
+# 14| v14_1(void) = EnterFunction :
+# 14| m14_2(unknown) = AliasedDefinition :
+# 14| m14_3(unknown) = InitializeNonLocal :
+# 14| m14_4(unknown) = Chi : total:m14_2, partial:m14_3
+# 14| r14_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 14| m14_6(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r14_5
+# 14| r14_7(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 14| m14_8(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r14_7
+# 15| r15_1(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 15| r15_2(glval) = FunctionAddress[__builtin_aarch64_uaddlv8qi_uuu] :
+# 15| r15_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 15| r15_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r15_3, m14_6
+# 15| r15_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 15| r15_6(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r15_5, m14_8
+# 15| r15_7(__attribute((neon_vector_type(8))) unsigned short) = Call[__builtin_aarch64_uaddlv8qi_uuu] : func:r15_2, 0:r15_4, 1:r15_6
+# 15| m15_8(unknown) = ^CallSideEffect : ~m14_4
+# 15| m15_9(unknown) = Chi : total:m14_4, partial:m15_8
+# 15| m15_10(__attribute((neon_vector_type(8))) unsigned short) = Store[#return] : &:r15_1, r15_7
+# 14| r14_9(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 14| v14_10(void) = ReturnValue : &:r14_9, m15_10
+# 14| v14_11(void) = AliasedUse : ~m15_9
+# 14| v14_12(void) = ExitFunction :
+
+# 18| uint16x8_t arm_add(uint8x8_t, uint8x8_t)
+# 18| Block 0
+# 18| v18_1(void) = EnterFunction :
+# 18| m18_2(unknown) = AliasedDefinition :
+# 18| m18_3(unknown) = InitializeNonLocal :
+# 18| m18_4(unknown) = Chi : total:m18_2, partial:m18_3
+# 18| r18_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 18| m18_6(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r18_5
+# 18| r18_7(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 18| m18_8(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r18_7
+# 19| r19_1(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[c] :
+# 19| r19_2(glval) = FunctionAddress[vadd_u8] :
+# 19| r19_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 19| r19_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r19_3, m18_6
+# 19| r19_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 19| r19_6(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r19_5, m18_8
+# 19| r19_7(__attribute((neon_vector_type(8))) unsigned char) = Call[vadd_u8] : func:r19_2, 0:r19_4, 1:r19_6
+# 19| m19_8(unknown) = ^CallSideEffect : ~m18_4
+# 19| m19_9(unknown) = Chi : total:m18_4, partial:m19_8
+# 19| m19_10(__attribute((neon_vector_type(8))) unsigned char) = Store[c] : &:r19_1, r19_7
+# 20| r20_1(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 20| r20_2(glval) = FunctionAddress[vaddl_u8] :
+# 20| r20_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 20| r20_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r20_3, m18_6
+# 20| r20_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[c] :
+# 20| r20_6(__attribute((neon_vector_type(8))) unsigned char) = Load[c] : &:r20_5, m19_10
+# 20| r20_7(__attribute((neon_vector_type(8))) unsigned short) = Call[vaddl_u8] : func:r20_2, 0:r20_4, 1:r20_6
+# 20| m20_8(unknown) = ^CallSideEffect : ~m19_9
+# 20| m20_9(unknown) = Chi : total:m19_9, partial:m20_8
+# 20| m20_10(__attribute((neon_vector_type(8))) unsigned short) = Store[#return] : &:r20_1, r20_7
+# 18| r18_9(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 18| v18_10(void) = ReturnValue : &:r18_9, m20_10
+# 18| v18_11(void) = AliasedUse : ~m20_9
+# 18| v18_12(void) = ExitFunction :
+
bad_asts.cpp:
# 9| int Bad::S::MemberFunction(int)
# 9| Block 0
diff --git a/cpp/ql/test/library-tests/ir/ir/arm.cpp b/cpp/ql/test/library-tests/ir/ir/arm.cpp
new file mode 100644
index 000000000000..36e20715bc57
--- /dev/null
+++ b/cpp/ql/test/library-tests/ir/ir/arm.cpp
@@ -0,0 +1,21 @@
+// semmle-extractor-options: --edg --target --edg linux_arm64
+
+typedef __Uint8x8_t uint8x8_t;
+typedef __Uint16x8_t uint16x8_t;
+
+uint8x8_t vadd_u8(uint8x8_t a, uint8x8_t b) {
+ return a + b;
+}
+
+// Workaround: the frontend only exposes this when the arm_neon.h
+// header is encountered.
+uint16x8_t __builtin_aarch64_uaddlv8qi_uuu(uint8x8_t, uint8x8_t);
+
+uint16x8_t vaddl_u8(uint8x8_t a, uint8x8_t b) {
+ return __builtin_aarch64_uaddlv8qi_uuu (a, b);
+}
+
+uint16x8_t arm_add(uint8x8_t a, uint8x8_t b) {
+ uint8x8_t c = vadd_u8(a, b);
+ return vaddl_u8(a, c);
+}
diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
index 11d74a2a26bd..978d05d4b165 100644
--- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
@@ -1,3 +1,80 @@
+arm.cpp:
+# 6| uint8x8_t vadd_u8(uint8x8_t, uint8x8_t)
+# 6| Block 0
+# 6| v6_1(void) = EnterFunction :
+# 6| mu6_2(unknown) = AliasedDefinition :
+# 6| mu6_3(unknown) = InitializeNonLocal :
+# 6| r6_4(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 6| mu6_5(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r6_4
+# 6| r6_6(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 6| mu6_7(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r6_6
+# 7| r7_1(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[#return] :
+# 7| r7_2(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 7| r7_3(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r7_2, ~m?
+# 7| r7_4(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 7| r7_5(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r7_4, ~m?
+# 7| r7_6(__attribute((neon_vector_type(8))) unsigned char) = Add : r7_3, r7_5
+# 7| mu7_7(__attribute((neon_vector_type(8))) unsigned char) = Store[#return] : &:r7_1, r7_6
+# 6| r6_8(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[#return] :
+# 6| v6_9(void) = ReturnValue : &:r6_8, ~m?
+# 6| v6_10(void) = AliasedUse : ~m?
+# 6| v6_11(void) = ExitFunction :
+
+# 14| uint16x8_t vaddl_u8(uint8x8_t, uint8x8_t)
+# 14| Block 0
+# 14| v14_1(void) = EnterFunction :
+# 14| mu14_2(unknown) = AliasedDefinition :
+# 14| mu14_3(unknown) = InitializeNonLocal :
+# 14| r14_4(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 14| mu14_5(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r14_4
+# 14| r14_6(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 14| mu14_7(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r14_6
+# 15| r15_1(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 15| r15_2(glval) = FunctionAddress[__builtin_aarch64_uaddlv8qi_uuu] :
+# 15| r15_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 15| r15_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r15_3, ~m?
+# 15| r15_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 15| r15_6(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r15_5, ~m?
+# 15| r15_7(__attribute((neon_vector_type(8))) unsigned short) = Call[__builtin_aarch64_uaddlv8qi_uuu] : func:r15_2, 0:r15_4, 1:r15_6
+# 15| mu15_8(unknown) = ^CallSideEffect : ~m?
+# 15| mu15_9(__attribute((neon_vector_type(8))) unsigned short) = Store[#return] : &:r15_1, r15_7
+# 14| r14_8(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 14| v14_9(void) = ReturnValue : &:r14_8, ~m?
+# 14| v14_10(void) = AliasedUse : ~m?
+# 14| v14_11(void) = ExitFunction :
+
+# 18| uint16x8_t arm_add(uint8x8_t, uint8x8_t)
+# 18| Block 0
+# 18| v18_1(void) = EnterFunction :
+# 18| mu18_2(unknown) = AliasedDefinition :
+# 18| mu18_3(unknown) = InitializeNonLocal :
+# 18| r18_4(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 18| mu18_5(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[a] : &:r18_4
+# 18| r18_6(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 18| mu18_7(__attribute((neon_vector_type(8))) unsigned char) = InitializeParameter[b] : &:r18_6
+# 19| r19_1(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[c] :
+# 19| r19_2(glval) = FunctionAddress[vadd_u8] :
+# 19| r19_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 19| r19_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r19_3, ~m?
+# 19| r19_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[b] :
+# 19| r19_6(__attribute((neon_vector_type(8))) unsigned char) = Load[b] : &:r19_5, ~m?
+# 19| r19_7(__attribute((neon_vector_type(8))) unsigned char) = Call[vadd_u8] : func:r19_2, 0:r19_4, 1:r19_6
+# 19| mu19_8(unknown) = ^CallSideEffect : ~m?
+# 19| mu19_9(__attribute((neon_vector_type(8))) unsigned char) = Store[c] : &:r19_1, r19_7
+# 20| r20_1(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 20| r20_2(glval) = FunctionAddress[vaddl_u8] :
+# 20| r20_3(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[a] :
+# 20| r20_4(__attribute((neon_vector_type(8))) unsigned char) = Load[a] : &:r20_3, ~m?
+# 20| r20_5(glval<__attribute((neon_vector_type(8))) unsigned char>) = VariableAddress[c] :
+# 20| r20_6(__attribute((neon_vector_type(8))) unsigned char) = Load[c] : &:r20_5, ~m?
+# 20| r20_7(__attribute((neon_vector_type(8))) unsigned short) = Call[vaddl_u8] : func:r20_2, 0:r20_4, 1:r20_6
+# 20| mu20_8(unknown) = ^CallSideEffect : ~m?
+# 20| mu20_9(__attribute((neon_vector_type(8))) unsigned short) = Store[#return] : &:r20_1, r20_7
+# 18| r18_8(glval<__attribute((neon_vector_type(8))) unsigned short>) = VariableAddress[#return] :
+# 18| v18_9(void) = ReturnValue : &:r18_8, ~m?
+# 18| v18_10(void) = AliasedUse : ~m?
+# 18| v18_11(void) = ExitFunction :
+
bad_asts.cpp:
# 9| int Bad::S::MemberFunction(int)
# 9| Block 0
diff --git a/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.expected b/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.expected
new file mode 100644
index 000000000000..1beb3eed3b39
--- /dev/null
+++ b/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.expected
@@ -0,0 +1,11 @@
+| parameters.cpp:2:5:2:23 | [...](...){...} | with list | 2 |
+| parameters.cpp:4:5:4:22 | [...](...){...} | with list | 1 |
+| parameters.cpp:6:5:6:17 | [...](...){...} | with list | 1 |
+| parameters.cpp:8:5:8:20 | [...](...){...} | with list | 0 |
+| parameters.cpp:10:5:10:26 | [...](...){...} | with list | 0 |
+| parameters.cpp:11:5:11:24 | [...](...){...} | without list | 0 |
+| parameters.cpp:13:5:13:20 | [...](...){...} | with list | 0 |
+| parameters.cpp:16:5:18:5 | [...](...){...} | with list | 0 |
+| parameters.cpp:20:5:22:5 | [...](...){...} | without list | 0 |
+| parameters.cpp:24:5:24:10 | [...](...){...} | without list | 0 |
+| parameters.cpp:25:5:25:14 | [...](...){...} | with list | 0 |
diff --git a/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.ql b/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.ql
new file mode 100644
index 000000000000..ae2043687a0a
--- /dev/null
+++ b/cpp/ql/test/library-tests/lambdas/syntax/empty_declarator.ql
@@ -0,0 +1,5 @@
+import cpp
+
+from LambdaExpression e, string parameterList
+where if e.hasParameterList() then parameterList = "with list" else parameterList = "without list"
+select e, parameterList, e.getLambdaFunction().getNumberOfParameters()
diff --git a/cpp/ql/test/library-tests/lambdas/syntax/parameters.cpp b/cpp/ql/test/library-tests/lambdas/syntax/parameters.cpp
new file mode 100644
index 000000000000..6d9bca191b16
--- /dev/null
+++ b/cpp/ql/test/library-tests/lambdas/syntax/parameters.cpp
@@ -0,0 +1,26 @@
+void test_lambda_declarator() {
+ [=](int, float) { };
+
+ [](int x = 42) { };
+
+ [](int x) { };
+
+ []() mutable { };
+
+ []() [[nodiscard]] { };
+ [] [[nodiscard]] { };
+
+ []() -> void { };
+
+ int i;
+ [&i]() {
+ i += 1;
+ };
+
+ [&i] {
+ i += 1;
+ };
+
+ [] { };
+ [=] () { };
+}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/stmt/leave/leave.cpp b/cpp/ql/test/library-tests/stmt/leave/leave.cpp
new file mode 100644
index 000000000000..f81f63d4a922
--- /dev/null
+++ b/cpp/ql/test/library-tests/stmt/leave/leave.cpp
@@ -0,0 +1,28 @@
+//semmle-extractor-options: --microsoft
+void leave_try_finally_test(bool condition){
+ __try {
+ if(condition){
+ __leave;
+ }
+ }
+ __finally {
+ }
+}
+
+int except_handler();
+
+void leave_try_except_test(bool condition){
+ __try {
+ try {
+ if(condition)
+ __leave;
+ }
+ catch(...) {
+ }
+ if(condition){
+ __leave;
+ }
+ }
+ __except (except_handler()) {
+ }
+}
diff --git a/cpp/ql/test/library-tests/stmt/leave/leave.expected b/cpp/ql/test/library-tests/stmt/leave/leave.expected
new file mode 100644
index 000000000000..d33c0876597f
--- /dev/null
+++ b/cpp/ql/test/library-tests/stmt/leave/leave.expected
@@ -0,0 +1,3 @@
+| leave.cpp:5:8:5:15 | __leave; | leave.cpp:3:5:7:5 | __try { ... } __finally { ... } |
+| leave.cpp:18:17:18:24 | __leave; | leave.cpp:15:5:25:5 | __try { ... } __except( ... ) { ... } |
+| leave.cpp:23:13:23:20 | __leave; | leave.cpp:15:5:25:5 | __try { ... } __except( ... ) { ... } |
diff --git a/cpp/ql/test/library-tests/stmt/leave/leave.ql b/cpp/ql/test/library-tests/stmt/leave/leave.ql
new file mode 100644
index 000000000000..c863b64d3510
--- /dev/null
+++ b/cpp/ql/test/library-tests/stmt/leave/leave.ql
@@ -0,0 +1,4 @@
+import cpp
+
+from LeaveStmt s
+select s, s.getEnclosingTry()
diff --git a/cpp/ql/test/library-tests/templates/type_instantiations/types.expected b/cpp/ql/test/library-tests/templates/type_instantiations/types.expected
index 3539e52eecfb..a86ab5e7bbd5 100644
--- a/cpp/ql/test/library-tests/templates/type_instantiations/types.expected
+++ b/cpp/ql/test/library-tests/templates/type_instantiations/types.expected
@@ -25,6 +25,7 @@
| file://:0:0:0:0 | __float128 |
| file://:0:0:0:0 | __fp16 |
| file://:0:0:0:0 | __int128 |
+| file://:0:0:0:0 | __mfp8 |
| file://:0:0:0:0 | __va_list_tag |
| file://:0:0:0:0 | __va_list_tag & |
| file://:0:0:0:0 | __va_list_tag && |
diff --git a/cpp/ql/test/library-tests/type_sizes/type_sizes.expected b/cpp/ql/test/library-tests/type_sizes/type_sizes.expected
index b7bc9e04fe34..08e8b26f5256 100644
--- a/cpp/ql/test/library-tests/type_sizes/type_sizes.expected
+++ b/cpp/ql/test/library-tests/type_sizes/type_sizes.expected
@@ -46,6 +46,7 @@
| file://:0:0:0:0 | __float128 | 16 |
| file://:0:0:0:0 | __fp16 | 2 |
| file://:0:0:0:0 | __int128 | 16 |
+| file://:0:0:0:0 | __mfp8 | 1 |
| file://:0:0:0:0 | __va_list_tag | 24 |
| file://:0:0:0:0 | __va_list_tag & | 8 |
| file://:0:0:0:0 | __va_list_tag && | 8 |
diff --git a/cpp/ql/test/library-tests/unspecified_type/types/unspecified_type.expected b/cpp/ql/test/library-tests/unspecified_type/types/unspecified_type.expected
index 00ae3fa5d8f3..2e5091754b99 100644
--- a/cpp/ql/test/library-tests/unspecified_type/types/unspecified_type.expected
+++ b/cpp/ql/test/library-tests/unspecified_type/types/unspecified_type.expected
@@ -27,6 +27,7 @@
| file://:0:0:0:0 | __float128 | __float128 |
| file://:0:0:0:0 | __fp16 | __fp16 |
| file://:0:0:0:0 | __int128 | __int128 |
+| file://:0:0:0:0 | __mfp8 | __mfp8 |
| file://:0:0:0:0 | __va_list_tag & | __va_list_tag & |
| file://:0:0:0:0 | __va_list_tag && | __va_list_tag && |
| file://:0:0:0:0 | auto | auto |
diff --git a/cpp/ql/test/library-tests/variables/variables/types.expected b/cpp/ql/test/library-tests/variables/variables/types.expected
index 6ecf14875ca4..1d091ac2571b 100644
--- a/cpp/ql/test/library-tests/variables/variables/types.expected
+++ b/cpp/ql/test/library-tests/variables/variables/types.expected
@@ -26,6 +26,7 @@
| __float128 | Float128Type | | | | |
| __fp16 | BinaryFloatingPointType, RealNumberType | | | | |
| __int128 | Int128Type | | | | |
+| __mfp8 | BinaryFloatingPointType, RealNumberType | | | | |
| __va_list_tag | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |
| __va_list_tag & | LValueReferenceType, PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection | | __va_list_tag | | |
| __va_list_tag && | PointerOrArrayOrReferenceType, PointerOrArrayOrReferenceTypeIndirection, RValueReferenceType | | __va_list_tag | | |
diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
index 212ac56d39d6..a86abb4812b6 100644
--- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
+++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
-version: 1.7.42
+version: 1.7.43-dev
groups:
- csharp
- solorigate
diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml
index 16bf35874035..caf1e66033e4 100644
--- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml
+++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
-version: 1.7.42
+version: 1.7.43-dev
groups:
- csharp
- solorigate
diff --git a/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected b/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected
index 14934899e0d8..89e7cff7f29e 100644
--- a/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected
+++ b/csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected
@@ -2,6 +2,8 @@ ql/csharp/ql/src/API Abuse/CallToGCCollect.ql
ql/csharp/ql/src/API Abuse/FormatInvalid.ql
ql/csharp/ql/src/API Abuse/NoDisposeCallOnLocalIDisposable.ql
ql/csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql
+ql/csharp/ql/src/CSI/NullAlways.ql
+ql/csharp/ql/src/CSI/NullMaybe.ql
ql/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql
ql/csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql
ql/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql
@@ -11,6 +13,7 @@ ql/csharp/ql/src/Likely Bugs/EqualityCheckOnFloats.ql
ql/csharp/ql/src/Likely Bugs/ReferenceEqualsOnValueTypes.ql
ql/csharp/ql/src/Likely Bugs/SelfAssignment.ql
ql/csharp/ql/src/Likely Bugs/UncheckedCastInEquals.ql
+ql/csharp/ql/src/Performance/StringConcatenationInLoop.ql
ql/csharp/ql/src/Performance/UseTryGetValue.ql
ql/csharp/ql/src/Useless code/DefaultToString.ql
ql/csharp/ql/src/Useless code/IntGetHashCode.ql
diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml
index 84b613c84979..464284c56cb4 100644
--- a/csharp/ql/lib/qlpack.yml
+++ b/csharp/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-all
-version: 5.1.8
+version: 5.1.9-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll
index a990455f4307..7e8ed0aadc04 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Nullness.qll
@@ -544,8 +544,13 @@ class Dereference extends G::DereferenceableExpr {
p.hasExtensionMethodModifier() and
not emc.isConditional()
|
- p.fromSource() // assume all non-source extension methods perform a dereference
- implies
+ // Assume all non-source extension methods on
+ // (1) nullable types are null-safe
+ // (2) non-nullable types are doing a dereference.
+ p.fromLibrary() and
+ not p.getAnnotatedType().isNullableRefType()
+ or
+ p.fromSource() and
exists(
Ssa::ImplicitParameterDefinition def,
AssignableDefinitions::ImplicitParameterDefinition pdef
diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll
index 14d7497ec330..b5c036fa9f40 100644
--- a/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll
+++ b/csharp/ql/lib/semmle/code/csharp/frameworks/system/Diagnostics.qll
@@ -41,9 +41,7 @@ class SystemDiagnosticsDebugClass extends SystemDiagnosticsClass {
/** Gets an `Assert(bool, ...)` method. */
Method getAssertMethod() {
result.getDeclaringType() = this and
- result.hasName("Assert") and
- result.getParameter(0).getType() instanceof BoolType and
- result.getReturnType() instanceof VoidType
+ result.hasName("Assert")
}
}
diff --git a/csharp/ql/src/CSI/NullAlways.ql b/csharp/ql/src/CSI/NullAlways.ql
index e52abdc3cd5a..1696f857fde5 100644
--- a/csharp/ql/src/CSI/NullAlways.ql
+++ b/csharp/ql/src/CSI/NullAlways.ql
@@ -9,6 +9,7 @@
* correctness
* exceptions
* external/cwe/cwe-476
+ * quality
*/
import csharp
diff --git a/csharp/ql/src/CSI/NullMaybe.ql b/csharp/ql/src/CSI/NullMaybe.ql
index bb886f199290..c69df839958b 100644
--- a/csharp/ql/src/CSI/NullMaybe.ql
+++ b/csharp/ql/src/CSI/NullMaybe.ql
@@ -10,6 +10,7 @@
* correctness
* exceptions
* external/cwe/cwe-476
+ * quality
*/
import csharp
diff --git a/csharp/ql/src/Performance/StringConcatenationInLoop.ql b/csharp/ql/src/Performance/StringConcatenationInLoop.ql
index aba7d3b74368..b1b420434e94 100644
--- a/csharp/ql/src/Performance/StringConcatenationInLoop.ql
+++ b/csharp/ql/src/Performance/StringConcatenationInLoop.ql
@@ -7,6 +7,7 @@
* @id cs/string-concatenation-in-loop
* @tags efficiency
* maintainability
+ * quality
*/
import csharp
diff --git a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql
index b99839226c59..3fc132eb3016 100644
--- a/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql
+++ b/csharp/ql/src/Security Features/CWE-134/UncontrolledFormatString.ql
@@ -4,7 +4,7 @@
* and cause a denial of service.
* @kind path-problem
* @problem.severity error
- * @security-severity 9.3
+ * @security-severity 7.3
* @precision high
* @id cs/uncontrolled-format-string
* @tags security
diff --git a/csharp/ql/src/change-notes/2025-06-03-dereferece-extension-method.md b/csharp/ql/src/change-notes/2025-06-03-dereferece-extension-method.md
new file mode 100644
index 000000000000..b12ec9768d5a
--- /dev/null
+++ b/csharp/ql/src/change-notes/2025-06-03-dereferece-extension-method.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* The queries `cs/dereferenced-value-is-always-null` and `cs/dereferenced-value-may-be-null` have been improved to reduce false positives. The queries no longer assume that expressions are dereferenced when passed as the receiver (`this` parameter) to extension methods where that parameter is a nullable type.
diff --git a/csharp/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md b/csharp/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md
new file mode 100644
index 000000000000..60006391ac61
--- /dev/null
+++ b/csharp/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md
@@ -0,0 +1,4 @@
+---
+category: queryMetadata
+---
+* Adjusts the `@security-severity` from 9.3 to 7.3 for `cs/uncontrolled-format-string` to align `CWE-134` severity for memory safe languages to better reflect their impact.
diff --git a/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls b/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls
index 5bb3a54f6eec..b224499edce2 100644
--- a/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls
+++ b/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls
@@ -1,4 +1,143 @@
- description: Security-and-quality queries for C#
- queries: .
-- apply: security-and-quality-selectors.yml
- from: codeql/suite-helpers
+- include:
+ kind:
+ - problem
+ - path-problem
+ precision:
+ - high
+ - very-high
+ tags contain:
+ - security
+- include:
+ kind:
+ - problem
+ - path-problem
+ precision: medium
+ problem.severity:
+ - error
+ - warning
+ tags contain:
+ - security
+- include:
+ id:
+ - cs/asp/response-write
+ - cs/call-to-gc
+ - cs/call-to-object-tostring
+ - cs/call-to-obsolete-method
+ - cs/call-to-unmanaged-code
+ - cs/cast-from-abstract-to-concrete-collection
+ - cs/cast-of-this-to-type-parameter
+ - cs/catch-nullreferenceexception
+ - cs/catch-of-all-exceptions
+ - cs/chained-type-tests
+ - cs/class-implements-icloneable
+ - cs/class-missing-equals
+ - cs/class-name-comparison
+ - cs/class-name-matches-base-class
+ - cs/coalesce-of-identical-expressions
+ - cs/comparison-of-identical-expressions
+ - cs/complex-block
+ - cs/complex-condition
+ - cs/constant-comparison
+ - cs/constant-condition
+ - cs/coupled-types
+ - cs/dereferenced-value-is-always-null
+ - cs/dereferenced-value-may-be-null
+ - cs/dispose-not-called-on-throw
+ - cs/downcast-of-this
+ - cs/empty-block
+ - cs/empty-catch-block
+ - cs/empty-collection
+ - cs/empty-lock-statement
+ - cs/equality-on-floats
+ - cs/equals-on-arrays
+ - cs/equals-on-unrelated-types
+ - cs/equals-uses-as
+ - cs/equals-uses-is
+ - cs/expose-implementation
+ - cs/field-masks-base-field
+ - cs/gethashcode-is-not-defined
+ - cs/impossible-array-cast
+ - cs/inconsistent-compareto-and-equals
+ - cs/inconsistent-equals-and-gethashcode
+ - cs/inconsistent-lock-sequence
+ - cs/index-out-of-bounds
+ - cs/inefficient-containskey
+ - cs/invalid-dynamic-call
+ - cs/invalid-string-formatting
+ - cs/linq/inconsistent-enumeration
+ - cs/linq/missed-all
+ - cs/linq/missed-cast
+ - cs/linq/missed-oftype
+ - cs/linq/missed-select
+ - cs/linq/missed-where
+ - cs/linq/useless-select
+ - cs/local-not-disposed
+ - cs/local-shadows-member
+ - cs/lock-this
+ - cs/locked-wait
+ - cs/loss-of-precision
+ - cs/mishandling-japanese-era
+ - cs/misleading-indentation
+ - cs/missed-readonly-modifier
+ - cs/missed-ternary-operator
+ - cs/missed-using-statement
+ - cs/nested-if-statements
+ - cs/nested-loops-with-same-variable
+ - cs/non-short-circuit
+ - cs/null-argument-to-equals
+ - cs/path-combine
+ - cs/recursive-equals-call
+ - cs/recursive-operator-equals-call
+ - cs/reference-equality-on-valuetypes
+ - cs/reference-equality-with-object
+ - cs/rethrown-exception-variable
+ - cs/self-assignment
+ - cs/simplifiable-boolean-expression
+ - cs/static-field-written-by-instance
+ - cs/string-concatenation-in-loop
+ - cs/stringbuilder-creation-in-loop
+ - cs/stringbuilder-initialized-with-character
+ - cs/test-for-negative-container-size
+ - cs/too-many-ref-parameters
+ - cs/type-test-of-this
+ - cs/unchecked-cast-in-equals
+ - cs/unmanaged-code
+ - cs/unsafe-double-checked-lock
+ - cs/unsafe-sync-on-field
+ - cs/unsafe-year-construction
+ - cs/unsynchronized-getter
+ - cs/unsynchronized-static-access
+ - cs/unused-collection
+ - cs/unused-label
+ - cs/unused-property-value
+ - cs/useless-assignment-to-local
+ - cs/useless-cast-to-self
+ - cs/useless-gethashcode-call
+ - cs/useless-if-statement
+ - cs/useless-tostring-call
+ - cs/useless-type-test
+ - cs/useless-upcast
+ - cs/virtual-call-in-constructor
+ - cs/wrong-compareto-signature
+ - cs/wrong-equals-signature
+ - cs/xmldoc/missing-summary
+- include:
+ kind:
+ - diagnostic
+- include:
+ kind:
+ - metric
+ tags contain:
+ - summary
+- exclude:
+ deprecated: //
+- exclude:
+ query path:
+ - /^experimental\/.*/
+ - Metrics/Summaries/FrameworkCoverage.ql
+- exclude:
+ tags contain:
+ - modeleditor
+ - modelgenerator
diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml
index 24cacd047ce0..6437a730f150 100644
--- a/csharp/ql/src/qlpack.yml
+++ b/csharp/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/csharp-queries
-version: 1.2.2
+version: 1.2.3-dev
groups:
- csharp
- queries
diff --git a/csharp/ql/test/query-tests/Nullness/A.cs b/csharp/ql/test/query-tests/Nullness/A.cs
index 51bbc280e3c8..12f5d74d5a29 100644
--- a/csharp/ql/test/query-tests/Nullness/A.cs
+++ b/csharp/ql/test/query-tests/Nullness/A.cs
@@ -5,7 +5,7 @@ class A
public void Lock()
{
object synchronizedAlways = null;
- lock (synchronizedAlways) // BAD (always)
+ lock (synchronizedAlways) // $ Alert[cs/dereferenced-value-is-always-null]
{
synchronizedAlways.GetHashCode(); // GOOD
}
@@ -14,7 +14,7 @@ public void Lock()
public void ArrayAssignTest()
{
int[] arrayNull = null;
- arrayNull[0] = 10; // BAD (always)
+ arrayNull[0] = 10; // $ Alert[cs/dereferenced-value-is-always-null]
int[] arrayOk;
arrayOk = new int[10];
@@ -28,10 +28,10 @@ public void Access()
object methodAccess = null;
object methodCall = null;
- Console.WriteLine(arrayAccess[1]); // BAD (always)
- Console.WriteLine(fieldAccess.Length); // BAD (always)
- Func tmp = methodAccess.ToString; // BAD (always)
- Console.WriteLine(methodCall.ToString()); // BAD (always)
+ Console.WriteLine(arrayAccess[1]); // $ Alert[cs/dereferenced-value-is-always-null]
+ Console.WriteLine(fieldAccess.Length); // $ Alert[cs/dereferenced-value-is-always-null]
+ Func tmp = methodAccess.ToString; // $ Alert[cs/dereferenced-value-is-always-null]
+ Console.WriteLine(methodCall.ToString()); // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(arrayAccess[1]); // GOOD
Console.WriteLine(fieldAccess.Length); // GOOD
@@ -47,7 +47,7 @@ public void OutOrRef()
object varRef = null;
TestMethod2(ref varRef);
- varRef.ToString(); // BAD (always)
+ varRef.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
varRef = null;
TestMethod3(ref varRef);
diff --git a/csharp/ql/test/query-tests/Nullness/Assert.cs b/csharp/ql/test/query-tests/Nullness/Assert.cs
index 0236977aa393..86a99708a1f5 100644
--- a/csharp/ql/test/query-tests/Nullness/Assert.cs
+++ b/csharp/ql/test/query-tests/Nullness/Assert.cs
@@ -12,7 +12,7 @@ void Fn(bool b)
s = b ? null : "";
Assert.IsNull(s);
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : "";
Assert.IsNotNull(s);
@@ -20,7 +20,7 @@ void Fn(bool b)
s = b ? null : "";
Assert.IsTrue(s == null);
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : "";
Assert.IsTrue(s != null);
@@ -28,7 +28,7 @@ void Fn(bool b)
s = b ? null : "";
Assert.IsFalse(s != null);
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : "";
Assert.IsFalse(s == null);
@@ -44,10 +44,10 @@ void Fn(bool b)
s = b ? null : "";
Assert.IsTrue(s == null && b);
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
s = b ? null : "";
Assert.IsFalse(s != null || !b);
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
}
}
diff --git a/csharp/ql/test/query-tests/Nullness/B.cs b/csharp/ql/test/query-tests/Nullness/B.cs
index 76ebb6ffd8ee..946bacecefba 100644
--- a/csharp/ql/test/query-tests/Nullness/B.cs
+++ b/csharp/ql/test/query-tests/Nullness/B.cs
@@ -10,7 +10,7 @@ public void OperatorCall()
B neqCallAlways = null;
if (eqCallAlways == null)
- eqCallAlways.ToString(); // BAD (always)
+ eqCallAlways.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
if (b2 != null)
b2.ToString(); // GOOD
@@ -21,7 +21,7 @@ public void OperatorCall()
if (neqCallAlways != null) { }
else
- neqCallAlways.ToString(); // BAD (always)
+ neqCallAlways.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
public static bool operator ==(B b1, B b2)
diff --git a/csharp/ql/test/query-tests/Nullness/C.cs b/csharp/ql/test/query-tests/Nullness/C.cs
index 805d9e2cae4f..405dceb74d5a 100644
--- a/csharp/ql/test/query-tests/Nullness/C.cs
+++ b/csharp/ql/test/query-tests/Nullness/C.cs
@@ -15,7 +15,7 @@ public void NotTest()
if (!(o != null))
{
- o.GetHashCode(); // BAD (always)
+ o.GetHashCode(); // $ Alert[cs/dereferenced-value-is-always-null]
}
}
@@ -39,7 +39,7 @@ public void AssertTest()
{
var s = Maybe() ? null : "";
Debug.Assert(s == null);
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = Maybe() ? null : "";
Debug.Assert(s != null);
@@ -50,22 +50,22 @@ public void AssertNullTest()
{
var o1 = new object();
AssertNull(o1);
- o1.ToString(); // BAD (always) (false negative)
+ o1.ToString(); // $ MISSING: Alert[cs/dereferenced-value-is-always-null]
var o2 = Maybe() ? null : "";
Assert.IsNull(o2);
- o2.ToString(); // BAD (always)
+ o2.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
public void AssertNotNullTest()
{
- var o1 = Maybe() ? null : new object();
+ var o1 = Maybe() ? null : new object(); // $ Source[cs/dereferenced-value-may-be-null]
AssertNonNull(o1);
- o1.ToString(); // GOOD (false positive)
+ o1.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
- var o2 = Maybe() ? null : new object();
+ var o2 = Maybe() ? null : new object(); // $ Source[cs/dereferenced-value-may-be-null]
AssertNonNull(o1);
- o2.ToString(); // BAD (maybe)
+ o2.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
var o3 = Maybe() ? null : new object();
Assert.IsNotNull(o3);
@@ -91,16 +91,16 @@ public void InstanceOf()
public void Lock()
{
- var o = Maybe() ? null : new object();
- lock (o) // BAD (maybe)
+ var o = Maybe() ? null : new object(); // $ Source[cs/dereferenced-value-may-be-null]
+ lock (o) // $ Alert[cs/dereferenced-value-may-be-null]
o.ToString(); // GOOD
}
public void Foreach(IEnumerable list)
{
if (Maybe())
- list = null;
- foreach (var x in list) // BAD (maybe)
+ list = null; // $ Source[cs/dereferenced-value-may-be-null]
+ foreach (var x in list) // $ Alert[cs/dereferenced-value-may-be-null]
{
x.ToString(); // GOOD
list.ToString(); // GOOD
@@ -159,7 +159,7 @@ public void DoWhile()
s = null;
do
{
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = null;
}
while (s != null);
@@ -167,15 +167,15 @@ public void DoWhile()
s = null;
do
{
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
while (s != null);
s = "";
do
{
- s.ToString(); // BAD (maybe)
- s = null;
+ s.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
+ s = null; // $ Source[cs/dereferenced-value-may-be-null]
}
while (true);
}
@@ -193,15 +193,15 @@ public void While()
s = null;
while (b)
{
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = null;
}
s = "";
while (true)
{
- s.ToString(); // BAD (maybe)
- s = null;
+ s.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
+ s = null; // $ Source[cs/dereferenced-value-may-be-null]
}
}
@@ -215,12 +215,12 @@ public void If()
}
if (s == null)
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
s = "";
if (s != null && s.Length % 2 == 0)
- s = null;
- s.ToString(); // BAD (maybe)
+ s = null; // $ Source[cs/dereferenced-value-may-be-null]
+ s.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
public void For()
@@ -230,23 +230,23 @@ public void For()
{
s.ToString(); // GOOD
}
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
for (s = null; s == null; s = null)
{
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
- for (s = ""; ; s = null)
+ for (s = ""; ; s = null) // $ Source[cs/dereferenced-value-may-be-null]
{
- s.ToString(); // BAD (maybe)
+ s.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
}
public void ArrayAssignTest()
{
int[] a = null;
- a[0] = 10; // BAD (always)
+ a[0] = 10; // $ Alert[cs/dereferenced-value-is-always-null]
a = new int[10];
a[0] = 42; // GOOD
@@ -257,8 +257,8 @@ public void Access()
int[] ia = null;
string[] sa = null;
- ia[1] = 0; // BAD (always)
- var temp = sa.Length; // BAD (always)
+ ia[1] = 0; // $ Alert[cs/dereferenced-value-is-always-null]
+ var temp = sa.Length; // $ Alert[cs/dereferenced-value-is-always-null]
ia[1] = 0; // BAD (always), but not first
temp = sa.Length; // BAD (always), but not first
diff --git a/csharp/ql/test/query-tests/Nullness/D.cs b/csharp/ql/test/query-tests/Nullness/D.cs
index 40419b7f5775..ffc4fd193c77 100644
--- a/csharp/ql/test/query-tests/Nullness/D.cs
+++ b/csharp/ql/test/query-tests/Nullness/D.cs
@@ -14,22 +14,22 @@ public D(bool b, bool f)
public void Caller()
{
Callee1(new object());
- Callee1(null);
+ Callee1(null); // $ Source[cs/dereferenced-value-may-be-null]
Callee2(new object());
}
public void Callee1(object param)
{
- param.ToString(); // BAD (maybe)
+ param.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
- public void Callee2(object param)
+ public void Callee2(object param) // $ Source[cs/dereferenced-value-may-be-null]
{
if (param != null)
{
param.ToString(); // GOOD
}
- param.ToString(); // BAD (maybe)
+ param.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
private static bool CustomIsNull(object x)
@@ -55,54 +55,54 @@ public void NullGuards()
if ((2 > 1 && o4 != null) != false)
o4.ToString(); // GOOD
- var o5 = (o4 != null) ? "" : null;
+ var o5 = (o4 != null) ? "" : null; // $ Source[cs/dereferenced-value-may-be-null]
if (o5 != null)
o4.ToString(); // GOOD
if (o4 != null)
- o5.ToString(); // GOOD (false positive)
+ o5.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
var o6 = maybe ? null : "";
if (!CustomIsNull(o6))
o6.ToString(); // GOOD
- var o7 = maybe ? null : "";
+ var o7 = maybe ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
var ok = o7 != null && 2 > 1;
if (ok)
o7.ToString(); // GOOD
else
- o7.ToString(); // BAD (maybe)
+ o7.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
- var o8 = maybe ? null : "";
+ var o8 = maybe ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
int track = o8 == null ? 42 : 1 + 1;
if (track == 2)
o8.ToString(); // GOOD
if (track != 42)
o8.ToString(); // GOOD
if (track < 42)
- o8.ToString(); // GOOD (false positive)
+ o8.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (track <= 41)
- o8.ToString(); // GOOD (false positive)
+ o8.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void Deref(int i)
{
- int[] xs = maybe ? null : new int[2];
+ int[] xs = maybe ? null : new int[2]; // $ Source[cs/dereferenced-value-may-be-null]
if (i > 1)
- xs[0] = 5; // BAD (maybe)
+ xs[0] = 5; // $ Alert[cs/dereferenced-value-may-be-null]
if (i > 2)
- maybe = xs[1] > 5; // BAD (maybe)
+ maybe = xs[1] > 5; // $ Alert[cs/dereferenced-value-may-be-null]
if (i > 3)
{
- var l = xs.Length; // BAD (maybe)
+ var l = xs.Length; // $ Alert[cs/dereferenced-value-may-be-null]
}
if (i > 4)
- foreach (var _ in xs) ; // BAD (maybe)
+ foreach (var _ in xs) ; // $ Alert[cs/dereferenced-value-may-be-null]
if (i > 5)
- lock (xs) // BAD (maybe)
+ lock (xs) // $ Alert[cs/dereferenced-value-may-be-null]
xs.ToString(); // Not reported - same basic block
if (i > 6)
@@ -117,12 +117,12 @@ public void F(bool b)
var x = b ? null : "abc";
x = x == null ? "" : x;
if (x == null)
- x.ToString(); // BAD (always)
+ x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
else
x.ToString(); // GOOD
}
- public void LengthGuard(int[] a, int[] b)
+ public void LengthGuard(int[] a, int[] b) // $ Source[cs/dereferenced-value-may-be-null]
{
int alen = a == null ? 0 : a.Length; // GOOD
int blen = b == null ? 0 : b.Length; // GOOD
@@ -131,8 +131,8 @@ public void LengthGuard(int[] a, int[] b)
{
for (int i = 0; i < alen; i++)
{
- sum += a[i]; // GOOD (false positive)
- sum += b[i]; // GOOD (false positive)
+ sum += a[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
+ sum += b[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
}
int alen2;
@@ -142,13 +142,13 @@ public void LengthGuard(int[] a, int[] b)
alen2 = 0;
for (int i = 1; i <= alen2; ++i)
{
- sum += a[i - 1]; // GOOD (false positive)
+ sum += a[i - 1]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
}
- public void MissedGuard(object obj)
+ public void MissedGuard(object obj) // $ Source[cs/dereferenced-value-may-be-null]
{
- obj.ToString(); // BAD (maybe)
+ obj.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
var x = obj != null ? 1 : 0;
}
@@ -160,7 +160,7 @@ private object MkMaybe()
public void Exceptions()
{
- object obj = null;
+ object obj = null; // $ Source[cs/dereferenced-value-may-be-null]
try
{
obj = MkMaybe();
@@ -168,7 +168,7 @@ public void Exceptions()
catch (Exception e)
{
}
- obj.ToString(); // BAD (maybe)
+ obj.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
object obj2 = null;
try
@@ -194,7 +194,7 @@ public void ClearNotNull()
{
var o = new Object();
if (o == null)
- o.ToString(); // BAD (always)
+ o.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o.ToString(); // GOOD
try
@@ -204,7 +204,7 @@ public void ClearNotNull()
catch (Exception e)
{
if (e == null)
- e.ToString(); // BAD (always)
+ e.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
e.ToString(); // GOOD
}
@@ -214,12 +214,12 @@ public void ClearNotNull()
var o3 = "abc";
if (o3 == null)
- o3.ToString(); // BAD (always)
+ o3.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o3.ToString(); // GOOD
var o4 = "" + null;
if (o4 == null)
- o4.ToString(); // BAD (always)
+ o4.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
o4.ToString(); // GOOD
}
@@ -237,25 +237,25 @@ public void CorrelatedConditions(bool cond, int num)
if (flag)
o.ToString(); // GOOD
- o = null;
+ o = null; // $ Source[cs/dereferenced-value-may-be-null]
var other = maybe ? null : "";
if (other == null)
o = "";
if (other != null)
- o.ToString(); // BAD (always) (reported as maybe)
+ o.ToString(); // $ Alert[cs/dereferenced-value-may-be-null] (always - but reported as maybe)
else
- o.ToString(); // GOOD (false positive)
+ o.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
- var o2 = (num < 0) ? null : "";
+ var o2 = (num < 0) ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
if (num < 0)
o2 = "";
else
- o2.ToString(); // GOOD (false positive)
+ o2.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void TrackingVariable(int[] a)
{
- object o = null;
+ object o = null; // $ Source[cs/dereferenced-value-may-be-null]
object other = null;
if (maybe)
{
@@ -264,9 +264,9 @@ public void TrackingVariable(int[] a)
}
if (other is string)
- o.ToString(); // GOOD (false positive)
+ o.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
- o = null;
+ o = null; // $ Source[cs/dereferenced-value-may-be-null]
int count = 0;
var found = false;
for (var i = 0; i < a.Length; i++)
@@ -280,7 +280,7 @@ public void TrackingVariable(int[] a)
}
if (a[i] > 10000)
{
- o = null;
+ o = null; // $ Source[cs/dereferenced-value-may-be-null]
count = 0;
if (2 > i) { }
found = false;
@@ -288,20 +288,20 @@ public void TrackingVariable(int[] a)
}
if (count > 3)
- o.ToString(); // GOOD (false positive)
+ o.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (found)
- o.ToString(); // GOOD (false positive)
+ o.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
- object prev = null;
+ object prev = null; // $ Source[cs/dereferenced-value-may-be-null]
for (var i = 0; i < a.Length; ++i)
{
if (i != 0)
- prev.ToString(); // GOOD (false positive)
+ prev.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
prev = a[i];
}
- string s = null;
+ string s = null; // $ Source[cs/dereferenced-value-may-be-null]
{
var s_null = true;
foreach (var i in a)
@@ -310,10 +310,10 @@ public void TrackingVariable(int[] a)
s = "" + a;
}
if (!s_null)
- s.ToString(); // GOOD (false positive)
+ s.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
- object r = null;
+ object r = null; // $ Source[cs/dereferenced-value-may-be-null]
var stat = MyStatus.INIT;
while (stat == MyStatus.INIT && stat != MyStatus.READY)
{
@@ -321,7 +321,7 @@ public void TrackingVariable(int[] a)
if (stat == MyStatus.INIT)
stat = MyStatus.READY;
}
- r.ToString(); // GOOD (false positive)
+ r.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public enum MyStatus
@@ -348,28 +348,28 @@ public void G(object obj)
public void LoopCorr(int iters)
{
- int[] a = null;
+ int[] a = null; // $ Source[cs/dereferenced-value-may-be-null]
if (iters > 0)
a = new int[iters];
for (var i = 0; i < iters; ++i)
- a[i] = 0; // GOOD (false positive)
+ a[i] = 0; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (iters > 0)
{
- string last = null;
+ string last = null; // $ Source[cs/dereferenced-value-may-be-null]
for (var i = 0; i < iters; i++)
last = "abc";
- last.ToString(); // GOOD (false positive)
+ last.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
- int[] b = maybe ? null : new int[iters];
+ int[] b = maybe ? null : new int[iters]; // $ Source[cs/dereferenced-value-may-be-null]
if (iters > 0 && (b == null || b.Length < iters))
throw new Exception();
for (var i = 0; i < iters; ++i)
{
- b[i] = 0; // GOOD (false positive)
+ b[i] = 0; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
}
@@ -382,33 +382,33 @@ void Test(Exception e, bool b)
if (ioe != null)
ioe = e;
else
- ioe.ToString(); // BAD (always)
+ ioe.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
- public void LengthGuard2(int[] a, int[] b)
+ public void LengthGuard2(int[] a, int[] b) // $ Source[cs/dereferenced-value-may-be-null]
{
int alen = a == null ? 0 : a.Length; // GOOD
int sum = 0;
int i;
for (i = 0; i < alen; i++)
{
- sum += a[i]; // GOOD (false positive)
+ sum += a[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
int blen = b == null ? 0 : b.Length; // GOOD
for (i = 0; i < blen; i++)
{
- sum += b[i]; // GOOD (false positive)
+ sum += b[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
i = -3;
}
- public void CorrConds2(object x, object y)
+ public void CorrConds2(object x, object y) // $ Source[cs/dereferenced-value-may-be-null]
{
if ((x != null && y == null) || (x == null && y != null))
return;
if (x != null)
- y.ToString(); // GOOD (false positive)
+ y.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (y != null)
- x.ToString(); // GOOD (false positive)
+ x.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
}
diff --git a/csharp/ql/test/query-tests/Nullness/E.cs b/csharp/ql/test/query-tests/Nullness/E.cs
index ec1fa1613923..f8264523b687 100644
--- a/csharp/ql/test/query-tests/Nullness/E.cs
+++ b/csharp/ql/test/query-tests/Nullness/E.cs
@@ -6,12 +6,12 @@ public class E
{
public void Ex1(long[][][] a1, int ix, int len)
{
- long[][] a2 = null;
+ long[][] a2 = null; // $ Source[cs/dereferenced-value-may-be-null]
var haveA2 = ix < len && (a2 = a1[ix]) != null;
- long[] a3 = null;
- var haveA3 = haveA2 && (a3 = a2[ix]) != null; // GOOD (FALSE POSITIVE)
+ long[] a3 = null; // $ Source[cs/dereferenced-value-may-be-null]
+ var haveA3 = haveA2 && (a3 = a2[ix]) != null; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (haveA3)
- a3[0] = 0; // GOOD (FALSE POSITIVE)
+ a3[0] = 0; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void Ex2(bool x, bool y)
@@ -20,11 +20,11 @@ public void Ex2(bool x, bool y)
var s2 = (s1 == null) ? null : "";
if (s2 == null)
{
- s1 = y ? null : "";
+ s1 = y ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
s2 = (s1 == null) ? null : "";
}
if (s2 != null)
- s1.ToString(); // GOOD (FALSE POSITIVE)
+ s1.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void Ex3(IEnumerable ss)
@@ -48,7 +48,7 @@ public void Ex4(IEnumerable list, int step)
{
int index = 0;
var result = new List>();
- List slice = null;
+ List slice = null; // $ Source[cs/dereferenced-value-may-be-null]
var iter = list.GetEnumerator();
while (iter.MoveNext())
{
@@ -58,19 +58,19 @@ public void Ex4(IEnumerable list, int step)
slice = new List();
result.Add(slice);
}
- slice.Add(str); // GOOD (FALSE POSITIVE)
+ slice.Add(str); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
++index;
}
}
- public void Ex5(bool hasArr, int[] arr)
+ public void Ex5(bool hasArr, int[] arr) // $ Source[cs/dereferenced-value-may-be-null]
{
int arrLen = 0;
if (hasArr)
arrLen = arr == null ? 0 : arr.Length;
if (arrLen > 0)
- arr[0] = 0; // GOOD (FALSE POSITIVE)
+ arr[0] = 0; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public const int MY_CONST_A = 1;
@@ -104,12 +104,12 @@ public void Ex6(int[] vals, bool b1, bool b2)
public void Ex7(int[] arr1)
{
- int[] arr2 = null;
+ int[] arr2 = null; // $ Source[cs/dereferenced-value-may-be-null]
if (arr1.Length > 0)
arr2 = new int[arr1.Length];
for (var i = 0; i < arr1.Length; i++)
- arr2[i] = arr1[i]; // GOOD (FALSE POSITIVE)
+ arr2[i] = arr1[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void Ex8(int x, int lim)
@@ -122,7 +122,7 @@ public void Ex8(int x, int lim)
int j = 0;
while (!stop && j < lim)
{
- int step = (j * obj.GetHashCode()) % 10; // GOOD (FALSE POSITIVE)
+ int step = (j * obj.GetHashCode()) % 10; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (step == 0)
{
obj.ToString(); // GOOD
@@ -134,7 +134,7 @@ public void Ex8(int x, int lim)
}
else
{
- obj = null;
+ obj = null; // $ Source[cs/dereferenced-value-may-be-null]
}
continue;
}
@@ -149,33 +149,33 @@ public void Ex9(bool cond, object obj1)
{
return;
}
- object obj2 = obj1;
+ object obj2 = obj1; // $ Source[cs/dereferenced-value-may-be-null]
if (obj2 != null && obj2.GetHashCode() % 5 > 2)
{
obj2.ToString(); // GOOD
cond = true;
}
if (cond)
- obj2.ToString(); // GOOD (FALSE POSITIVE)
+ obj2.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
- public void Ex10(int[] a)
+ public void Ex10(int[] a) // $ Source[cs/dereferenced-value-may-be-null]
{
int n = a == null ? 0 : a.Length;
for (var i = 0; i < n; i++)
{
- int x = a[i]; // GOOD (FALSE POSITIVE)
+ int x = a[i]; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
if (x > 7)
a = new int[n];
}
}
- public void Ex11(object obj, bool b1)
+ public void Ex11(object obj, bool b1) // $ Source[cs/dereferenced-value-may-be-null]
{
bool b2 = obj == null ? false : b1;
if (b2 == null)
{
- obj.ToString(); // GOOD (FALSE POSITIVE)
+ obj.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
if (obj == null)
{
@@ -183,61 +183,61 @@ public void Ex11(object obj, bool b1)
}
if (b1 == null)
{
- obj.ToString(); // GOOD (FALSE POSITIVE)
+ obj.ToString(); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
}
- public void Ex12(object o)
+ public void Ex12(object o) // $ Source[cs/dereferenced-value-may-be-null]
{
- var i = o.GetHashCode(); // BAD (maybe)
+ var i = o.GetHashCode(); // $ Alert[cs/dereferenced-value-may-be-null]
var s = o?.ToString();
}
public void Ex13(bool b)
{
- var o = b ? null : "";
+ var o = b ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
o.M1(); // GOOD
if (b)
- o.M2(); // BAD (maybe)
+ o.M2(); // $ Alert[cs/dereferenced-value-may-be-null]
else
- o.Select(x => x); // BAD (maybe)
+ o.Select(x => x); // $ Alert[cs/dereferenced-value-may-be-null]
}
public int Ex14(string s)
{
if (s is string)
return s.Length;
- return s.GetHashCode(); // BAD (always)
+ return s.GetHashCode(); // $ Alert[cs/dereferenced-value-is-always-null]
}
public void Ex15(bool b)
{
var x = "";
if (b)
- x = null;
- x.ToString(); // BAD (maybe)
+ x = null; // $ Source[cs/dereferenced-value-may-be-null]
+ x.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
if (b)
- x.ToString(); // BAD (always)
+ x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
public void Ex16(bool b)
{
var x = "";
if (b)
- x = null;
+ x = null; // $ Source[cs/dereferenced-value-may-be-null]
if (b)
- x.ToString(); // BAD (always)
- x.ToString(); // BAD (maybe)
+ x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
+ x.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
- public int Ex17(int? i)
+ public int Ex17(int? i) // $ Source[cs/dereferenced-value-may-be-null]
{
- return i.Value; // BAD (maybe)
+ return i.Value; // $ Alert[cs/dereferenced-value-may-be-null]
}
- public int Ex18(int? i)
+ public int Ex18(int? i) // $ Source[cs/dereferenced-value-may-be-null]
{
- return (int)i; // BAD (maybe)
+ return (int)i; // $ Alert[cs/dereferenced-value-may-be-null]
}
public int Ex19(int? i)
@@ -280,9 +280,9 @@ public void Ex23(bool b)
{
if (b)
b.ToString();
- var o = Make();
+ var o = Make(); // $ Source[cs/dereferenced-value-may-be-null]
o?.ToString();
- o.ToString(); // BAD (maybe)
+ o.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
if (b)
b.ToString();
}
@@ -298,8 +298,8 @@ public void Ex24(bool b)
public void Ex25(object o)
{
- var s = o as string;
- s.ToString(); // BAD (maybe)
+ var s = o as string; // $ Source[cs/dereferenced-value-may-be-null]
+ s.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
private long? l;
@@ -320,15 +320,15 @@ static void Ex27(string s1, string s2)
{
if ((s1 ?? s2) is null)
{
- s1.ToString(); // BAD (always)
- s2.ToString(); // BAD (always)
+ s1.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
+ s2.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
}
static void Ex28()
{
var x = (string)null ?? null;
- x.ToString(); // BAD (always)
+ x.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
static void Ex29(string s)
@@ -339,14 +339,14 @@ static void Ex29(string s)
static void Ex30(string s, object o)
{
- var x = s ?? o as string;
- x.ToString(); // BAD (maybe)
+ var x = s ?? o as string; // $ Source[cs/dereferenced-value-may-be-null]
+ x.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
static void Ex31(string s, object o)
{
- dynamic x = s ?? o as string;
- x.ToString(); // BAD (maybe)
+ dynamic x = s ?? o as string; // $ Source[cs/dereferenced-value-may-be-null]
+ x.ToString(); // $ Alert[cs/dereferenced-value-may-be-null]
}
static void Ex32(string s, object o)
@@ -363,7 +363,7 @@ static void Ex33(string s, object o)
x.ToString(); // GOOD
}
- static int Ex34(string s = null) => s.Length; // BAD (maybe)
+ static int Ex34(string s = null) => s.Length; // $ Alert[cs/dereferenced-value-may-be-null]
static int Ex35(string s = "null") => s.Length; // GOOD
@@ -371,19 +371,19 @@ static int Ex36(object o)
{
if (o is string)
{
- var s = o as string;
- return s.Length; // GOOD (FALSE POSITIVE)
+ var s = o as string; // $ Source[cs/dereferenced-value-may-be-null]
+ return s.Length; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
return -1;
}
- static bool Ex37(E e1, E e2)
+ static bool Ex37(E e1, E e2) // $ Source[cs/dereferenced-value-may-be-null]
{
if ((e1 == null && e2 != null) || (e1 != null && e2 == null))
return false;
if (e1 == null && e2 == null)
return true;
- return e1.Long == e2.Long; // GOOD (FALSE POSITIVE)
+ return e1.Long == e2.Long; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
int Ex38(int? i)
@@ -402,7 +402,7 @@ int Ex40()
{
int? i = null;
i ??= null;
- return i.Value; // BAD (always)
+ return i.Value; // $ Alert[cs/dereferenced-value-is-always-null]
}
int Ex41()
@@ -414,20 +414,20 @@ int Ex41()
static bool Ex42(int? i, IEnumerable @is)
{
- return @is.Any(j => j == i.Value); // BAD (maybe)
+ return @is.Any(j => j == i.Value); // $ Alert[cs/dereferenced-value-may-be-null]
}
static bool Ex43(int? i, IEnumerable @is)
{
if (i.HasValue)
- return @is.Any(j => j == i.Value); // GOOD (FALSE POSITIVE)
+ return @is.Any(j => j == i.Value); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
return false;
}
static bool Ex44(int? i, IEnumerable @is)
{
if (i.HasValue)
- @is = @is.Where(j => j == i.Value); // BAD (always)
+ @is = @is.Where(j => j == i.Value); // $ Alert[cs/dereferenced-value-may-be-null]
i = null;
return @is.Any();
}
@@ -436,12 +436,12 @@ static void Ex45(string s)
{
if (s is null)
{
- s.ToString(); // BAD (always)
+ s.ToString(); // $ Alert[cs/dereferenced-value-is-always-null]
}
if (s is not not null)
{
- s.ToString(); // BAD (always) (FALSE NEGATIVE)
+ s.ToString(); // $ MISSING: Alert[cs/dereferenced-value-is-always-null]
}
if (s is not null)
diff --git a/csharp/ql/test/query-tests/Nullness/F.cs b/csharp/ql/test/query-tests/Nullness/F.cs
new file mode 100644
index 000000000000..b5d6b66b9496
--- /dev/null
+++ b/csharp/ql/test/query-tests/Nullness/F.cs
@@ -0,0 +1,16 @@
+using Library;
+
+public class F
+{
+ public void M1()
+ {
+ object o = null;
+ o.Accept(); // $ Alert[cs/dereferenced-value-is-always-null]
+ }
+
+ public void M2()
+ {
+ object? o = null;
+ o.AcceptNullable();
+ }
+}
diff --git a/csharp/ql/test/query-tests/Nullness/Forwarding.cs b/csharp/ql/test/query-tests/Nullness/Forwarding.cs
index fc7b69da490f..122c5036567b 100644
--- a/csharp/ql/test/query-tests/Nullness/Forwarding.cs
+++ b/csharp/ql/test/query-tests/Nullness/Forwarding.cs
@@ -33,11 +33,11 @@ void Fn()
if (IsNotNullWrong(s))
{
- Console.WriteLine(s.Length); // BAD (always)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-is-always-null]
}
AssertIsNotNull(s);
- Console.WriteLine(s.Length); // GOOD (false positive)
+ Console.WriteLine(s.Length); // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-is-always-null]
}
bool IsNotNull(object o)
diff --git a/csharp/ql/test/query-tests/Nullness/GuardedString.cs b/csharp/ql/test/query-tests/Nullness/GuardedString.cs
index b5b74cf19cab..797955d95eb6 100644
--- a/csharp/ql/test/query-tests/Nullness/GuardedString.cs
+++ b/csharp/ql/test/query-tests/Nullness/GuardedString.cs
@@ -4,7 +4,7 @@ class GuardedStringTest
{
void Fn(bool b)
{
- string s = b ? null : "";
+ string s = b ? null : ""; // $ Source[cs/dereferenced-value-may-be-null]
if (!string.IsNullOrEmpty(s))
{
@@ -32,7 +32,7 @@ void Fn(bool b)
Console.WriteLine(s.Length); // GOOD
if (s?.Length != 0)
- Console.WriteLine(s.Length); // BAD (maybe)
+ Console.WriteLine(s.Length); // $ Alert[cs/dereferenced-value-may-be-null]
else
Console.WriteLine(s.Length); // GOOD
}
diff --git a/csharp/ql/test/query-tests/Nullness/Implications.expected b/csharp/ql/test/query-tests/Nullness/Implications.expected
index dbb6ab23a9aa..ec660dd44a42 100644
--- a/csharp/ql/test/query-tests/Nullness/Implications.expected
+++ b/csharp/ql/test/query-tests/Nullness/Implications.expected
@@ -1305,6 +1305,10 @@
| E.cs:442:13:442:29 | ... is ... | true | E.cs:442:13:442:13 | access to parameter s | non-null |
| E.cs:447:13:447:25 | ... is ... | true | E.cs:447:13:447:13 | access to parameter s | non-null |
| E.cs:452:13:452:23 | ... is ... | true | E.cs:452:13:452:13 | access to parameter s | non-null |
+| F.cs:8:9:8:9 | access to local variable o | non-null | F.cs:7:20:7:23 | null | non-null |
+| F.cs:8:9:8:9 | access to local variable o | null | F.cs:7:20:7:23 | null | null |
+| F.cs:14:9:14:9 | access to local variable o | non-null | F.cs:13:21:13:24 | null | non-null |
+| F.cs:14:9:14:9 | access to local variable o | null | F.cs:13:21:13:24 | null | null |
| Forwarding.cs:9:13:9:30 | !... | false | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | true |
| Forwarding.cs:9:13:9:30 | !... | true | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | false |
| Forwarding.cs:9:14:9:14 | access to local variable s | empty | Forwarding.cs:7:20:7:23 | null | empty |
diff --git a/csharp/ql/test/query-tests/Nullness/NullAlways.expected b/csharp/ql/test/query-tests/Nullness/NullAlways.expected
index ec8a78e817b5..e2e594b2e2c1 100644
--- a/csharp/ql/test/query-tests/Nullness/NullAlways.expected
+++ b/csharp/ql/test/query-tests/Nullness/NullAlways.expected
@@ -38,6 +38,7 @@
| E.cs:331:9:331:9 | access to local variable x | Variable $@ is always null at this dereference. | E.cs:330:13:330:13 | x | x |
| E.cs:405:16:405:16 | access to local variable i | Variable $@ is always null at this dereference. | E.cs:403:14:403:14 | i | i |
| E.cs:439:13:439:13 | access to parameter s | Variable $@ is always null at this dereference. | E.cs:435:29:435:29 | s | s |
+| F.cs:8:9:8:9 | access to local variable o | Variable $@ is always null at this dereference. | F.cs:7:16:7:16 | o | o |
| Forwarding.cs:36:31:36:31 | access to local variable s | Variable $@ is always null at this dereference. | Forwarding.cs:7:16:7:16 | s | s |
| Forwarding.cs:40:27:40:27 | access to local variable s | Variable $@ is always null at this dereference. | Forwarding.cs:7:16:7:16 | s | s |
| NullAlwaysBad.cs:9:30:9:30 | access to parameter s | Variable $@ is always null at this dereference. | NullAlwaysBad.cs:7:29:7:29 | s | s |
diff --git a/csharp/ql/test/query-tests/Nullness/NullAlways.qlref b/csharp/ql/test/query-tests/Nullness/NullAlways.qlref
index 16785ed3e7ad..9f937e609520 100644
--- a/csharp/ql/test/query-tests/Nullness/NullAlways.qlref
+++ b/csharp/ql/test/query-tests/Nullness/NullAlways.qlref
@@ -1 +1,2 @@
-CSI/NullAlways.ql
+query: CSI/NullAlways.ql
+postprocess: utils/test/InlineExpectationsTestQuery.ql
diff --git a/csharp/ql/test/query-tests/Nullness/NullAlwaysBad.cs b/csharp/ql/test/query-tests/Nullness/NullAlwaysBad.cs
index 6f0d486f1c77..107a4f3381ef 100644
--- a/csharp/ql/test/query-tests/Nullness/NullAlwaysBad.cs
+++ b/csharp/ql/test/query-tests/Nullness/NullAlwaysBad.cs
@@ -6,7 +6,7 @@ class Bad
{
void DoPrint(string s)
{
- if (s != null || s.Length > 0)
+ if (s != null || s.Length > 0) // $ Alert[cs/dereferenced-value-is-always-null]
Console.WriteLine(s);
}
}
diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected
index 631c2cd77660..876cde548b6a 100644
--- a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected
+++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected
@@ -1,457 +1,92 @@
-nodes
-| A.cs:7:16:7:40 | SSA def(synchronizedAlways) |
-| A.cs:8:15:8:32 | access to local variable synchronizedAlways |
-| A.cs:10:13:10:30 | access to local variable synchronizedAlways |
-| A.cs:16:15:16:30 | SSA def(arrayNull) |
-| A.cs:17:9:17:17 | access to local variable arrayNull |
-| A.cs:26:15:26:32 | SSA def(arrayAccess) |
-| A.cs:27:18:27:35 | SSA def(fieldAccess) |
-| A.cs:28:16:28:34 | SSA def(methodAccess) |
-| A.cs:29:16:29:32 | SSA def(methodCall) |
-| A.cs:31:27:31:37 | access to local variable arrayAccess |
-| A.cs:32:27:32:37 | access to local variable fieldAccess |
-| A.cs:33:28:33:39 | access to local variable methodAccess |
-| A.cs:34:27:34:36 | access to local variable methodCall |
-| A.cs:36:27:36:37 | access to local variable arrayAccess |
-| A.cs:37:27:37:37 | access to local variable fieldAccess |
-| A.cs:38:15:38:26 | access to local variable methodAccess |
-| A.cs:39:27:39:36 | access to local variable methodCall |
-| A.cs:48:16:48:28 | SSA def(varRef) |
-| A.cs:50:9:50:14 | access to local variable varRef |
-| Assert.cs:13:9:13:25 | [b (line 7): false] SSA def(s) |
-| Assert.cs:13:9:13:25 | [b (line 7): true] SSA def(s) |
-| Assert.cs:15:27:15:27 | access to local variable s |
-| Assert.cs:15:27:15:27 | access to local variable s |
-| Assert.cs:21:9:21:25 | [b (line 7): false] SSA def(s) |
-| Assert.cs:21:9:21:25 | [b (line 7): true] SSA def(s) |
-| Assert.cs:23:27:23:27 | access to local variable s |
-| Assert.cs:23:27:23:27 | access to local variable s |
-| Assert.cs:29:9:29:25 | [b (line 7): false] SSA def(s) |
-| Assert.cs:29:9:29:25 | [b (line 7): true] SSA def(s) |
-| Assert.cs:31:27:31:27 | access to local variable s |
-| Assert.cs:31:27:31:27 | access to local variable s |
-| Assert.cs:45:9:45:25 | [b (line 7): true] SSA def(s) |
-| Assert.cs:46:23:46:36 | [true, b (line 7): true] ... && ... |
-| Assert.cs:46:36:46:36 | [b (line 7): true] access to parameter b |
-| Assert.cs:47:27:47:27 | access to local variable s |
-| Assert.cs:49:9:49:25 | [b (line 7): true] SSA def(s) |
-| Assert.cs:50:24:50:38 | [false] ... \|\| ... |
-| Assert.cs:50:37:50:38 | [false] !... |
-| Assert.cs:50:38:50:38 | [b (line 7): true] access to parameter b |
-| Assert.cs:51:27:51:27 | access to local variable s |
-| B.cs:7:11:7:29 | SSA def(eqCallAlways) |
-| B.cs:10:11:10:30 | SSA def(neqCallAlways) |
-| B.cs:13:13:13:24 | access to local variable eqCallAlways |
-| B.cs:13:13:13:36 | ...; |
-| B.cs:15:9:16:26 | if (...) ... |
-| B.cs:16:13:16:26 | ...; |
-| B.cs:18:9:20:26 | if (...) ... |
-| B.cs:18:25:18:27 | {...} |
-| B.cs:20:13:20:26 | ...; |
-| B.cs:22:9:24:37 | if (...) ... |
-| B.cs:24:13:24:25 | access to local variable neqCallAlways |
-| C.cs:10:16:10:23 | SSA def(o) |
-| C.cs:11:13:11:30 | [false] !... |
-| C.cs:11:15:11:29 | [true] !... |
-| C.cs:11:17:11:28 | [false] !... |
-| C.cs:16:9:19:9 | if (...) ... |
-| C.cs:16:13:16:24 | [true] !... |
-| C.cs:18:13:18:13 | access to local variable o |
-| C.cs:40:13:40:35 | SSA def(s) |
-| C.cs:42:9:42:9 | access to local variable s |
-| C.cs:55:13:55:36 | SSA def(o2) |
-| C.cs:57:9:57:10 | access to local variable o2 |
-| C.cs:62:13:62:46 | SSA def(o1) |
-| C.cs:64:9:64:10 | access to local variable o1 |
-| C.cs:66:13:66:46 | SSA def(o2) |
-| C.cs:68:9:68:10 | access to local variable o2 |
-| C.cs:94:13:94:45 | SSA def(o) |
-| C.cs:95:15:95:15 | access to local variable o |
-| C.cs:96:13:96:13 | access to local variable o |
-| C.cs:102:13:102:23 | SSA def(list) |
-| C.cs:103:9:107:9 | foreach (... ... in ...) ... |
-| C.cs:103:22:103:22 | Int32 x |
-| C.cs:103:27:103:30 | access to parameter list |
-| C.cs:103:27:103:30 | access to parameter list |
-| C.cs:106:13:106:16 | access to parameter list |
-| C.cs:159:9:159:16 | SSA def(s) |
-| C.cs:162:13:162:13 | access to local variable s |
-| C.cs:167:9:167:16 | SSA def(s) |
-| C.cs:170:13:170:13 | access to local variable s |
-| C.cs:177:13:177:13 | access to local variable s |
-| C.cs:178:13:178:20 | SSA def(s) |
-| C.cs:193:9:193:16 | SSA def(s) |
-| C.cs:196:13:196:13 | access to local variable s |
-| C.cs:197:13:197:20 | [b (line 192): true] SSA def(s) |
-| C.cs:201:16:201:19 | true |
-| C.cs:203:13:203:13 | access to local variable s |
-| C.cs:204:13:204:20 | SSA def(s) |
-| C.cs:210:13:210:35 | SSA def(s) |
-| C.cs:214:13:214:20 | SSA def(s) |
-| C.cs:217:9:218:25 | if (...) ... |
-| C.cs:218:13:218:13 | access to local variable s |
-| C.cs:222:13:222:20 | SSA def(s) |
-| C.cs:223:9:223:9 | access to local variable s |
-| C.cs:229:22:229:22 | access to local variable s |
-| C.cs:229:33:229:40 | SSA def(s) |
-| C.cs:233:9:233:9 | access to local variable s |
-| C.cs:235:14:235:21 | SSA def(s) |
-| C.cs:235:24:235:24 | access to local variable s |
-| C.cs:235:35:235:42 | SSA def(s) |
-| C.cs:237:13:237:13 | access to local variable s |
-| C.cs:240:24:240:31 | SSA def(s) |
-| C.cs:242:13:242:13 | access to local variable s |
-| C.cs:248:15:248:22 | SSA def(a) |
-| C.cs:249:9:249:9 | access to local variable a |
-| C.cs:257:15:257:23 | SSA def(ia) |
-| C.cs:258:18:258:26 | SSA def(sa) |
-| C.cs:260:9:260:10 | access to local variable ia |
-| C.cs:261:20:261:21 | access to local variable sa |
-| C.cs:263:9:263:10 | access to local variable ia |
-| C.cs:264:16:264:17 | access to local variable sa |
-| D.cs:17:17:17:20 | null |
-| D.cs:23:9:23:13 | access to parameter param |
-| D.cs:26:32:26:36 | SSA param(param) |
-| D.cs:32:9:32:13 | access to parameter param |
-| D.cs:58:13:58:41 | SSA def(o5) |
-| D.cs:61:9:62:26 | if (...) ... |
-| D.cs:62:13:62:14 | access to local variable o5 |
-| D.cs:68:13:68:34 | SSA def(o7) |
-| D.cs:69:18:69:36 | ... && ... |
-| D.cs:73:13:73:14 | access to local variable o7 |
-| D.cs:75:13:75:34 | SSA def(o8) |
-| D.cs:76:21:76:43 | ... ? ... : ... |
-| D.cs:76:34:76:35 | 42 |
-| D.cs:79:9:80:26 | if (...) ... |
-| D.cs:81:9:82:26 | if (...) ... |
-| D.cs:82:13:82:14 | access to local variable o8 |
-| D.cs:82:13:82:26 | ...; |
-| D.cs:83:9:84:26 | if (...) ... |
-| D.cs:84:13:84:14 | access to local variable o8 |
-| D.cs:89:15:89:44 | SSA def(xs) |
-| D.cs:91:13:91:14 | access to local variable xs |
-| D.cs:91:13:91:22 | ...; |
-| D.cs:93:9:94:30 | if (...) ... |
-| D.cs:94:13:94:30 | ...; |
-| D.cs:94:21:94:22 | access to local variable xs |
-| D.cs:96:9:99:9 | if (...) ... |
-| D.cs:97:9:99:9 | {...} |
-| D.cs:98:21:98:22 | access to local variable xs |
-| D.cs:101:9:102:35 | if (...) ... |
-| D.cs:102:13:102:35 | foreach (... ... in ...) ... |
-| D.cs:102:26:102:26 | Int32 _ |
-| D.cs:102:31:102:32 | access to local variable xs |
-| D.cs:102:31:102:32 | access to local variable xs |
-| D.cs:104:9:106:30 | if (...) ... |
-| D.cs:105:19:105:20 | access to local variable xs |
-| D.cs:106:17:106:18 | access to local variable xs |
-| D.cs:118:9:118:30 | SSA def(x) |
-| D.cs:120:13:120:13 | access to local variable x |
-| D.cs:125:35:125:35 | SSA param(a) |
-| D.cs:125:35:125:35 | SSA param(a) |
-| D.cs:125:44:125:44 | SSA param(b) |
-| D.cs:127:20:127:43 | ... ? ... : ... |
-| D.cs:127:20:127:43 | ... ? ... : ... |
-| D.cs:127:32:127:32 | 0 |
-| D.cs:127:32:127:32 | 0 |
-| D.cs:127:36:127:36 | access to parameter a |
-| D.cs:128:20:128:43 | ... ? ... : ... |
-| D.cs:128:20:128:43 | ... ? ... : ... |
-| D.cs:128:32:128:32 | 0 |
-| D.cs:128:32:128:32 | 0 |
-| D.cs:128:36:128:36 | access to parameter b |
-| D.cs:131:9:137:9 | {...} |
-| D.cs:131:9:137:9 | {...} |
-| D.cs:132:29:132:29 | access to local variable i |
-| D.cs:132:29:132:29 | access to local variable i |
-| D.cs:133:13:136:13 | {...} |
-| D.cs:133:13:136:13 | {...} |
-| D.cs:134:24:134:24 | access to parameter a |
-| D.cs:135:24:135:24 | access to parameter b |
-| D.cs:138:9:138:18 | ... ...; |
-| D.cs:142:13:142:22 | ...; |
-| D.cs:143:9:146:9 | for (...;...;...) ... |
-| D.cs:143:25:143:25 | access to local variable i |
-| D.cs:144:9:146:9 | {...} |
-| D.cs:145:20:145:20 | access to parameter a |
-| D.cs:149:36:149:38 | SSA param(obj) |
-| D.cs:151:9:151:11 | access to parameter obj |
-| D.cs:163:16:163:25 | SSA def(obj) |
-| D.cs:168:9:170:9 | [exception: Exception] catch (...) {...} |
-| D.cs:168:26:168:26 | [exception: Exception] Exception e |
-| D.cs:171:9:171:11 | access to local variable obj |
-| D.cs:240:9:240:16 | SSA def(o) |
-| D.cs:241:21:241:37 | ... ? ... : ... |
-| D.cs:241:29:241:32 | null |
-| D.cs:241:36:241:37 | "" |
-| D.cs:244:9:247:25 | if (...) ... |
-| D.cs:245:13:245:13 | access to local variable o |
-| D.cs:247:13:247:13 | access to local variable o |
-| D.cs:249:13:249:38 | SSA def(o2) |
-| D.cs:253:13:253:14 | access to local variable o2 |
-| D.cs:258:16:258:23 | SSA def(o) |
-| D.cs:266:9:267:25 | if (...) ... |
-| D.cs:266:13:266:27 | [true] ... is ... |
-| D.cs:267:13:267:13 | access to local variable o |
-| D.cs:269:9:269:16 | SSA def(o) |
-| D.cs:272:25:272:25 | access to local variable i |
-| D.cs:272:39:272:39 | access to local variable i |
-| D.cs:273:9:288:9 | {...} |
-| D.cs:281:13:287:13 | if (...) ... |
-| D.cs:283:17:283:24 | SSA def(o) |
-| D.cs:285:28:285:30 | {...} |
-| D.cs:286:17:286:30 | ...; |
-| D.cs:290:9:291:25 | if (...) ... |
-| D.cs:291:13:291:13 | access to local variable o |
-| D.cs:291:13:291:25 | ...; |
-| D.cs:293:9:294:25 | if (...) ... |
-| D.cs:294:13:294:13 | access to local variable o |
-| D.cs:296:16:296:26 | SSA def(prev) |
-| D.cs:297:25:297:25 | access to local variable i |
-| D.cs:298:9:302:9 | {...} |
-| D.cs:300:17:300:20 | access to local variable prev |
-| D.cs:304:16:304:23 | SSA def(s) |
-| D.cs:307:13:311:13 | foreach (... ... in ...) ... |
-| D.cs:312:13:313:29 | if (...) ... |
-| D.cs:312:17:312:23 | [true] !... |
-| D.cs:313:17:313:17 | access to local variable s |
-| D.cs:316:16:316:23 | SSA def(r) |
-| D.cs:318:16:318:19 | access to local variable stat |
-| D.cs:318:16:318:62 | [false] ... && ... |
-| D.cs:318:41:318:44 | access to local variable stat |
-| D.cs:324:9:324:9 | access to local variable r |
-| D.cs:351:15:351:22 | SSA def(a) |
-| D.cs:355:9:356:21 | for (...;...;...) ... |
-| D.cs:355:25:355:25 | access to local variable i |
-| D.cs:356:13:356:13 | access to local variable a |
-| D.cs:356:13:356:21 | ...; |
-| D.cs:360:20:360:30 | SSA def(last) |
-| D.cs:361:29:361:29 | access to local variable i |
-| D.cs:363:13:363:16 | access to local variable last |
-| D.cs:366:15:366:47 | SSA def(b) |
-| D.cs:367:13:367:56 | [false] ... && ... |
-| D.cs:370:9:373:9 | for (...;...;...) ... |
-| D.cs:370:25:370:25 | access to local variable i |
-| D.cs:371:9:373:9 | {...} |
-| D.cs:372:13:372:13 | access to local variable b |
-| D.cs:378:19:378:28 | SSA def(ioe) |
-| D.cs:382:9:385:27 | if (...) ... |
-| D.cs:385:13:385:15 | access to local variable ioe |
-| D.cs:388:36:388:36 | SSA param(a) |
-| D.cs:388:45:388:45 | SSA param(b) |
-| D.cs:390:20:390:43 | ... ? ... : ... |
-| D.cs:390:20:390:43 | ... ? ... : ... |
-| D.cs:390:32:390:32 | 0 |
-| D.cs:390:32:390:32 | 0 |
-| D.cs:390:36:390:36 | access to parameter a |
-| D.cs:393:21:393:21 | access to local variable i |
-| D.cs:393:21:393:21 | access to local variable i |
-| D.cs:394:9:396:9 | {...} |
-| D.cs:394:9:396:9 | {...} |
-| D.cs:395:20:395:20 | access to parameter a |
-| D.cs:397:9:397:44 | ... ...; |
-| D.cs:397:20:397:43 | ... ? ... : ... |
-| D.cs:397:32:397:32 | 0 |
-| D.cs:398:21:398:21 | access to local variable i |
-| D.cs:399:9:401:9 | {...} |
-| D.cs:400:20:400:20 | access to parameter b |
-| D.cs:405:35:405:35 | SSA param(x) |
-| D.cs:405:35:405:35 | SSA param(x) |
-| D.cs:405:35:405:35 | SSA param(x) |
-| D.cs:405:45:405:45 | SSA param(y) |
-| D.cs:405:45:405:45 | SSA param(y) |
-| D.cs:405:45:405:45 | SSA param(y) |
-| D.cs:407:13:407:64 | [false] ... \|\| ... |
-| D.cs:407:13:407:64 | [false] ... \|\| ... |
-| D.cs:407:14:407:35 | [false] ... && ... |
-| D.cs:407:14:407:35 | [false] ... && ... |
-| D.cs:407:42:407:42 | access to parameter x |
-| D.cs:407:42:407:42 | access to parameter x |
-| D.cs:407:42:407:63 | [false] ... && ... |
-| D.cs:407:42:407:63 | [false] ... && ... |
-| D.cs:407:55:407:55 | access to parameter y |
-| D.cs:407:55:407:55 | access to parameter y |
-| D.cs:409:9:410:25 | if (...) ... |
-| D.cs:409:9:410:25 | if (...) ... |
-| D.cs:410:13:410:13 | access to parameter y |
-| D.cs:411:9:412:25 | if (...) ... |
-| D.cs:412:13:412:13 | access to parameter x |
-| E.cs:9:18:9:26 | SSA def(a2) |
-| E.cs:10:22:10:54 | ... && ... |
-| E.cs:11:16:11:24 | SSA def(a3) |
-| E.cs:12:22:12:52 | ... && ... |
-| E.cs:12:38:12:39 | access to local variable a2 |
-| E.cs:14:13:14:14 | access to local variable a3 |
-| E.cs:23:13:23:30 | SSA def(s1) |
-| E.cs:24:18:24:41 | ... ? ... : ... |
-| E.cs:24:33:24:36 | null |
-| E.cs:26:9:27:26 | if (...) ... |
-| E.cs:27:13:27:14 | access to local variable s1 |
-| E.cs:51:22:51:33 | SSA def(slice) |
-| E.cs:53:16:53:19 | access to local variable iter |
-| E.cs:54:9:63:9 | {...} |
-| E.cs:61:13:61:17 | access to local variable slice |
-| E.cs:61:13:61:27 | ...; |
-| E.cs:66:40:66:42 | SSA param(arr) |
-| E.cs:70:13:70:50 | ...; |
-| E.cs:70:22:70:49 | ... ? ... : ... |
-| E.cs:70:36:70:36 | 0 |
-| E.cs:72:9:73:23 | if (...) ... |
-| E.cs:73:13:73:15 | access to parameter arr |
-| E.cs:107:15:107:25 | SSA def(arr2) |
-| E.cs:111:9:112:30 | for (...;...;...) ... |
-| E.cs:111:25:111:25 | access to local variable i |
-| E.cs:112:13:112:16 | access to local variable arr2 |
-| E.cs:112:13:112:30 | ...; |
-| E.cs:120:16:120:20 | [true] !... |
-| E.cs:120:17:120:20 | access to local variable stop |
-| E.cs:121:9:143:9 | {...} |
-| E.cs:123:20:123:24 | [false] !... |
-| E.cs:123:20:123:24 | [true] !... |
-| E.cs:123:20:123:35 | [false] ... && ... |
-| E.cs:123:20:123:35 | [true] ... && ... |
-| E.cs:123:21:123:24 | access to local variable stop |
-| E.cs:123:29:123:29 | access to local variable j |
-| E.cs:124:13:142:13 | {...} |
-| E.cs:125:33:125:35 | access to local variable obj |
-| E.cs:128:21:128:23 | access to local variable obj |
-| E.cs:137:25:137:34 | SSA def(obj) |
-| E.cs:139:21:139:29 | continue; |
-| E.cs:141:17:141:26 | ...; |
-| E.cs:152:16:152:26 | SSA def(obj2) |
-| E.cs:153:13:153:54 | [false] ... && ... |
-| E.cs:158:9:159:28 | if (...) ... |
-| E.cs:159:13:159:16 | access to local variable obj2 |
-| E.cs:162:28:162:28 | SSA param(a) |
-| E.cs:164:17:164:40 | ... ? ... : ... |
-| E.cs:164:29:164:29 | 0 |
-| E.cs:165:25:165:25 | access to local variable i |
-| E.cs:165:32:165:32 | access to local variable i |
-| E.cs:166:9:170:9 | {...} |
-| E.cs:167:21:167:21 | access to parameter a |
-| E.cs:173:29:173:31 | SSA param(obj) |
-| E.cs:173:29:173:31 | SSA param(obj) |
-| E.cs:175:19:175:42 | ... ? ... : ... |
-| E.cs:175:33:175:37 | false |
-| E.cs:177:9:179:9 | {...} |
-| E.cs:178:13:178:15 | access to parameter obj |
-| E.cs:180:9:183:9 | if (...) ... |
-| E.cs:181:9:183:9 | {...} |
-| E.cs:184:9:187:9 | if (...) ... |
-| E.cs:186:13:186:15 | access to parameter obj |
-| E.cs:190:29:190:29 | SSA param(o) |
-| E.cs:192:17:192:17 | access to parameter o |
-| E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) |
-| E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) |
-| E.cs:201:13:201:13 | access to local variable o |
-| E.cs:203:13:203:13 | access to local variable o |
-| E.cs:206:28:206:28 | SSA param(s) |
-| E.cs:208:13:208:23 | [false] ... is ... |
-| E.cs:210:16:210:16 | access to parameter s |
-| E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) |
-| E.cs:218:9:218:9 | access to local variable x |
-| E.cs:220:13:220:13 | access to local variable x |
-| E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) |
-| E.cs:229:13:229:13 | access to local variable x |
-| E.cs:229:13:229:25 | ...; |
-| E.cs:230:9:230:9 | access to local variable x |
-| E.cs:233:26:233:26 | SSA param(i) |
-| E.cs:235:16:235:16 | access to parameter i |
-| E.cs:238:26:238:26 | SSA param(i) |
-| E.cs:240:21:240:21 | access to parameter i |
-| E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) |
-| E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) |
-| E.cs:285:9:285:9 | access to local variable o |
-| E.cs:285:9:285:9 | access to local variable o |
-| E.cs:301:13:301:27 | SSA def(s) |
-| E.cs:302:9:302:9 | access to local variable s |
-| E.cs:319:29:319:30 | SSA param(s1) |
-| E.cs:321:13:321:30 | [true] ... is ... |
-| E.cs:321:14:321:21 | ... ?? ... |
-| E.cs:321:20:321:21 | access to parameter s2 |
-| E.cs:323:13:323:14 | access to parameter s1 |
-| E.cs:330:13:330:36 | SSA def(x) |
-| E.cs:331:9:331:9 | access to local variable x |
-| E.cs:342:13:342:32 | SSA def(x) |
-| E.cs:343:9:343:9 | access to local variable x |
-| E.cs:348:17:348:36 | SSA def(x) |
-| E.cs:349:9:349:9 | access to local variable x |
-| E.cs:366:28:366:28 | SSA param(s) |
-| E.cs:366:41:366:41 | access to parameter s |
-| E.cs:374:17:374:31 | SSA def(s) |
-| E.cs:375:20:375:20 | access to local variable s |
-| E.cs:380:24:380:25 | SSA param(e1) |
-| E.cs:380:24:380:25 | SSA param(e1) |
-| E.cs:380:24:380:25 | SSA param(e1) |
-| E.cs:380:30:380:31 | SSA param(e2) |
-| E.cs:380:30:380:31 | SSA param(e2) |
-| E.cs:380:30:380:31 | SSA param(e2) |
-| E.cs:382:13:382:68 | [false] ... \|\| ... |
-| E.cs:382:13:382:68 | [false] ... \|\| ... |
-| E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:382:28:382:29 | access to parameter e2 |
-| E.cs:382:28:382:29 | access to parameter e2 |
-| E.cs:382:44:382:45 | access to parameter e1 |
-| E.cs:382:44:382:45 | access to parameter e1 |
-| E.cs:382:44:382:67 | [false] ... && ... |
-| E.cs:382:44:382:67 | [false] ... && ... |
-| E.cs:384:9:385:24 | if (...) ... |
-| E.cs:384:9:385:24 | if (...) ... |
-| E.cs:384:13:384:36 | [false] ... && ... |
-| E.cs:384:13:384:36 | [false] ... && ... |
-| E.cs:384:27:384:28 | access to parameter e2 |
-| E.cs:386:16:386:17 | access to parameter e1 |
-| E.cs:386:27:386:28 | access to parameter e2 |
-| E.cs:404:9:404:18 | SSA def(i) |
-| E.cs:404:9:404:18 | SSA def(i) |
-| E.cs:405:16:405:16 | access to local variable i |
-| E.cs:417:24:417:40 | SSA capture def(i) |
-| E.cs:417:34:417:34 | access to parameter i |
-| E.cs:423:28:423:44 | SSA capture def(i) |
-| E.cs:423:38:423:38 | access to parameter i |
-| E.cs:430:29:430:45 | SSA capture def(i) |
-| E.cs:430:39:430:39 | access to parameter i |
-| E.cs:435:29:435:29 | SSA param(s) |
-| E.cs:437:13:437:21 | [true] ... is ... |
-| E.cs:439:13:439:13 | access to parameter s |
-| Forwarding.cs:7:16:7:23 | SSA def(s) |
-| Forwarding.cs:9:13:9:30 | [false] !... |
-| Forwarding.cs:14:9:17:9 | if (...) ... |
-| Forwarding.cs:19:9:22:9 | if (...) ... |
-| Forwarding.cs:19:13:19:23 | [false] !... |
-| Forwarding.cs:24:9:27:9 | if (...) ... |
-| Forwarding.cs:29:9:32:9 | if (...) ... |
-| Forwarding.cs:34:9:37:9 | if (...) ... |
-| Forwarding.cs:35:9:37:9 | {...} |
-| Forwarding.cs:36:31:36:31 | access to local variable s |
-| Forwarding.cs:40:27:40:27 | access to local variable s |
-| GuardedString.cs:7:16:7:32 | SSA def(s) |
-| GuardedString.cs:9:13:9:36 | [false] !... |
-| GuardedString.cs:14:9:17:9 | if (...) ... |
-| GuardedString.cs:14:13:14:41 | [false] !... |
-| GuardedString.cs:19:9:20:40 | if (...) ... |
-| GuardedString.cs:19:26:19:26 | 0 |
-| GuardedString.cs:22:9:23:40 | if (...) ... |
-| GuardedString.cs:22:25:22:25 | 0 |
-| GuardedString.cs:25:9:26:40 | if (...) ... |
-| GuardedString.cs:25:26:25:26 | 0 |
-| GuardedString.cs:28:9:29:40 | if (...) ... |
-| GuardedString.cs:28:25:28:26 | 10 |
-| GuardedString.cs:31:9:32:40 | if (...) ... |
-| GuardedString.cs:31:26:31:27 | 10 |
-| GuardedString.cs:34:9:37:40 | if (...) ... |
-| GuardedString.cs:34:26:34:26 | 0 |
-| GuardedString.cs:35:31:35:31 | access to local variable s |
-| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) |
-| NullAlwaysBad.cs:9:30:9:30 | access to parameter s |
-| NullMaybeBad.cs:7:27:7:27 | access to parameter o |
-| NullMaybeBad.cs:13:17:13:20 | null |
-| Params.cs:14:17:14:20 | access to parameter args |
-| Params.cs:20:12:20:15 | null |
-| StringConcatenation.cs:14:16:14:23 | SSA def(s) |
-| StringConcatenation.cs:15:16:15:16 | access to local variable s |
-| StringConcatenation.cs:16:17:16:17 | access to local variable s |
+#select
+| C.cs:64:9:64:10 | access to local variable o1 | C.cs:62:13:62:46 | SSA def(o1) | C.cs:64:9:64:10 | access to local variable o1 | Variable $@ may be null at this access because of $@ assignment. | C.cs:62:13:62:14 | o1 | o1 | C.cs:62:13:62:46 | Object o1 = ... | this |
+| C.cs:68:9:68:10 | access to local variable o2 | C.cs:66:13:66:46 | SSA def(o2) | C.cs:68:9:68:10 | access to local variable o2 | Variable $@ may be null at this access because of $@ assignment. | C.cs:66:13:66:14 | o2 | o2 | C.cs:66:13:66:46 | Object o2 = ... | this |
+| C.cs:95:15:95:15 | access to local variable o | C.cs:94:13:94:45 | SSA def(o) | C.cs:95:15:95:15 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | C.cs:94:13:94:13 | o | o | C.cs:94:13:94:45 | Object o = ... | this |
+| C.cs:103:27:103:30 | access to parameter list | C.cs:102:13:102:23 | SSA def(list) | C.cs:103:27:103:30 | access to parameter list | Variable $@ may be null at this access because of $@ assignment. | C.cs:99:42:99:45 | list | list | C.cs:102:13:102:23 | ... = ... | this |
+| C.cs:177:13:177:13 | access to local variable s | C.cs:178:13:178:20 | SSA def(s) | C.cs:177:13:177:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:151:13:151:13 | s | s | C.cs:178:13:178:20 | ... = ... | this |
+| C.cs:203:13:203:13 | access to local variable s | C.cs:204:13:204:20 | SSA def(s) | C.cs:203:13:203:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:185:13:185:13 | s | s | C.cs:204:13:204:20 | ... = ... | this |
+| C.cs:223:9:223:9 | access to local variable s | C.cs:222:13:222:20 | SSA def(s) | C.cs:223:9:223:9 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:210:13:210:13 | s | s | C.cs:222:13:222:20 | ... = ... | this |
+| C.cs:242:13:242:13 | access to local variable s | C.cs:240:24:240:31 | SSA def(s) | C.cs:242:13:242:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:228:16:228:16 | s | s | C.cs:240:24:240:31 | ... = ... | this |
+| D.cs:23:9:23:13 | access to parameter param | D.cs:17:17:17:20 | null | D.cs:23:9:23:13 | access to parameter param | Variable $@ may be null at this access because of $@ null argument. | D.cs:21:32:21:36 | param | param | D.cs:17:17:17:20 | null | this |
+| D.cs:32:9:32:13 | access to parameter param | D.cs:26:32:26:36 | SSA param(param) | D.cs:32:9:32:13 | access to parameter param | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:26:32:26:36 | param | param | D.cs:28:13:28:25 | ... != ... | this |
+| D.cs:62:13:62:14 | access to local variable o5 | D.cs:58:13:58:41 | SSA def(o5) | D.cs:62:13:62:14 | access to local variable o5 | Variable $@ may be null at this access because of $@ assignment. | D.cs:58:13:58:14 | o5 | o5 | D.cs:58:13:58:41 | String o5 = ... | this |
+| D.cs:73:13:73:14 | access to local variable o7 | D.cs:68:13:68:34 | SSA def(o7) | D.cs:73:13:73:14 | access to local variable o7 | Variable $@ may be null at this access because of $@ assignment. | D.cs:68:13:68:14 | o7 | o7 | D.cs:68:13:68:34 | String o7 = ... | this |
+| D.cs:82:13:82:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:82:13:82:14 | access to local variable o8 | Variable $@ may be null at this access because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this |
+| D.cs:84:13:84:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:84:13:84:14 | access to local variable o8 | Variable $@ may be null at this access because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this |
+| D.cs:91:13:91:14 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:91:13:91:14 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
+| D.cs:94:21:94:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:94:21:94:22 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
+| D.cs:98:21:98:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:98:21:98:22 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
+| D.cs:102:31:102:32 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:102:31:102:32 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
+| D.cs:105:19:105:20 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:105:19:105:20 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
+| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this |
+| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this |
+| D.cs:135:24:135:24 | access to parameter b | D.cs:125:44:125:44 | SSA param(b) | D.cs:135:24:135:24 | access to parameter b | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:44:125:44 | b | b | D.cs:128:20:128:28 | ... == ... | this |
+| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this |
+| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this |
+| D.cs:151:9:151:11 | access to parameter obj | D.cs:149:36:149:38 | SSA param(obj) | D.cs:151:9:151:11 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:149:36:149:38 | obj | obj | D.cs:152:17:152:27 | ... != ... | this |
+| D.cs:171:9:171:11 | access to local variable obj | D.cs:163:16:163:25 | SSA def(obj) | D.cs:171:9:171:11 | access to local variable obj | Variable $@ may be null at this access because of $@ assignment. | D.cs:163:16:163:18 | obj | obj | D.cs:163:16:163:25 | Object obj = ... | this |
+| D.cs:245:13:245:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:245:13:245:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this |
+| D.cs:247:13:247:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:247:13:247:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this |
+| D.cs:253:13:253:14 | access to local variable o2 | D.cs:249:13:249:38 | SSA def(o2) | D.cs:253:13:253:14 | access to local variable o2 | Variable $@ may be null at this access because of $@ assignment. | D.cs:249:13:249:14 | o2 | o2 | D.cs:249:13:249:38 | String o2 = ... | this |
+| D.cs:267:13:267:13 | access to local variable o | D.cs:258:16:258:23 | SSA def(o) | D.cs:267:13:267:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:258:16:258:23 | Object o = ... | this |
+| D.cs:291:13:291:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this |
+| D.cs:291:13:291:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this |
+| D.cs:294:13:294:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this |
+| D.cs:294:13:294:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this |
+| D.cs:300:17:300:20 | access to local variable prev | D.cs:296:16:296:26 | SSA def(prev) | D.cs:300:17:300:20 | access to local variable prev | Variable $@ may be null at this access because of $@ assignment. | D.cs:296:16:296:19 | prev | prev | D.cs:296:16:296:26 | Object prev = ... | this |
+| D.cs:313:17:313:17 | access to local variable s | D.cs:304:16:304:23 | SSA def(s) | D.cs:313:17:313:17 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | D.cs:304:16:304:16 | s | s | D.cs:304:16:304:23 | String s = ... | this |
+| D.cs:324:9:324:9 | access to local variable r | D.cs:316:16:316:23 | SSA def(r) | D.cs:324:9:324:9 | access to local variable r | Variable $@ may be null at this access because of $@ assignment. | D.cs:316:16:316:16 | r | r | D.cs:316:16:316:23 | Object r = ... | this |
+| D.cs:356:13:356:13 | access to local variable a | D.cs:351:15:351:22 | SSA def(a) | D.cs:356:13:356:13 | access to local variable a | Variable $@ may be null at this access because of $@ assignment. | D.cs:351:15:351:15 | a | a | D.cs:351:15:351:22 | Int32[] a = ... | this |
+| D.cs:363:13:363:16 | access to local variable last | D.cs:360:20:360:30 | SSA def(last) | D.cs:363:13:363:16 | access to local variable last | Variable $@ may be null at this access because of $@ assignment. | D.cs:360:20:360:23 | last | last | D.cs:360:20:360:30 | String last = ... | this |
+| D.cs:372:13:372:13 | access to local variable b | D.cs:366:15:366:47 | SSA def(b) | D.cs:372:13:372:13 | access to local variable b | Variable $@ may be null at this access because of $@ assignment. | D.cs:366:15:366:15 | b | b | D.cs:366:15:366:47 | Int32[] b = ... | this |
+| D.cs:395:20:395:20 | access to parameter a | D.cs:388:36:388:36 | SSA param(a) | D.cs:395:20:395:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:388:36:388:36 | a | a | D.cs:390:20:390:28 | ... == ... | this |
+| D.cs:400:20:400:20 | access to parameter b | D.cs:388:45:388:45 | SSA param(b) | D.cs:400:20:400:20 | access to parameter b | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:388:45:388:45 | b | b | D.cs:397:20:397:28 | ... == ... | this |
+| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:27:407:35 | ... == ... | this |
+| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:55:407:63 | ... != ... | this |
+| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:411:13:411:21 | ... != ... | this |
+| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:14:407:22 | ... != ... | this |
+| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:42:407:50 | ... == ... | this |
+| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:409:13:409:21 | ... != ... | this |
+| E.cs:12:38:12:39 | access to local variable a2 | E.cs:9:18:9:26 | SSA def(a2) | E.cs:12:38:12:39 | access to local variable a2 | Variable $@ may be null at this access because of $@ assignment. | E.cs:9:18:9:19 | a2 | a2 | E.cs:9:18:9:26 | Int64[][] a2 = ... | this |
+| E.cs:14:13:14:14 | access to local variable a3 | E.cs:11:16:11:24 | SSA def(a3) | E.cs:14:13:14:14 | access to local variable a3 | Variable $@ may be null at this access because of $@ assignment. | E.cs:11:16:11:17 | a3 | a3 | E.cs:11:16:11:24 | Int64[] a3 = ... | this |
+| E.cs:27:13:27:14 | access to local variable s1 | E.cs:23:13:23:30 | SSA def(s1) | E.cs:27:13:27:14 | access to local variable s1 | Variable $@ may be null at this access because of $@ assignment. | E.cs:19:13:19:14 | s1 | s1 | E.cs:23:13:23:30 | ... = ... | this |
+| E.cs:61:13:61:17 | access to local variable slice | E.cs:51:22:51:33 | SSA def(slice) | E.cs:61:13:61:17 | access to local variable slice | Variable $@ may be null at this access because of $@ assignment. | E.cs:51:22:51:26 | slice | slice | E.cs:51:22:51:33 | List slice = ... | this |
+| E.cs:73:13:73:15 | access to parameter arr | E.cs:66:40:66:42 | SSA param(arr) | E.cs:73:13:73:15 | access to parameter arr | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:66:40:66:42 | arr | arr | E.cs:70:22:70:32 | ... == ... | this |
+| E.cs:112:13:112:16 | access to local variable arr2 | E.cs:107:15:107:25 | SSA def(arr2) | E.cs:112:13:112:16 | access to local variable arr2 | Variable $@ may be null at this access because of $@ assignment. | E.cs:107:15:107:18 | arr2 | arr2 | E.cs:107:15:107:25 | Int32[] arr2 = ... | this |
+| E.cs:125:33:125:35 | access to local variable obj | E.cs:137:25:137:34 | SSA def(obj) | E.cs:125:33:125:35 | access to local variable obj | Variable $@ may be null at this access because of $@ assignment. | E.cs:119:13:119:15 | obj | obj | E.cs:137:25:137:34 | ... = ... | this |
+| E.cs:159:13:159:16 | access to local variable obj2 | E.cs:152:16:152:26 | SSA def(obj2) | E.cs:159:13:159:16 | access to local variable obj2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:152:16:152:19 | obj2 | obj2 | E.cs:153:13:153:24 | ... != ... | this |
+| E.cs:167:21:167:21 | access to parameter a | E.cs:162:28:162:28 | SSA param(a) | E.cs:167:21:167:21 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:162:28:162:28 | a | a | E.cs:164:17:164:25 | ... == ... | this |
+| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this |
+| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this |
+| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this |
+| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this |
+| E.cs:192:17:192:17 | access to parameter o | E.cs:190:29:190:29 | SSA param(o) | E.cs:192:17:192:17 | access to parameter o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:190:29:190:29 | o | o | E.cs:193:17:193:17 | access to parameter o | this |
+| E.cs:201:13:201:13 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | E.cs:201:13:201:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this |
+| E.cs:203:13:203:13 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | E.cs:203:13:203:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this |
+| E.cs:218:9:218:9 | access to local variable x | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:218:9:218:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:215:13:215:13 | x | x | E.cs:217:13:217:20 | ... = ... | this |
+| E.cs:230:9:230:9 | access to local variable x | E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this |
+| E.cs:235:16:235:16 | access to parameter i | E.cs:233:26:233:26 | SSA param(i) | E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this |
+| E.cs:240:21:240:21 | access to parameter i | E.cs:238:26:238:26 | SSA param(i) | E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this |
+| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this |
+| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this |
+| E.cs:302:9:302:9 | access to local variable s | E.cs:301:13:301:27 | SSA def(s) | E.cs:302:9:302:9 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | E.cs:301:13:301:13 | s | s | E.cs:301:13:301:27 | String s = ... | this |
+| E.cs:343:9:343:9 | access to local variable x | E.cs:342:13:342:32 | SSA def(x) | E.cs:343:9:343:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:342:13:342:13 | x | x | E.cs:342:13:342:32 | String x = ... | this |
+| E.cs:349:9:349:9 | access to local variable x | E.cs:348:17:348:36 | SSA def(x) | E.cs:349:9:349:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:348:17:348:17 | x | x | E.cs:348:17:348:36 | dynamic x = ... | this |
+| E.cs:366:41:366:41 | access to parameter s | E.cs:366:28:366:28 | SSA param(s) | E.cs:366:41:366:41 | access to parameter s | Variable $@ may be null at this access because the parameter has a null default value. | E.cs:366:28:366:28 | s | s | E.cs:366:32:366:35 | null | this |
+| E.cs:375:20:375:20 | access to local variable s | E.cs:374:17:374:31 | SSA def(s) | E.cs:375:20:375:20 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | E.cs:374:17:374:17 | s | s | E.cs:374:17:374:31 | String s = ... | this |
+| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:382:14:382:23 | ... == ... | this |
+| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:382:44:382:53 | ... != ... | this |
+| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:384:13:384:22 | ... == ... | this |
+| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:28:382:37 | ... != ... | this |
+| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:58:382:67 | ... == ... | this |
+| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:384:27:384:36 | ... == ... | this |
+| E.cs:417:34:417:34 | access to parameter i | E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:415:27:415:27 | i | i | E.cs:415:27:415:27 | i | this |
+| E.cs:423:38:423:38 | access to parameter i | E.cs:423:28:423:44 | SSA capture def(i) | E.cs:423:38:423:38 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:420:27:420:27 | i | i | E.cs:420:27:420:27 | i | this |
+| E.cs:430:39:430:39 | access to parameter i | E.cs:430:29:430:45 | SSA capture def(i) | E.cs:430:39:430:39 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:427:27:427:27 | i | i | E.cs:427:27:427:27 | i | this |
+| GuardedString.cs:35:31:35:31 | access to local variable s | GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this |
+| NullMaybeBad.cs:7:27:7:27 | access to parameter o | NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null at this access because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this |
+| Params.cs:14:17:14:20 | access to parameter args | Params.cs:20:12:20:15 | null | Params.cs:14:17:14:20 | access to parameter args | Variable $@ may be null at this access because of $@ null argument. | Params.cs:12:36:12:39 | args | args | Params.cs:20:12:20:15 | null | this |
+| StringConcatenation.cs:16:17:16:17 | access to local variable s | StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this |
edges
| A.cs:7:16:7:40 | SSA def(synchronizedAlways) | A.cs:8:15:8:32 | access to local variable synchronizedAlways |
| A.cs:7:16:7:40 | SSA def(synchronizedAlways) | A.cs:10:13:10:30 | access to local variable synchronizedAlways |
@@ -784,150 +419,518 @@ edges
| E.cs:380:24:380:25 | SSA param(e1) | E.cs:382:28:382:29 | access to parameter e2 |
| E.cs:380:24:380:25 | SSA param(e1) | E.cs:382:28:382:29 | access to parameter e2 |
| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
-| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
-| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
-| E.cs:382:13:382:68 | [false] ... \|\| ... | E.cs:384:9:385:24 | if (...) ... |
-| E.cs:382:13:382:68 | [false] ... \|\| ... | E.cs:384:9:385:24 | if (...) ... |
-| E.cs:382:14:382:37 | [false] ... && ... | E.cs:382:44:382:45 | access to parameter e1 |
-| E.cs:382:14:382:37 | [false] ... && ... | E.cs:382:44:382:45 | access to parameter e1 |
-| E.cs:382:28:382:29 | access to parameter e2 | E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:382:28:382:29 | access to parameter e2 | E.cs:382:14:382:37 | [false] ... && ... |
-| E.cs:382:44:382:45 | access to parameter e1 | E.cs:382:44:382:67 | [false] ... && ... |
-| E.cs:382:44:382:45 | access to parameter e1 | E.cs:382:44:382:67 | [false] ... && ... |
-| E.cs:382:44:382:67 | [false] ... && ... | E.cs:382:13:382:68 | [false] ... \|\| ... |
-| E.cs:382:44:382:67 | [false] ... && ... | E.cs:382:13:382:68 | [false] ... \|\| ... |
-| E.cs:384:9:385:24 | if (...) ... | E.cs:384:13:384:36 | [false] ... && ... |
-| E.cs:384:9:385:24 | if (...) ... | E.cs:384:27:384:28 | access to parameter e2 |
-| E.cs:384:13:384:36 | [false] ... && ... | E.cs:386:16:386:17 | access to parameter e1 |
-| E.cs:384:13:384:36 | [false] ... && ... | E.cs:386:27:386:28 | access to parameter e2 |
-| E.cs:384:27:384:28 | access to parameter e2 | E.cs:384:13:384:36 | [false] ... && ... |
-| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
-| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
-| E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i |
-| E.cs:423:28:423:44 | SSA capture def(i) | E.cs:423:38:423:38 | access to parameter i |
-| E.cs:430:29:430:45 | SSA capture def(i) | E.cs:430:39:430:39 | access to parameter i |
-| E.cs:435:29:435:29 | SSA param(s) | E.cs:437:13:437:21 | [true] ... is ... |
-| E.cs:437:13:437:21 | [true] ... is ... | E.cs:439:13:439:13 | access to parameter s |
-| Forwarding.cs:7:16:7:23 | SSA def(s) | Forwarding.cs:9:13:9:30 | [false] !... |
-| Forwarding.cs:9:13:9:30 | [false] !... | Forwarding.cs:14:9:17:9 | if (...) ... |
-| Forwarding.cs:14:9:17:9 | if (...) ... | Forwarding.cs:19:9:22:9 | if (...) ... |
-| Forwarding.cs:19:9:22:9 | if (...) ... | Forwarding.cs:19:13:19:23 | [false] !... |
-| Forwarding.cs:19:13:19:23 | [false] !... | Forwarding.cs:24:9:27:9 | if (...) ... |
-| Forwarding.cs:24:9:27:9 | if (...) ... | Forwarding.cs:29:9:32:9 | if (...) ... |
-| Forwarding.cs:29:9:32:9 | if (...) ... | Forwarding.cs:34:9:37:9 | if (...) ... |
-| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:35:9:37:9 | {...} |
-| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:36:31:36:31 | access to local variable s |
-| Forwarding.cs:35:9:37:9 | {...} | Forwarding.cs:40:27:40:27 | access to local variable s |
-| GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:9:13:9:36 | [false] !... |
-| GuardedString.cs:9:13:9:36 | [false] !... | GuardedString.cs:14:9:17:9 | if (...) ... |
-| GuardedString.cs:14:9:17:9 | if (...) ... | GuardedString.cs:14:13:14:41 | [false] !... |
-| GuardedString.cs:14:13:14:41 | [false] !... | GuardedString.cs:19:9:20:40 | if (...) ... |
-| GuardedString.cs:19:9:20:40 | if (...) ... | GuardedString.cs:19:26:19:26 | 0 |
-| GuardedString.cs:19:26:19:26 | 0 | GuardedString.cs:22:9:23:40 | if (...) ... |
-| GuardedString.cs:22:9:23:40 | if (...) ... | GuardedString.cs:22:25:22:25 | 0 |
-| GuardedString.cs:22:25:22:25 | 0 | GuardedString.cs:25:9:26:40 | if (...) ... |
-| GuardedString.cs:25:9:26:40 | if (...) ... | GuardedString.cs:25:26:25:26 | 0 |
-| GuardedString.cs:25:26:25:26 | 0 | GuardedString.cs:28:9:29:40 | if (...) ... |
-| GuardedString.cs:28:9:29:40 | if (...) ... | GuardedString.cs:28:25:28:26 | 10 |
-| GuardedString.cs:28:25:28:26 | 10 | GuardedString.cs:31:9:32:40 | if (...) ... |
-| GuardedString.cs:31:9:32:40 | if (...) ... | GuardedString.cs:31:26:31:27 | 10 |
-| GuardedString.cs:31:26:31:27 | 10 | GuardedString.cs:34:9:37:40 | if (...) ... |
-| GuardedString.cs:34:9:37:40 | if (...) ... | GuardedString.cs:34:26:34:26 | 0 |
-| GuardedString.cs:34:26:34:26 | 0 | GuardedString.cs:35:31:35:31 | access to local variable s |
-| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) | NullAlwaysBad.cs:9:30:9:30 | access to parameter s |
-| NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o |
-| Params.cs:20:12:20:15 | null | Params.cs:14:17:14:20 | access to parameter args |
-| StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:15:16:15:16 | access to local variable s |
-| StringConcatenation.cs:15:16:15:16 | access to local variable s | StringConcatenation.cs:16:17:16:17 | access to local variable s |
-#select
-| C.cs:64:9:64:10 | access to local variable o1 | C.cs:62:13:62:46 | SSA def(o1) | C.cs:64:9:64:10 | access to local variable o1 | Variable $@ may be null at this access because of $@ assignment. | C.cs:62:13:62:14 | o1 | o1 | C.cs:62:13:62:46 | Object o1 = ... | this |
-| C.cs:68:9:68:10 | access to local variable o2 | C.cs:66:13:66:46 | SSA def(o2) | C.cs:68:9:68:10 | access to local variable o2 | Variable $@ may be null at this access because of $@ assignment. | C.cs:66:13:66:14 | o2 | o2 | C.cs:66:13:66:46 | Object o2 = ... | this |
-| C.cs:95:15:95:15 | access to local variable o | C.cs:94:13:94:45 | SSA def(o) | C.cs:95:15:95:15 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | C.cs:94:13:94:13 | o | o | C.cs:94:13:94:45 | Object o = ... | this |
-| C.cs:103:27:103:30 | access to parameter list | C.cs:102:13:102:23 | SSA def(list) | C.cs:103:27:103:30 | access to parameter list | Variable $@ may be null at this access because of $@ assignment. | C.cs:99:42:99:45 | list | list | C.cs:102:13:102:23 | ... = ... | this |
-| C.cs:177:13:177:13 | access to local variable s | C.cs:178:13:178:20 | SSA def(s) | C.cs:177:13:177:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:151:13:151:13 | s | s | C.cs:178:13:178:20 | ... = ... | this |
-| C.cs:203:13:203:13 | access to local variable s | C.cs:204:13:204:20 | SSA def(s) | C.cs:203:13:203:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:185:13:185:13 | s | s | C.cs:204:13:204:20 | ... = ... | this |
-| C.cs:223:9:223:9 | access to local variable s | C.cs:222:13:222:20 | SSA def(s) | C.cs:223:9:223:9 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:210:13:210:13 | s | s | C.cs:222:13:222:20 | ... = ... | this |
-| C.cs:242:13:242:13 | access to local variable s | C.cs:240:24:240:31 | SSA def(s) | C.cs:242:13:242:13 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | C.cs:228:16:228:16 | s | s | C.cs:240:24:240:31 | ... = ... | this |
-| D.cs:23:9:23:13 | access to parameter param | D.cs:17:17:17:20 | null | D.cs:23:9:23:13 | access to parameter param | Variable $@ may be null at this access because of $@ null argument. | D.cs:21:32:21:36 | param | param | D.cs:17:17:17:20 | null | this |
-| D.cs:32:9:32:13 | access to parameter param | D.cs:26:32:26:36 | SSA param(param) | D.cs:32:9:32:13 | access to parameter param | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:26:32:26:36 | param | param | D.cs:28:13:28:25 | ... != ... | this |
-| D.cs:62:13:62:14 | access to local variable o5 | D.cs:58:13:58:41 | SSA def(o5) | D.cs:62:13:62:14 | access to local variable o5 | Variable $@ may be null at this access because of $@ assignment. | D.cs:58:13:58:14 | o5 | o5 | D.cs:58:13:58:41 | String o5 = ... | this |
-| D.cs:73:13:73:14 | access to local variable o7 | D.cs:68:13:68:34 | SSA def(o7) | D.cs:73:13:73:14 | access to local variable o7 | Variable $@ may be null at this access because of $@ assignment. | D.cs:68:13:68:14 | o7 | o7 | D.cs:68:13:68:34 | String o7 = ... | this |
-| D.cs:82:13:82:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:82:13:82:14 | access to local variable o8 | Variable $@ may be null at this access because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this |
-| D.cs:84:13:84:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:84:13:84:14 | access to local variable o8 | Variable $@ may be null at this access because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this |
-| D.cs:91:13:91:14 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:91:13:91:14 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
-| D.cs:94:21:94:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:94:21:94:22 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
-| D.cs:98:21:98:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:98:21:98:22 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
-| D.cs:102:31:102:32 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:102:31:102:32 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
-| D.cs:105:19:105:20 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:105:19:105:20 | access to local variable xs | Variable $@ may be null at this access because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this |
-| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this |
-| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this |
-| D.cs:135:24:135:24 | access to parameter b | D.cs:125:44:125:44 | SSA param(b) | D.cs:135:24:135:24 | access to parameter b | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:44:125:44 | b | b | D.cs:128:20:128:28 | ... == ... | this |
-| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this |
-| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this |
-| D.cs:151:9:151:11 | access to parameter obj | D.cs:149:36:149:38 | SSA param(obj) | D.cs:151:9:151:11 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:149:36:149:38 | obj | obj | D.cs:152:17:152:27 | ... != ... | this |
-| D.cs:171:9:171:11 | access to local variable obj | D.cs:163:16:163:25 | SSA def(obj) | D.cs:171:9:171:11 | access to local variable obj | Variable $@ may be null at this access because of $@ assignment. | D.cs:163:16:163:18 | obj | obj | D.cs:163:16:163:25 | Object obj = ... | this |
-| D.cs:245:13:245:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:245:13:245:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this |
-| D.cs:247:13:247:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:247:13:247:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this |
-| D.cs:253:13:253:14 | access to local variable o2 | D.cs:249:13:249:38 | SSA def(o2) | D.cs:253:13:253:14 | access to local variable o2 | Variable $@ may be null at this access because of $@ assignment. | D.cs:249:13:249:14 | o2 | o2 | D.cs:249:13:249:38 | String o2 = ... | this |
-| D.cs:267:13:267:13 | access to local variable o | D.cs:258:16:258:23 | SSA def(o) | D.cs:267:13:267:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:258:16:258:23 | Object o = ... | this |
-| D.cs:291:13:291:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this |
-| D.cs:291:13:291:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this |
-| D.cs:294:13:294:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this |
-| D.cs:294:13:294:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this |
-| D.cs:300:17:300:20 | access to local variable prev | D.cs:296:16:296:26 | SSA def(prev) | D.cs:300:17:300:20 | access to local variable prev | Variable $@ may be null at this access because of $@ assignment. | D.cs:296:16:296:19 | prev | prev | D.cs:296:16:296:26 | Object prev = ... | this |
-| D.cs:313:17:313:17 | access to local variable s | D.cs:304:16:304:23 | SSA def(s) | D.cs:313:17:313:17 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | D.cs:304:16:304:16 | s | s | D.cs:304:16:304:23 | String s = ... | this |
-| D.cs:324:9:324:9 | access to local variable r | D.cs:316:16:316:23 | SSA def(r) | D.cs:324:9:324:9 | access to local variable r | Variable $@ may be null at this access because of $@ assignment. | D.cs:316:16:316:16 | r | r | D.cs:316:16:316:23 | Object r = ... | this |
-| D.cs:356:13:356:13 | access to local variable a | D.cs:351:15:351:22 | SSA def(a) | D.cs:356:13:356:13 | access to local variable a | Variable $@ may be null at this access because of $@ assignment. | D.cs:351:15:351:15 | a | a | D.cs:351:15:351:22 | Int32[] a = ... | this |
-| D.cs:363:13:363:16 | access to local variable last | D.cs:360:20:360:30 | SSA def(last) | D.cs:363:13:363:16 | access to local variable last | Variable $@ may be null at this access because of $@ assignment. | D.cs:360:20:360:23 | last | last | D.cs:360:20:360:30 | String last = ... | this |
-| D.cs:372:13:372:13 | access to local variable b | D.cs:366:15:366:47 | SSA def(b) | D.cs:372:13:372:13 | access to local variable b | Variable $@ may be null at this access because of $@ assignment. | D.cs:366:15:366:15 | b | b | D.cs:366:15:366:47 | Int32[] b = ... | this |
-| D.cs:395:20:395:20 | access to parameter a | D.cs:388:36:388:36 | SSA param(a) | D.cs:395:20:395:20 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:388:36:388:36 | a | a | D.cs:390:20:390:28 | ... == ... | this |
-| D.cs:400:20:400:20 | access to parameter b | D.cs:388:45:388:45 | SSA param(b) | D.cs:400:20:400:20 | access to parameter b | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:388:45:388:45 | b | b | D.cs:397:20:397:28 | ... == ... | this |
-| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:27:407:35 | ... == ... | this |
-| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:55:407:63 | ... != ... | this |
-| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:411:13:411:21 | ... != ... | this |
-| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:14:407:22 | ... != ... | this |
-| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:42:407:50 | ... == ... | this |
-| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null at this access as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:409:13:409:21 | ... != ... | this |
-| E.cs:12:38:12:39 | access to local variable a2 | E.cs:9:18:9:26 | SSA def(a2) | E.cs:12:38:12:39 | access to local variable a2 | Variable $@ may be null at this access because of $@ assignment. | E.cs:9:18:9:19 | a2 | a2 | E.cs:9:18:9:26 | Int64[][] a2 = ... | this |
-| E.cs:14:13:14:14 | access to local variable a3 | E.cs:11:16:11:24 | SSA def(a3) | E.cs:14:13:14:14 | access to local variable a3 | Variable $@ may be null at this access because of $@ assignment. | E.cs:11:16:11:17 | a3 | a3 | E.cs:11:16:11:24 | Int64[] a3 = ... | this |
-| E.cs:27:13:27:14 | access to local variable s1 | E.cs:23:13:23:30 | SSA def(s1) | E.cs:27:13:27:14 | access to local variable s1 | Variable $@ may be null at this access because of $@ assignment. | E.cs:19:13:19:14 | s1 | s1 | E.cs:23:13:23:30 | ... = ... | this |
-| E.cs:61:13:61:17 | access to local variable slice | E.cs:51:22:51:33 | SSA def(slice) | E.cs:61:13:61:17 | access to local variable slice | Variable $@ may be null at this access because of $@ assignment. | E.cs:51:22:51:26 | slice | slice | E.cs:51:22:51:33 | List slice = ... | this |
-| E.cs:73:13:73:15 | access to parameter arr | E.cs:66:40:66:42 | SSA param(arr) | E.cs:73:13:73:15 | access to parameter arr | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:66:40:66:42 | arr | arr | E.cs:70:22:70:32 | ... == ... | this |
-| E.cs:112:13:112:16 | access to local variable arr2 | E.cs:107:15:107:25 | SSA def(arr2) | E.cs:112:13:112:16 | access to local variable arr2 | Variable $@ may be null at this access because of $@ assignment. | E.cs:107:15:107:18 | arr2 | arr2 | E.cs:107:15:107:25 | Int32[] arr2 = ... | this |
-| E.cs:125:33:125:35 | access to local variable obj | E.cs:137:25:137:34 | SSA def(obj) | E.cs:125:33:125:35 | access to local variable obj | Variable $@ may be null at this access because of $@ assignment. | E.cs:119:13:119:15 | obj | obj | E.cs:137:25:137:34 | ... = ... | this |
-| E.cs:159:13:159:16 | access to local variable obj2 | E.cs:152:16:152:26 | SSA def(obj2) | E.cs:159:13:159:16 | access to local variable obj2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:152:16:152:19 | obj2 | obj2 | E.cs:153:13:153:24 | ... != ... | this |
-| E.cs:167:21:167:21 | access to parameter a | E.cs:162:28:162:28 | SSA param(a) | E.cs:167:21:167:21 | access to parameter a | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:162:28:162:28 | a | a | E.cs:164:17:164:25 | ... == ... | this |
-| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this |
-| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this |
-| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this |
-| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this |
-| E.cs:192:17:192:17 | access to parameter o | E.cs:190:29:190:29 | SSA param(o) | E.cs:192:17:192:17 | access to parameter o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:190:29:190:29 | o | o | E.cs:193:17:193:17 | access to parameter o | this |
-| E.cs:201:13:201:13 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | E.cs:201:13:201:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this |
-| E.cs:203:13:203:13 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | E.cs:203:13:203:13 | access to local variable o | Variable $@ may be null at this access because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this |
-| E.cs:218:9:218:9 | access to local variable x | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:218:9:218:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:215:13:215:13 | x | x | E.cs:217:13:217:20 | ... = ... | this |
-| E.cs:230:9:230:9 | access to local variable x | E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this |
-| E.cs:235:16:235:16 | access to parameter i | E.cs:233:26:233:26 | SSA param(i) | E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this |
-| E.cs:240:21:240:21 | access to parameter i | E.cs:238:26:238:26 | SSA param(i) | E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this |
-| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this |
-| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this |
-| E.cs:302:9:302:9 | access to local variable s | E.cs:301:13:301:27 | SSA def(s) | E.cs:302:9:302:9 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | E.cs:301:13:301:13 | s | s | E.cs:301:13:301:27 | String s = ... | this |
-| E.cs:343:9:343:9 | access to local variable x | E.cs:342:13:342:32 | SSA def(x) | E.cs:343:9:343:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:342:13:342:13 | x | x | E.cs:342:13:342:32 | String x = ... | this |
-| E.cs:349:9:349:9 | access to local variable x | E.cs:348:17:348:36 | SSA def(x) | E.cs:349:9:349:9 | access to local variable x | Variable $@ may be null at this access because of $@ assignment. | E.cs:348:17:348:17 | x | x | E.cs:348:17:348:36 | dynamic x = ... | this |
-| E.cs:366:41:366:41 | access to parameter s | E.cs:366:28:366:28 | SSA param(s) | E.cs:366:41:366:41 | access to parameter s | Variable $@ may be null at this access because the parameter has a null default value. | E.cs:366:28:366:28 | s | s | E.cs:366:32:366:35 | null | this |
-| E.cs:375:20:375:20 | access to local variable s | E.cs:374:17:374:31 | SSA def(s) | E.cs:375:20:375:20 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | E.cs:374:17:374:17 | s | s | E.cs:374:17:374:31 | String s = ... | this |
-| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:382:14:382:23 | ... == ... | this |
-| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:382:44:382:53 | ... != ... | this |
-| E.cs:386:16:386:17 | access to parameter e1 | E.cs:380:24:380:25 | SSA param(e1) | E.cs:386:16:386:17 | access to parameter e1 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:24:380:25 | e1 | e1 | E.cs:384:13:384:22 | ... == ... | this |
-| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:28:382:37 | ... != ... | this |
-| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:382:58:382:67 | ... == ... | this |
-| E.cs:386:27:386:28 | access to parameter e2 | E.cs:380:30:380:31 | SSA param(e2) | E.cs:386:27:386:28 | access to parameter e2 | Variable $@ may be null at this access as suggested by $@ null check. | E.cs:380:30:380:31 | e2 | e2 | E.cs:384:27:384:36 | ... == ... | this |
-| E.cs:417:34:417:34 | access to parameter i | E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:415:27:415:27 | i | i | E.cs:415:27:415:27 | i | this |
-| E.cs:423:38:423:38 | access to parameter i | E.cs:423:28:423:44 | SSA capture def(i) | E.cs:423:38:423:38 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:420:27:420:27 | i | i | E.cs:420:27:420:27 | i | this |
-| E.cs:430:39:430:39 | access to parameter i | E.cs:430:29:430:45 | SSA capture def(i) | E.cs:430:39:430:39 | access to parameter i | Variable $@ may be null at this access because it has a nullable type. | E.cs:427:27:427:27 | i | i | E.cs:427:27:427:27 | i | this |
-| GuardedString.cs:35:31:35:31 | access to local variable s | GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this |
-| NullMaybeBad.cs:7:27:7:27 | access to parameter o | NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null at this access because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this |
-| Params.cs:14:17:14:20 | access to parameter args | Params.cs:20:12:20:15 | null | Params.cs:14:17:14:20 | access to parameter args | Variable $@ may be null at this access because of $@ null argument. | Params.cs:12:36:12:39 | args | args | Params.cs:20:12:20:15 | null | this |
-| StringConcatenation.cs:16:17:16:17 | access to local variable s | StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null at this access because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this |
+| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
+| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
+| E.cs:380:30:380:31 | SSA param(e2) | E.cs:382:28:382:29 | access to parameter e2 |
+| E.cs:382:13:382:68 | [false] ... \|\| ... | E.cs:384:9:385:24 | if (...) ... |
+| E.cs:382:13:382:68 | [false] ... \|\| ... | E.cs:384:9:385:24 | if (...) ... |
+| E.cs:382:14:382:37 | [false] ... && ... | E.cs:382:44:382:45 | access to parameter e1 |
+| E.cs:382:14:382:37 | [false] ... && ... | E.cs:382:44:382:45 | access to parameter e1 |
+| E.cs:382:28:382:29 | access to parameter e2 | E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:382:28:382:29 | access to parameter e2 | E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:382:44:382:45 | access to parameter e1 | E.cs:382:44:382:67 | [false] ... && ... |
+| E.cs:382:44:382:45 | access to parameter e1 | E.cs:382:44:382:67 | [false] ... && ... |
+| E.cs:382:44:382:67 | [false] ... && ... | E.cs:382:13:382:68 | [false] ... \|\| ... |
+| E.cs:382:44:382:67 | [false] ... && ... | E.cs:382:13:382:68 | [false] ... \|\| ... |
+| E.cs:384:9:385:24 | if (...) ... | E.cs:384:13:384:36 | [false] ... && ... |
+| E.cs:384:9:385:24 | if (...) ... | E.cs:384:27:384:28 | access to parameter e2 |
+| E.cs:384:13:384:36 | [false] ... && ... | E.cs:386:16:386:17 | access to parameter e1 |
+| E.cs:384:13:384:36 | [false] ... && ... | E.cs:386:27:386:28 | access to parameter e2 |
+| E.cs:384:27:384:28 | access to parameter e2 | E.cs:384:13:384:36 | [false] ... && ... |
+| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
+| E.cs:404:9:404:18 | SSA def(i) | E.cs:405:16:405:16 | access to local variable i |
+| E.cs:417:24:417:40 | SSA capture def(i) | E.cs:417:34:417:34 | access to parameter i |
+| E.cs:423:28:423:44 | SSA capture def(i) | E.cs:423:38:423:38 | access to parameter i |
+| E.cs:430:29:430:45 | SSA capture def(i) | E.cs:430:39:430:39 | access to parameter i |
+| E.cs:435:29:435:29 | SSA param(s) | E.cs:437:13:437:21 | [true] ... is ... |
+| E.cs:437:13:437:21 | [true] ... is ... | E.cs:439:13:439:13 | access to parameter s |
+| F.cs:7:16:7:23 | SSA def(o) | F.cs:8:9:8:9 | access to local variable o |
+| Forwarding.cs:7:16:7:23 | SSA def(s) | Forwarding.cs:9:13:9:30 | [false] !... |
+| Forwarding.cs:9:13:9:30 | [false] !... | Forwarding.cs:14:9:17:9 | if (...) ... |
+| Forwarding.cs:14:9:17:9 | if (...) ... | Forwarding.cs:19:9:22:9 | if (...) ... |
+| Forwarding.cs:19:9:22:9 | if (...) ... | Forwarding.cs:19:13:19:23 | [false] !... |
+| Forwarding.cs:19:13:19:23 | [false] !... | Forwarding.cs:24:9:27:9 | if (...) ... |
+| Forwarding.cs:24:9:27:9 | if (...) ... | Forwarding.cs:29:9:32:9 | if (...) ... |
+| Forwarding.cs:29:9:32:9 | if (...) ... | Forwarding.cs:34:9:37:9 | if (...) ... |
+| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:35:9:37:9 | {...} |
+| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:36:31:36:31 | access to local variable s |
+| Forwarding.cs:35:9:37:9 | {...} | Forwarding.cs:40:27:40:27 | access to local variable s |
+| GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:9:13:9:36 | [false] !... |
+| GuardedString.cs:9:13:9:36 | [false] !... | GuardedString.cs:14:9:17:9 | if (...) ... |
+| GuardedString.cs:14:9:17:9 | if (...) ... | GuardedString.cs:14:13:14:41 | [false] !... |
+| GuardedString.cs:14:13:14:41 | [false] !... | GuardedString.cs:19:9:20:40 | if (...) ... |
+| GuardedString.cs:19:9:20:40 | if (...) ... | GuardedString.cs:19:26:19:26 | 0 |
+| GuardedString.cs:19:26:19:26 | 0 | GuardedString.cs:22:9:23:40 | if (...) ... |
+| GuardedString.cs:22:9:23:40 | if (...) ... | GuardedString.cs:22:25:22:25 | 0 |
+| GuardedString.cs:22:25:22:25 | 0 | GuardedString.cs:25:9:26:40 | if (...) ... |
+| GuardedString.cs:25:9:26:40 | if (...) ... | GuardedString.cs:25:26:25:26 | 0 |
+| GuardedString.cs:25:26:25:26 | 0 | GuardedString.cs:28:9:29:40 | if (...) ... |
+| GuardedString.cs:28:9:29:40 | if (...) ... | GuardedString.cs:28:25:28:26 | 10 |
+| GuardedString.cs:28:25:28:26 | 10 | GuardedString.cs:31:9:32:40 | if (...) ... |
+| GuardedString.cs:31:9:32:40 | if (...) ... | GuardedString.cs:31:26:31:27 | 10 |
+| GuardedString.cs:31:26:31:27 | 10 | GuardedString.cs:34:9:37:40 | if (...) ... |
+| GuardedString.cs:34:9:37:40 | if (...) ... | GuardedString.cs:34:26:34:26 | 0 |
+| GuardedString.cs:34:26:34:26 | 0 | GuardedString.cs:35:31:35:31 | access to local variable s |
+| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) | NullAlwaysBad.cs:9:30:9:30 | access to parameter s |
+| NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o |
+| Params.cs:20:12:20:15 | null | Params.cs:14:17:14:20 | access to parameter args |
+| StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:15:16:15:16 | access to local variable s |
+| StringConcatenation.cs:15:16:15:16 | access to local variable s | StringConcatenation.cs:16:17:16:17 | access to local variable s |
+nodes
+| A.cs:7:16:7:40 | SSA def(synchronizedAlways) |
+| A.cs:8:15:8:32 | access to local variable synchronizedAlways |
+| A.cs:10:13:10:30 | access to local variable synchronizedAlways |
+| A.cs:16:15:16:30 | SSA def(arrayNull) |
+| A.cs:17:9:17:17 | access to local variable arrayNull |
+| A.cs:26:15:26:32 | SSA def(arrayAccess) |
+| A.cs:27:18:27:35 | SSA def(fieldAccess) |
+| A.cs:28:16:28:34 | SSA def(methodAccess) |
+| A.cs:29:16:29:32 | SSA def(methodCall) |
+| A.cs:31:27:31:37 | access to local variable arrayAccess |
+| A.cs:32:27:32:37 | access to local variable fieldAccess |
+| A.cs:33:28:33:39 | access to local variable methodAccess |
+| A.cs:34:27:34:36 | access to local variable methodCall |
+| A.cs:36:27:36:37 | access to local variable arrayAccess |
+| A.cs:37:27:37:37 | access to local variable fieldAccess |
+| A.cs:38:15:38:26 | access to local variable methodAccess |
+| A.cs:39:27:39:36 | access to local variable methodCall |
+| A.cs:48:16:48:28 | SSA def(varRef) |
+| A.cs:50:9:50:14 | access to local variable varRef |
+| Assert.cs:13:9:13:25 | [b (line 7): false] SSA def(s) |
+| Assert.cs:13:9:13:25 | [b (line 7): true] SSA def(s) |
+| Assert.cs:15:27:15:27 | access to local variable s |
+| Assert.cs:15:27:15:27 | access to local variable s |
+| Assert.cs:21:9:21:25 | [b (line 7): false] SSA def(s) |
+| Assert.cs:21:9:21:25 | [b (line 7): true] SSA def(s) |
+| Assert.cs:23:27:23:27 | access to local variable s |
+| Assert.cs:23:27:23:27 | access to local variable s |
+| Assert.cs:29:9:29:25 | [b (line 7): false] SSA def(s) |
+| Assert.cs:29:9:29:25 | [b (line 7): true] SSA def(s) |
+| Assert.cs:31:27:31:27 | access to local variable s |
+| Assert.cs:31:27:31:27 | access to local variable s |
+| Assert.cs:45:9:45:25 | [b (line 7): true] SSA def(s) |
+| Assert.cs:46:23:46:36 | [true, b (line 7): true] ... && ... |
+| Assert.cs:46:36:46:36 | [b (line 7): true] access to parameter b |
+| Assert.cs:47:27:47:27 | access to local variable s |
+| Assert.cs:49:9:49:25 | [b (line 7): true] SSA def(s) |
+| Assert.cs:50:24:50:38 | [false] ... \|\| ... |
+| Assert.cs:50:37:50:38 | [false] !... |
+| Assert.cs:50:38:50:38 | [b (line 7): true] access to parameter b |
+| Assert.cs:51:27:51:27 | access to local variable s |
+| B.cs:7:11:7:29 | SSA def(eqCallAlways) |
+| B.cs:10:11:10:30 | SSA def(neqCallAlways) |
+| B.cs:13:13:13:24 | access to local variable eqCallAlways |
+| B.cs:13:13:13:36 | ...; |
+| B.cs:15:9:16:26 | if (...) ... |
+| B.cs:16:13:16:26 | ...; |
+| B.cs:18:9:20:26 | if (...) ... |
+| B.cs:18:25:18:27 | {...} |
+| B.cs:20:13:20:26 | ...; |
+| B.cs:22:9:24:37 | if (...) ... |
+| B.cs:24:13:24:25 | access to local variable neqCallAlways |
+| C.cs:10:16:10:23 | SSA def(o) |
+| C.cs:11:13:11:30 | [false] !... |
+| C.cs:11:15:11:29 | [true] !... |
+| C.cs:11:17:11:28 | [false] !... |
+| C.cs:16:9:19:9 | if (...) ... |
+| C.cs:16:13:16:24 | [true] !... |
+| C.cs:18:13:18:13 | access to local variable o |
+| C.cs:40:13:40:35 | SSA def(s) |
+| C.cs:42:9:42:9 | access to local variable s |
+| C.cs:55:13:55:36 | SSA def(o2) |
+| C.cs:57:9:57:10 | access to local variable o2 |
+| C.cs:62:13:62:46 | SSA def(o1) |
+| C.cs:64:9:64:10 | access to local variable o1 |
+| C.cs:66:13:66:46 | SSA def(o2) |
+| C.cs:68:9:68:10 | access to local variable o2 |
+| C.cs:94:13:94:45 | SSA def(o) |
+| C.cs:95:15:95:15 | access to local variable o |
+| C.cs:96:13:96:13 | access to local variable o |
+| C.cs:102:13:102:23 | SSA def(list) |
+| C.cs:103:9:107:9 | foreach (... ... in ...) ... |
+| C.cs:103:22:103:22 | Int32 x |
+| C.cs:103:27:103:30 | access to parameter list |
+| C.cs:103:27:103:30 | access to parameter list |
+| C.cs:106:13:106:16 | access to parameter list |
+| C.cs:159:9:159:16 | SSA def(s) |
+| C.cs:162:13:162:13 | access to local variable s |
+| C.cs:167:9:167:16 | SSA def(s) |
+| C.cs:170:13:170:13 | access to local variable s |
+| C.cs:177:13:177:13 | access to local variable s |
+| C.cs:178:13:178:20 | SSA def(s) |
+| C.cs:193:9:193:16 | SSA def(s) |
+| C.cs:196:13:196:13 | access to local variable s |
+| C.cs:197:13:197:20 | [b (line 192): true] SSA def(s) |
+| C.cs:201:16:201:19 | true |
+| C.cs:203:13:203:13 | access to local variable s |
+| C.cs:204:13:204:20 | SSA def(s) |
+| C.cs:210:13:210:35 | SSA def(s) |
+| C.cs:214:13:214:20 | SSA def(s) |
+| C.cs:217:9:218:25 | if (...) ... |
+| C.cs:218:13:218:13 | access to local variable s |
+| C.cs:222:13:222:20 | SSA def(s) |
+| C.cs:223:9:223:9 | access to local variable s |
+| C.cs:229:22:229:22 | access to local variable s |
+| C.cs:229:33:229:40 | SSA def(s) |
+| C.cs:233:9:233:9 | access to local variable s |
+| C.cs:235:14:235:21 | SSA def(s) |
+| C.cs:235:24:235:24 | access to local variable s |
+| C.cs:235:35:235:42 | SSA def(s) |
+| C.cs:237:13:237:13 | access to local variable s |
+| C.cs:240:24:240:31 | SSA def(s) |
+| C.cs:242:13:242:13 | access to local variable s |
+| C.cs:248:15:248:22 | SSA def(a) |
+| C.cs:249:9:249:9 | access to local variable a |
+| C.cs:257:15:257:23 | SSA def(ia) |
+| C.cs:258:18:258:26 | SSA def(sa) |
+| C.cs:260:9:260:10 | access to local variable ia |
+| C.cs:261:20:261:21 | access to local variable sa |
+| C.cs:263:9:263:10 | access to local variable ia |
+| C.cs:264:16:264:17 | access to local variable sa |
+| D.cs:17:17:17:20 | null |
+| D.cs:23:9:23:13 | access to parameter param |
+| D.cs:26:32:26:36 | SSA param(param) |
+| D.cs:32:9:32:13 | access to parameter param |
+| D.cs:58:13:58:41 | SSA def(o5) |
+| D.cs:61:9:62:26 | if (...) ... |
+| D.cs:62:13:62:14 | access to local variable o5 |
+| D.cs:68:13:68:34 | SSA def(o7) |
+| D.cs:69:18:69:36 | ... && ... |
+| D.cs:73:13:73:14 | access to local variable o7 |
+| D.cs:75:13:75:34 | SSA def(o8) |
+| D.cs:76:21:76:43 | ... ? ... : ... |
+| D.cs:76:34:76:35 | 42 |
+| D.cs:79:9:80:26 | if (...) ... |
+| D.cs:81:9:82:26 | if (...) ... |
+| D.cs:82:13:82:14 | access to local variable o8 |
+| D.cs:82:13:82:26 | ...; |
+| D.cs:83:9:84:26 | if (...) ... |
+| D.cs:84:13:84:14 | access to local variable o8 |
+| D.cs:89:15:89:44 | SSA def(xs) |
+| D.cs:91:13:91:14 | access to local variable xs |
+| D.cs:91:13:91:22 | ...; |
+| D.cs:93:9:94:30 | if (...) ... |
+| D.cs:94:13:94:30 | ...; |
+| D.cs:94:21:94:22 | access to local variable xs |
+| D.cs:96:9:99:9 | if (...) ... |
+| D.cs:97:9:99:9 | {...} |
+| D.cs:98:21:98:22 | access to local variable xs |
+| D.cs:101:9:102:35 | if (...) ... |
+| D.cs:102:13:102:35 | foreach (... ... in ...) ... |
+| D.cs:102:26:102:26 | Int32 _ |
+| D.cs:102:31:102:32 | access to local variable xs |
+| D.cs:102:31:102:32 | access to local variable xs |
+| D.cs:104:9:106:30 | if (...) ... |
+| D.cs:105:19:105:20 | access to local variable xs |
+| D.cs:106:17:106:18 | access to local variable xs |
+| D.cs:118:9:118:30 | SSA def(x) |
+| D.cs:120:13:120:13 | access to local variable x |
+| D.cs:125:35:125:35 | SSA param(a) |
+| D.cs:125:35:125:35 | SSA param(a) |
+| D.cs:125:44:125:44 | SSA param(b) |
+| D.cs:127:20:127:43 | ... ? ... : ... |
+| D.cs:127:20:127:43 | ... ? ... : ... |
+| D.cs:127:32:127:32 | 0 |
+| D.cs:127:32:127:32 | 0 |
+| D.cs:127:36:127:36 | access to parameter a |
+| D.cs:128:20:128:43 | ... ? ... : ... |
+| D.cs:128:20:128:43 | ... ? ... : ... |
+| D.cs:128:32:128:32 | 0 |
+| D.cs:128:32:128:32 | 0 |
+| D.cs:128:36:128:36 | access to parameter b |
+| D.cs:131:9:137:9 | {...} |
+| D.cs:131:9:137:9 | {...} |
+| D.cs:132:29:132:29 | access to local variable i |
+| D.cs:132:29:132:29 | access to local variable i |
+| D.cs:133:13:136:13 | {...} |
+| D.cs:133:13:136:13 | {...} |
+| D.cs:134:24:134:24 | access to parameter a |
+| D.cs:135:24:135:24 | access to parameter b |
+| D.cs:138:9:138:18 | ... ...; |
+| D.cs:142:13:142:22 | ...; |
+| D.cs:143:9:146:9 | for (...;...;...) ... |
+| D.cs:143:25:143:25 | access to local variable i |
+| D.cs:144:9:146:9 | {...} |
+| D.cs:145:20:145:20 | access to parameter a |
+| D.cs:149:36:149:38 | SSA param(obj) |
+| D.cs:151:9:151:11 | access to parameter obj |
+| D.cs:163:16:163:25 | SSA def(obj) |
+| D.cs:168:9:170:9 | [exception: Exception] catch (...) {...} |
+| D.cs:168:26:168:26 | [exception: Exception] Exception e |
+| D.cs:171:9:171:11 | access to local variable obj |
+| D.cs:240:9:240:16 | SSA def(o) |
+| D.cs:241:21:241:37 | ... ? ... : ... |
+| D.cs:241:29:241:32 | null |
+| D.cs:241:36:241:37 | "" |
+| D.cs:244:9:247:25 | if (...) ... |
+| D.cs:245:13:245:13 | access to local variable o |
+| D.cs:247:13:247:13 | access to local variable o |
+| D.cs:249:13:249:38 | SSA def(o2) |
+| D.cs:253:13:253:14 | access to local variable o2 |
+| D.cs:258:16:258:23 | SSA def(o) |
+| D.cs:266:9:267:25 | if (...) ... |
+| D.cs:266:13:266:27 | [true] ... is ... |
+| D.cs:267:13:267:13 | access to local variable o |
+| D.cs:269:9:269:16 | SSA def(o) |
+| D.cs:272:25:272:25 | access to local variable i |
+| D.cs:272:39:272:39 | access to local variable i |
+| D.cs:273:9:288:9 | {...} |
+| D.cs:281:13:287:13 | if (...) ... |
+| D.cs:283:17:283:24 | SSA def(o) |
+| D.cs:285:28:285:30 | {...} |
+| D.cs:286:17:286:30 | ...; |
+| D.cs:290:9:291:25 | if (...) ... |
+| D.cs:291:13:291:13 | access to local variable o |
+| D.cs:291:13:291:25 | ...; |
+| D.cs:293:9:294:25 | if (...) ... |
+| D.cs:294:13:294:13 | access to local variable o |
+| D.cs:296:16:296:26 | SSA def(prev) |
+| D.cs:297:25:297:25 | access to local variable i |
+| D.cs:298:9:302:9 | {...} |
+| D.cs:300:17:300:20 | access to local variable prev |
+| D.cs:304:16:304:23 | SSA def(s) |
+| D.cs:307:13:311:13 | foreach (... ... in ...) ... |
+| D.cs:312:13:313:29 | if (...) ... |
+| D.cs:312:17:312:23 | [true] !... |
+| D.cs:313:17:313:17 | access to local variable s |
+| D.cs:316:16:316:23 | SSA def(r) |
+| D.cs:318:16:318:19 | access to local variable stat |
+| D.cs:318:16:318:62 | [false] ... && ... |
+| D.cs:318:41:318:44 | access to local variable stat |
+| D.cs:324:9:324:9 | access to local variable r |
+| D.cs:351:15:351:22 | SSA def(a) |
+| D.cs:355:9:356:21 | for (...;...;...) ... |
+| D.cs:355:25:355:25 | access to local variable i |
+| D.cs:356:13:356:13 | access to local variable a |
+| D.cs:356:13:356:21 | ...; |
+| D.cs:360:20:360:30 | SSA def(last) |
+| D.cs:361:29:361:29 | access to local variable i |
+| D.cs:363:13:363:16 | access to local variable last |
+| D.cs:366:15:366:47 | SSA def(b) |
+| D.cs:367:13:367:56 | [false] ... && ... |
+| D.cs:370:9:373:9 | for (...;...;...) ... |
+| D.cs:370:25:370:25 | access to local variable i |
+| D.cs:371:9:373:9 | {...} |
+| D.cs:372:13:372:13 | access to local variable b |
+| D.cs:378:19:378:28 | SSA def(ioe) |
+| D.cs:382:9:385:27 | if (...) ... |
+| D.cs:385:13:385:15 | access to local variable ioe |
+| D.cs:388:36:388:36 | SSA param(a) |
+| D.cs:388:45:388:45 | SSA param(b) |
+| D.cs:390:20:390:43 | ... ? ... : ... |
+| D.cs:390:20:390:43 | ... ? ... : ... |
+| D.cs:390:32:390:32 | 0 |
+| D.cs:390:32:390:32 | 0 |
+| D.cs:390:36:390:36 | access to parameter a |
+| D.cs:393:21:393:21 | access to local variable i |
+| D.cs:393:21:393:21 | access to local variable i |
+| D.cs:394:9:396:9 | {...} |
+| D.cs:394:9:396:9 | {...} |
+| D.cs:395:20:395:20 | access to parameter a |
+| D.cs:397:9:397:44 | ... ...; |
+| D.cs:397:20:397:43 | ... ? ... : ... |
+| D.cs:397:32:397:32 | 0 |
+| D.cs:398:21:398:21 | access to local variable i |
+| D.cs:399:9:401:9 | {...} |
+| D.cs:400:20:400:20 | access to parameter b |
+| D.cs:405:35:405:35 | SSA param(x) |
+| D.cs:405:35:405:35 | SSA param(x) |
+| D.cs:405:35:405:35 | SSA param(x) |
+| D.cs:405:45:405:45 | SSA param(y) |
+| D.cs:405:45:405:45 | SSA param(y) |
+| D.cs:405:45:405:45 | SSA param(y) |
+| D.cs:407:13:407:64 | [false] ... \|\| ... |
+| D.cs:407:13:407:64 | [false] ... \|\| ... |
+| D.cs:407:14:407:35 | [false] ... && ... |
+| D.cs:407:14:407:35 | [false] ... && ... |
+| D.cs:407:42:407:42 | access to parameter x |
+| D.cs:407:42:407:42 | access to parameter x |
+| D.cs:407:42:407:63 | [false] ... && ... |
+| D.cs:407:42:407:63 | [false] ... && ... |
+| D.cs:407:55:407:55 | access to parameter y |
+| D.cs:407:55:407:55 | access to parameter y |
+| D.cs:409:9:410:25 | if (...) ... |
+| D.cs:409:9:410:25 | if (...) ... |
+| D.cs:410:13:410:13 | access to parameter y |
+| D.cs:411:9:412:25 | if (...) ... |
+| D.cs:412:13:412:13 | access to parameter x |
+| E.cs:9:18:9:26 | SSA def(a2) |
+| E.cs:10:22:10:54 | ... && ... |
+| E.cs:11:16:11:24 | SSA def(a3) |
+| E.cs:12:22:12:52 | ... && ... |
+| E.cs:12:38:12:39 | access to local variable a2 |
+| E.cs:14:13:14:14 | access to local variable a3 |
+| E.cs:23:13:23:30 | SSA def(s1) |
+| E.cs:24:18:24:41 | ... ? ... : ... |
+| E.cs:24:33:24:36 | null |
+| E.cs:26:9:27:26 | if (...) ... |
+| E.cs:27:13:27:14 | access to local variable s1 |
+| E.cs:51:22:51:33 | SSA def(slice) |
+| E.cs:53:16:53:19 | access to local variable iter |
+| E.cs:54:9:63:9 | {...} |
+| E.cs:61:13:61:17 | access to local variable slice |
+| E.cs:61:13:61:27 | ...; |
+| E.cs:66:40:66:42 | SSA param(arr) |
+| E.cs:70:13:70:50 | ...; |
+| E.cs:70:22:70:49 | ... ? ... : ... |
+| E.cs:70:36:70:36 | 0 |
+| E.cs:72:9:73:23 | if (...) ... |
+| E.cs:73:13:73:15 | access to parameter arr |
+| E.cs:107:15:107:25 | SSA def(arr2) |
+| E.cs:111:9:112:30 | for (...;...;...) ... |
+| E.cs:111:25:111:25 | access to local variable i |
+| E.cs:112:13:112:16 | access to local variable arr2 |
+| E.cs:112:13:112:30 | ...; |
+| E.cs:120:16:120:20 | [true] !... |
+| E.cs:120:17:120:20 | access to local variable stop |
+| E.cs:121:9:143:9 | {...} |
+| E.cs:123:20:123:24 | [false] !... |
+| E.cs:123:20:123:24 | [true] !... |
+| E.cs:123:20:123:35 | [false] ... && ... |
+| E.cs:123:20:123:35 | [true] ... && ... |
+| E.cs:123:21:123:24 | access to local variable stop |
+| E.cs:123:29:123:29 | access to local variable j |
+| E.cs:124:13:142:13 | {...} |
+| E.cs:125:33:125:35 | access to local variable obj |
+| E.cs:128:21:128:23 | access to local variable obj |
+| E.cs:137:25:137:34 | SSA def(obj) |
+| E.cs:139:21:139:29 | continue; |
+| E.cs:141:17:141:26 | ...; |
+| E.cs:152:16:152:26 | SSA def(obj2) |
+| E.cs:153:13:153:54 | [false] ... && ... |
+| E.cs:158:9:159:28 | if (...) ... |
+| E.cs:159:13:159:16 | access to local variable obj2 |
+| E.cs:162:28:162:28 | SSA param(a) |
+| E.cs:164:17:164:40 | ... ? ... : ... |
+| E.cs:164:29:164:29 | 0 |
+| E.cs:165:25:165:25 | access to local variable i |
+| E.cs:165:32:165:32 | access to local variable i |
+| E.cs:166:9:170:9 | {...} |
+| E.cs:167:21:167:21 | access to parameter a |
+| E.cs:173:29:173:31 | SSA param(obj) |
+| E.cs:173:29:173:31 | SSA param(obj) |
+| E.cs:175:19:175:42 | ... ? ... : ... |
+| E.cs:175:33:175:37 | false |
+| E.cs:177:9:179:9 | {...} |
+| E.cs:178:13:178:15 | access to parameter obj |
+| E.cs:180:9:183:9 | if (...) ... |
+| E.cs:181:9:183:9 | {...} |
+| E.cs:184:9:187:9 | if (...) ... |
+| E.cs:186:13:186:15 | access to parameter obj |
+| E.cs:190:29:190:29 | SSA param(o) |
+| E.cs:192:17:192:17 | access to parameter o |
+| E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) |
+| E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) |
+| E.cs:201:13:201:13 | access to local variable o |
+| E.cs:203:13:203:13 | access to local variable o |
+| E.cs:206:28:206:28 | SSA param(s) |
+| E.cs:208:13:208:23 | [false] ... is ... |
+| E.cs:210:16:210:16 | access to parameter s |
+| E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) |
+| E.cs:218:9:218:9 | access to local variable x |
+| E.cs:220:13:220:13 | access to local variable x |
+| E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) |
+| E.cs:229:13:229:13 | access to local variable x |
+| E.cs:229:13:229:25 | ...; |
+| E.cs:230:9:230:9 | access to local variable x |
+| E.cs:233:26:233:26 | SSA param(i) |
+| E.cs:235:16:235:16 | access to parameter i |
+| E.cs:238:26:238:26 | SSA param(i) |
+| E.cs:240:21:240:21 | access to parameter i |
+| E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) |
+| E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) |
+| E.cs:285:9:285:9 | access to local variable o |
+| E.cs:285:9:285:9 | access to local variable o |
+| E.cs:301:13:301:27 | SSA def(s) |
+| E.cs:302:9:302:9 | access to local variable s |
+| E.cs:319:29:319:30 | SSA param(s1) |
+| E.cs:321:13:321:30 | [true] ... is ... |
+| E.cs:321:14:321:21 | ... ?? ... |
+| E.cs:321:20:321:21 | access to parameter s2 |
+| E.cs:323:13:323:14 | access to parameter s1 |
+| E.cs:330:13:330:36 | SSA def(x) |
+| E.cs:331:9:331:9 | access to local variable x |
+| E.cs:342:13:342:32 | SSA def(x) |
+| E.cs:343:9:343:9 | access to local variable x |
+| E.cs:348:17:348:36 | SSA def(x) |
+| E.cs:349:9:349:9 | access to local variable x |
+| E.cs:366:28:366:28 | SSA param(s) |
+| E.cs:366:41:366:41 | access to parameter s |
+| E.cs:374:17:374:31 | SSA def(s) |
+| E.cs:375:20:375:20 | access to local variable s |
+| E.cs:380:24:380:25 | SSA param(e1) |
+| E.cs:380:24:380:25 | SSA param(e1) |
+| E.cs:380:24:380:25 | SSA param(e1) |
+| E.cs:380:30:380:31 | SSA param(e2) |
+| E.cs:380:30:380:31 | SSA param(e2) |
+| E.cs:380:30:380:31 | SSA param(e2) |
+| E.cs:382:13:382:68 | [false] ... \|\| ... |
+| E.cs:382:13:382:68 | [false] ... \|\| ... |
+| E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:382:14:382:37 | [false] ... && ... |
+| E.cs:382:28:382:29 | access to parameter e2 |
+| E.cs:382:28:382:29 | access to parameter e2 |
+| E.cs:382:44:382:45 | access to parameter e1 |
+| E.cs:382:44:382:45 | access to parameter e1 |
+| E.cs:382:44:382:67 | [false] ... && ... |
+| E.cs:382:44:382:67 | [false] ... && ... |
+| E.cs:384:9:385:24 | if (...) ... |
+| E.cs:384:9:385:24 | if (...) ... |
+| E.cs:384:13:384:36 | [false] ... && ... |
+| E.cs:384:13:384:36 | [false] ... && ... |
+| E.cs:384:27:384:28 | access to parameter e2 |
+| E.cs:386:16:386:17 | access to parameter e1 |
+| E.cs:386:27:386:28 | access to parameter e2 |
+| E.cs:404:9:404:18 | SSA def(i) |
+| E.cs:404:9:404:18 | SSA def(i) |
+| E.cs:405:16:405:16 | access to local variable i |
+| E.cs:417:24:417:40 | SSA capture def(i) |
+| E.cs:417:34:417:34 | access to parameter i |
+| E.cs:423:28:423:44 | SSA capture def(i) |
+| E.cs:423:38:423:38 | access to parameter i |
+| E.cs:430:29:430:45 | SSA capture def(i) |
+| E.cs:430:39:430:39 | access to parameter i |
+| E.cs:435:29:435:29 | SSA param(s) |
+| E.cs:437:13:437:21 | [true] ... is ... |
+| E.cs:439:13:439:13 | access to parameter s |
+| F.cs:7:16:7:23 | SSA def(o) |
+| F.cs:8:9:8:9 | access to local variable o |
+| Forwarding.cs:7:16:7:23 | SSA def(s) |
+| Forwarding.cs:9:13:9:30 | [false] !... |
+| Forwarding.cs:14:9:17:9 | if (...) ... |
+| Forwarding.cs:19:9:22:9 | if (...) ... |
+| Forwarding.cs:19:13:19:23 | [false] !... |
+| Forwarding.cs:24:9:27:9 | if (...) ... |
+| Forwarding.cs:29:9:32:9 | if (...) ... |
+| Forwarding.cs:34:9:37:9 | if (...) ... |
+| Forwarding.cs:35:9:37:9 | {...} |
+| Forwarding.cs:36:31:36:31 | access to local variable s |
+| Forwarding.cs:40:27:40:27 | access to local variable s |
+| GuardedString.cs:7:16:7:32 | SSA def(s) |
+| GuardedString.cs:9:13:9:36 | [false] !... |
+| GuardedString.cs:14:9:17:9 | if (...) ... |
+| GuardedString.cs:14:13:14:41 | [false] !... |
+| GuardedString.cs:19:9:20:40 | if (...) ... |
+| GuardedString.cs:19:26:19:26 | 0 |
+| GuardedString.cs:22:9:23:40 | if (...) ... |
+| GuardedString.cs:22:25:22:25 | 0 |
+| GuardedString.cs:25:9:26:40 | if (...) ... |
+| GuardedString.cs:25:26:25:26 | 0 |
+| GuardedString.cs:28:9:29:40 | if (...) ... |
+| GuardedString.cs:28:25:28:26 | 10 |
+| GuardedString.cs:31:9:32:40 | if (...) ... |
+| GuardedString.cs:31:26:31:27 | 10 |
+| GuardedString.cs:34:9:37:40 | if (...) ... |
+| GuardedString.cs:34:26:34:26 | 0 |
+| GuardedString.cs:35:31:35:31 | access to local variable s |
+| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) |
+| NullAlwaysBad.cs:9:30:9:30 | access to parameter s |
+| NullMaybeBad.cs:7:27:7:27 | access to parameter o |
+| NullMaybeBad.cs:13:17:13:20 | null |
+| Params.cs:14:17:14:20 | access to parameter args |
+| Params.cs:20:12:20:15 | null |
+| StringConcatenation.cs:14:16:14:23 | SSA def(s) |
+| StringConcatenation.cs:15:16:15:16 | access to local variable s |
+| StringConcatenation.cs:16:17:16:17 | access to local variable s |
diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.qlref b/csharp/ql/test/query-tests/Nullness/NullMaybe.qlref
index caf2eefb3d8f..6615576178c6 100644
--- a/csharp/ql/test/query-tests/Nullness/NullMaybe.qlref
+++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.qlref
@@ -1 +1,2 @@
-CSI/NullMaybe.ql
+query: CSI/NullMaybe.ql
+postprocess: utils/test/InlineExpectationsTestQuery.ql
diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybeBad.cs b/csharp/ql/test/query-tests/Nullness/NullMaybeBad.cs
index 9950bc3c1ee8..433a4edc1126 100644
--- a/csharp/ql/test/query-tests/Nullness/NullMaybeBad.cs
+++ b/csharp/ql/test/query-tests/Nullness/NullMaybeBad.cs
@@ -4,12 +4,12 @@ class Bad
{
void DoPrint(object o)
{
- Console.WriteLine(o.ToString());
+ Console.WriteLine(o.ToString()); // $ Alert[cs/dereferenced-value-may-be-null]
}
void M()
{
DoPrint("Hello");
- DoPrint(null);
+ DoPrint(null); // $ Source[cs/dereferenced-value-may-be-null]
}
}
diff --git a/csharp/ql/test/query-tests/Nullness/Params.cs b/csharp/ql/test/query-tests/Nullness/Params.cs
index 17c9cf861d7b..b7f2c9e46e8a 100644
--- a/csharp/ql/test/query-tests/Nullness/Params.cs
+++ b/csharp/ql/test/query-tests/Nullness/Params.cs
@@ -11,12 +11,12 @@ public void M1(params string[] args)
public void M2(params string[] args)
{
- var l = args.Length; // Good
+ var l = args.Length; // $ SPURIOUS (false positive): Alert[cs/dereferenced-value-may-be-null]
}
public void M()
{
M1("a", "b", "c", null);
- M2(null);
+ M2(null); // $ Source[cs/dereferenced-value-may-be-null]
}
-}
\ No newline at end of file
+}
diff --git a/csharp/ql/test/query-tests/Nullness/StringConcatenation.cs b/csharp/ql/test/query-tests/Nullness/StringConcatenation.cs
index 394ea9077693..1cc8f146aec7 100644
--- a/csharp/ql/test/query-tests/Nullness/StringConcatenation.cs
+++ b/csharp/ql/test/query-tests/Nullness/StringConcatenation.cs
@@ -11,9 +11,9 @@ void StringAdded()
void StringMaybeNull()
{
- string s = null;
+ string s = null; // $ Source[cs/dereferenced-value-may-be-null]
while (s != "")
- s = s.Trim(); // BAD (maybe)
+ s = s.Trim(); // $ Alert[cs/dereferenced-value-may-be-null]
}
void StringNotNull()
diff --git a/csharp/ql/test/query-tests/Nullness/options b/csharp/ql/test/query-tests/Nullness/options
index ca78c4312494..1039aa6de18c 100644
--- a/csharp/ql/test/query-tests/Nullness/options
+++ b/csharp/ql/test/query-tests/Nullness/options
@@ -1,3 +1,4 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj
-semmle-extractor-options: ${testdir}/../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs
\ No newline at end of file
+semmle-extractor-options: ${testdir}/../../resources/stubs/Microsoft.VisualStudio.TestTools.UnitTesting.cs
+semmle-extractor-options: ${testdir}/../../resources/stubs/Library.cs
diff --git a/csharp/ql/test/resources/stubs/Library.cs b/csharp/ql/test/resources/stubs/Library.cs
new file mode 100644
index 000000000000..0efffd3f21b7
--- /dev/null
+++ b/csharp/ql/test/resources/stubs/Library.cs
@@ -0,0 +1,13 @@
+namespace Library;
+
+/*
+ * This file is for making stubs for library methods used for testing purposes.
+ * The file is located in the stubs folder, because then the code is not
+ * recognized as being from source.
+ */
+public static class MyExtensions
+{
+ public static void Accept(this object o) { }
+
+ public static void AcceptNullable(this object? o) { }
+}
diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst
index 754b6d2c4dad..51ff05b0c3b1 100644
--- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst
+++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.19.4.rst
@@ -79,4 +79,4 @@ JavaScript/TypeScript
* Added taint-steps for :code:`Array.prototype.toReversed`.
* Added taint-steps for :code:`Array.prototype.toSorted`.
* Added support for :code:`String.prototype.matchAll`.
-* Added taint-steps for :code:`Array.prototype.reverse`.
+* Added taint-steps for :code:`Array.prototype.reverse`.
diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst
new file mode 100644
index 000000000000..04920497e4ea
--- /dev/null
+++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.22.0.rst
@@ -0,0 +1,82 @@
+.. _codeql-cli-2.22.0:
+
+==========================
+CodeQL 2.22.0 (2025-06-11)
+==========================
+
+.. contents:: Contents
+ :depth: 2
+ :local:
+ :backlinks: none
+
+This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__.
+
+Security Coverage
+-----------------
+
+CodeQL 2.22.0 runs a total of 450 security queries when configured with the Default suite (covering 165 CWE). The Extended suite enables an additional 128 queries (covering 33 more CWE). 1 security query has been added with this release.
+
+CodeQL CLI
+----------
+
+Breaking Changes
+~~~~~~~~~~~~~~~~
+
+* A number of breaking changes have been made to the C and C++ CodeQL test environment as used by :code:`codeql test run`\ :
+
+ * Options starting with a :code:`/` are no longer supported by
+ :code:`semmle-extractor-options`. Any option starting with a :code:`/` should be replaced by the equivalent option starting with a :code:`-`, e.g., :code:`/D` should be replaced by :code:`-D`.
+ * Preprocessor command line options of the form :code:`-D#` are no longer supported by :code:`semmle-extractor-options`. :code:`-D=` should be used instead.
+ * The :code:`/Fp` and :code:`-o` options are no longer supported by
+ :code:`semmle-extractor-options`. The options should be omitted.
+ * The :code:`-emit-pch`, :code:`-include-pch`, :code:`/Yc`, and :code:`/Yu` options, and the
+ :code:`--preinclude` option taking a pre-compiled header as its argument, are no longer supported by :code:`semmle-extractor-options`. Any test that makes use of this should be replaced by a test that invokes the CodeQL CLI with the
+ :code:`create database` option and that runs the relevant queries on the created database.
+
+Query Packs
+-----------
+
+Minor Analysis Improvements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Python
+""""""
+
+* Added SQL injection models from the :code:`pandas` PyPI package.
+
+New Queries
+~~~~~~~~~~~
+
+Golang
+""""""
+
+* Query (:code:`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the :code:`html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in `https://github.com/github/codeql-go/pull/493 `_.
+
+Language Libraries
+------------------
+
+Minor Analysis Improvements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Golang
+""""""
+
+* The first argument of :code:`Client.Query` in :code:`cloud.google.com/go/bigquery` is now recognized as a SQL injection sink.
+
+JavaScript/TypeScript
+"""""""""""""""""""""
+
+* Added taint flow through the :code:`URL` constructor from the :code:`url` package, improving the identification of SSRF vulnerabilities.
+
+Swift
+"""""
+
+* Updated to allow analysis of Swift 6.1.2.
+
+New Features
+~~~~~~~~~~~~
+
+C/C++
+"""""
+
+* Added a predicate :code:`getReferencedMember` to :code:`UsingDeclarationEntry`, which yields a member depending on a type template parameter.
diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst
index be6d2582d6ec..af427fd69150 100644
--- a/docs/codeql/codeql-overview/codeql-changelog/index.rst
+++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst
@@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here .
+* Query (`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the `html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in https://github.com/github/codeql-go/pull/493.
## 1.2.1
diff --git a/go/ql/src/change-notes/released/1.3.0.md b/go/ql/src/change-notes/released/1.3.0.md
index fe0c5a7af3c4..84afeabc50de 100644
--- a/go/ql/src/change-notes/released/1.3.0.md
+++ b/go/ql/src/change-notes/released/1.3.0.md
@@ -2,4 +2,4 @@
### New Queries
-* Query (`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the `html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in .
+* Query (`go/html-template-escaping-bypass-xss`) has been promoted to the main query suite. This query finds potential cross-site scripting (XSS) vulnerabilities when using the `html/template` package, caused by user input being cast to a type which bypasses the HTML autoescaping. It was originally contributed to the experimental query pack by @gagliardetto in https://github.com/github/codeql-go/pull/493.
diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml
index 8278ece9be56..874d6e093fce 100644
--- a/go/ql/src/qlpack.yml
+++ b/go/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/go-queries
-version: 1.3.0
+version: 1.3.1-dev
groups:
- go
- queries
diff --git a/java/ql/integration-tests/java/query-suite/java-code-scanning.qls.expected b/java/ql/integration-tests/java/query-suite/java-code-scanning.qls.expected
index a8ce00aca6c5..3290e0d84b0e 100644
--- a/java/ql/integration-tests/java/query-suite/java-code-scanning.qls.expected
+++ b/java/ql/integration-tests/java/query-suite/java-code-scanning.qls.expected
@@ -12,7 +12,6 @@ ql/java/ql/src/Security/CWE/CWE-023/PartialPathTraversalFromRemote.ql
ql/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql
ql/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql
ql/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql
-ql/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
ql/java/ql/src/Security/CWE/CWE-079/XSS.ql
ql/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql
ql/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql
diff --git a/java/ql/lib/change-notes/2025-06-12-assert-cfg.md b/java/ql/lib/change-notes/2025-06-12-assert-cfg.md
new file mode 100644
index 000000000000..69219633166e
--- /dev/null
+++ b/java/ql/lib/change-notes/2025-06-12-assert-cfg.md
@@ -0,0 +1,4 @@
+---
+category: minorAnalysis
+---
+* Java `assert` statements are now assumed to be executed for the purpose of analysing control flow. This improves precision for a number of queries.
diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml
index b8d73e706429..35f35a391c5f 100644
--- a/java/ql/lib/qlpack.yml
+++ b/java/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-all
-version: 7.3.1
+version: 7.3.2-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java
diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll
index e3c7ed6e5d9e..0d9d685cc716 100644
--- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll
+++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll
@@ -327,12 +327,18 @@ private module ControlFlowGraphImpl {
)
}
+ private ThrowableType assertionError() { result.hasQualifiedName("java.lang", "AssertionError") }
+
/**
* Gets an exception type that may be thrown during execution of the
* body or the resources (if any) of `try`.
*/
private ThrowableType thrownInBody(TryStmt try) {
- exists(AstNode n | mayThrow(n, result) |
+ exists(AstNode n |
+ mayThrow(n, result)
+ or
+ n instanceof AssertStmt and result = assertionError()
+ |
n.getEnclosingStmt().getEnclosingStmt+() = try.getBlock() or
n.(Expr).getParent*() = try.getAResource()
)
@@ -394,10 +400,7 @@ private module ControlFlowGraphImpl {
exists(LogicExpr logexpr |
logexpr.(BinaryExpr).getLeftOperand() = b
or
- // Cannot use LogicExpr.getAnOperand or BinaryExpr.getAnOperand as they remove parentheses.
- logexpr.(BinaryExpr).getRightOperand() = b and inBooleanContext(logexpr)
- or
- logexpr.(UnaryExpr).getExpr() = b and inBooleanContext(logexpr)
+ logexpr.getAnOperand() = b and inBooleanContext(logexpr)
)
or
exists(ConditionalExpr condexpr |
@@ -407,6 +410,8 @@ private module ControlFlowGraphImpl {
inBooleanContext(condexpr)
)
or
+ exists(AssertStmt assertstmt | assertstmt.getExpr() = b)
+ or
exists(SwitchExpr switch |
inBooleanContext(switch) and
switch.getAResult() = b
@@ -672,8 +677,6 @@ private module ControlFlowGraphImpl {
this instanceof EmptyStmt
or
this instanceof LocalTypeDeclStmt
- or
- this instanceof AssertStmt
}
/** Gets child nodes in their order of execution. Indexing starts at either -1 or 0. */
@@ -744,8 +747,6 @@ private module ControlFlowGraphImpl {
or
index = 0 and result = this.(ThrowStmt).getExpr()
or
- index = 0 and result = this.(AssertStmt).getExpr()
- or
result = this.(RecordPatternExpr).getSubPattern(index)
}
@@ -807,9 +808,12 @@ private module ControlFlowGraphImpl {
or
result = first(n.(SynchronizedStmt).getExpr())
or
+ result = first(n.(AssertStmt).getExpr())
+ or
result.asStmt() = n and
not n instanceof PostOrderNode and
- not n instanceof SynchronizedStmt
+ not n instanceof SynchronizedStmt and
+ not n instanceof AssertStmt
or
result.asExpr() = n and n instanceof SwitchExpr
}
@@ -1112,7 +1116,22 @@ private module ControlFlowGraphImpl {
// `return` statements give rise to a `Return` completion
last.asStmt() = n.(ReturnStmt) and completion = ReturnCompletion()
or
- // `throw` statements or throwing calls give rise to ` Throw` completion
+ exists(AssertStmt assertstmt | assertstmt = n |
+ // `assert` statements may complete normally - we use the `AssertStmt` itself
+ // to represent this outcome
+ last.asStmt() = assertstmt and completion = NormalCompletion()
+ or
+ // `assert` statements may throw
+ completion = ThrowCompletion(assertionError()) and
+ (
+ last(assertstmt.getMessage(), last, NormalCompletion())
+ or
+ not exists(assertstmt.getMessage()) and
+ last(assertstmt.getExpr(), last, BooleanCompletion(false, _))
+ )
+ )
+ or
+ // `throw` statements or throwing calls give rise to `Throw` completion
exists(ThrowableType tt | mayThrow(n, tt) |
last = n.getCfgNode() and completion = ThrowCompletion(tt)
)
@@ -1520,6 +1539,17 @@ private module ControlFlowGraphImpl {
exists(int i | last(s.getVariable(i), n, completion) and result = first(s.getVariable(i + 1)))
)
or
+ // Assert statements:
+ exists(AssertStmt assertstmt |
+ last(assertstmt.getExpr(), n, completion) and
+ completion = BooleanCompletion(true, _) and
+ result.asStmt() = assertstmt
+ or
+ last(assertstmt.getExpr(), n, completion) and
+ completion = BooleanCompletion(false, _) and
+ result = first(assertstmt.getMessage())
+ )
+ or
// When expressions:
exists(WhenExpr whenexpr |
n.asExpr() = whenexpr and
diff --git a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll
index 786207d34865..36ad96c497f0 100644
--- a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll
+++ b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll
@@ -141,8 +141,6 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) {
private ControlFlowNode ensureNotNull(SsaVariable v) {
result = varDereference(v, _)
or
- result.asStmt().(AssertStmt).getExpr() = nullGuard(v, true, false)
- or
exists(AssertTrueMethod m | result.asCall() = m.getACheck(nullGuard(v, true, false)))
or
exists(AssertFalseMethod m | result.asCall() = m.getACheck(nullGuard(v, false, false)))
diff --git a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll
index e7f86b9bfd81..e1601c854e4e 100644
--- a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll
+++ b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll
@@ -110,11 +110,17 @@ predicate assertFail(BasicBlock bb, ControlFlowNode n) {
(
exists(AssertTrueMethod m |
n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = false))
- ) or
+ )
+ or
exists(AssertFalseMethod m |
n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = true))
- ) or
- exists(AssertFailMethod m | n.asExpr() = m.getACheck()) or
- n.asStmt().(AssertStmt).getExpr().(BooleanLiteral).getBooleanValue() = false
+ )
+ or
+ exists(AssertFailMethod m | n.asExpr() = m.getACheck())
+ or
+ exists(AssertStmt a |
+ n.asExpr() = a.getExpr() and
+ a.getExpr().(BooleanLiteral).getBooleanValue() = false
+ )
)
}
diff --git a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
index d50f583bbfe3..afa675c7f7b2 100644
--- a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
+++ b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql
@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity error
* @security-severity 9.8
- * @precision high
+ * @precision medium
* @id java/concatenated-command-line
* @tags security
* external/cwe/cwe-078
diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql
index fc5af977a331..ffb191327a2b 100644
--- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql
+++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql
@@ -3,7 +3,7 @@
* @description Using external input in format strings can lead to exceptions or information leaks.
* @kind path-problem
* @problem.severity error
- * @security-severity 9.3
+ * @security-severity 7.3
* @precision high
* @id java/tainted-format-string
* @tags security
diff --git a/java/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md b/java/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md
new file mode 100644
index 000000000000..6ab4beb72905
--- /dev/null
+++ b/java/ql/src/change-notes/2025-06-06-reduce-CWE-134-for-memory-safe-languages.md
@@ -0,0 +1,4 @@
+---
+category: queryMetadata
+---
+* Adjusts the `@security-severity` from 9.3 to 7.3 for `java/tainted-format-string` to align `CWE-134` severity for memory safe languages to better reflect their impact.
diff --git a/java/ql/src/change-notes/2025-06-10-reduce-precision-for-building-cmdline-with-string-concatenation.md b/java/ql/src/change-notes/2025-06-10-reduce-precision-for-building-cmdline-with-string-concatenation.md
new file mode 100644
index 000000000000..392e1965defa
--- /dev/null
+++ b/java/ql/src/change-notes/2025-06-10-reduce-precision-for-building-cmdline-with-string-concatenation.md
@@ -0,0 +1,4 @@
+---
+category: queryMetadata
+---
+* Adjusts the `@precision` from high to medium for `java/concatenated-command-line` because it is producing false positive alerts when the concatenated strings are hard-coded.
diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml
index 4ea0bc399ca8..a0b518b6876f 100644
--- a/java/ql/src/qlpack.yml
+++ b/java/ql/src/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/java-queries
-version: 1.5.2
+version: 1.5.3-dev
groups:
- java
- queries
diff --git a/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java b/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java
index e7306e77e016..43e70160fe8f 100644
--- a/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java
+++ b/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java
@@ -426,7 +426,6 @@ public Void visit(Identifier nd, Void v) {
// cases where we turn on the 'declKind' flags
@Override
public Void visit(FunctionDeclaration nd, Void v) {
- if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
// strict mode functions are block-scoped, non-strict mode ones aren't
if (blockscope == isStrict) visit(nd.getId(), DeclKind.var);
return null;
@@ -434,7 +433,6 @@ public Void visit(FunctionDeclaration nd, Void v) {
@Override
public Void visit(ClassDeclaration nd, Void c) {
- if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
if (blockscope) visit(nd.getClassDef().getId(), DeclKind.varAndType);
return null;
}
@@ -483,7 +481,6 @@ public Void visit(EnhancedForStatement nd, Void v) {
@Override
public Void visit(VariableDeclaration nd, Void v) {
- if (nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile()) return null;
// in block scoping mode, only process 'let'; in non-block scoping
// mode, only process non-'let'
if (blockscope == nd.isBlockScoped(ecmaVersion)) visit(nd.getDeclarations());
@@ -518,8 +515,7 @@ public Void visit(ClassBody nd, Void c) {
@Override
public Void visit(NamespaceDeclaration nd, Void c) {
if (blockscope) return null;
- boolean isAmbientOutsideDtsFile = nd.hasDeclareKeyword() && !isInTypeScriptDeclarationFile();
- boolean hasVariable = nd.isInstantiated() && !isAmbientOutsideDtsFile;
+ boolean hasVariable = nd.isInstantiated();
visit(nd.getName(), hasVariable ? DeclKind.varAndNamespace : DeclKind.namespace);
return null;
}
diff --git a/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap b/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap
index 0751d283e6cc..2a1c0efbd441 100644
--- a/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap
+++ b/javascript/extractor/tests/ts/output/trap/conditionalTypes.ts.trap
@@ -8434,1316 +8434,1316 @@ namespacedecl(#22807,#22182)
scopes(#22808,9)
scopenodes(#22805,#22808)
scopenesting(#22808,#20000)
-#22809=@"local_type_name;{Unpacked};{#22808}"
-local_type_names(#22809,"Unpacked",#22808)
-#22810=@"local_type_name;{T0};{#22808}"
-local_type_names(#22810,"T0",#22808)
-#22811=@"local_type_name;{T1};{#22808}"
-local_type_names(#22811,"T1",#22808)
-#22812=@"local_type_name;{T2};{#22808}"
-local_type_names(#22812,"T2",#22808)
-#22813=@"local_type_name;{T3};{#22808}"
-local_type_names(#22813,"T3",#22808)
-#22814=@"local_type_name;{T4};{#22808}"
-local_type_names(#22814,"T4",#22808)
-#22815=@"local_type_name;{T5};{#22808}"
-local_type_names(#22815,"T5",#22808)
-#22816=@"local_type_name;{Foo};{#22808}"
-local_type_names(#22816,"Foo",#22808)
-#22817=@"local_type_name;{T10};{#22808}"
-local_type_names(#22817,"T10",#22808)
-#22818=@"local_type_name;{T11};{#22808}"
-local_type_names(#22818,"T11",#22808)
-#22819=@"local_type_name;{Bar};{#22808}"
-local_type_names(#22819,"Bar",#22808)
-#22820=@"local_type_name;{T20};{#22808}"
-local_type_names(#22820,"T20",#22808)
-#22821=@"local_type_name;{T21};{#22808}"
-local_type_names(#22821,"T21",#22808)
-#22822=@"local_type_name;{T30};{#22808}"
-local_type_names(#22822,"T30",#22808)
-#22823=@"local_type_name;{AnyFunction};{#22808}"
-local_type_names(#22823,"AnyFunction",#22808)
-#22824=@"local_type_name;{ReturnType};{#22808}"
-local_type_names(#22824,"ReturnType",#22808)
-#22825=*
-stmts(#22825,35,#22805,0,"type Un ... \n T;")
-#22826=@"loc,{#10000},73,3,77,6"
-locations_default(#22826,#10000,73,3,77,6)
-hasLocation(#22825,#22826)
-stmt_containers(#22825,#22805)
-#22827=*
-typeexprs(#22827,1,#22825,0,"Unpacked")
-hasLocation(#22827,#21482)
-enclosing_stmt(#22827,#22825)
-expr_containers(#22827,#22805)
-literals("Unpacked","Unpacked",#22827)
-typedecl(#22827,#22809)
+#22809=@"var;{foo};{#22808}"
+variables(#22809,"foo",#22808)
+#22810=@"local_type_name;{Unpacked};{#22808}"
+local_type_names(#22810,"Unpacked",#22808)
+#22811=@"local_type_name;{T0};{#22808}"
+local_type_names(#22811,"T0",#22808)
+#22812=@"local_type_name;{T1};{#22808}"
+local_type_names(#22812,"T1",#22808)
+#22813=@"local_type_name;{T2};{#22808}"
+local_type_names(#22813,"T2",#22808)
+#22814=@"local_type_name;{T3};{#22808}"
+local_type_names(#22814,"T3",#22808)
+#22815=@"local_type_name;{T4};{#22808}"
+local_type_names(#22815,"T4",#22808)
+#22816=@"local_type_name;{T5};{#22808}"
+local_type_names(#22816,"T5",#22808)
+#22817=@"local_type_name;{Foo};{#22808}"
+local_type_names(#22817,"Foo",#22808)
+#22818=@"local_type_name;{T10};{#22808}"
+local_type_names(#22818,"T10",#22808)
+#22819=@"local_type_name;{T11};{#22808}"
+local_type_names(#22819,"T11",#22808)
+#22820=@"local_type_name;{Bar};{#22808}"
+local_type_names(#22820,"Bar",#22808)
+#22821=@"local_type_name;{T20};{#22808}"
+local_type_names(#22821,"T20",#22808)
+#22822=@"local_type_name;{T21};{#22808}"
+local_type_names(#22822,"T21",#22808)
+#22823=@"local_type_name;{T30};{#22808}"
+local_type_names(#22823,"T30",#22808)
+#22824=@"local_type_name;{AnyFunction};{#22808}"
+local_type_names(#22824,"AnyFunction",#22808)
+#22825=@"local_type_name;{ReturnType};{#22808}"
+local_type_names(#22825,"ReturnType",#22808)
+#22826=*
+stmts(#22826,35,#22805,0,"type Un ... \n T;")
+#22827=@"loc,{#10000},73,3,77,6"
+locations_default(#22827,#10000,73,3,77,6)
+hasLocation(#22826,#22827)
+stmt_containers(#22826,#22805)
#22828=*
-scopes(#22828,12)
-scopenodes(#22825,#22828)
-scopenesting(#22828,#22808)
-#22829=@"local_type_name;{T};{#22828}"
-local_type_names(#22829,"T",#22828)
-#22830=*
-typeexprs(#22830,22,#22825,2,"T")
-hasLocation(#22830,#21486)
-enclosing_stmt(#22830,#22825)
-expr_containers(#22830,#22805)
+typeexprs(#22828,1,#22826,0,"Unpacked")
+hasLocation(#22828,#21482)
+enclosing_stmt(#22828,#22826)
+expr_containers(#22828,#22805)
+literals("Unpacked","Unpacked",#22828)
+typedecl(#22828,#22810)
+#22829=*
+scopes(#22829,12)
+scopenodes(#22826,#22829)
+scopenesting(#22829,#22808)
+#22830=@"local_type_name;{T};{#22829}"
+local_type_names(#22830,"T",#22829)
#22831=*
-typeexprs(#22831,1,#22830,0,"T")
+typeexprs(#22831,22,#22826,2,"T")
hasLocation(#22831,#21486)
-enclosing_stmt(#22831,#22825)
+enclosing_stmt(#22831,#22826)
expr_containers(#22831,#22805)
-literals("T","T",#22831)
-typedecl(#22831,#22829)
#22832=*
-typeexprs(#22832,28,#22825,1,"T exten ... :\n T")
-#22833=@"loc,{#10000},74,5,77,5"
-locations_default(#22833,#10000,74,5,77,5)
-hasLocation(#22832,#22833)
-enclosing_stmt(#22832,#22825)
+typeexprs(#22832,1,#22831,0,"T")
+hasLocation(#22832,#21486)
+enclosing_stmt(#22832,#22826)
expr_containers(#22832,#22805)
-#22834=*
-typeexprs(#22834,0,#22832,0,"T")
-hasLocation(#22834,#21492)
-enclosing_stmt(#22834,#22825)
-expr_containers(#22834,#22805)
-literals("T","T",#22834)
-typebind(#22834,#22829)
+literals("T","T",#22832)
+typedecl(#22832,#22830)
+#22833=*
+typeexprs(#22833,28,#22826,1,"T exten ... :\n T")
+#22834=@"loc,{#10000},74,5,77,5"
+locations_default(#22834,#10000,74,5,77,5)
+hasLocation(#22833,#22834)
+enclosing_stmt(#22833,#22826)
+expr_containers(#22833,#22805)
#22835=*
-scopes(#22835,16)
-scopenodes(#22832,#22835)
-scopenesting(#22835,#22828)
-#22836=@"local_type_name;{U};{#22835}"
-local_type_names(#22836,"U",#22835)
-#22837=*
-typeexprs(#22837,6,#22832,1,"(infer U)[]")
-#22838=@"loc,{#10000},74,15,74,25"
-locations_default(#22838,#10000,74,15,74,25)
-hasLocation(#22837,#22838)
-enclosing_stmt(#22837,#22825)
-expr_containers(#22837,#22805)
-#22839=*
-typeexprs(#22839,10,#22837,0,"(infer U)")
-#22840=@"loc,{#10000},74,15,74,23"
-locations_default(#22840,#10000,74,15,74,23)
-hasLocation(#22839,#22840)
-enclosing_stmt(#22839,#22825)
-expr_containers(#22839,#22805)
-#22841=*
-typeexprs(#22841,29,#22839,0,"infer U")
-#22842=@"loc,{#10000},74,16,74,22"
-locations_default(#22842,#10000,74,16,74,22)
-hasLocation(#22841,#22842)
-enclosing_stmt(#22841,#22825)
-expr_containers(#22841,#22805)
-#22843=*
-typeexprs(#22843,22,#22841,0,"U")
-hasLocation(#22843,#21500)
-enclosing_stmt(#22843,#22825)
-expr_containers(#22843,#22805)
+typeexprs(#22835,0,#22833,0,"T")
+hasLocation(#22835,#21492)
+enclosing_stmt(#22835,#22826)
+expr_containers(#22835,#22805)
+literals("T","T",#22835)
+typebind(#22835,#22830)
+#22836=*
+scopes(#22836,16)
+scopenodes(#22833,#22836)
+scopenesting(#22836,#22829)
+#22837=@"local_type_name;{U};{#22836}"
+local_type_names(#22837,"U",#22836)
+#22838=*
+typeexprs(#22838,6,#22833,1,"(infer U)[]")
+#22839=@"loc,{#10000},74,15,74,25"
+locations_default(#22839,#10000,74,15,74,25)
+hasLocation(#22838,#22839)
+enclosing_stmt(#22838,#22826)
+expr_containers(#22838,#22805)
+#22840=*
+typeexprs(#22840,10,#22838,0,"(infer U)")
+#22841=@"loc,{#10000},74,15,74,23"
+locations_default(#22841,#10000,74,15,74,23)
+hasLocation(#22840,#22841)
+enclosing_stmt(#22840,#22826)
+expr_containers(#22840,#22805)
+#22842=*
+typeexprs(#22842,29,#22840,0,"infer U")
+#22843=@"loc,{#10000},74,16,74,22"
+locations_default(#22843,#10000,74,16,74,22)
+hasLocation(#22842,#22843)
+enclosing_stmt(#22842,#22826)
+expr_containers(#22842,#22805)
#22844=*
-typeexprs(#22844,1,#22843,0,"U")
+typeexprs(#22844,22,#22842,0,"U")
hasLocation(#22844,#21500)
-enclosing_stmt(#22844,#22825)
+enclosing_stmt(#22844,#22826)
expr_containers(#22844,#22805)
-literals("U","U",#22844)
-typedecl(#22844,#22836)
#22845=*
-typeexprs(#22845,0,#22832,2,"U")
-hasLocation(#22845,#21510)
-enclosing_stmt(#22845,#22825)
+typeexprs(#22845,1,#22844,0,"U")
+hasLocation(#22845,#21500)
+enclosing_stmt(#22845,#22826)
expr_containers(#22845,#22805)
literals("U","U",#22845)
-typebind(#22845,#22836)
+typedecl(#22845,#22837)
#22846=*
-typeexprs(#22846,28,#22832,3,"T exten ... :\n T")
-#22847=@"loc,{#10000},75,5,77,5"
-locations_default(#22847,#10000,75,5,77,5)
-hasLocation(#22846,#22847)
-enclosing_stmt(#22846,#22825)
+typeexprs(#22846,0,#22833,2,"U")
+hasLocation(#22846,#21510)
+enclosing_stmt(#22846,#22826)
expr_containers(#22846,#22805)
-#22848=*
-typeexprs(#22848,0,#22846,0,"T")
-hasLocation(#22848,#21514)
-enclosing_stmt(#22848,#22825)
-expr_containers(#22848,#22805)
-literals("T","T",#22848)
-typebind(#22848,#22829)
+literals("U","U",#22846)
+typebind(#22846,#22837)
+#22847=*
+typeexprs(#22847,28,#22833,3,"T exten ... :\n T")
+#22848=@"loc,{#10000},75,5,77,5"
+locations_default(#22848,#10000,75,5,77,5)
+hasLocation(#22847,#22848)
+enclosing_stmt(#22847,#22826)
+expr_containers(#22847,#22805)
#22849=*
-scopes(#22849,16)
-scopenodes(#22846,#22849)
-scopenesting(#22849,#22828)
-#22850=@"local_type_name;{U};{#22849}"
-local_type_names(#22850,"U",#22849)
-#22851=*
-typeexprs(#22851,23,#22846,1,"(...arg ... infer U")
-#22852=@"loc,{#10000},75,15,75,41"
-locations_default(#22852,#10000,75,15,75,41)
-hasLocation(#22851,#22852)
-enclosing_stmt(#22851,#22825)
-expr_containers(#22851,#22805)
-#22853=*
-exprs(#22853,9,#22851,0,"(...arg ... infer U")
-hasLocation(#22853,#22852)
-enclosing_stmt(#22853,#22825)
-expr_containers(#22853,#22805)
+typeexprs(#22849,0,#22847,0,"T")
+hasLocation(#22849,#21514)
+enclosing_stmt(#22849,#22826)
+expr_containers(#22849,#22805)
+literals("T","T",#22849)
+typebind(#22849,#22830)
+#22850=*
+scopes(#22850,16)
+scopenodes(#22847,#22850)
+scopenesting(#22850,#22829)
+#22851=@"local_type_name;{U};{#22850}"
+local_type_names(#22851,"U",#22850)
+#22852=*
+typeexprs(#22852,23,#22847,1,"(...arg ... infer U")
+#22853=@"loc,{#10000},75,15,75,41"
+locations_default(#22853,#10000,75,15,75,41)
+hasLocation(#22852,#22853)
+enclosing_stmt(#22852,#22826)
+expr_containers(#22852,#22805)
#22854=*
-scopes(#22854,1)
-scopenodes(#22853,#22854)
-scopenesting(#22854,#22849)
-#22855=@"var;{args};{#22854}"
-variables(#22855,"args",#22854)
-#22856=*
-exprs(#22856,78,#22853,0,"args")
-hasLocation(#22856,#21522)
-expr_containers(#22856,#22853)
-literals("args","args",#22856)
-decl(#22856,#22855)
-#22857=@"var;{arguments};{#22854}"
-variables(#22857,"arguments",#22854)
-is_arguments_object(#22857)
-#22858=*
-typeexprs(#22858,29,#22853,-3,"infer U")
-#22859=@"loc,{#10000},75,35,75,41"
-locations_default(#22859,#10000,75,35,75,41)
-hasLocation(#22858,#22859)
-expr_containers(#22858,#22853)
-#22860=*
-typeexprs(#22860,22,#22858,0,"U")
-hasLocation(#22860,#21538)
-expr_containers(#22860,#22853)
+exprs(#22854,9,#22852,0,"(...arg ... infer U")
+hasLocation(#22854,#22853)
+enclosing_stmt(#22854,#22826)
+expr_containers(#22854,#22805)
+#22855=*
+scopes(#22855,1)
+scopenodes(#22854,#22855)
+scopenesting(#22855,#22850)
+#22856=@"var;{args};{#22855}"
+variables(#22856,"args",#22855)
+#22857=*
+exprs(#22857,78,#22854,0,"args")
+hasLocation(#22857,#21522)
+expr_containers(#22857,#22854)
+literals("args","args",#22857)
+decl(#22857,#22856)
+#22858=@"var;{arguments};{#22855}"
+variables(#22858,"arguments",#22855)
+is_arguments_object(#22858)
+#22859=*
+typeexprs(#22859,29,#22854,-3,"infer U")
+#22860=@"loc,{#10000},75,35,75,41"
+locations_default(#22860,#10000,75,35,75,41)
+hasLocation(#22859,#22860)
+expr_containers(#22859,#22854)
#22861=*
-typeexprs(#22861,1,#22860,0,"U")
+typeexprs(#22861,22,#22859,0,"U")
hasLocation(#22861,#21538)
-expr_containers(#22861,#22853)
-literals("U","U",#22861)
-typedecl(#22861,#22850)
+expr_containers(#22861,#22854)
#22862=*
-typeexprs(#22862,6,#22853,-6,"any[]")
-#22863=@"loc,{#10000},75,25,75,29"
-locations_default(#22863,#10000,75,25,75,29)
-hasLocation(#22862,#22863)
-expr_containers(#22862,#22853)
-#22864=*
-typeexprs(#22864,2,#22862,0,"any")
-hasLocation(#22864,#21526)
-expr_containers(#22864,#22853)
-literals("any","any",#22864)
-has_rest_parameter(#22853)
+typeexprs(#22862,1,#22861,0,"U")
+hasLocation(#22862,#21538)
+expr_containers(#22862,#22854)
+literals("U","U",#22862)
+typedecl(#22862,#22851)
+#22863=*
+typeexprs(#22863,6,#22854,-6,"any[]")
+#22864=@"loc,{#10000},75,25,75,29"
+locations_default(#22864,#10000,75,25,75,29)
+hasLocation(#22863,#22864)
+expr_containers(#22863,#22854)
#22865=*
-typeexprs(#22865,0,#22846,2,"U")
-hasLocation(#22865,#21542)
-enclosing_stmt(#22865,#22825)
-expr_containers(#22865,#22805)
-literals("U","U",#22865)
-typebind(#22865,#22850)
+typeexprs(#22865,2,#22863,0,"any")
+hasLocation(#22865,#21526)
+expr_containers(#22865,#22854)
+literals("any","any",#22865)
+has_rest_parameter(#22854)
#22866=*
-typeexprs(#22866,28,#22846,3,"T exten ... :\n T")
-#22867=@"loc,{#10000},76,5,77,5"
-locations_default(#22867,#10000,76,5,77,5)
-hasLocation(#22866,#22867)
-enclosing_stmt(#22866,#22825)
+typeexprs(#22866,0,#22847,2,"U")
+hasLocation(#22866,#21542)
+enclosing_stmt(#22866,#22826)
expr_containers(#22866,#22805)
-#22868=*
-typeexprs(#22868,0,#22866,0,"T")
-hasLocation(#22868,#21546)
-enclosing_stmt(#22868,#22825)
-expr_containers(#22868,#22805)
-literals("T","T",#22868)
-typebind(#22868,#22829)
+literals("U","U",#22866)
+typebind(#22866,#22851)
+#22867=*
+typeexprs(#22867,28,#22847,3,"T exten ... :\n T")
+#22868=@"loc,{#10000},76,5,77,5"
+locations_default(#22868,#10000,76,5,77,5)
+hasLocation(#22867,#22868)
+enclosing_stmt(#22867,#22826)
+expr_containers(#22867,#22805)
#22869=*
-scopes(#22869,16)
-scopenodes(#22866,#22869)
-scopenesting(#22869,#22828)
-#22870=@"local_type_name;{U};{#22869}"
-local_type_names(#22870,"U",#22869)
-#22871=*
-typeexprs(#22871,14,#22866,1,"Promise")
-#22872=@"loc,{#10000},76,15,76,30"
-locations_default(#22872,#10000,76,15,76,30)
-hasLocation(#22871,#22872)
-enclosing_stmt(#22871,#22825)
-expr_containers(#22871,#22805)
-#22873=*
-typeexprs(#22873,0,#22871,-1,"Promise")
-hasLocation(#22873,#21550)
-enclosing_stmt(#22873,#22825)
-expr_containers(#22873,#22805)
-literals("Promise","Promise",#22873)
+typeexprs(#22869,0,#22867,0,"T")
+hasLocation(#22869,#21546)
+enclosing_stmt(#22869,#22826)
+expr_containers(#22869,#22805)
+literals("T","T",#22869)
+typebind(#22869,#22830)
+#22870=*
+scopes(#22870,16)
+scopenodes(#22867,#22870)
+scopenesting(#22870,#22829)
+#22871=@"local_type_name;{U};{#22870}"
+local_type_names(#22871,"U",#22870)
+#22872=*
+typeexprs(#22872,14,#22867,1,"Promise")
+#22873=@"loc,{#10000},76,15,76,30"
+locations_default(#22873,#10000,76,15,76,30)
+hasLocation(#22872,#22873)
+enclosing_stmt(#22872,#22826)
+expr_containers(#22872,#22805)
#22874=*
-typeexprs(#22874,29,#22871,0,"infer U")
-#22875=@"loc,{#10000},76,23,76,29"
-locations_default(#22875,#10000,76,23,76,29)
-hasLocation(#22874,#22875)
-enclosing_stmt(#22874,#22825)
+typeexprs(#22874,0,#22872,-1,"Promise")
+hasLocation(#22874,#21550)
+enclosing_stmt(#22874,#22826)
expr_containers(#22874,#22805)
-#22876=*
-typeexprs(#22876,22,#22874,0,"U")
-hasLocation(#22876,#21556)
-enclosing_stmt(#22876,#22825)
-expr_containers(#22876,#22805)
+literals("Promise","Promise",#22874)
+#22875=*
+typeexprs(#22875,29,#22872,0,"infer U")
+#22876=@"loc,{#10000},76,23,76,29"
+locations_default(#22876,#10000,76,23,76,29)
+hasLocation(#22875,#22876)
+enclosing_stmt(#22875,#22826)
+expr_containers(#22875,#22805)
#22877=*
-typeexprs(#22877,1,#22876,0,"U")
+typeexprs(#22877,22,#22875,0,"U")
hasLocation(#22877,#21556)
-enclosing_stmt(#22877,#22825)
+enclosing_stmt(#22877,#22826)
expr_containers(#22877,#22805)
-literals("U","U",#22877)
-typedecl(#22877,#22870)
#22878=*
-typeexprs(#22878,0,#22866,2,"U")
-hasLocation(#22878,#21562)
-enclosing_stmt(#22878,#22825)
+typeexprs(#22878,1,#22877,0,"U")
+hasLocation(#22878,#21556)
+enclosing_stmt(#22878,#22826)
expr_containers(#22878,#22805)
literals("U","U",#22878)
-typebind(#22878,#22870)
+typedecl(#22878,#22871)
#22879=*
-typeexprs(#22879,0,#22866,3,"T")
-hasLocation(#22879,#21566)
-enclosing_stmt(#22879,#22825)
+typeexprs(#22879,0,#22867,2,"U")
+hasLocation(#22879,#21562)
+enclosing_stmt(#22879,#22826)
expr_containers(#22879,#22805)
-literals("T","T",#22879)
-typebind(#22879,#22829)
+literals("U","U",#22879)
+typebind(#22879,#22871)
#22880=*
-stmts(#22880,35,#22805,1,"type T0 ... tring>;")
-#22881=@"loc,{#10000},79,3,79,29"
-locations_default(#22881,#10000,79,3,79,29)
-hasLocation(#22880,#22881)
-stmt_containers(#22880,#22805)
-#22882=*
-typeexprs(#22882,1,#22880,0,"T0")
-hasLocation(#22882,#21572)
-enclosing_stmt(#22882,#22880)
-expr_containers(#22882,#22805)
-literals("T0","T0",#22882)
-typedecl(#22882,#22810)
+typeexprs(#22880,0,#22867,3,"T")
+hasLocation(#22880,#21566)
+enclosing_stmt(#22880,#22826)
+expr_containers(#22880,#22805)
+literals("T","T",#22880)
+typebind(#22880,#22830)
+#22881=*
+stmts(#22881,35,#22805,1,"type T0 ... tring>;")
+#22882=@"loc,{#10000},79,3,79,29"
+locations_default(#22882,#10000,79,3,79,29)
+hasLocation(#22881,#22882)
+stmt_containers(#22881,#22805)
#22883=*
-typeexprs(#22883,14,#22880,1,"Unpacked")
-#22884=@"loc,{#10000},79,13,79,28"
-locations_default(#22884,#10000,79,13,79,28)
-hasLocation(#22883,#22884)
-enclosing_stmt(#22883,#22880)
+typeexprs(#22883,1,#22881,0,"T0")
+hasLocation(#22883,#21572)
+enclosing_stmt(#22883,#22881)
expr_containers(#22883,#22805)
-#22885=*
-typeexprs(#22885,0,#22883,-1,"Unpacked")
-hasLocation(#22885,#21576)
-enclosing_stmt(#22885,#22880)
-expr_containers(#22885,#22805)
-literals("Unpacked","Unpacked",#22885)
-typebind(#22885,#22809)
+literals("T0","T0",#22883)
+typedecl(#22883,#22811)
+#22884=*
+typeexprs(#22884,14,#22881,1,"Unpacked")
+#22885=@"loc,{#10000},79,13,79,28"
+locations_default(#22885,#10000,79,13,79,28)
+hasLocation(#22884,#22885)
+enclosing_stmt(#22884,#22881)
+expr_containers(#22884,#22805)
#22886=*
-typeexprs(#22886,2,#22883,0,"string")
-hasLocation(#22886,#21580)
-enclosing_stmt(#22886,#22880)
+typeexprs(#22886,0,#22884,-1,"Unpacked")
+hasLocation(#22886,#21576)
+enclosing_stmt(#22886,#22881)
expr_containers(#22886,#22805)
-literals("string","string",#22886)
+literals("Unpacked","Unpacked",#22886)
+typebind(#22886,#22810)
#22887=*
-stmts(#22887,35,#22805,2,"type T1 ... ing[]>;")
-#22888=@"loc,{#10000},80,3,80,31"
-locations_default(#22888,#10000,80,3,80,31)
-hasLocation(#22887,#22888)
-stmt_containers(#22887,#22805)
-#22889=*
-typeexprs(#22889,1,#22887,0,"T1")
-hasLocation(#22889,#21588)
-enclosing_stmt(#22889,#22887)
-expr_containers(#22889,#22805)
-literals("T1","T1",#22889)
-typedecl(#22889,#22811)
+typeexprs(#22887,2,#22884,0,"string")
+hasLocation(#22887,#21580)
+enclosing_stmt(#22887,#22881)
+expr_containers(#22887,#22805)
+literals("string","string",#22887)
+#22888=*
+stmts(#22888,35,#22805,2,"type T1 ... ing[]>;")
+#22889=@"loc,{#10000},80,3,80,31"
+locations_default(#22889,#10000,80,3,80,31)
+hasLocation(#22888,#22889)
+stmt_containers(#22888,#22805)
#22890=*
-typeexprs(#22890,14,#22887,1,"Unpacked")
-#22891=@"loc,{#10000},80,13,80,30"
-locations_default(#22891,#10000,80,13,80,30)
-hasLocation(#22890,#22891)
-enclosing_stmt(#22890,#22887)
+typeexprs(#22890,1,#22888,0,"T1")
+hasLocation(#22890,#21588)
+enclosing_stmt(#22890,#22888)
expr_containers(#22890,#22805)
-#22892=*
-typeexprs(#22892,0,#22890,-1,"Unpacked")
-hasLocation(#22892,#21592)
-enclosing_stmt(#22892,#22887)
-expr_containers(#22892,#22805)
-literals("Unpacked","Unpacked",#22892)
-typebind(#22892,#22809)
+literals("T1","T1",#22890)
+typedecl(#22890,#22812)
+#22891=*
+typeexprs(#22891,14,#22888,1,"Unpacked")
+#22892=@"loc,{#10000},80,13,80,30"
+locations_default(#22892,#10000,80,13,80,30)
+hasLocation(#22891,#22892)
+enclosing_stmt(#22891,#22888)
+expr_containers(#22891,#22805)
#22893=*
-typeexprs(#22893,6,#22890,0,"string[]")
-#22894=@"loc,{#10000},80,22,80,29"
-locations_default(#22894,#10000,80,22,80,29)
-hasLocation(#22893,#22894)
-enclosing_stmt(#22893,#22887)
+typeexprs(#22893,0,#22891,-1,"Unpacked")
+hasLocation(#22893,#21592)
+enclosing_stmt(#22893,#22888)
expr_containers(#22893,#22805)
-#22895=*
-typeexprs(#22895,2,#22893,0,"string")
-hasLocation(#22895,#21596)
-enclosing_stmt(#22895,#22887)
-expr_containers(#22895,#22805)
-literals("string","string",#22895)
+literals("Unpacked","Unpacked",#22893)
+typebind(#22893,#22810)
+#22894=*
+typeexprs(#22894,6,#22891,0,"string[]")
+#22895=@"loc,{#10000},80,22,80,29"
+locations_default(#22895,#10000,80,22,80,29)
+hasLocation(#22894,#22895)
+enclosing_stmt(#22894,#22888)
+expr_containers(#22894,#22805)
#22896=*
-stmts(#22896,35,#22805,3,"type T2 ... tring>;")
-#22897=@"loc,{#10000},81,3,81,35"
-locations_default(#22897,#10000,81,3,81,35)
-hasLocation(#22896,#22897)
-stmt_containers(#22896,#22805)
-#22898=*
-typeexprs(#22898,1,#22896,0,"T2")
-hasLocation(#22898,#21608)
-enclosing_stmt(#22898,#22896)
-expr_containers(#22898,#22805)
-literals("T2","T2",#22898)
-typedecl(#22898,#22812)
+typeexprs(#22896,2,#22894,0,"string")
+hasLocation(#22896,#21596)
+enclosing_stmt(#22896,#22888)
+expr_containers(#22896,#22805)
+literals("string","string",#22896)
+#22897=*
+stmts(#22897,35,#22805,3,"type T2 ... tring>;")
+#22898=@"loc,{#10000},81,3,81,35"
+locations_default(#22898,#10000,81,3,81,35)
+hasLocation(#22897,#22898)
+stmt_containers(#22897,#22805)
#22899=*
-typeexprs(#22899,14,#22896,1,"Unpacke ... string>")
-#22900=@"loc,{#10000},81,13,81,34"
-locations_default(#22900,#10000,81,13,81,34)
-hasLocation(#22899,#22900)
-enclosing_stmt(#22899,#22896)
+typeexprs(#22899,1,#22897,0,"T2")
+hasLocation(#22899,#21608)
+enclosing_stmt(#22899,#22897)
expr_containers(#22899,#22805)
-#22901=*
-typeexprs(#22901,0,#22899,-1,"Unpacked")
-hasLocation(#22901,#21612)
-enclosing_stmt(#22901,#22896)
-expr_containers(#22901,#22805)
-literals("Unpacked","Unpacked",#22901)
-typebind(#22901,#22809)
+literals("T2","T2",#22899)
+typedecl(#22899,#22813)
+#22900=*
+typeexprs(#22900,14,#22897,1,"Unpacke ... string>")
+#22901=@"loc,{#10000},81,13,81,34"
+locations_default(#22901,#10000,81,13,81,34)
+hasLocation(#22900,#22901)
+enclosing_stmt(#22900,#22897)
+expr_containers(#22900,#22805)
#22902=*
-typeexprs(#22902,23,#22899,0,"() => string")
-#22903=@"loc,{#10000},81,22,81,33"
-locations_default(#22903,#10000,81,22,81,33)
-hasLocation(#22902,#22903)
-enclosing_stmt(#22902,#22896)
+typeexprs(#22902,0,#22900,-1,"Unpacked")
+hasLocation(#22902,#21612)
+enclosing_stmt(#22902,#22897)
expr_containers(#22902,#22805)
-#22904=*
-exprs(#22904,9,#22902,0,"() => string")
-hasLocation(#22904,#22903)
-enclosing_stmt(#22904,#22896)
-expr_containers(#22904,#22805)
+literals("Unpacked","Unpacked",#22902)
+typebind(#22902,#22810)
+#22903=*
+typeexprs(#22903,23,#22900,0,"() => string")
+#22904=@"loc,{#10000},81,22,81,33"
+locations_default(#22904,#10000,81,22,81,33)
+hasLocation(#22903,#22904)
+enclosing_stmt(#22903,#22897)
+expr_containers(#22903,#22805)
#22905=*
-scopes(#22905,1)
-scopenodes(#22904,#22905)
-scopenesting(#22905,#22808)
-#22906=@"var;{arguments};{#22905}"
-variables(#22906,"arguments",#22905)
-is_arguments_object(#22906)
-#22907=*
-typeexprs(#22907,2,#22904,-3,"string")
-hasLocation(#22907,#21622)
-expr_containers(#22907,#22904)
-literals("string","string",#22907)
+exprs(#22905,9,#22903,0,"() => string")
+hasLocation(#22905,#22904)
+enclosing_stmt(#22905,#22897)
+expr_containers(#22905,#22805)
+#22906=*
+scopes(#22906,1)
+scopenodes(#22905,#22906)
+scopenesting(#22906,#22808)
+#22907=@"var;{arguments};{#22906}"
+variables(#22907,"arguments",#22906)
+is_arguments_object(#22907)
#22908=*
-stmts(#22908,35,#22805,4,"type T3 ... ring>>;")
-#22909=@"loc,{#10000},82,3,82,38"
-locations_default(#22909,#10000,82,3,82,38)
-hasLocation(#22908,#22909)
-stmt_containers(#22908,#22805)
-#22910=*
-typeexprs(#22910,1,#22908,0,"T3")
-hasLocation(#22910,#21630)
-enclosing_stmt(#22910,#22908)
-expr_containers(#22910,#22805)
-literals("T3","T3",#22910)
-typedecl(#22910,#22813)
+typeexprs(#22908,2,#22905,-3,"string")
+hasLocation(#22908,#21622)
+expr_containers(#22908,#22905)
+literals("string","string",#22908)
+#22909=*
+stmts(#22909,35,#22805,4,"type T3 ... ring>>;")
+#22910=@"loc,{#10000},82,3,82,38"
+locations_default(#22910,#10000,82,3,82,38)
+hasLocation(#22909,#22910)
+stmt_containers(#22909,#22805)
#22911=*
-typeexprs(#22911,14,#22908,1,"Unpacke ... tring>>")
-#22912=@"loc,{#10000},82,13,82,37"
-locations_default(#22912,#10000,82,13,82,37)
-hasLocation(#22911,#22912)
-enclosing_stmt(#22911,#22908)
+typeexprs(#22911,1,#22909,0,"T3")
+hasLocation(#22911,#21630)
+enclosing_stmt(#22911,#22909)
expr_containers(#22911,#22805)
-#22913=*
-typeexprs(#22913,0,#22911,-1,"Unpacked")
-hasLocation(#22913,#21634)
-enclosing_stmt(#22913,#22908)
-expr_containers(#22913,#22805)
-literals("Unpacked","Unpacked",#22913)
-typebind(#22913,#22809)
+literals("T3","T3",#22911)
+typedecl(#22911,#22814)
+#22912=*
+typeexprs(#22912,14,#22909,1,"Unpacke ... tring>>")
+#22913=@"loc,{#10000},82,13,82,37"
+locations_default(#22913,#10000,82,13,82,37)
+hasLocation(#22912,#22913)
+enclosing_stmt(#22912,#22909)
+expr_containers(#22912,#22805)
#22914=*
-typeexprs(#22914,14,#22911,0,"Promise")
-#22915=@"loc,{#10000},82,22,82,36"
-locations_default(#22915,#10000,82,22,82,36)
-hasLocation(#22914,#22915)
-enclosing_stmt(#22914,#22908)
+typeexprs(#22914,0,#22912,-1,"Unpacked")
+hasLocation(#22914,#21634)
+enclosing_stmt(#22914,#22909)
expr_containers(#22914,#22805)
-#22916=*
-typeexprs(#22916,0,#22914,-1,"Promise")
-hasLocation(#22916,#21638)
-enclosing_stmt(#22916,#22908)
-expr_containers(#22916,#22805)
-literals("Promise","Promise",#22916)
+literals("Unpacked","Unpacked",#22914)
+typebind(#22914,#22810)
+#22915=*
+typeexprs(#22915,14,#22912,0,"Promise")
+#22916=@"loc,{#10000},82,22,82,36"
+locations_default(#22916,#10000,82,22,82,36)
+hasLocation(#22915,#22916)
+enclosing_stmt(#22915,#22909)
+expr_containers(#22915,#22805)
#22917=*
-typeexprs(#22917,2,#22914,0,"string")
-hasLocation(#22917,#21642)
-enclosing_stmt(#22917,#22908)
+typeexprs(#22917,0,#22915,-1,"Promise")
+hasLocation(#22917,#21638)
+enclosing_stmt(#22917,#22909)
expr_containers(#22917,#22805)
-literals("string","string",#22917)
+literals("Promise","Promise",#22917)
#22918=*
-stmts(#22918,35,#22805,5,"type T4 ... ng>[]>;")
-#22919=@"loc,{#10000},83,3,83,40"
-locations_default(#22919,#10000,83,3,83,40)
-hasLocation(#22918,#22919)
-stmt_containers(#22918,#22805)
-#22920=*
-typeexprs(#22920,1,#22918,0,"T4")
-hasLocation(#22920,#21652)
-enclosing_stmt(#22920,#22918)
-expr_containers(#22920,#22805)
-literals("T4","T4",#22920)
-typedecl(#22920,#22814)
+typeexprs(#22918,2,#22915,0,"string")
+hasLocation(#22918,#21642)
+enclosing_stmt(#22918,#22909)
+expr_containers(#22918,#22805)
+literals("string","string",#22918)
+#22919=*
+stmts(#22919,35,#22805,5,"type T4 ... ng>[]>;")
+#22920=@"loc,{#10000},83,3,83,40"
+locations_default(#22920,#10000,83,3,83,40)
+hasLocation(#22919,#22920)
+stmt_containers(#22919,#22805)
#22921=*
-typeexprs(#22921,14,#22918,1,"Unpacke ... ing>[]>")
-#22922=@"loc,{#10000},83,13,83,39"
-locations_default(#22922,#10000,83,13,83,39)
-hasLocation(#22921,#22922)
-enclosing_stmt(#22921,#22918)
+typeexprs(#22921,1,#22919,0,"T4")
+hasLocation(#22921,#21652)
+enclosing_stmt(#22921,#22919)
expr_containers(#22921,#22805)
-#22923=*
-typeexprs(#22923,0,#22921,-1,"Unpacked")
-hasLocation(#22923,#21656)
-enclosing_stmt(#22923,#22918)
-expr_containers(#22923,#22805)
-literals("Unpacked","Unpacked",#22923)
-typebind(#22923,#22809)
+literals("T4","T4",#22921)
+typedecl(#22921,#22815)
+#22922=*
+typeexprs(#22922,14,#22919,1,"Unpacke ... ing>[]>")
+#22923=@"loc,{#10000},83,13,83,39"
+locations_default(#22923,#10000,83,13,83,39)
+hasLocation(#22922,#22923)
+enclosing_stmt(#22922,#22919)
+expr_containers(#22922,#22805)
#22924=*
-typeexprs(#22924,6,#22921,0,"Promise[]")
-#22925=@"loc,{#10000},83,22,83,38"
-locations_default(#22925,#10000,83,22,83,38)
-hasLocation(#22924,#22925)
-enclosing_stmt(#22924,#22918)
+typeexprs(#22924,0,#22922,-1,"Unpacked")
+hasLocation(#22924,#21656)
+enclosing_stmt(#22924,#22919)
expr_containers(#22924,#22805)
-#22926=*
-typeexprs(#22926,14,#22924,0,"Promise")
-#22927=@"loc,{#10000},83,22,83,36"
-locations_default(#22927,#10000,83,22,83,36)
-hasLocation(#22926,#22927)
-enclosing_stmt(#22926,#22918)
-expr_containers(#22926,#22805)
-#22928=*
-typeexprs(#22928,0,#22926,-1,"Promise")
-hasLocation(#22928,#21660)
-enclosing_stmt(#22928,#22918)
-expr_containers(#22928,#22805)
-literals("Promise","Promise",#22928)
+literals("Unpacked","Unpacked",#22924)
+typebind(#22924,#22810)
+#22925=*
+typeexprs(#22925,6,#22922,0,"Promise[]")
+#22926=@"loc,{#10000},83,22,83,38"
+locations_default(#22926,#10000,83,22,83,38)
+hasLocation(#22925,#22926)
+enclosing_stmt(#22925,#22919)
+expr_containers(#22925,#22805)
+#22927=*
+typeexprs(#22927,14,#22925,0,"Promise")
+#22928=@"loc,{#10000},83,22,83,36"
+locations_default(#22928,#10000,83,22,83,36)
+hasLocation(#22927,#22928)
+enclosing_stmt(#22927,#22919)
+expr_containers(#22927,#22805)
#22929=*
-typeexprs(#22929,2,#22926,0,"string")
-hasLocation(#22929,#21664)
-enclosing_stmt(#22929,#22918)
+typeexprs(#22929,0,#22927,-1,"Promise")
+hasLocation(#22929,#21660)
+enclosing_stmt(#22929,#22919)
expr_containers(#22929,#22805)
-literals("string","string",#22929)
+literals("Promise","Promise",#22929)
#22930=*
-stmts(#22930,35,#22805,6,"type T5 ... g>[]>>;")
-#22931=@"loc,{#10000},84,3,84,50"
-locations_default(#22931,#10000,84,3,84,50)
-hasLocation(#22930,#22931)
-stmt_containers(#22930,#22805)
-#22932=*
-typeexprs(#22932,1,#22930,0,"T5")
-hasLocation(#22932,#21678)
-enclosing_stmt(#22932,#22930)
-expr_containers(#22932,#22805)
-literals("T5","T5",#22932)
-typedecl(#22932,#22815)
+typeexprs(#22930,2,#22927,0,"string")
+hasLocation(#22930,#21664)
+enclosing_stmt(#22930,#22919)
+expr_containers(#22930,#22805)
+literals("string","string",#22930)
+#22931=*
+stmts(#22931,35,#22805,6,"type T5 ... g>[]>>;")
+#22932=@"loc,{#10000},84,3,84,50"
+locations_default(#22932,#10000,84,3,84,50)
+hasLocation(#22931,#22932)
+stmt_containers(#22931,#22805)
#22933=*
-typeexprs(#22933,14,#22930,1,"Unpacke ... ng>[]>>")
-#22934=@"loc,{#10000},84,13,84,49"
-locations_default(#22934,#10000,84,13,84,49)
-hasLocation(#22933,#22934)
-enclosing_stmt(#22933,#22930)
+typeexprs(#22933,1,#22931,0,"T5")
+hasLocation(#22933,#21678)
+enclosing_stmt(#22933,#22931)
expr_containers(#22933,#22805)
-#22935=*
-typeexprs(#22935,0,#22933,-1,"Unpacked")
-hasLocation(#22935,#21682)
-enclosing_stmt(#22935,#22930)
-expr_containers(#22935,#22805)
-literals("Unpacked","Unpacked",#22935)
-typebind(#22935,#22809)
+literals("T5","T5",#22933)
+typedecl(#22933,#22816)
+#22934=*
+typeexprs(#22934,14,#22931,1,"Unpacke ... ng>[]>>")
+#22935=@"loc,{#10000},84,13,84,49"
+locations_default(#22935,#10000,84,13,84,49)
+hasLocation(#22934,#22935)
+enclosing_stmt(#22934,#22931)
+expr_containers(#22934,#22805)
#22936=*
-typeexprs(#22936,14,#22933,0,"Unpacke ... ing>[]>")
-#22937=@"loc,{#10000},84,22,84,48"
-locations_default(#22937,#10000,84,22,84,48)
-hasLocation(#22936,#22937)
-enclosing_stmt(#22936,#22930)
+typeexprs(#22936,0,#22934,-1,"Unpacked")
+hasLocation(#22936,#21682)
+enclosing_stmt(#22936,#22931)
expr_containers(#22936,#22805)
-#22938=*
-typeexprs(#22938,0,#22936,-1,"Unpacked")
-hasLocation(#22938,#21686)
-enclosing_stmt(#22938,#22930)
-expr_containers(#22938,#22805)
-literals("Unpacked","Unpacked",#22938)
-typebind(#22938,#22809)
+literals("Unpacked","Unpacked",#22936)
+typebind(#22936,#22810)
+#22937=*
+typeexprs(#22937,14,#22934,0,"Unpacke ... ing>[]>")
+#22938=@"loc,{#10000},84,22,84,48"
+locations_default(#22938,#10000,84,22,84,48)
+hasLocation(#22937,#22938)
+enclosing_stmt(#22937,#22931)
+expr_containers(#22937,#22805)
#22939=*
-typeexprs(#22939,6,#22936,0,"Promise[]")
-#22940=@"loc,{#10000},84,31,84,47"
-locations_default(#22940,#10000,84,31,84,47)
-hasLocation(#22939,#22940)
-enclosing_stmt(#22939,#22930)
+typeexprs(#22939,0,#22937,-1,"Unpacked")
+hasLocation(#22939,#21686)
+enclosing_stmt(#22939,#22931)
expr_containers(#22939,#22805)
-#22941=*
-typeexprs(#22941,14,#22939,0,"Promise")
-#22942=@"loc,{#10000},84,31,84,45"
-locations_default(#22942,#10000,84,31,84,45)
-hasLocation(#22941,#22942)
-enclosing_stmt(#22941,#22930)
-expr_containers(#22941,#22805)
-#22943=*
-typeexprs(#22943,0,#22941,-1,"Promise")
-hasLocation(#22943,#21690)
-enclosing_stmt(#22943,#22930)
-expr_containers(#22943,#22805)
-literals("Promise","Promise",#22943)
+literals("Unpacked","Unpacked",#22939)
+typebind(#22939,#22810)
+#22940=*
+typeexprs(#22940,6,#22937,0,"Promise[]")
+#22941=@"loc,{#10000},84,31,84,47"
+locations_default(#22941,#10000,84,31,84,47)
+hasLocation(#22940,#22941)
+enclosing_stmt(#22940,#22931)
+expr_containers(#22940,#22805)
+#22942=*
+typeexprs(#22942,14,#22940,0,"Promise")
+#22943=@"loc,{#10000},84,31,84,45"
+locations_default(#22943,#10000,84,31,84,45)
+hasLocation(#22942,#22943)
+enclosing_stmt(#22942,#22931)
+expr_containers(#22942,#22805)
#22944=*
-typeexprs(#22944,2,#22941,0,"string")
-hasLocation(#22944,#21694)
-enclosing_stmt(#22944,#22930)
+typeexprs(#22944,0,#22942,-1,"Promise")
+hasLocation(#22944,#21690)
+enclosing_stmt(#22944,#22931)
expr_containers(#22944,#22805)
-literals("string","string",#22944)
+literals("Promise","Promise",#22944)
#22945=*
-stmts(#22945,35,#22805,7,"type Fo ... never;")
-#22946=@"loc,{#10000},86,3,86,65"
-locations_default(#22946,#10000,86,3,86,65)
-hasLocation(#22945,#22946)
-stmt_containers(#22945,#22805)
-#22947=*
-typeexprs(#22947,1,#22945,0,"Foo")
-hasLocation(#22947,#21710)
-enclosing_stmt(#22947,#22945)
-expr_containers(#22947,#22805)
-literals("Foo","Foo",#22947)
-typedecl(#22947,#22816)
+typeexprs(#22945,2,#22942,0,"string")
+hasLocation(#22945,#21694)
+enclosing_stmt(#22945,#22931)
+expr_containers(#22945,#22805)
+literals("string","string",#22945)
+#22946=*
+stmts(#22946,35,#22805,7,"type Fo ... never;")
+#22947=@"loc,{#10000},86,3,86,65"
+locations_default(#22947,#10000,86,3,86,65)
+hasLocation(#22946,#22947)
+stmt_containers(#22946,#22805)
#22948=*
-scopes(#22948,12)
-scopenodes(#22945,#22948)
-scopenesting(#22948,#22808)
-#22949=@"local_type_name;{T};{#22948}"
-local_type_names(#22949,"T",#22948)
-#22950=*
-typeexprs(#22950,22,#22945,2,"T")
-hasLocation(#22950,#21714)
-enclosing_stmt(#22950,#22945)
-expr_containers(#22950,#22805)
+typeexprs(#22948,1,#22946,0,"Foo")
+hasLocation(#22948,#21710)
+enclosing_stmt(#22948,#22946)
+expr_containers(#22948,#22805)
+literals("Foo","Foo",#22948)
+typedecl(#22948,#22817)
+#22949=*
+scopes(#22949,12)
+scopenodes(#22946,#22949)
+scopenesting(#22949,#22808)
+#22950=@"local_type_name;{T};{#22949}"
+local_type_names(#22950,"T",#22949)
#22951=*
-typeexprs(#22951,1,#22950,0,"T")
+typeexprs(#22951,22,#22946,2,"T")
hasLocation(#22951,#21714)
-enclosing_stmt(#22951,#22945)
+enclosing_stmt(#22951,#22946)
expr_containers(#22951,#22805)
-literals("T","T",#22951)
-typedecl(#22951,#22949)
#22952=*
-typeexprs(#22952,28,#22945,1,"T exten ... : never")
-#22953=@"loc,{#10000},86,17,86,64"
-locations_default(#22953,#10000,86,17,86,64)
-hasLocation(#22952,#22953)
-enclosing_stmt(#22952,#22945)
+typeexprs(#22952,1,#22951,0,"T")
+hasLocation(#22952,#21714)
+enclosing_stmt(#22952,#22946)
expr_containers(#22952,#22805)
-#22954=*
-typeexprs(#22954,0,#22952,0,"T")
-hasLocation(#22954,#21720)
-enclosing_stmt(#22954,#22945)
-expr_containers(#22954,#22805)
-literals("T","T",#22954)
-typebind(#22954,#22949)
+literals("T","T",#22952)
+typedecl(#22952,#22950)
+#22953=*
+typeexprs(#22953,28,#22946,1,"T exten ... : never")
+#22954=@"loc,{#10000},86,17,86,64"
+locations_default(#22954,#10000,86,17,86,64)
+hasLocation(#22953,#22954)
+enclosing_stmt(#22953,#22946)
+expr_containers(#22953,#22805)
#22955=*
-typeexprs(#22955,21,#22952,1,"{ a: in ... fer U }")
-#22956=@"loc,{#10000},86,27,86,52"
-locations_default(#22956,#10000,86,27,86,52)
-hasLocation(#22955,#22956)
-enclosing_stmt(#22955,#22945)
+typeexprs(#22955,0,#22953,0,"T")
+hasLocation(#22955,#21720)
+enclosing_stmt(#22955,#22946)
expr_containers(#22955,#22805)
-#22957=*
-properties(#22957,#22955,0,8,"a: infer U,")
-#22958=@"loc,{#10000},86,29,86,39"
-locations_default(#22958,#10000,86,29,86,39)
-hasLocation(#22957,#22958)
-#22959=*
-exprs(#22959,0,#22957,0,"a")
-hasLocation(#22959,#21726)
-enclosing_stmt(#22959,#22945)
-expr_containers(#22959,#22805)
-literals("a","a",#22959)
-is_abstract_member(#22957)
+literals("T","T",#22955)
+typebind(#22955,#22950)
+#22956=*
+typeexprs(#22956,21,#22953,1,"{ a: in ... fer U }")
+#22957=@"loc,{#10000},86,27,86,52"
+locations_default(#22957,#10000,86,27,86,52)
+hasLocation(#22956,#22957)
+enclosing_stmt(#22956,#22946)
+expr_containers(#22956,#22805)
+#22958=*
+properties(#22958,#22956,0,8,"a: infer U,")
+#22959=@"loc,{#10000},86,29,86,39"
+locations_default(#22959,#10000,86,29,86,39)
+hasLocation(#22958,#22959)
#22960=*
-typeexprs(#22960,29,#22957,2,"infer U")
-#22961=@"loc,{#10000},86,32,86,38"
-locations_default(#22961,#10000,86,32,86,38)
-hasLocation(#22960,#22961)
-enclosing_stmt(#22960,#22945)
+exprs(#22960,0,#22958,0,"a")
+hasLocation(#22960,#21726)
+enclosing_stmt(#22960,#22946)
expr_containers(#22960,#22805)
-#22962=*
-typeexprs(#22962,22,#22960,0,"U")
-hasLocation(#22962,#21732)
-enclosing_stmt(#22962,#22945)
-expr_containers(#22962,#22805)
+literals("a","a",#22960)
+is_abstract_member(#22958)
+#22961=*
+typeexprs(#22961,29,#22958,2,"infer U")
+#22962=@"loc,{#10000},86,32,86,38"
+locations_default(#22962,#10000,86,32,86,38)
+hasLocation(#22961,#22962)
+enclosing_stmt(#22961,#22946)
+expr_containers(#22961,#22805)
#22963=*
-typeexprs(#22963,1,#22962,0,"U")
+typeexprs(#22963,22,#22961,0,"U")
hasLocation(#22963,#21732)
-enclosing_stmt(#22963,#22945)
+enclosing_stmt(#22963,#22946)
expr_containers(#22963,#22805)
-literals("U","U",#22963)
#22964=*
-properties(#22964,#22955,1,8,"b: infer U")
-#22965=@"loc,{#10000},86,41,86,50"
-locations_default(#22965,#10000,86,41,86,50)
-hasLocation(#22964,#22965)
-#22966=*
-exprs(#22966,0,#22964,0,"b")
-hasLocation(#22966,#21736)
-enclosing_stmt(#22966,#22945)
-expr_containers(#22966,#22805)
-literals("b","b",#22966)
-is_abstract_member(#22964)
+typeexprs(#22964,1,#22963,0,"U")
+hasLocation(#22964,#21732)
+enclosing_stmt(#22964,#22946)
+expr_containers(#22964,#22805)
+literals("U","U",#22964)
+#22965=*
+properties(#22965,#22956,1,8,"b: infer U")
+#22966=@"loc,{#10000},86,41,86,50"
+locations_default(#22966,#10000,86,41,86,50)
+hasLocation(#22965,#22966)
#22967=*
-typeexprs(#22967,29,#22964,2,"infer U")
-#22968=@"loc,{#10000},86,44,86,50"
-locations_default(#22968,#10000,86,44,86,50)
-hasLocation(#22967,#22968)
-enclosing_stmt(#22967,#22945)
+exprs(#22967,0,#22965,0,"b")
+hasLocation(#22967,#21736)
+enclosing_stmt(#22967,#22946)
expr_containers(#22967,#22805)
-#22969=*
-typeexprs(#22969,22,#22967,0,"U")
-hasLocation(#22969,#21742)
-enclosing_stmt(#22969,#22945)
-expr_containers(#22969,#22805)
+literals("b","b",#22967)
+is_abstract_member(#22965)
+#22968=*
+typeexprs(#22968,29,#22965,2,"infer U")
+#22969=@"loc,{#10000},86,44,86,50"
+locations_default(#22969,#10000,86,44,86,50)
+hasLocation(#22968,#22969)
+enclosing_stmt(#22968,#22946)
+expr_containers(#22968,#22805)
#22970=*
-typeexprs(#22970,1,#22969,0,"U")
+typeexprs(#22970,22,#22968,0,"U")
hasLocation(#22970,#21742)
-enclosing_stmt(#22970,#22945)
+enclosing_stmt(#22970,#22946)
expr_containers(#22970,#22805)
-literals("U","U",#22970)
#22971=*
-typeexprs(#22971,0,#22952,2,"U")
-hasLocation(#22971,#21748)
-enclosing_stmt(#22971,#22945)
+typeexprs(#22971,1,#22970,0,"U")
+hasLocation(#22971,#21742)
+enclosing_stmt(#22971,#22946)
expr_containers(#22971,#22805)
literals("U","U",#22971)
#22972=*
-typeexprs(#22972,2,#22952,3,"never")
-hasLocation(#22972,#21752)
-enclosing_stmt(#22972,#22945)
+typeexprs(#22972,0,#22953,2,"U")
+hasLocation(#22972,#21748)
+enclosing_stmt(#22972,#22946)
expr_containers(#22972,#22805)
-literals("never","never",#22972)
+literals("U","U",#22972)
#22973=*
-stmts(#22973,35,#22805,8,"type T1 ... ing }>;")
-#22974=@"loc,{#10000},87,3,87,43"
-locations_default(#22974,#10000,87,3,87,43)
-hasLocation(#22973,#22974)
-stmt_containers(#22973,#22805)
-#22975=*
-typeexprs(#22975,1,#22973,0,"T10")
-hasLocation(#22975,#21758)
-enclosing_stmt(#22975,#22973)
-expr_containers(#22975,#22805)
-literals("T10","T10",#22975)
-typedecl(#22975,#22817)
+typeexprs(#22973,2,#22953,3,"never")
+hasLocation(#22973,#21752)
+enclosing_stmt(#22973,#22946)
+expr_containers(#22973,#22805)
+literals("never","never",#22973)
+#22974=*
+stmts(#22974,35,#22805,8,"type T1 ... ing }>;")
+#22975=@"loc,{#10000},87,3,87,43"
+locations_default(#22975,#10000,87,3,87,43)
+hasLocation(#22974,#22975)
+stmt_containers(#22974,#22805)
#22976=*
-typeexprs(#22976,14,#22973,1,"Foo<{ a ... ring }>")
-#22977=@"loc,{#10000},87,14,87,42"
-locations_default(#22977,#10000,87,14,87,42)
-hasLocation(#22976,#22977)
-enclosing_stmt(#22976,#22973)
+typeexprs(#22976,1,#22974,0,"T10")
+hasLocation(#22976,#21758)
+enclosing_stmt(#22976,#22974)
expr_containers(#22976,#22805)
-#22978=*
-typeexprs(#22978,0,#22976,-1,"Foo")
-hasLocation(#22978,#21762)
-enclosing_stmt(#22978,#22973)
-expr_containers(#22978,#22805)
-literals("Foo","Foo",#22978)
-typebind(#22978,#22816)
+literals("T10","T10",#22976)
+typedecl(#22976,#22818)
+#22977=*
+typeexprs(#22977,14,#22974,1,"Foo<{ a ... ring }>")
+#22978=@"loc,{#10000},87,14,87,42"
+locations_default(#22978,#10000,87,14,87,42)
+hasLocation(#22977,#22978)
+enclosing_stmt(#22977,#22974)
+expr_containers(#22977,#22805)
#22979=*
-typeexprs(#22979,21,#22976,0,"{ a: st ... tring }")
-#22980=@"loc,{#10000},87,18,87,41"
-locations_default(#22980,#10000,87,18,87,41)
-hasLocation(#22979,#22980)
-enclosing_stmt(#22979,#22973)
+typeexprs(#22979,0,#22977,-1,"Foo")
+hasLocation(#22979,#21762)
+enclosing_stmt(#22979,#22974)
expr_containers(#22979,#22805)
-#22981=*
-properties(#22981,#22979,0,8,"a: string,")
-#22982=@"loc,{#10000},87,20,87,29"
-locations_default(#22982,#10000,87,20,87,29)
-hasLocation(#22981,#22982)
-#22983=*
-exprs(#22983,0,#22981,0,"a")
-hasLocation(#22983,#21768)
-enclosing_stmt(#22983,#22973)
-expr_containers(#22983,#22805)
-literals("a","a",#22983)
-is_abstract_member(#22981)
+literals("Foo","Foo",#22979)
+typebind(#22979,#22817)
+#22980=*
+typeexprs(#22980,21,#22977,0,"{ a: st ... tring }")
+#22981=@"loc,{#10000},87,18,87,41"
+locations_default(#22981,#10000,87,18,87,41)
+hasLocation(#22980,#22981)
+enclosing_stmt(#22980,#22974)
+expr_containers(#22980,#22805)
+#22982=*
+properties(#22982,#22980,0,8,"a: string,")
+#22983=@"loc,{#10000},87,20,87,29"
+locations_default(#22983,#10000,87,20,87,29)
+hasLocation(#22982,#22983)
#22984=*
-typeexprs(#22984,2,#22981,2,"string")
-hasLocation(#22984,#21772)
-enclosing_stmt(#22984,#22973)
+exprs(#22984,0,#22982,0,"a")
+hasLocation(#22984,#21768)
+enclosing_stmt(#22984,#22974)
expr_containers(#22984,#22805)
-literals("string","string",#22984)
+literals("a","a",#22984)
+is_abstract_member(#22982)
#22985=*
-properties(#22985,#22979,1,8,"b: string")
-#22986=@"loc,{#10000},87,31,87,39"
-locations_default(#22986,#10000,87,31,87,39)
-hasLocation(#22985,#22986)
-#22987=*
-exprs(#22987,0,#22985,0,"b")
-hasLocation(#22987,#21776)
-enclosing_stmt(#22987,#22973)
-expr_containers(#22987,#22805)
-literals("b","b",#22987)
-is_abstract_member(#22985)
+typeexprs(#22985,2,#22982,2,"string")
+hasLocation(#22985,#21772)
+enclosing_stmt(#22985,#22974)
+expr_containers(#22985,#22805)
+literals("string","string",#22985)
+#22986=*
+properties(#22986,#22980,1,8,"b: string")
+#22987=@"loc,{#10000},87,31,87,39"
+locations_default(#22987,#10000,87,31,87,39)
+hasLocation(#22986,#22987)
#22988=*
-typeexprs(#22988,2,#22985,2,"string")
-hasLocation(#22988,#21780)
-enclosing_stmt(#22988,#22973)
+exprs(#22988,0,#22986,0,"b")
+hasLocation(#22988,#21776)
+enclosing_stmt(#22988,#22974)
expr_containers(#22988,#22805)
-literals("string","string",#22988)
+literals("b","b",#22988)
+is_abstract_member(#22986)
#22989=*
-stmts(#22989,35,#22805,9,"type T1 ... ber }>;")
-#22990=@"loc,{#10000},88,3,88,43"
-locations_default(#22990,#10000,88,3,88,43)
-hasLocation(#22989,#22990)
-stmt_containers(#22989,#22805)
-#22991=*
-typeexprs(#22991,1,#22989,0,"T11")
-hasLocation(#22991,#21790)
-enclosing_stmt(#22991,#22989)
-expr_containers(#22991,#22805)
-literals("T11","T11",#22991)
-typedecl(#22991,#22818)
+typeexprs(#22989,2,#22986,2,"string")
+hasLocation(#22989,#21780)
+enclosing_stmt(#22989,#22974)
+expr_containers(#22989,#22805)
+literals("string","string",#22989)
+#22990=*
+stmts(#22990,35,#22805,9,"type T1 ... ber }>;")
+#22991=@"loc,{#10000},88,3,88,43"
+locations_default(#22991,#10000,88,3,88,43)
+hasLocation(#22990,#22991)
+stmt_containers(#22990,#22805)
#22992=*
-typeexprs(#22992,14,#22989,1,"Foo<{ a ... mber }>")
-#22993=@"loc,{#10000},88,14,88,42"
-locations_default(#22993,#10000,88,14,88,42)
-hasLocation(#22992,#22993)
-enclosing_stmt(#22992,#22989)
+typeexprs(#22992,1,#22990,0,"T11")
+hasLocation(#22992,#21790)
+enclosing_stmt(#22992,#22990)
expr_containers(#22992,#22805)
-#22994=*
-typeexprs(#22994,0,#22992,-1,"Foo")
-hasLocation(#22994,#21794)
-enclosing_stmt(#22994,#22989)
-expr_containers(#22994,#22805)
-literals("Foo","Foo",#22994)
-typebind(#22994,#22816)
+literals("T11","T11",#22992)
+typedecl(#22992,#22819)
+#22993=*
+typeexprs(#22993,14,#22990,1,"Foo<{ a ... mber }>")
+#22994=@"loc,{#10000},88,14,88,42"
+locations_default(#22994,#10000,88,14,88,42)
+hasLocation(#22993,#22994)
+enclosing_stmt(#22993,#22990)
+expr_containers(#22993,#22805)
#22995=*
-typeexprs(#22995,21,#22992,0,"{ a: st ... umber }")
-#22996=@"loc,{#10000},88,18,88,41"
-locations_default(#22996,#10000,88,18,88,41)
-hasLocation(#22995,#22996)
-enclosing_stmt(#22995,#22989)
+typeexprs(#22995,0,#22993,-1,"Foo")
+hasLocation(#22995,#21794)
+enclosing_stmt(#22995,#22990)
expr_containers(#22995,#22805)
-#22997=*
-properties(#22997,#22995,0,8,"a: string,")
-#22998=@"loc,{#10000},88,20,88,29"
-locations_default(#22998,#10000,88,20,88,29)
-hasLocation(#22997,#22998)
-#22999=*
-exprs(#22999,0,#22997,0,"a")
-hasLocation(#22999,#21800)
-enclosing_stmt(#22999,#22989)
-expr_containers(#22999,#22805)
-literals("a","a",#22999)
-is_abstract_member(#22997)
+literals("Foo","Foo",#22995)
+typebind(#22995,#22817)
+#22996=*
+typeexprs(#22996,21,#22993,0,"{ a: st ... umber }")
+#22997=@"loc,{#10000},88,18,88,41"
+locations_default(#22997,#10000,88,18,88,41)
+hasLocation(#22996,#22997)
+enclosing_stmt(#22996,#22990)
+expr_containers(#22996,#22805)
+#22998=*
+properties(#22998,#22996,0,8,"a: string,")
+#22999=@"loc,{#10000},88,20,88,29"
+locations_default(#22999,#10000,88,20,88,29)
+hasLocation(#22998,#22999)
#23000=*
-typeexprs(#23000,2,#22997,2,"string")
-hasLocation(#23000,#21804)
-enclosing_stmt(#23000,#22989)
+exprs(#23000,0,#22998,0,"a")
+hasLocation(#23000,#21800)
+enclosing_stmt(#23000,#22990)
expr_containers(#23000,#22805)
-literals("string","string",#23000)
+literals("a","a",#23000)
+is_abstract_member(#22998)
#23001=*
-properties(#23001,#22995,1,8,"b: number")
-#23002=@"loc,{#10000},88,31,88,39"
-locations_default(#23002,#10000,88,31,88,39)
-hasLocation(#23001,#23002)
-#23003=*
-exprs(#23003,0,#23001,0,"b")
-hasLocation(#23003,#21808)
-enclosing_stmt(#23003,#22989)
-expr_containers(#23003,#22805)
-literals("b","b",#23003)
-is_abstract_member(#23001)
+typeexprs(#23001,2,#22998,2,"string")
+hasLocation(#23001,#21804)
+enclosing_stmt(#23001,#22990)
+expr_containers(#23001,#22805)
+literals("string","string",#23001)
+#23002=*
+properties(#23002,#22996,1,8,"b: number")
+#23003=@"loc,{#10000},88,31,88,39"
+locations_default(#23003,#10000,88,31,88,39)
+hasLocation(#23002,#23003)
#23004=*
-typeexprs(#23004,2,#23001,2,"number")
-hasLocation(#23004,#21812)
-enclosing_stmt(#23004,#22989)
+exprs(#23004,0,#23002,0,"b")
+hasLocation(#23004,#21808)
+enclosing_stmt(#23004,#22990)
expr_containers(#23004,#22805)
-literals("number","number",#23004)
+literals("b","b",#23004)
+is_abstract_member(#23002)
#23005=*
-stmts(#23005,35,#22805,10,"type Ba ... never;")
-#23006=@"loc,{#10000},90,3,90,91"
-locations_default(#23006,#10000,90,3,90,91)
-hasLocation(#23005,#23006)
-stmt_containers(#23005,#22805)
-#23007=*
-typeexprs(#23007,1,#23005,0,"Bar")
-hasLocation(#23007,#21822)
-enclosing_stmt(#23007,#23005)
-expr_containers(#23007,#22805)
-literals("Bar","Bar",#23007)
-typedecl(#23007,#22819)
+typeexprs(#23005,2,#23002,2,"number")
+hasLocation(#23005,#21812)
+enclosing_stmt(#23005,#22990)
+expr_containers(#23005,#22805)
+literals("number","number",#23005)
+#23006=*
+stmts(#23006,35,#22805,10,"type Ba ... never;")
+#23007=@"loc,{#10000},90,3,90,91"
+locations_default(#23007,#10000,90,3,90,91)
+hasLocation(#23006,#23007)
+stmt_containers(#23006,#22805)
#23008=*
-scopes(#23008,12)
-scopenodes(#23005,#23008)
-scopenesting(#23008,#22808)
-#23009=@"local_type_name;{T};{#23008}"
-local_type_names(#23009,"T",#23008)
-#23010=*
-typeexprs(#23010,22,#23005,2,"T")
-hasLocation(#23010,#21826)
-enclosing_stmt(#23010,#23005)
-expr_containers(#23010,#22805)
+typeexprs(#23008,1,#23006,0,"Bar")
+hasLocation(#23008,#21822)
+enclosing_stmt(#23008,#23006)
+expr_containers(#23008,#22805)
+literals("Bar","Bar",#23008)
+typedecl(#23008,#22820)
+#23009=*
+scopes(#23009,12)
+scopenodes(#23006,#23009)
+scopenesting(#23009,#22808)
+#23010=@"local_type_name;{T};{#23009}"
+local_type_names(#23010,"T",#23009)
#23011=*
-typeexprs(#23011,1,#23010,0,"T")
+typeexprs(#23011,22,#23006,2,"T")
hasLocation(#23011,#21826)
-enclosing_stmt(#23011,#23005)
+enclosing_stmt(#23011,#23006)
expr_containers(#23011,#22805)
-literals("T","T",#23011)
-typedecl(#23011,#23009)
#23012=*
-typeexprs(#23012,28,#23005,1,"T exten ... : never")
-#23013=@"loc,{#10000},90,17,90,90"
-locations_default(#23013,#10000,90,17,90,90)
-hasLocation(#23012,#23013)
-enclosing_stmt(#23012,#23005)
+typeexprs(#23012,1,#23011,0,"T")
+hasLocation(#23012,#21826)
+enclosing_stmt(#23012,#23006)
expr_containers(#23012,#22805)
-#23014=*
-typeexprs(#23014,0,#23012,0,"T")
-hasLocation(#23014,#21832)
-enclosing_stmt(#23014,#23005)
-expr_containers(#23014,#22805)
-literals("T","T",#23014)
-typebind(#23014,#23009)
+literals("T","T",#23012)
+typedecl(#23012,#23010)
+#23013=*
+typeexprs(#23013,28,#23006,1,"T exten ... : never")
+#23014=@"loc,{#10000},90,17,90,90"
+locations_default(#23014,#10000,90,17,90,90)
+hasLocation(#23013,#23014)
+enclosing_stmt(#23013,#23006)
+expr_containers(#23013,#22805)
#23015=*
-typeexprs(#23015,21,#23012,1,"{ a: (x ... void }")
-#23016=@"loc,{#10000},90,27,90,78"
-locations_default(#23016,#10000,90,27,90,78)
-hasLocation(#23015,#23016)
-enclosing_stmt(#23015,#23005)
+typeexprs(#23015,0,#23013,0,"T")
+hasLocation(#23015,#21832)
+enclosing_stmt(#23015,#23006)
expr_containers(#23015,#22805)
-#23017=*
-properties(#23017,#23015,0,8,"a: (x: ... > void,")
-#23018=@"loc,{#10000},90,29,90,52"
-locations_default(#23018,#10000,90,29,90,52)
-hasLocation(#23017,#23018)
-#23019=*
-exprs(#23019,0,#23017,0,"a")
-hasLocation(#23019,#21838)
-enclosing_stmt(#23019,#23005)
-expr_containers(#23019,#22805)
-literals("a","a",#23019)
-is_abstract_member(#23017)
+literals("T","T",#23015)
+typebind(#23015,#23010)
+#23016=*
+typeexprs(#23016,21,#23013,1,"{ a: (x ... void }")
+#23017=@"loc,{#10000},90,27,90,78"
+locations_default(#23017,#10000,90,27,90,78)
+hasLocation(#23016,#23017)
+enclosing_stmt(#23016,#23006)
+expr_containers(#23016,#22805)
+#23018=*
+properties(#23018,#23016,0,8,"a: (x: ... > void,")
+#23019=@"loc,{#10000},90,29,90,52"
+locations_default(#23019,#10000,90,29,90,52)
+hasLocation(#23018,#23019)
#23020=*
-typeexprs(#23020,23,#23017,2,"(x: infer U) => void")
-#23021=@"loc,{#10000},90,32,90,51"
-locations_default(#23021,#10000,90,32,90,51)
-hasLocation(#23020,#23021)
-enclosing_stmt(#23020,#23005)
+exprs(#23020,0,#23018,0,"a")
+hasLocation(#23020,#21838)
+enclosing_stmt(#23020,#23006)
expr_containers(#23020,#22805)
-#23022=*
-exprs(#23022,9,#23020,0,"(x: infer U) => void")
-hasLocation(#23022,#23021)
-enclosing_stmt(#23022,#23005)
-expr_containers(#23022,#22805)
+literals("a","a",#23020)
+is_abstract_member(#23018)
+#23021=*
+typeexprs(#23021,23,#23018,2,"(x: infer U) => void")
+#23022=@"loc,{#10000},90,32,90,51"
+locations_default(#23022,#10000,90,32,90,51)
+hasLocation(#23021,#23022)
+enclosing_stmt(#23021,#23006)
+expr_containers(#23021,#22805)
#23023=*
-scopes(#23023,1)
-scopenodes(#23022,#23023)
-scopenesting(#23023,#23008)
-#23024=@"var;{x};{#23023}"
-variables(#23024,"x",#23023)
-#23025=*
-exprs(#23025,78,#23022,0,"x")
-hasLocation(#23025,#21844)
-expr_containers(#23025,#23022)
-literals("x","x",#23025)
-decl(#23025,#23024)
-#23026=@"var;{arguments};{#23023}"
-variables(#23026,"arguments",#23023)
-is_arguments_object(#23026)
-#23027=*
-typeexprs(#23027,2,#23022,-3,"void")
-hasLocation(#23027,#21856)
-expr_containers(#23027,#23022)
-literals("void","void",#23027)
+exprs(#23023,9,#23021,0,"(x: infer U) => void")
+hasLocation(#23023,#23022)
+enclosing_stmt(#23023,#23006)
+expr_containers(#23023,#22805)
+#23024=*
+scopes(#23024,1)
+scopenodes(#23023,#23024)
+scopenesting(#23024,#23009)
+#23025=@"var;{x};{#23024}"
+variables(#23025,"x",#23024)
+#23026=*
+exprs(#23026,78,#23023,0,"x")
+hasLocation(#23026,#21844)
+expr_containers(#23026,#23023)
+literals("x","x",#23026)
+decl(#23026,#23025)
+#23027=@"var;{arguments};{#23024}"
+variables(#23027,"arguments",#23024)
+is_arguments_object(#23027)
#23028=*
-typeexprs(#23028,29,#23022,-6,"infer U")
-#23029=@"loc,{#10000},90,36,90,42"
-locations_default(#23029,#10000,90,36,90,42)
-hasLocation(#23028,#23029)
-expr_containers(#23028,#23022)
-#23030=*
-typeexprs(#23030,22,#23028,0,"U")
-hasLocation(#23030,#21850)
-expr_containers(#23030,#23022)
+typeexprs(#23028,2,#23023,-3,"void")
+hasLocation(#23028,#21856)
+expr_containers(#23028,#23023)
+literals("void","void",#23028)
+#23029=*
+typeexprs(#23029,29,#23023,-6,"infer U")
+#23030=@"loc,{#10000},90,36,90,42"
+locations_default(#23030,#10000,90,36,90,42)
+hasLocation(#23029,#23030)
+expr_containers(#23029,#23023)
#23031=*
-typeexprs(#23031,1,#23030,0,"U")
+typeexprs(#23031,22,#23029,0,"U")
hasLocation(#23031,#21850)
-expr_containers(#23031,#23022)
-literals("U","U",#23031)
+expr_containers(#23031,#23023)
#23032=*
-properties(#23032,#23015,1,8,"b: (x: ... => void")
-#23033=@"loc,{#10000},90,54,90,76"
-locations_default(#23033,#10000,90,54,90,76)
-hasLocation(#23032,#23033)
-#23034=*
-exprs(#23034,0,#23032,0,"b")
-hasLocation(#23034,#21860)
-enclosing_stmt(#23034,#23005)
-expr_containers(#23034,#22805)
-literals("b","b",#23034)
-is_abstract_member(#23032)
+typeexprs(#23032,1,#23031,0,"U")
+hasLocation(#23032,#21850)
+expr_containers(#23032,#23023)
+literals("U","U",#23032)
+#23033=*
+properties(#23033,#23016,1,8,"b: (x: ... => void")
+#23034=@"loc,{#10000},90,54,90,76"
+locations_default(#23034,#10000,90,54,90,76)
+hasLocation(#23033,#23034)
#23035=*
-typeexprs(#23035,23,#23032,2,"(x: infer U) => void")
-#23036=@"loc,{#10000},90,57,90,76"
-locations_default(#23036,#10000,90,57,90,76)
-hasLocation(#23035,#23036)
-enclosing_stmt(#23035,#23005)
+exprs(#23035,0,#23033,0,"b")
+hasLocation(#23035,#21860)
+enclosing_stmt(#23035,#23006)
expr_containers(#23035,#22805)
-#23037=*
-exprs(#23037,9,#23035,0,"(x: infer U) => void")
-hasLocation(#23037,#23036)
-enclosing_stmt(#23037,#23005)
-expr_containers(#23037,#22805)
+literals("b","b",#23035)
+is_abstract_member(#23033)
+#23036=*
+typeexprs(#23036,23,#23033,2,"(x: infer U) => void")
+#23037=@"loc,{#10000},90,57,90,76"
+locations_default(#23037,#10000,90,57,90,76)
+hasLocation(#23036,#23037)
+enclosing_stmt(#23036,#23006)
+expr_containers(#23036,#22805)
#23038=*
-scopes(#23038,1)
-scopenodes(#23037,#23038)
-scopenesting(#23038,#23008)
-#23039=@"var;{x};{#23038}"
-variables(#23039,"x",#23038)
-#23040=*
-exprs(#23040,78,#23037,0,"x")
-hasLocation(#23040,#21866)
-expr_containers(#23040,#23037)
-literals("x","x",#23040)
-decl(#23040,#23039)
-#23041=@"var;{arguments};{#23038}"
-variables(#23041,"arguments",#23038)
-is_arguments_object(#23041)
-#23042=*
-typeexprs(#23042,2,#23037,-3,"void")
-hasLocation(#23042,#21878)
-expr_containers(#23042,#23037)
-literals("void","void",#23042)
+exprs(#23038,9,#23036,0,"(x: infer U) => void")
+hasLocation(#23038,#23037)
+enclosing_stmt(#23038,#23006)
+expr_containers(#23038,#22805)
+#23039=*
+scopes(#23039,1)
+scopenodes(#23038,#23039)
+scopenesting(#23039,#23009)
+#23040=@"var;{x};{#23039}"
+variables(#23040,"x",#23039)
+#23041=*
+exprs(#23041,78,#23038,0,"x")
+hasLocation(#23041,#21866)
+expr_containers(#23041,#23038)
+literals("x","x",#23041)
+decl(#23041,#23040)
+#23042=@"var;{arguments};{#23039}"
+variables(#23042,"arguments",#23039)
+is_arguments_object(#23042)
#23043=*
-typeexprs(#23043,29,#23037,-6,"infer U")
-#23044=@"loc,{#10000},90,61,90,67"
-locations_default(#23044,#10000,90,61,90,67)
-hasLocation(#23043,#23044)
-expr_containers(#23043,#23037)
-#23045=*
-typeexprs(#23045,22,#23043,0,"U")
-hasLocation(#23045,#21872)
-expr_containers(#23045,#23037)
+typeexprs(#23043,2,#23038,-3,"void")
+hasLocation(#23043,#21878)
+expr_containers(#23043,#23038)
+literals("void","void",#23043)
+#23044=*
+typeexprs(#23044,29,#23038,-6,"infer U")
+#23045=@"loc,{#10000},90,61,90,67"
+locations_default(#23045,#10000,90,61,90,67)
+hasLocation(#23044,#23045)
+expr_containers(#23044,#23038)
#23046=*
-typeexprs(#23046,1,#23045,0,"U")
+typeexprs(#23046,22,#23044,0,"U")
hasLocation(#23046,#21872)
-expr_containers(#23046,#23037)
-literals("U","U",#23046)
+expr_containers(#23046,#23038)
#23047=*
-typeexprs(#23047,0,#23012,2,"U")
-hasLocation(#23047,#21884)
-enclosing_stmt(#23047,#23005)
-expr_containers(#23047,#22805)
+typeexprs(#23047,1,#23046,0,"U")
+hasLocation(#23047,#21872)
+expr_containers(#23047,#23038)
literals("U","U",#23047)
#23048=*
-typeexprs(#23048,2,#23012,3,"never")
-hasLocation(#23048,#21888)
-enclosing_stmt(#23048,#23005)
+typeexprs(#23048,0,#23013,2,"U")
+hasLocation(#23048,#21884)
+enclosing_stmt(#23048,#23006)
expr_containers(#23048,#22805)
-literals("never","never",#23048)
+literals("U","U",#23048)
#23049=*
-stmts(#23049,35,#22805,11,"type T2 ... oid }>;")
-#23050=@"loc,{#10000},91,3,91,69"
-locations_default(#23050,#10000,91,3,91,69)
-hasLocation(#23049,#23050)
-stmt_containers(#23049,#22805)
-#23051=*
-typeexprs(#23051,1,#23049,0,"T20")
-hasLocation(#23051,#21894)
-enclosing_stmt(#23051,#23049)
-expr_containers(#23051,#22805)
-literals("T20","T20",#23051)
-typedecl(#23051,#22820)
+typeexprs(#23049,2,#23013,3,"never")
+hasLocation(#23049,#21888)
+enclosing_stmt(#23049,#23006)
+expr_containers(#23049,#22805)
+literals("never","never",#23049)
+#23050=*
+stmts(#23050,35,#22805,11,"type T2 ... oid }>;")
+#23051=@"loc,{#10000},91,3,91,69"
+locations_default(#23051,#10000,91,3,91,69)
+hasLocation(#23050,#23051)
+stmt_containers(#23050,#22805)
#23052=*
-typeexprs(#23052,14,#23049,1,"Bar<{ a ... void }>")
-#23053=@"loc,{#10000},91,14,91,68"
-locations_default(#23053,#10000,91,14,91,68)
-hasLocation(#23052,#23053)
-enclosing_stmt(#23052,#23049)
+typeexprs(#23052,1,#23050,0,"T20")
+hasLocation(#23052,#21894)
+enclosing_stmt(#23052,#23050)
expr_containers(#23052,#22805)
-#23054=*
-typeexprs(#23054,0,#23052,-1,"Bar")
-hasLocation(#23054,#21898)
-enclosing_stmt(#23054,#23049)
-expr_containers(#23054,#22805)
-literals("Bar","Bar",#23054)
-typebind(#23054,#22819)
+literals("T20","T20",#23052)
+typedecl(#23052,#22821)
+#23053=*
+typeexprs(#23053,14,#23050,1,"Bar<{ a ... void }>")
+#23054=@"loc,{#10000},91,14,91,68"
+locations_default(#23054,#10000,91,14,91,68)
+hasLocation(#23053,#23054)
+enclosing_stmt(#23053,#23050)
+expr_containers(#23053,#22805)
#23055=*
-typeexprs(#23055,21,#23052,0,"{ a: (x ... void }")
-#23056=@"loc,{#10000},91,18,91,67"
-locations_default(#23056,#10000,91,18,91,67)
-hasLocation(#23055,#23056)
-enclosing_stmt(#23055,#23049)
+typeexprs(#23055,0,#23053,-1,"Bar")
+hasLocation(#23055,#21898)
+enclosing_stmt(#23055,#23050)
expr_containers(#23055,#22805)
-#23057=*
-properties(#23057,#23055,0,8,"a: (x: ... > void,")
-#23058=@"loc,{#10000},91,20,91,42"
-locations_default(#23058,#10000,91,20,91,42)
-hasLocation(#23057,#23058)
-#23059=*
-exprs(#23059,0,#23057,0,"a")
-hasLocation(#23059,#21904)
-enclosing_stmt(#23059,#23049)
-expr_containers(#23059,#22805)
-literals("a","a",#23059)
-is_abstract_member(#23057)
+literals("Bar","Bar",#23055)
+typebind(#23055,#22820)
+#23056=*
+typeexprs(#23056,21,#23053,0,"{ a: (x ... void }")
+#23057=@"loc,{#10000},91,18,91,67"
+locations_default(#23057,#10000,91,18,91,67)
+hasLocation(#23056,#23057)
+enclosing_stmt(#23056,#23050)
+expr_containers(#23056,#22805)
+#23058=*
+properties(#23058,#23056,0,8,"a: (x: ... > void,")
+#23059=@"loc,{#10000},91,20,91,42"
+locations_default(#23059,#10000,91,20,91,42)
+hasLocation(#23058,#23059)
#23060=*
-typeexprs(#23060,23,#23057,2,"(x: string) => void")
-#23061=@"loc,{#10000},91,23,91,41"
-locations_default(#23061,#10000,91,23,91,41)
-hasLocation(#23060,#23061)
-enclosing_stmt(#23060,#23049)
+exprs(#23060,0,#23058,0,"a")
+hasLocation(#23060,#21904)
+enclosing_stmt(#23060,#23050)
expr_containers(#23060,#22805)
-#23062=*
-exprs(#23062,9,#23060,0,"(x: string) => void")
-hasLocation(#23062,#23061)
-enclosing_stmt(#23062,#23049)
-expr_containers(#23062,#22805)
+literals("a","a",#23060)
+is_abstract_member(#23058)
+#23061=*
+typeexprs(#23061,23,#23058,2,"(x: string) => void")
+#23062=@"loc,{#10000},91,23,91,41"
+locations_default(#23062,#10000,91,23,91,41)
+hasLocation(#23061,#23062)
+enclosing_stmt(#23061,#23050)
+expr_containers(#23061,#22805)
#23063=*
-scopes(#23063,1)
-scopenodes(#23062,#23063)
-scopenesting(#23063,#22808)
-#23064=@"var;{x};{#23063}"
-variables(#23064,"x",#23063)
-#23065=*
-exprs(#23065,78,#23062,0,"x")
-hasLocation(#23065,#21910)
-expr_containers(#23065,#23062)
-literals("x","x",#23065)
-decl(#23065,#23064)
-#23066=@"var;{arguments};{#23063}"
-variables(#23066,"arguments",#23063)
-is_arguments_object(#23066)
-#23067=*
-typeexprs(#23067,2,#23062,-3,"void")
-hasLocation(#23067,#21920)
-expr_containers(#23067,#23062)
-literals("void","void",#23067)
+exprs(#23063,9,#23061,0,"(x: string) => void")
+hasLocation(#23063,#23062)
+enclosing_stmt(#23063,#23050)
+expr_containers(#23063,#22805)
+#23064=*
+scopes(#23064,1)
+scopenodes(#23063,#23064)
+scopenesting(#23064,#22808)
+#23065=@"var;{x};{#23064}"
+variables(#23065,"x",#23064)
+#23066=*
+exprs(#23066,78,#23063,0,"x")
+hasLocation(#23066,#21910)
+expr_containers(#23066,#23063)
+literals("x","x",#23066)
+decl(#23066,#23065)
+#23067=@"var;{arguments};{#23064}"
+variables(#23067,"arguments",#23064)
+is_arguments_object(#23067)
#23068=*
-typeexprs(#23068,2,#23062,-6,"string")
-hasLocation(#23068,#21914)
-expr_containers(#23068,#23062)
-literals("string","string",#23068)
+typeexprs(#23068,2,#23063,-3,"void")
+hasLocation(#23068,#21920)
+expr_containers(#23068,#23063)
+literals("void","void",#23068)
#23069=*
-properties(#23069,#23055,1,8,"b: (x: ... => void")
-#23070=@"loc,{#10000},91,44,91,65"
-locations_default(#23070,#10000,91,44,91,65)
-hasLocation(#23069,#23070)
-#23071=*
-exprs(#23071,0,#23069,0,"b")
-hasLocation(#23071,#21924)
-enclosing_stmt(#23071,#23049)
-expr_containers(#23071,#22805)
-literals("b","b",#23071)
-is_abstract_member(#23069)
+typeexprs(#23069,2,#23063,-6,"string")
+hasLocation(#23069,#21914)
+expr_containers(#23069,#23063)
+literals("string","string",#23069)
+#23070=*
+properties(#23070,#23056,1,8,"b: (x: ... => void")
+#23071=@"loc,{#10000},91,44,91,65"
+locations_default(#23071,#10000,91,44,91,65)
+hasLocation(#23070,#23071)
#23072=*
-typeexprs(#23072,23,#23069,2,"(x: string) => void")
-#23073=@"loc,{#10000},91,47,91,65"
-locations_default(#23073,#10000,91,47,91,65)
-hasLocation(#23072,#23073)
-enclosing_stmt(#23072,#23049)
+exprs(#23072,0,#23070,0,"b")
+hasLocation(#23072,#21924)
+enclosing_stmt(#23072,#23050)
expr_containers(#23072,#22805)
-#23074=*
-exprs(#23074,9,#23072,0,"(x: string) => void")
-hasLocation(#23074,#23073)
-enclosing_stmt(#23074,#23049)
-expr_containers(#23074,#22805)
+literals("b","b",#23072)
+is_abstract_member(#23070)
+#23073=*
+typeexprs(#23073,23,#23070,2,"(x: string) => void")
+#23074=@"loc,{#10000},91,47,91,65"
+locations_default(#23074,#10000,91,47,91,65)
+hasLocation(#23073,#23074)
+enclosing_stmt(#23073,#23050)
+expr_containers(#23073,#22805)
#23075=*
-scopes(#23075,1)
-scopenodes(#23074,#23075)
-scopenesting(#23075,#22808)
-#23076=@"var;{x};{#23075}"
-variables(#23076,"x",#23075)
-#23077=*
-exprs(#23077,78,#23074,0,"x")
-hasLocation(#23077,#21930)
-expr_containers(#23077,#23074)
-literals("x","x",#23077)
-decl(#23077,#23076)
-#23078=@"var;{arguments};{#23075}"
-variables(#23078,"arguments",#23075)
-is_arguments_object(#23078)
-#23079=*
-typeexprs(#23079,2,#23074,-3,"void")
-hasLocation(#23079,#21940)
-expr_containers(#23079,#23074)
-literals("void","void",#23079)
+exprs(#23075,9,#23073,0,"(x: string) => void")
+hasLocation(#23075,#23074)
+enclosing_stmt(#23075,#23050)
+expr_containers(#23075,#22805)
+#23076=*
+scopes(#23076,1)
+scopenodes(#23075,#23076)
+scopenesting(#23076,#22808)
+#23077=@"var;{x};{#23076}"
+variables(#23077,"x",#23076)
+#23078=*
+exprs(#23078,78,#23075,0,"x")
+hasLocation(#23078,#21930)
+expr_containers(#23078,#23075)
+literals("x","x",#23078)
+decl(#23078,#23077)
+#23079=@"var;{arguments};{#23076}"
+variables(#23079,"arguments",#23076)
+is_arguments_object(#23079)
#23080=*
-typeexprs(#23080,2,#23074,-6,"string")
-hasLocation(#23080,#21934)
-expr_containers(#23080,#23074)
-literals("string","string",#23080)
+typeexprs(#23080,2,#23075,-3,"void")
+hasLocation(#23080,#21940)
+expr_containers(#23080,#23075)
+literals("void","void",#23080)
#23081=*
-stmts(#23081,35,#22805,12,"type T2 ... oid }>;")
-#23082=@"loc,{#10000},92,3,92,69"
-locations_default(#23082,#10000,92,3,92,69)
-hasLocation(#23081,#23082)
-stmt_containers(#23081,#22805)
-#23083=*
-typeexprs(#23083,1,#23081,0,"T21")
-hasLocation(#23083,#21950)
-enclosing_stmt(#23083,#23081)
-expr_containers(#23083,#22805)
-literals("T21","T21",#23083)
-typedecl(#23083,#22821)
+typeexprs(#23081,2,#23075,-6,"string")
+hasLocation(#23081,#21934)
+expr_containers(#23081,#23075)
+literals("string","string",#23081)
+#23082=*
+stmts(#23082,35,#22805,12,"type T2 ... oid }>;")
+#23083=@"loc,{#10000},92,3,92,69"
+locations_default(#23083,#10000,92,3,92,69)
+hasLocation(#23082,#23083)
+stmt_containers(#23082,#22805)
#23084=*
-typeexprs(#23084,14,#23081,1,"Bar<{ a ... void }>")
-#23085=@"loc,{#10000},92,14,92,68"
-locations_default(#23085,#10000,92,14,92,68)
-hasLocation(#23084,#23085)
-enclosing_stmt(#23084,#23081)
+typeexprs(#23084,1,#23082,0,"T21")
+hasLocation(#23084,#21950)
+enclosing_stmt(#23084,#23082)
expr_containers(#23084,#22805)
-#23086=*
-typeexprs(#23086,0,#23084,-1,"Bar")
-hasLocation(#23086,#21954)
-enclosing_stmt(#23086,#23081)
-expr_containers(#23086,#22805)
-literals("Bar","Bar",#23086)
-typebind(#23086,#22819)
+literals("T21","T21",#23084)
+typedecl(#23084,#22822)
+#23085=*
+typeexprs(#23085,14,#23082,1,"Bar<{ a ... void }>")
+#23086=@"loc,{#10000},92,14,92,68"
+locations_default(#23086,#10000,92,14,92,68)
+hasLocation(#23085,#23086)
+enclosing_stmt(#23085,#23082)
+expr_containers(#23085,#22805)
#23087=*
-typeexprs(#23087,21,#23084,0,"{ a: (x ... void }")
-#23088=@"loc,{#10000},92,18,92,67"
-locations_default(#23088,#10000,92,18,92,67)
-hasLocation(#23087,#23088)
-enclosing_stmt(#23087,#23081)
+typeexprs(#23087,0,#23085,-1,"Bar")
+hasLocation(#23087,#21954)
+enclosing_stmt(#23087,#23082)
expr_containers(#23087,#22805)
-#23089=*
-properties(#23089,#23087,0,8,"a: (x: ... > void,")
-#23090=@"loc,{#10000},92,20,92,42"
-locations_default(#23090,#10000,92,20,92,42)
-hasLocation(#23089,#23090)
-#23091=*
-exprs(#23091,0,#23089,0,"a")
-hasLocation(#23091,#21960)
-enclosing_stmt(#23091,#23081)
-expr_containers(#23091,#22805)
-literals("a","a",#23091)
-is_abstract_member(#23089)
+literals("Bar","Bar",#23087)
+typebind(#23087,#22820)
+#23088=*
+typeexprs(#23088,21,#23085,0,"{ a: (x ... void }")
+#23089=@"loc,{#10000},92,18,92,67"
+locations_default(#23089,#10000,92,18,92,67)
+hasLocation(#23088,#23089)
+enclosing_stmt(#23088,#23082)
+expr_containers(#23088,#22805)
+#23090=*
+properties(#23090,#23088,0,8,"a: (x: ... > void,")
+#23091=@"loc,{#10000},92,20,92,42"
+locations_default(#23091,#10000,92,20,92,42)
+hasLocation(#23090,#23091)
#23092=*
-typeexprs(#23092,23,#23089,2,"(x: string) => void")
-#23093=@"loc,{#10000},92,23,92,41"
-locations_default(#23093,#10000,92,23,92,41)
-hasLocation(#23092,#23093)
-enclosing_stmt(#23092,#23081)
+exprs(#23092,0,#23090,0,"a")
+hasLocation(#23092,#21960)
+enclosing_stmt(#23092,#23082)
expr_containers(#23092,#22805)
-#23094=*
-exprs(#23094,9,#23092,0,"(x: string) => void")
-hasLocation(#23094,#23093)
-enclosing_stmt(#23094,#23081)
-expr_containers(#23094,#22805)
+literals("a","a",#23092)
+is_abstract_member(#23090)
+#23093=*
+typeexprs(#23093,23,#23090,2,"(x: string) => void")
+#23094=@"loc,{#10000},92,23,92,41"
+locations_default(#23094,#10000,92,23,92,41)
+hasLocation(#23093,#23094)
+enclosing_stmt(#23093,#23082)
+expr_containers(#23093,#22805)
#23095=*
-scopes(#23095,1)
-scopenodes(#23094,#23095)
-scopenesting(#23095,#22808)
-#23096=@"var;{x};{#23095}"
-variables(#23096,"x",#23095)
-#23097=*
-exprs(#23097,78,#23094,0,"x")
-hasLocation(#23097,#21966)
-expr_containers(#23097,#23094)
-literals("x","x",#23097)
-decl(#23097,#23096)
-#23098=@"var;{arguments};{#23095}"
-variables(#23098,"arguments",#23095)
-is_arguments_object(#23098)
-#23099=*
-typeexprs(#23099,2,#23094,-3,"void")
-hasLocation(#23099,#21976)
-expr_containers(#23099,#23094)
-literals("void","void",#23099)
+exprs(#23095,9,#23093,0,"(x: string) => void")
+hasLocation(#23095,#23094)
+enclosing_stmt(#23095,#23082)
+expr_containers(#23095,#22805)
+#23096=*
+scopes(#23096,1)
+scopenodes(#23095,#23096)
+scopenesting(#23096,#22808)
+#23097=@"var;{x};{#23096}"
+variables(#23097,"x",#23096)
+#23098=*
+exprs(#23098,78,#23095,0,"x")
+hasLocation(#23098,#21966)
+expr_containers(#23098,#23095)
+literals("x","x",#23098)
+decl(#23098,#23097)
+#23099=@"var;{arguments};{#23096}"
+variables(#23099,"arguments",#23096)
+is_arguments_object(#23099)
#23100=*
-typeexprs(#23100,2,#23094,-6,"string")
-hasLocation(#23100,#21970)
-expr_containers(#23100,#23094)
-literals("string","string",#23100)
+typeexprs(#23100,2,#23095,-3,"void")
+hasLocation(#23100,#21976)
+expr_containers(#23100,#23095)
+literals("void","void",#23100)
#23101=*
-properties(#23101,#23087,1,8,"b: (x: ... => void")
-#23102=@"loc,{#10000},92,44,92,65"
-locations_default(#23102,#10000,92,44,92,65)
-hasLocation(#23101,#23102)
-#23103=*
-exprs(#23103,0,#23101,0,"b")
-hasLocation(#23103,#21980)
-enclosing_stmt(#23103,#23081)
-expr_containers(#23103,#22805)
-literals("b","b",#23103)
-is_abstract_member(#23101)
+typeexprs(#23101,2,#23095,-6,"string")
+hasLocation(#23101,#21970)
+expr_containers(#23101,#23095)
+literals("string","string",#23101)
+#23102=*
+properties(#23102,#23088,1,8,"b: (x: ... => void")
+#23103=@"loc,{#10000},92,44,92,65"
+locations_default(#23103,#10000,92,44,92,65)
+hasLocation(#23102,#23103)
#23104=*
-typeexprs(#23104,23,#23101,2,"(x: number) => void")
-#23105=@"loc,{#10000},92,47,92,65"
-locations_default(#23105,#10000,92,47,92,65)
-hasLocation(#23104,#23105)
-enclosing_stmt(#23104,#23081)
+exprs(#23104,0,#23102,0,"b")
+hasLocation(#23104,#21980)
+enclosing_stmt(#23104,#23082)
expr_containers(#23104,#22805)
-#23106=*
-exprs(#23106,9,#23104,0,"(x: number) => void")
-hasLocation(#23106,#23105)
-enclosing_stmt(#23106,#23081)
-expr_containers(#23106,#22805)
+literals("b","b",#23104)
+is_abstract_member(#23102)
+#23105=*
+typeexprs(#23105,23,#23102,2,"(x: number) => void")
+#23106=@"loc,{#10000},92,47,92,65"
+locations_default(#23106,#10000,92,47,92,65)
+hasLocation(#23105,#23106)
+enclosing_stmt(#23105,#23082)
+expr_containers(#23105,#22805)
#23107=*
-scopes(#23107,1)
-scopenodes(#23106,#23107)
-scopenesting(#23107,#22808)
-#23108=@"var;{x};{#23107}"
-variables(#23108,"x",#23107)
-#23109=*
-exprs(#23109,78,#23106,0,"x")
-hasLocation(#23109,#21986)
-expr_containers(#23109,#23106)
-literals("x","x",#23109)
-decl(#23109,#23108)
-#23110=@"var;{arguments};{#23107}"
-variables(#23110,"arguments",#23107)
-is_arguments_object(#23110)
-#23111=*
-typeexprs(#23111,2,#23106,-3,"void")
-hasLocation(#23111,#21996)
-expr_containers(#23111,#23106)
-literals("void","void",#23111)
+exprs(#23107,9,#23105,0,"(x: number) => void")
+hasLocation(#23107,#23106)
+enclosing_stmt(#23107,#23082)
+expr_containers(#23107,#22805)
+#23108=*
+scopes(#23108,1)
+scopenodes(#23107,#23108)
+scopenesting(#23108,#22808)
+#23109=@"var;{x};{#23108}"
+variables(#23109,"x",#23108)
+#23110=*
+exprs(#23110,78,#23107,0,"x")
+hasLocation(#23110,#21986)
+expr_containers(#23110,#23107)
+literals("x","x",#23110)
+decl(#23110,#23109)
+#23111=@"var;{arguments};{#23108}"
+variables(#23111,"arguments",#23108)
+is_arguments_object(#23111)
#23112=*
-typeexprs(#23112,2,#23106,-6,"number")
-hasLocation(#23112,#21990)
-expr_containers(#23112,#23106)
-literals("number","number",#23112)
+typeexprs(#23112,2,#23107,-3,"void")
+hasLocation(#23112,#21996)
+expr_containers(#23112,#23107)
+literals("void","void",#23112)
#23113=*
-stmts(#23113,17,#22805,13,"declare ... number;")
-#23114=@"loc,{#10000},94,3,94,42"
-locations_default(#23114,#10000,94,3,94,42)
-hasLocation(#23113,#23114)
-stmt_containers(#23113,#22805)
-has_declare_keyword(#23113)
-#23115=*
-exprs(#23115,78,#23113,-1,"foo")
-hasLocation(#23115,#22008)
-expr_containers(#23115,#23113)
-literals("foo","foo",#23115)
-#23116=@"var;{foo};{#20000}"
-variables(#23116,"foo",#20000)
-decl(#23115,#23116)
+typeexprs(#23113,2,#23107,-6,"number")
+hasLocation(#23113,#21990)
+expr_containers(#23113,#23107)
+literals("number","number",#23113)
+#23114=*
+stmts(#23114,17,#22805,13,"declare ... number;")
+#23115=@"loc,{#10000},94,3,94,42"
+locations_default(#23115,#10000,94,3,94,42)
+hasLocation(#23114,#23115)
+stmt_containers(#23114,#22805)
+has_declare_keyword(#23114)
+#23116=*
+exprs(#23116,78,#23114,-1,"foo")
+hasLocation(#23116,#22008)
+expr_containers(#23116,#23114)
+literals("foo","foo",#23116)
+decl(#23116,#22809)
#23117=*
scopes(#23117,1)
-scopenodes(#23113,#23117)
+scopenodes(#23114,#23117)
scopenesting(#23117,#22808)
#23118=@"var;{x};{#23117}"
variables(#23118,"x",#23117)
#23119=*
-exprs(#23119,78,#23113,0,"x")
+exprs(#23119,78,#23114,0,"x")
hasLocation(#23119,#22012)
-expr_containers(#23119,#23113)
+expr_containers(#23119,#23114)
literals("x","x",#23119)
decl(#23119,#23118)
#23120=@"var;{arguments};{#23117}"
variables(#23120,"arguments",#23117)
is_arguments_object(#23120)
#23121=*
-typeexprs(#23121,2,#23113,-3,"number")
+typeexprs(#23121,2,#23114,-3,"number")
hasLocation(#23121,#22022)
-expr_containers(#23121,#23113)
+expr_containers(#23121,#23114)
literals("number","number",#23121)
#23122=*
-typeexprs(#23122,2,#23113,-6,"string")
+typeexprs(#23122,2,#23114,-6,"string")
hasLocation(#23122,#22016)
-expr_containers(#23122,#23113)
+expr_containers(#23122,#23114)
literals("string","string",#23122)
#23123=*
stmts(#23123,17,#22805,14,"declare ... string;")
@@ -9757,7 +9757,7 @@ exprs(#23125,78,#23123,-1,"foo")
hasLocation(#23125,#22030)
expr_containers(#23125,#23123)
literals("foo","foo",#23125)
-decl(#23125,#23116)
+decl(#23125,#22809)
#23126=*
scopes(#23126,1)
scopenodes(#23123,#23126)
@@ -9795,7 +9795,7 @@ exprs(#23134,78,#23132,-1,"foo")
hasLocation(#23134,#22052)
expr_containers(#23134,#23132)
literals("foo","foo",#23134)
-decl(#23134,#23116)
+decl(#23134,#22809)
#23135=*
scopes(#23135,1)
scopenodes(#23132,#23135)
@@ -9855,7 +9855,7 @@ hasLocation(#23149,#22080)
enclosing_stmt(#23149,#23147)
expr_containers(#23149,#22805)
literals("T30","T30",#23149)
-typedecl(#23149,#22822)
+typedecl(#23149,#22823)
#23150=*
typeexprs(#23150,14,#23147,1,"ReturnT ... of foo>")
#23151=@"loc,{#10000},97,14,97,35"
@@ -9869,7 +9869,7 @@ hasLocation(#23152,#22084)
enclosing_stmt(#23152,#23147)
expr_containers(#23152,#22805)
literals("ReturnType","ReturnType",#23152)
-typebind(#23152,#22824)
+typebind(#23152,#22825)
#23153=*
typeexprs(#23153,16,#23150,0,"typeof foo")
#23154=@"loc,{#10000},97,25,97,34"
@@ -9883,7 +9883,7 @@ hasLocation(#23155,#22090)
enclosing_stmt(#23155,#23147)
expr_containers(#23155,#22805)
literals("foo","foo",#23155)
-bind(#23155,#23116)
+bind(#23155,#22809)
#23156=*
stmts(#23156,35,#22805,17,"type An ... => any;")
#23157=@"loc,{#10000},99,3,99,45"
@@ -9896,7 +9896,7 @@ hasLocation(#23158,#22098)
enclosing_stmt(#23158,#23156)
expr_containers(#23158,#22805)
literals("AnyFunction","AnyFunction",#23158)
-typedecl(#23158,#22823)
+typedecl(#23158,#22824)
#23159=*
typeexprs(#23159,23,#23156,1,"(...arg ... => any")
#23160=@"loc,{#10000},99,22,99,44"
@@ -9953,7 +9953,7 @@ hasLocation(#23172,#22126)
enclosing_stmt(#23172,#23170)
expr_containers(#23172,#22805)
literals("ReturnType","ReturnType",#23172)
-typedecl(#23172,#22824)
+typedecl(#23172,#22825)
#23173=*
scopes(#23173,12)
scopenodes(#23170,#23173)
@@ -9980,7 +9980,7 @@ hasLocation(#23178,#22134)
enclosing_stmt(#23178,#23170)
expr_containers(#23178,#22805)
literals("AnyFunction","AnyFunction",#23178)
-typebind(#23178,#22823)
+typebind(#23178,#22824)
#23179=*
typeexprs(#23179,28,#23170,1,"T exten ... R : any")
#23180=@"loc,{#10000},100,44,100,90"
@@ -10084,21 +10084,21 @@ successor(#23156,#23170)
successor(#23147,#23156)
successor(#23132,#23147)
successor(#23123,#23132)
-successor(#23113,#23123)
-successor(#23081,#23113)
-successor(#23049,#23081)
-successor(#23005,#23049)
-successor(#22989,#23005)
-successor(#22973,#22989)
-successor(#22945,#22973)
-successor(#22930,#22945)
-successor(#22918,#22930)
-successor(#22908,#22918)
-successor(#22896,#22908)
-successor(#22887,#22896)
-successor(#22880,#22887)
-successor(#22825,#22880)
-successor(#22805,#22825)
+successor(#23114,#23123)
+successor(#23082,#23114)
+successor(#23050,#23082)
+successor(#23006,#23050)
+successor(#22990,#23006)
+successor(#22974,#22990)
+successor(#22946,#22974)
+successor(#22931,#22946)
+successor(#22919,#22931)
+successor(#22909,#22919)
+successor(#22897,#22909)
+successor(#22888,#22897)
+successor(#22881,#22888)
+successor(#22826,#22881)
+successor(#22805,#22826)
successor(#22185,#22183)
successor(#22777,#22807)
successor(#22770,#22777)
diff --git a/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap b/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap
index 6bc9fb5ffb25..83ada22ef89a 100644
--- a/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap
+++ b/javascript/extractor/tests/ts/output/trap/declareClass.ts.trap
@@ -50,61 +50,64 @@ toplevels(#20001,0)
#20016=@"loc,{#10000},1,1,2,0"
locations_default(#20016,#10000,1,1,2,0)
hasLocation(#20001,#20016)
-#20017=*
-stmts(#20017,26,#20001,0,"declare class C {}")
-hasLocation(#20017,#20003)
-stmt_containers(#20017,#20001)
-has_declare_keyword(#20017)
-#20018=*
-exprs(#20018,78,#20017,0,"C")
-hasLocation(#20018,#20009)
-enclosing_stmt(#20018,#20017)
-expr_containers(#20018,#20001)
-literals("C","C",#20018)
-#20019=@"var;{C};{#20000}"
-variables(#20019,"C",#20000)
-decl(#20018,#20019)
+#20017=@"var;{C};{#20000}"
+variables(#20017,"C",#20000)
+#20018=@"local_type_name;{C};{#20000}"
+local_type_names(#20018,"C",#20000)
+#20019=*
+stmts(#20019,26,#20001,0,"declare class C {}")
+hasLocation(#20019,#20003)
+stmt_containers(#20019,#20001)
+has_declare_keyword(#20019)
#20020=*
-scopes(#20020,10)
-scopenodes(#20017,#20020)
-scopenesting(#20020,#20000)
+exprs(#20020,78,#20019,0,"C")
+hasLocation(#20020,#20009)
+enclosing_stmt(#20020,#20019)
+expr_containers(#20020,#20001)
+literals("C","C",#20020)
+decl(#20020,#20017)
+typedecl(#20020,#20018)
#20021=*
-properties(#20021,#20017,2,0,"constructor() {}")
-#20022=@"loc,{#10000},1,17,1,16"
-locations_default(#20022,#10000,1,17,1,16)
-hasLocation(#20021,#20022)
-#20023=*
-exprs(#20023,0,#20021,0,"constructor")
-hasLocation(#20023,#20022)
-enclosing_stmt(#20023,#20017)
-expr_containers(#20023,#20001)
-literals("constructor","constructor",#20023)
+scopes(#20021,10)
+scopenodes(#20019,#20021)
+scopenesting(#20021,#20000)
+#20022=*
+properties(#20022,#20019,2,0,"constructor() {}")
+#20023=@"loc,{#10000},1,17,1,16"
+locations_default(#20023,#10000,1,17,1,16)
+hasLocation(#20022,#20023)
#20024=*
-exprs(#20024,9,#20021,1,"() {}")
-hasLocation(#20024,#20022)
-enclosing_stmt(#20024,#20017)
+exprs(#20024,0,#20022,0,"constructor")
+hasLocation(#20024,#20023)
+enclosing_stmt(#20024,#20019)
expr_containers(#20024,#20001)
+literals("constructor","constructor",#20024)
#20025=*
-scopes(#20025,1)
-scopenodes(#20024,#20025)
-scopenesting(#20025,#20020)
-#20026=@"var;{arguments};{#20025}"
-variables(#20026,"arguments",#20025)
-is_arguments_object(#20026)
-#20027=*
-stmts(#20027,1,#20024,-2,"{}")
-hasLocation(#20027,#20022)
-stmt_containers(#20027,#20024)
-is_method(#20021)
+exprs(#20025,9,#20022,1,"() {}")
+hasLocation(#20025,#20023)
+enclosing_stmt(#20025,#20019)
+expr_containers(#20025,#20001)
+#20026=*
+scopes(#20026,1)
+scopenodes(#20025,#20026)
+scopenesting(#20026,#20021)
+#20027=@"var;{arguments};{#20026}"
+variables(#20027,"arguments",#20026)
+is_arguments_object(#20027)
#20028=*
-entry_cfg_node(#20028,#20001)
-#20029=@"loc,{#10000},1,1,1,0"
-locations_default(#20029,#10000,1,1,1,0)
-hasLocation(#20028,#20029)
-#20030=*
-exit_cfg_node(#20030,#20001)
-hasLocation(#20030,#20015)
-successor(#20017,#20030)
-successor(#20028,#20017)
+stmts(#20028,1,#20025,-2,"{}")
+hasLocation(#20028,#20023)
+stmt_containers(#20028,#20025)
+is_method(#20022)
+#20029=*
+entry_cfg_node(#20029,#20001)
+#20030=@"loc,{#10000},1,1,1,0"
+locations_default(#20030,#10000,1,1,1,0)
+hasLocation(#20029,#20030)
+#20031=*
+exit_cfg_node(#20031,#20001)
+hasLocation(#20031,#20015)
+successor(#20019,#20031)
+successor(#20029,#20019)
numlines(#10000,1,1,0)
filetype(#10000,"typescript")
diff --git a/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap b/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap
index 89cd17604433..00276bb64641 100644
--- a/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap
+++ b/javascript/extractor/tests/ts/output/trap/functiondecorators.ts.trap
@@ -584,62 +584,63 @@ toplevels(#20001,0)
#20221=@"loc,{#10000},1,1,16,0"
locations_default(#20221,#10000,1,1,16,0)
hasLocation(#20001,#20221)
-#20222=@"var;{C};{#20000}"
-variables(#20222,"C",#20000)
-#20223=@"local_type_name;{C};{#20000}"
-local_type_names(#20223,"C",#20000)
-#20224=*
-stmts(#20224,18,#20001,0,"declare var A : any;")
-hasLocation(#20224,#20003)
-stmt_containers(#20224,#20001)
-has_declare_keyword(#20224)
-#20225=*
-exprs(#20225,64,#20224,0,"A : any")
-#20226=@"loc,{#10000},1,13,1,19"
-locations_default(#20226,#10000,1,13,1,19)
-hasLocation(#20225,#20226)
-enclosing_stmt(#20225,#20224)
-expr_containers(#20225,#20001)
+#20222=@"var;{A};{#20000}"
+variables(#20222,"A",#20000)
+#20223=@"var;{B};{#20000}"
+variables(#20223,"B",#20000)
+#20224=@"var;{C};{#20000}"
+variables(#20224,"C",#20000)
+variables(#20224,"C",#20000)
+#20225=@"local_type_name;{C};{#20000}"
+local_type_names(#20225,"C",#20000)
+#20226=*
+stmts(#20226,18,#20001,0,"declare var A : any;")
+hasLocation(#20226,#20003)
+stmt_containers(#20226,#20001)
+has_declare_keyword(#20226)
#20227=*
-exprs(#20227,78,#20225,0,"A")
-hasLocation(#20227,#20037)
-enclosing_stmt(#20227,#20224)
+exprs(#20227,64,#20226,0,"A : any")
+#20228=@"loc,{#10000},1,13,1,19"
+locations_default(#20228,#10000,1,13,1,19)
+hasLocation(#20227,#20228)
+enclosing_stmt(#20227,#20226)
expr_containers(#20227,#20001)
-literals("A","A",#20227)
-#20228=@"var;{A};{#20000}"
-variables(#20228,"A",#20000)
-decl(#20227,#20228)
#20229=*
-typeexprs(#20229,2,#20225,2,"any")
-hasLocation(#20229,#20041)
-enclosing_stmt(#20229,#20224)
+exprs(#20229,78,#20227,0,"A")
+hasLocation(#20229,#20037)
+enclosing_stmt(#20229,#20226)
expr_containers(#20229,#20001)
-literals("any","any",#20229)
+literals("A","A",#20229)
+decl(#20229,#20222)
#20230=*
-stmts(#20230,18,#20001,1,"declare var B : any;")
-hasLocation(#20230,#20005)
-stmt_containers(#20230,#20001)
-has_declare_keyword(#20230)
+typeexprs(#20230,2,#20227,2,"any")
+hasLocation(#20230,#20041)
+enclosing_stmt(#20230,#20226)
+expr_containers(#20230,#20001)
+literals("any","any",#20230)
#20231=*
-exprs(#20231,64,#20230,0,"B : any")
-#20232=@"loc,{#10000},2,13,2,19"
-locations_default(#20232,#10000,2,13,2,19)
-hasLocation(#20231,#20232)
-enclosing_stmt(#20231,#20230)
-expr_containers(#20231,#20001)
-#20233=*
-exprs(#20233,78,#20231,0,"B")
-hasLocation(#20233,#20049)
-enclosing_stmt(#20233,#20230)
-expr_containers(#20233,#20001)
-literals("B","B",#20233)
-#20234=@"var;{B};{#20000}"
-variables(#20234,"B",#20000)
-decl(#20233,#20234)
+stmts(#20231,18,#20001,1,"declare var B : any;")
+hasLocation(#20231,#20005)
+stmt_containers(#20231,#20001)
+has_declare_keyword(#20231)
+#20232=*
+exprs(#20232,64,#20231,0,"B : any")
+#20233=@"loc,{#10000},2,13,2,19"
+locations_default(#20233,#10000,2,13,2,19)
+hasLocation(#20232,#20233)
+enclosing_stmt(#20232,#20231)
+expr_containers(#20232,#20001)
+#20234=*
+exprs(#20234,78,#20232,0,"B")
+hasLocation(#20234,#20049)
+enclosing_stmt(#20234,#20231)
+expr_containers(#20234,#20001)
+literals("B","B",#20234)
+decl(#20234,#20223)
#20235=*
-typeexprs(#20235,2,#20231,2,"any")
+typeexprs(#20235,2,#20232,2,"any")
hasLocation(#20235,#20053)
-enclosing_stmt(#20235,#20230)
+enclosing_stmt(#20235,#20231)
expr_containers(#20235,#20001)
literals("any","any",#20235)
#20236=*
@@ -660,7 +661,7 @@ hasLocation(#20239,#20061)
enclosing_stmt(#20239,#20236)
expr_containers(#20239,#20001)
literals("C","C",#20239)
-decl(#20239,#20222)
+decl(#20239,#20224)
#20240=*
typeexprs(#20240,2,#20237,2,"any")
hasLocation(#20240,#20065)
@@ -679,8 +680,8 @@ hasLocation(#20243,#20071)
enclosing_stmt(#20243,#20241)
expr_containers(#20243,#20001)
literals("C","C",#20243)
-decl(#20243,#20222)
-typedecl(#20243,#20223)
+decl(#20243,#20224)
+typedecl(#20243,#20225)
#20244=*
scopes(#20244,10)
scopenodes(#20241,#20244)
@@ -769,7 +770,7 @@ exprs(#20266,79,#20265,0,"A")
hasLocation(#20266,#20093)
expr_containers(#20266,#20258)
literals("A","A",#20266)
-bind(#20266,#20228)
+bind(#20266,#20222)
#20267=*
stmts(#20267,1,#20258,-2,"{}")
#20268=@"loc,{#10000},7,12,7,13"
@@ -825,7 +826,7 @@ exprs(#20281,79,#20279,0,"A")
hasLocation(#20281,#20109)
expr_containers(#20281,#20272)
literals("A","A",#20281)
-bind(#20281,#20228)
+bind(#20281,#20222)
#20282=*
exprs(#20282,94,#20277,1,"@B")
#20283=@"loc,{#10000},8,9,8,10"
@@ -837,7 +838,7 @@ exprs(#20284,79,#20282,0,"B")
hasLocation(#20284,#20113)
expr_containers(#20284,#20272)
literals("B","B",#20284)
-bind(#20284,#20234)
+bind(#20284,#20223)
#20285=*
stmts(#20285,1,#20272,-2,"{}")
#20286=@"loc,{#10000},8,16,8,17"
@@ -899,7 +900,7 @@ exprs(#20300,79,#20299,0,"A")
hasLocation(#20300,#20133)
expr_containers(#20300,#20290)
literals("A","A",#20300)
-bind(#20300,#20228)
+bind(#20300,#20222)
#20301=*
stmts(#20301,1,#20290,-2,"{}")
#20302=@"loc,{#10000},10,18,10,19"
@@ -963,7 +964,7 @@ exprs(#20317,79,#20315,0,"A")
hasLocation(#20317,#20153)
expr_containers(#20317,#20306)
literals("A","A",#20317)
-bind(#20317,#20228)
+bind(#20317,#20222)
#20318=*
exprs(#20318,94,#20313,1,"@B")
#20319=@"loc,{#10000},11,15,11,16"
@@ -975,7 +976,7 @@ exprs(#20320,79,#20318,0,"B")
hasLocation(#20320,#20157)
expr_containers(#20320,#20306)
literals("B","B",#20320)
-bind(#20320,#20234)
+bind(#20320,#20223)
#20321=*
stmts(#20321,1,#20306,-2,"{}")
#20322=@"loc,{#10000},11,22,11,23"
@@ -1037,7 +1038,7 @@ exprs(#20336,79,#20335,0,"A")
hasLocation(#20336,#20173)
expr_containers(#20336,#20326)
literals("A","A",#20336)
-bind(#20336,#20228)
+bind(#20336,#20222)
#20337=*
exprs(#20337,104,#20326,-12,"@B")
#20338=@"loc,{#10000},13,12,13,13"
@@ -1053,7 +1054,7 @@ exprs(#20340,79,#20339,0,"B")
hasLocation(#20340,#20181)
expr_containers(#20340,#20326)
literals("B","B",#20340)
-bind(#20340,#20234)
+bind(#20340,#20223)
#20341=*
stmts(#20341,1,#20326,-2,"{}")
#20342=@"loc,{#10000},13,18,13,19"
@@ -1115,7 +1116,7 @@ exprs(#20356,79,#20355,0,"A")
hasLocation(#20356,#20197)
expr_containers(#20356,#20346)
literals("A","A",#20356)
-bind(#20356,#20228)
+bind(#20356,#20222)
#20357=*
exprs(#20357,104,#20346,-12,"@B @C")
#20358=@"loc,{#10000},14,12,14,16"
@@ -1133,7 +1134,7 @@ exprs(#20361,79,#20359,0,"B")
hasLocation(#20361,#20205)
expr_containers(#20361,#20346)
literals("B","B",#20361)
-bind(#20361,#20234)
+bind(#20361,#20223)
#20362=*
exprs(#20362,94,#20357,1,"@C")
#20363=@"loc,{#10000},14,15,14,16"
@@ -1145,7 +1146,7 @@ exprs(#20364,79,#20362,0,"C")
hasLocation(#20364,#20209)
expr_containers(#20364,#20346)
literals("C","C",#20364)
-bind(#20364,#20222)
+bind(#20364,#20224)
#20365=*
stmts(#20365,1,#20346,-2,"{}")
#20366=@"loc,{#10000},14,22,14,23"
@@ -1349,8 +1350,8 @@ successor(#20265,#20263)
successor(#20263,#20281)
successor(#20241,#20266)
successor(#20236,#20243)
-successor(#20230,#20236)
-successor(#20224,#20230)
-successor(#20374,#20224)
+successor(#20231,#20236)
+successor(#20226,#20231)
+successor(#20374,#20226)
numlines(#10000,15,12,0)
filetype(#10000,"typescript")
diff --git a/javascript/extractor/tests/ts/output/trap/nobody.ts.trap b/javascript/extractor/tests/ts/output/trap/nobody.ts.trap
index 44a32603e097..717d79423abd 100644
--- a/javascript/extractor/tests/ts/output/trap/nobody.ts.trap
+++ b/javascript/extractor/tests/ts/output/trap/nobody.ts.trap
@@ -694,506 +694,509 @@ toplevels(#20001,0)
#20252=@"loc,{#10000},2,1,30,0"
locations_default(#20252,#10000,2,1,30,0)
hasLocation(#20001,#20252)
-#20253=@"var;{C};{#20000}"
-variables(#20253,"C",#20000)
-#20254=@"local_type_name;{C};{#20000}"
-local_type_names(#20254,"C",#20000)
-#20255=*
-stmts(#20255,17,#20001,0,"declare ... on f();")
-hasLocation(#20255,#20020)
-stmt_containers(#20255,#20001)
-has_declare_keyword(#20255)
-#20256=*
-exprs(#20256,78,#20255,-1,"f")
-hasLocation(#20256,#20079)
-expr_containers(#20256,#20255)
-literals("f","f",#20256)
-#20257=@"var;{f};{#20000}"
-variables(#20257,"f",#20000)
-decl(#20256,#20257)
+#20253=@"var;{f};{#20000}"
+variables(#20253,"f",#20000)
+#20254=@"var;{C};{#20000}"
+variables(#20254,"C",#20000)
+#20255=@"var;{D};{#20000}"
+variables(#20255,"D",#20000)
+#20256=@"local_type_name;{C};{#20000}"
+local_type_names(#20256,"C",#20000)
+#20257=@"local_type_name;{D};{#20000}"
+local_type_names(#20257,"D",#20000)
#20258=*
-scopes(#20258,1)
-scopenodes(#20255,#20258)
-scopenesting(#20258,#20000)
-#20259=@"var;{arguments};{#20258}"
-variables(#20259,"arguments",#20258)
-is_arguments_object(#20259)
+stmts(#20258,17,#20001,0,"declare ... on f();")
+hasLocation(#20258,#20020)
+stmt_containers(#20258,#20001)
+has_declare_keyword(#20258)
+#20259=*
+exprs(#20259,78,#20258,-1,"f")
+hasLocation(#20259,#20079)
+expr_containers(#20259,#20258)
+literals("f","f",#20259)
+decl(#20259,#20253)
#20260=*
-stmts(#20260,26,#20001,1,"abstrac ... mber;\n}")
-#20261=@"loc,{#10000},4,1,15,1"
-locations_default(#20261,#10000,4,1,15,1)
-hasLocation(#20260,#20261)
-stmt_containers(#20260,#20001)
-is_abstract_class(#20260)
+scopes(#20260,1)
+scopenodes(#20258,#20260)
+scopenesting(#20260,#20000)
+#20261=@"var;{arguments};{#20260}"
+variables(#20261,"arguments",#20260)
+is_arguments_object(#20261)
#20262=*
-exprs(#20262,78,#20260,0,"C")
-hasLocation(#20262,#20091)
-enclosing_stmt(#20262,#20260)
-expr_containers(#20262,#20001)
-literals("C","C",#20262)
-decl(#20262,#20253)
-typedecl(#20262,#20254)
-#20263=*
-scopes(#20263,10)
-scopenodes(#20260,#20263)
-scopenesting(#20263,#20000)
+stmts(#20262,26,#20001,1,"abstrac ... mber;\n}")
+#20263=@"loc,{#10000},4,1,15,1"
+locations_default(#20263,#10000,4,1,15,1)
+hasLocation(#20262,#20263)
+stmt_containers(#20262,#20001)
+is_abstract_class(#20262)
#20264=*
-properties(#20264,#20260,2,0,"abstract h();")
-#20265=@"loc,{#10000},6,3,6,15"
-locations_default(#20265,#10000,6,3,6,15)
-hasLocation(#20264,#20265)
+exprs(#20264,78,#20262,0,"C")
+hasLocation(#20264,#20091)
+enclosing_stmt(#20264,#20262)
+expr_containers(#20264,#20001)
+literals("C","C",#20264)
+decl(#20264,#20254)
+typedecl(#20264,#20256)
+#20265=*
+scopes(#20265,10)
+scopenodes(#20262,#20265)
+scopenesting(#20265,#20000)
#20266=*
-exprs(#20266,0,#20264,0,"h")
-hasLocation(#20266,#20097)
-enclosing_stmt(#20266,#20260)
-expr_containers(#20266,#20001)
-literals("h","h",#20266)
-#20267=*
-exprs(#20267,9,#20264,1,"abstract h();")
-hasLocation(#20267,#20265)
-enclosing_stmt(#20267,#20260)
-expr_containers(#20267,#20001)
+properties(#20266,#20262,2,0,"abstract h();")
+#20267=@"loc,{#10000},6,3,6,15"
+locations_default(#20267,#10000,6,3,6,15)
+hasLocation(#20266,#20267)
#20268=*
-scopes(#20268,1)
-scopenodes(#20267,#20268)
-scopenesting(#20268,#20263)
-#20269=@"var;{arguments};{#20268}"
-variables(#20269,"arguments",#20268)
-is_arguments_object(#20269)
-is_method(#20264)
-is_abstract_member(#20264)
+exprs(#20268,0,#20266,0,"h")
+hasLocation(#20268,#20097)
+enclosing_stmt(#20268,#20262)
+expr_containers(#20268,#20001)
+literals("h","h",#20268)
+#20269=*
+exprs(#20269,9,#20266,1,"abstract h();")
+hasLocation(#20269,#20267)
+enclosing_stmt(#20269,#20262)
+expr_containers(#20269,#20001)
#20270=*
-properties(#20270,#20260,3,0,"g(x: nu ... number;")
-#20271=@"loc,{#10000},9,3,9,23"
-locations_default(#20271,#10000,9,3,9,23)
-hasLocation(#20270,#20271)
+scopes(#20270,1)
+scopenodes(#20269,#20270)
+scopenesting(#20270,#20265)
+#20271=@"var;{arguments};{#20270}"
+variables(#20271,"arguments",#20270)
+is_arguments_object(#20271)
+is_method(#20266)
+is_abstract_member(#20266)
#20272=*
-exprs(#20272,0,#20270,0,"g")
-hasLocation(#20272,#20105)
-enclosing_stmt(#20272,#20260)
-expr_containers(#20272,#20001)
-literals("g","g",#20272)
-#20273=*
-exprs(#20273,9,#20270,1,"g(x: nu ... number;")
-hasLocation(#20273,#20271)
-enclosing_stmt(#20273,#20260)
-expr_containers(#20273,#20001)
+properties(#20272,#20262,3,0,"g(x: nu ... number;")
+#20273=@"loc,{#10000},9,3,9,23"
+locations_default(#20273,#10000,9,3,9,23)
+hasLocation(#20272,#20273)
#20274=*
-scopes(#20274,1)
-scopenodes(#20273,#20274)
-scopenesting(#20274,#20263)
-#20275=@"var;{x};{#20274}"
-variables(#20275,"x",#20274)
+exprs(#20274,0,#20272,0,"g")
+hasLocation(#20274,#20105)
+enclosing_stmt(#20274,#20262)
+expr_containers(#20274,#20001)
+literals("g","g",#20274)
+#20275=*
+exprs(#20275,9,#20272,1,"g(x: nu ... number;")
+hasLocation(#20275,#20273)
+enclosing_stmt(#20275,#20262)
+expr_containers(#20275,#20001)
#20276=*
-exprs(#20276,78,#20273,0,"x")
-hasLocation(#20276,#20109)
-expr_containers(#20276,#20273)
-literals("x","x",#20276)
-decl(#20276,#20275)
-#20277=@"var;{arguments};{#20274}"
-variables(#20277,"arguments",#20274)
-is_arguments_object(#20277)
+scopes(#20276,1)
+scopenodes(#20275,#20276)
+scopenesting(#20276,#20265)
+#20277=@"var;{x};{#20276}"
+variables(#20277,"x",#20276)
#20278=*
-typeexprs(#20278,2,#20273,-3,"number")
-hasLocation(#20278,#20119)
-expr_containers(#20278,#20273)
-literals("number","number",#20278)
-#20279=*
-typeexprs(#20279,2,#20273,-6,"number")
-hasLocation(#20279,#20113)
-expr_containers(#20279,#20273)
-literals("number","number",#20279)
-is_method(#20270)
+exprs(#20278,78,#20275,0,"x")
+hasLocation(#20278,#20109)
+expr_containers(#20278,#20275)
+literals("x","x",#20278)
+decl(#20278,#20277)
+#20279=@"var;{arguments};{#20276}"
+variables(#20279,"arguments",#20276)
+is_arguments_object(#20279)
#20280=*
-properties(#20280,#20260,4,0,"g(x: st ... string;")
-#20281=@"loc,{#10000},10,3,10,23"
-locations_default(#20281,#10000,10,3,10,23)
-hasLocation(#20280,#20281)
+typeexprs(#20280,2,#20275,-3,"number")
+hasLocation(#20280,#20119)
+expr_containers(#20280,#20275)
+literals("number","number",#20280)
+#20281=*
+typeexprs(#20281,2,#20275,-6,"number")
+hasLocation(#20281,#20113)
+expr_containers(#20281,#20275)
+literals("number","number",#20281)
+is_method(#20272)
#20282=*
-exprs(#20282,0,#20280,0,"g")
-hasLocation(#20282,#20123)
-enclosing_stmt(#20282,#20260)
-expr_containers(#20282,#20001)
-literals("g","g",#20282)
-#20283=*
-exprs(#20283,9,#20280,1,"g(x: st ... string;")
-hasLocation(#20283,#20281)
-enclosing_stmt(#20283,#20260)
-expr_containers(#20283,#20001)
+properties(#20282,#20262,4,0,"g(x: st ... string;")
+#20283=@"loc,{#10000},10,3,10,23"
+locations_default(#20283,#10000,10,3,10,23)
+hasLocation(#20282,#20283)
#20284=*
-scopes(#20284,1)
-scopenodes(#20283,#20284)
-scopenesting(#20284,#20263)
-#20285=@"var;{x};{#20284}"
-variables(#20285,"x",#20284)
+exprs(#20284,0,#20282,0,"g")
+hasLocation(#20284,#20123)
+enclosing_stmt(#20284,#20262)
+expr_containers(#20284,#20001)
+literals("g","g",#20284)
+#20285=*
+exprs(#20285,9,#20282,1,"g(x: st ... string;")
+hasLocation(#20285,#20283)
+enclosing_stmt(#20285,#20262)
+expr_containers(#20285,#20001)
#20286=*
-exprs(#20286,78,#20283,0,"x")
-hasLocation(#20286,#20127)
-expr_containers(#20286,#20283)
-literals("x","x",#20286)
-decl(#20286,#20285)
-#20287=@"var;{arguments};{#20284}"
-variables(#20287,"arguments",#20284)
-is_arguments_object(#20287)
+scopes(#20286,1)
+scopenodes(#20285,#20286)
+scopenesting(#20286,#20265)
+#20287=@"var;{x};{#20286}"
+variables(#20287,"x",#20286)
#20288=*
-typeexprs(#20288,2,#20283,-3,"string")
-hasLocation(#20288,#20137)
-expr_containers(#20288,#20283)
-literals("string","string",#20288)
-#20289=*
-typeexprs(#20289,2,#20283,-6,"string")
-hasLocation(#20289,#20131)
-expr_containers(#20289,#20283)
-literals("string","string",#20289)
-is_method(#20280)
+exprs(#20288,78,#20285,0,"x")
+hasLocation(#20288,#20127)
+expr_containers(#20288,#20285)
+literals("x","x",#20288)
+decl(#20288,#20287)
+#20289=@"var;{arguments};{#20286}"
+variables(#20289,"arguments",#20286)
+is_arguments_object(#20289)
#20290=*
-properties(#20290,#20260,5,0,"g(x: any) {}")
-#20291=@"loc,{#10000},11,3,11,14"
-locations_default(#20291,#10000,11,3,11,14)
-hasLocation(#20290,#20291)
+typeexprs(#20290,2,#20285,-3,"string")
+hasLocation(#20290,#20137)
+expr_containers(#20290,#20285)
+literals("string","string",#20290)
+#20291=*
+typeexprs(#20291,2,#20285,-6,"string")
+hasLocation(#20291,#20131)
+expr_containers(#20291,#20285)
+literals("string","string",#20291)
+is_method(#20282)
#20292=*
-exprs(#20292,0,#20290,0,"g")
-hasLocation(#20292,#20141)
-enclosing_stmt(#20292,#20260)
-expr_containers(#20292,#20001)
-literals("g","g",#20292)
-#20293=*
-exprs(#20293,9,#20290,1,"g(x: any) {}")
-hasLocation(#20293,#20291)
-enclosing_stmt(#20293,#20260)
-expr_containers(#20293,#20001)
+properties(#20292,#20262,5,0,"g(x: any) {}")
+#20293=@"loc,{#10000},11,3,11,14"
+locations_default(#20293,#10000,11,3,11,14)
+hasLocation(#20292,#20293)
#20294=*
-scopes(#20294,1)
-scopenodes(#20293,#20294)
-scopenesting(#20294,#20263)
-#20295=@"var;{x};{#20294}"
-variables(#20295,"x",#20294)
+exprs(#20294,0,#20292,0,"g")
+hasLocation(#20294,#20141)
+enclosing_stmt(#20294,#20262)
+expr_containers(#20294,#20001)
+literals("g","g",#20294)
+#20295=*
+exprs(#20295,9,#20292,1,"g(x: any) {}")
+hasLocation(#20295,#20293)
+enclosing_stmt(#20295,#20262)
+expr_containers(#20295,#20001)
#20296=*
-exprs(#20296,78,#20293,0,"x")
-hasLocation(#20296,#20145)
-expr_containers(#20296,#20293)
-literals("x","x",#20296)
-decl(#20296,#20295)
-#20297=@"var;{arguments};{#20294}"
-variables(#20297,"arguments",#20294)
-is_arguments_object(#20297)
+scopes(#20296,1)
+scopenodes(#20295,#20296)
+scopenesting(#20296,#20265)
+#20297=@"var;{x};{#20296}"
+variables(#20297,"x",#20296)
#20298=*
-typeexprs(#20298,2,#20293,-6,"any")
-hasLocation(#20298,#20149)
-expr_containers(#20298,#20293)
-literals("any","any",#20298)
-#20299=*
-stmts(#20299,1,#20293,-2,"{}")
-#20300=@"loc,{#10000},11,13,11,14"
-locations_default(#20300,#10000,11,13,11,14)
-hasLocation(#20299,#20300)
-stmt_containers(#20299,#20293)
-is_method(#20290)
+exprs(#20298,78,#20295,0,"x")
+hasLocation(#20298,#20145)
+expr_containers(#20298,#20295)
+literals("x","x",#20298)
+decl(#20298,#20297)
+#20299=@"var;{arguments};{#20296}"
+variables(#20299,"arguments",#20296)
+is_arguments_object(#20299)
+#20300=*
+typeexprs(#20300,2,#20295,-6,"any")
+hasLocation(#20300,#20149)
+expr_containers(#20300,#20295)
+literals("any","any",#20300)
#20301=*
-properties(#20301,#20260,6,8,"abstract x: number;")
-#20302=@"loc,{#10000},14,3,14,21"
-locations_default(#20302,#10000,14,3,14,21)
+stmts(#20301,1,#20295,-2,"{}")
+#20302=@"loc,{#10000},11,13,11,14"
+locations_default(#20302,#10000,11,13,11,14)
hasLocation(#20301,#20302)
+stmt_containers(#20301,#20295)
+is_method(#20292)
#20303=*
-#20304=*
-exprs(#20304,0,#20301,0,"x")
-hasLocation(#20304,#20159)
-expr_containers(#20304,#20303)
-literals("x","x",#20304)
-is_abstract_member(#20301)
+properties(#20303,#20262,6,8,"abstract x: number;")
+#20304=@"loc,{#10000},14,3,14,21"
+locations_default(#20304,#10000,14,3,14,21)
+hasLocation(#20303,#20304)
#20305=*
-typeexprs(#20305,2,#20301,2,"number")
-hasLocation(#20305,#20163)
-enclosing_stmt(#20305,#20260)
-expr_containers(#20305,#20001)
-literals("number","number",#20305)
#20306=*
-properties(#20306,#20260,7,0,"constructor() {}")
-#20307=@"loc,{#10000},4,18,4,17"
-locations_default(#20307,#10000,4,18,4,17)
-hasLocation(#20306,#20307)
+exprs(#20306,0,#20303,0,"x")
+hasLocation(#20306,#20159)
+expr_containers(#20306,#20305)
+literals("x","x",#20306)
+is_abstract_member(#20303)
+#20307=*
+typeexprs(#20307,2,#20303,2,"number")
+hasLocation(#20307,#20163)
+enclosing_stmt(#20307,#20262)
+expr_containers(#20307,#20001)
+literals("number","number",#20307)
#20308=*
-exprs(#20308,0,#20306,0,"constructor")
-hasLocation(#20308,#20307)
-enclosing_stmt(#20308,#20260)
-expr_containers(#20308,#20001)
-literals("constructor","constructor",#20308)
-exprs(#20303,9,#20306,1,"() {}")
-hasLocation(#20303,#20307)
-enclosing_stmt(#20303,#20260)
-expr_containers(#20303,#20001)
-#20309=*
-scopes(#20309,1)
-scopenodes(#20303,#20309)
-scopenesting(#20309,#20263)
-#20310=@"var;{arguments};{#20309}"
-variables(#20310,"arguments",#20309)
-is_arguments_object(#20310)
+properties(#20308,#20262,7,0,"constructor() {}")
+#20309=@"loc,{#10000},4,18,4,17"
+locations_default(#20309,#10000,4,18,4,17)
+hasLocation(#20308,#20309)
+#20310=*
+exprs(#20310,0,#20308,0,"constructor")
+hasLocation(#20310,#20309)
+enclosing_stmt(#20310,#20262)
+expr_containers(#20310,#20001)
+literals("constructor","constructor",#20310)
+exprs(#20305,9,#20308,1,"() {}")
+hasLocation(#20305,#20309)
+enclosing_stmt(#20305,#20262)
+expr_containers(#20305,#20001)
#20311=*
-stmts(#20311,1,#20303,-2,"{}")
-hasLocation(#20311,#20307)
-stmt_containers(#20311,#20303)
-is_method(#20306)
-#20312=*
-stmts(#20312,26,#20001,2,"declare ... mber;\n}")
-#20313=@"loc,{#10000},18,1,29,1"
-locations_default(#20313,#10000,18,1,29,1)
-hasLocation(#20312,#20313)
-stmt_containers(#20312,#20001)
-has_declare_keyword(#20312)
-is_abstract_class(#20312)
+scopes(#20311,1)
+scopenodes(#20305,#20311)
+scopenesting(#20311,#20265)
+#20312=@"var;{arguments};{#20311}"
+variables(#20312,"arguments",#20311)
+is_arguments_object(#20312)
+#20313=*
+stmts(#20313,1,#20305,-2,"{}")
+hasLocation(#20313,#20309)
+stmt_containers(#20313,#20305)
+is_method(#20308)
#20314=*
-exprs(#20314,78,#20312,0,"D")
-hasLocation(#20314,#20174)
-enclosing_stmt(#20314,#20312)
-expr_containers(#20314,#20001)
-literals("D","D",#20314)
-#20315=@"var;{D};{#20000}"
-variables(#20315,"D",#20000)
-decl(#20314,#20315)
+stmts(#20314,26,#20001,2,"declare ... mber;\n}")
+#20315=@"loc,{#10000},18,1,29,1"
+locations_default(#20315,#10000,18,1,29,1)
+hasLocation(#20314,#20315)
+stmt_containers(#20314,#20001)
+has_declare_keyword(#20314)
+is_abstract_class(#20314)
#20316=*
-scopes(#20316,10)
-scopenodes(#20312,#20316)
-scopenesting(#20316,#20000)
+exprs(#20316,78,#20314,0,"D")
+hasLocation(#20316,#20174)
+enclosing_stmt(#20316,#20314)
+expr_containers(#20316,#20001)
+literals("D","D",#20316)
+decl(#20316,#20255)
+typedecl(#20316,#20257)
#20317=*
-properties(#20317,#20312,2,0,"abstract h();")
-#20318=@"loc,{#10000},20,3,20,15"
-locations_default(#20318,#10000,20,3,20,15)
-hasLocation(#20317,#20318)
-#20319=*
-exprs(#20319,0,#20317,0,"h")
-hasLocation(#20319,#20180)
-enclosing_stmt(#20319,#20312)
-expr_containers(#20319,#20001)
-literals("h","h",#20319)
+scopes(#20317,10)
+scopenodes(#20314,#20317)
+scopenesting(#20317,#20000)
+#20318=*
+properties(#20318,#20314,2,0,"abstract h();")
+#20319=@"loc,{#10000},20,3,20,15"
+locations_default(#20319,#10000,20,3,20,15)
+hasLocation(#20318,#20319)
#20320=*
-exprs(#20320,9,#20317,1,"abstract h();")
-hasLocation(#20320,#20318)
-enclosing_stmt(#20320,#20312)
+exprs(#20320,0,#20318,0,"h")
+hasLocation(#20320,#20180)
+enclosing_stmt(#20320,#20314)
expr_containers(#20320,#20001)
+literals("h","h",#20320)
#20321=*
-scopes(#20321,1)
-scopenodes(#20320,#20321)
-scopenesting(#20321,#20316)
-#20322=@"var;{arguments};{#20321}"
-variables(#20322,"arguments",#20321)
-is_arguments_object(#20322)
-is_method(#20317)
-is_abstract_member(#20317)
-#20323=*
-properties(#20323,#20312,3,0,"g(x: nu ... number;")
-#20324=@"loc,{#10000},23,3,23,23"
-locations_default(#20324,#10000,23,3,23,23)
-hasLocation(#20323,#20324)
-#20325=*
-exprs(#20325,0,#20323,0,"g")
-hasLocation(#20325,#20188)
-enclosing_stmt(#20325,#20312)
-expr_containers(#20325,#20001)
-literals("g","g",#20325)
+exprs(#20321,9,#20318,1,"abstract h();")
+hasLocation(#20321,#20319)
+enclosing_stmt(#20321,#20314)
+expr_containers(#20321,#20001)
+#20322=*
+scopes(#20322,1)
+scopenodes(#20321,#20322)
+scopenesting(#20322,#20317)
+#20323=@"var;{arguments};{#20322}"
+variables(#20323,"arguments",#20322)
+is_arguments_object(#20323)
+is_method(#20318)
+is_abstract_member(#20318)
+#20324=*
+properties(#20324,#20314,3,0,"g(x: nu ... number;")
+#20325=@"loc,{#10000},23,3,23,23"
+locations_default(#20325,#10000,23,3,23,23)
+hasLocation(#20324,#20325)
#20326=*
-exprs(#20326,9,#20323,1,"g(x: nu ... number;")
-hasLocation(#20326,#20324)
-enclosing_stmt(#20326,#20312)
+exprs(#20326,0,#20324,0,"g")
+hasLocation(#20326,#20188)
+enclosing_stmt(#20326,#20314)
expr_containers(#20326,#20001)
+literals("g","g",#20326)
#20327=*
-scopes(#20327,1)
-scopenodes(#20326,#20327)
-scopenesting(#20327,#20316)
-#20328=@"var;{x};{#20327}"
-variables(#20328,"x",#20327)
-#20329=*
-exprs(#20329,78,#20326,0,"x")
-hasLocation(#20329,#20192)
-expr_containers(#20329,#20326)
-literals("x","x",#20329)
-decl(#20329,#20328)
-#20330=@"var;{arguments};{#20327}"
-variables(#20330,"arguments",#20327)
-is_arguments_object(#20330)
-#20331=*
-typeexprs(#20331,2,#20326,-3,"number")
-hasLocation(#20331,#20202)
-expr_containers(#20331,#20326)
-literals("number","number",#20331)
+exprs(#20327,9,#20324,1,"g(x: nu ... number;")
+hasLocation(#20327,#20325)
+enclosing_stmt(#20327,#20314)
+expr_containers(#20327,#20001)
+#20328=*
+scopes(#20328,1)
+scopenodes(#20327,#20328)
+scopenesting(#20328,#20317)
+#20329=@"var;{x};{#20328}"
+variables(#20329,"x",#20328)
+#20330=*
+exprs(#20330,78,#20327,0,"x")
+hasLocation(#20330,#20192)
+expr_containers(#20330,#20327)
+literals("x","x",#20330)
+decl(#20330,#20329)
+#20331=@"var;{arguments};{#20328}"
+variables(#20331,"arguments",#20328)
+is_arguments_object(#20331)
#20332=*
-typeexprs(#20332,2,#20326,-6,"number")
-hasLocation(#20332,#20196)
-expr_containers(#20332,#20326)
+typeexprs(#20332,2,#20327,-3,"number")
+hasLocation(#20332,#20202)
+expr_containers(#20332,#20327)
literals("number","number",#20332)
-is_method(#20323)
#20333=*
-properties(#20333,#20312,4,0,"g(x: st ... string;")
-#20334=@"loc,{#10000},24,3,24,23"
-locations_default(#20334,#10000,24,3,24,23)
-hasLocation(#20333,#20334)
-#20335=*
-exprs(#20335,0,#20333,0,"g")
-hasLocation(#20335,#20206)
-enclosing_stmt(#20335,#20312)
-expr_containers(#20335,#20001)
-literals("g","g",#20335)
+typeexprs(#20333,2,#20327,-6,"number")
+hasLocation(#20333,#20196)
+expr_containers(#20333,#20327)
+literals("number","number",#20333)
+is_method(#20324)
+#20334=*
+properties(#20334,#20314,4,0,"g(x: st ... string;")
+#20335=@"loc,{#10000},24,3,24,23"
+locations_default(#20335,#10000,24,3,24,23)
+hasLocation(#20334,#20335)
#20336=*
-exprs(#20336,9,#20333,1,"g(x: st ... string;")
-hasLocation(#20336,#20334)
-enclosing_stmt(#20336,#20312)
+exprs(#20336,0,#20334,0,"g")
+hasLocation(#20336,#20206)
+enclosing_stmt(#20336,#20314)
expr_containers(#20336,#20001)
+literals("g","g",#20336)
#20337=*
-scopes(#20337,1)
-scopenodes(#20336,#20337)
-scopenesting(#20337,#20316)
-#20338=@"var;{x};{#20337}"
-variables(#20338,"x",#20337)
-#20339=*
-exprs(#20339,78,#20336,0,"x")
-hasLocation(#20339,#20210)
-expr_containers(#20339,#20336)
-literals("x","x",#20339)
-decl(#20339,#20338)
-#20340=@"var;{arguments};{#20337}"
-variables(#20340,"arguments",#20337)
-is_arguments_object(#20340)
-#20341=*
-typeexprs(#20341,2,#20336,-3,"string")
-hasLocation(#20341,#20220)
-expr_containers(#20341,#20336)
-literals("string","string",#20341)
+exprs(#20337,9,#20334,1,"g(x: st ... string;")
+hasLocation(#20337,#20335)
+enclosing_stmt(#20337,#20314)
+expr_containers(#20337,#20001)
+#20338=*
+scopes(#20338,1)
+scopenodes(#20337,#20338)
+scopenesting(#20338,#20317)
+#20339=@"var;{x};{#20338}"
+variables(#20339,"x",#20338)
+#20340=*
+exprs(#20340,78,#20337,0,"x")
+hasLocation(#20340,#20210)
+expr_containers(#20340,#20337)
+literals("x","x",#20340)
+decl(#20340,#20339)
+#20341=@"var;{arguments};{#20338}"
+variables(#20341,"arguments",#20338)
+is_arguments_object(#20341)
#20342=*
-typeexprs(#20342,2,#20336,-6,"string")
-hasLocation(#20342,#20214)
-expr_containers(#20342,#20336)
+typeexprs(#20342,2,#20337,-3,"string")
+hasLocation(#20342,#20220)
+expr_containers(#20342,#20337)
literals("string","string",#20342)
-is_method(#20333)
#20343=*
-properties(#20343,#20312,5,0,"g(x: any) {}")
-#20344=@"loc,{#10000},25,3,25,14"
-locations_default(#20344,#10000,25,3,25,14)
-hasLocation(#20343,#20344)
-#20345=*
-exprs(#20345,0,#20343,0,"g")
-hasLocation(#20345,#20224)
-enclosing_stmt(#20345,#20312)
-expr_containers(#20345,#20001)
-literals("g","g",#20345)
+typeexprs(#20343,2,#20337,-6,"string")
+hasLocation(#20343,#20214)
+expr_containers(#20343,#20337)
+literals("string","string",#20343)
+is_method(#20334)
+#20344=*
+properties(#20344,#20314,5,0,"g(x: any) {}")
+#20345=@"loc,{#10000},25,3,25,14"
+locations_default(#20345,#10000,25,3,25,14)
+hasLocation(#20344,#20345)
#20346=*
-exprs(#20346,9,#20343,1,"g(x: any) {}")
-hasLocation(#20346,#20344)
-enclosing_stmt(#20346,#20312)
+exprs(#20346,0,#20344,0,"g")
+hasLocation(#20346,#20224)
+enclosing_stmt(#20346,#20314)
expr_containers(#20346,#20001)
+literals("g","g",#20346)
#20347=*
-scopes(#20347,1)
-scopenodes(#20346,#20347)
-scopenesting(#20347,#20316)
-#20348=@"var;{x};{#20347}"
-variables(#20348,"x",#20347)
-#20349=*
-exprs(#20349,78,#20346,0,"x")
-hasLocation(#20349,#20228)
-expr_containers(#20349,#20346)
-literals("x","x",#20349)
-decl(#20349,#20348)
-#20350=@"var;{arguments};{#20347}"
-variables(#20350,"arguments",#20347)
-is_arguments_object(#20350)
-#20351=*
-typeexprs(#20351,2,#20346,-6,"any")
-hasLocation(#20351,#20232)
-expr_containers(#20351,#20346)
-literals("any","any",#20351)
+exprs(#20347,9,#20344,1,"g(x: any) {}")
+hasLocation(#20347,#20345)
+enclosing_stmt(#20347,#20314)
+expr_containers(#20347,#20001)
+#20348=*
+scopes(#20348,1)
+scopenodes(#20347,#20348)
+scopenesting(#20348,#20317)
+#20349=@"var;{x};{#20348}"
+variables(#20349,"x",#20348)
+#20350=*
+exprs(#20350,78,#20347,0,"x")
+hasLocation(#20350,#20228)
+expr_containers(#20350,#20347)
+literals("x","x",#20350)
+decl(#20350,#20349)
+#20351=@"var;{arguments};{#20348}"
+variables(#20351,"arguments",#20348)
+is_arguments_object(#20351)
#20352=*
-stmts(#20352,1,#20346,-2,"{}")
-#20353=@"loc,{#10000},25,13,25,14"
-locations_default(#20353,#10000,25,13,25,14)
-hasLocation(#20352,#20353)
-stmt_containers(#20352,#20346)
-is_method(#20343)
-#20354=*
-properties(#20354,#20312,6,8,"abstract x: number;")
-#20355=@"loc,{#10000},28,3,28,21"
-locations_default(#20355,#10000,28,3,28,21)
-hasLocation(#20354,#20355)
-#20356=*
+typeexprs(#20352,2,#20347,-6,"any")
+hasLocation(#20352,#20232)
+expr_containers(#20352,#20347)
+literals("any","any",#20352)
+#20353=*
+stmts(#20353,1,#20347,-2,"{}")
+#20354=@"loc,{#10000},25,13,25,14"
+locations_default(#20354,#10000,25,13,25,14)
+hasLocation(#20353,#20354)
+stmt_containers(#20353,#20347)
+is_method(#20344)
+#20355=*
+properties(#20355,#20314,6,8,"abstract x: number;")
+#20356=@"loc,{#10000},28,3,28,21"
+locations_default(#20356,#10000,28,3,28,21)
+hasLocation(#20355,#20356)
#20357=*
-exprs(#20357,0,#20354,0,"x")
-hasLocation(#20357,#20242)
-expr_containers(#20357,#20356)
-literals("x","x",#20357)
-is_abstract_member(#20354)
#20358=*
-typeexprs(#20358,2,#20354,2,"number")
-hasLocation(#20358,#20246)
-enclosing_stmt(#20358,#20312)
-expr_containers(#20358,#20001)
-literals("number","number",#20358)
+exprs(#20358,0,#20355,0,"x")
+hasLocation(#20358,#20242)
+expr_containers(#20358,#20357)
+literals("x","x",#20358)
+is_abstract_member(#20355)
#20359=*
-properties(#20359,#20312,7,0,"constructor() {}")
-#20360=@"loc,{#10000},18,26,18,25"
-locations_default(#20360,#10000,18,26,18,25)
-hasLocation(#20359,#20360)
-#20361=*
-exprs(#20361,0,#20359,0,"constructor")
-hasLocation(#20361,#20360)
-enclosing_stmt(#20361,#20312)
-expr_containers(#20361,#20001)
-literals("constructor","constructor",#20361)
-exprs(#20356,9,#20359,1,"() {}")
-hasLocation(#20356,#20360)
-enclosing_stmt(#20356,#20312)
-expr_containers(#20356,#20001)
+typeexprs(#20359,2,#20355,2,"number")
+hasLocation(#20359,#20246)
+enclosing_stmt(#20359,#20314)
+expr_containers(#20359,#20001)
+literals("number","number",#20359)
+#20360=*
+properties(#20360,#20314,7,0,"constructor() {}")
+#20361=@"loc,{#10000},18,26,18,25"
+locations_default(#20361,#10000,18,26,18,25)
+hasLocation(#20360,#20361)
#20362=*
-scopes(#20362,1)
-scopenodes(#20356,#20362)
-scopenesting(#20362,#20316)
-#20363=@"var;{arguments};{#20362}"
-variables(#20363,"arguments",#20362)
-is_arguments_object(#20363)
-#20364=*
-stmts(#20364,1,#20356,-2,"{}")
-hasLocation(#20364,#20360)
-stmt_containers(#20364,#20356)
-is_method(#20359)
+exprs(#20362,0,#20360,0,"constructor")
+hasLocation(#20362,#20361)
+enclosing_stmt(#20362,#20314)
+expr_containers(#20362,#20001)
+literals("constructor","constructor",#20362)
+exprs(#20357,9,#20360,1,"() {}")
+hasLocation(#20357,#20361)
+enclosing_stmt(#20357,#20314)
+expr_containers(#20357,#20001)
+#20363=*
+scopes(#20363,1)
+scopenodes(#20357,#20363)
+scopenesting(#20363,#20317)
+#20364=@"var;{arguments};{#20363}"
+variables(#20364,"arguments",#20363)
+is_arguments_object(#20364)
#20365=*
-entry_cfg_node(#20365,#20001)
-#20366=@"loc,{#10000},2,1,2,0"
-locations_default(#20366,#10000,2,1,2,0)
-hasLocation(#20365,#20366)
-#20367=*
-exit_cfg_node(#20367,#20001)
-hasLocation(#20367,#20251)
-successor(#20312,#20367)
-successor(#20303,#20306)
+stmts(#20365,1,#20357,-2,"{}")
+hasLocation(#20365,#20361)
+stmt_containers(#20365,#20357)
+is_method(#20360)
+#20366=*
+entry_cfg_node(#20366,#20001)
+#20367=@"loc,{#10000},2,1,2,0"
+locations_default(#20367,#10000,2,1,2,0)
+hasLocation(#20366,#20367)
#20368=*
-entry_cfg_node(#20368,#20303)
-hasLocation(#20368,#20307)
+exit_cfg_node(#20368,#20001)
+hasLocation(#20368,#20251)
+successor(#20314,#20368)
+successor(#20305,#20308)
#20369=*
-exit_cfg_node(#20369,#20303)
-hasLocation(#20369,#20307)
-successor(#20311,#20369)
-successor(#20368,#20311)
-successor(#20308,#20303)
-successor(#20306,#20260)
-successor(#20293,#20290)
+entry_cfg_node(#20369,#20305)
+hasLocation(#20369,#20309)
#20370=*
-entry_cfg_node(#20370,#20293)
-#20371=@"loc,{#10000},11,3,11,2"
-locations_default(#20371,#10000,11,3,11,2)
-hasLocation(#20370,#20371)
-#20372=*
-exit_cfg_node(#20372,#20293)
-#20373=@"loc,{#10000},11,15,11,14"
-locations_default(#20373,#10000,11,15,11,14)
-hasLocation(#20372,#20373)
-successor(#20299,#20372)
-successor(#20296,#20299)
-successor(#20370,#20296)
-successor(#20292,#20293)
-successor(#20290,#20308)
-successor(#20280,#20292)
-successor(#20270,#20280)
-successor(#20264,#20270)
-successor(#20262,#20264)
-successor(#20260,#20312)
-successor(#20255,#20262)
-successor(#20365,#20255)
+exit_cfg_node(#20370,#20305)
+hasLocation(#20370,#20309)
+successor(#20313,#20370)
+successor(#20369,#20313)
+successor(#20310,#20305)
+successor(#20308,#20262)
+successor(#20295,#20292)
+#20371=*
+entry_cfg_node(#20371,#20295)
+#20372=@"loc,{#10000},11,3,11,2"
+locations_default(#20372,#10000,11,3,11,2)
+hasLocation(#20371,#20372)
+#20373=*
+exit_cfg_node(#20373,#20295)
+#20374=@"loc,{#10000},11,15,11,14"
+locations_default(#20374,#10000,11,15,11,14)
+hasLocation(#20373,#20374)
+successor(#20301,#20373)
+successor(#20298,#20301)
+successor(#20371,#20298)
+successor(#20294,#20295)
+successor(#20292,#20310)
+successor(#20282,#20294)
+successor(#20272,#20282)
+successor(#20266,#20272)
+successor(#20264,#20266)
+successor(#20262,#20314)
+successor(#20258,#20264)
+successor(#20366,#20258)
numlines(#10000,29,15,8)
filetype(#10000,"typescript")
diff --git a/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap b/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap
index 0e766cf77b99..27b075f05c76 100644
--- a/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap
+++ b/javascript/extractor/tests/ts/output/trap/thisparameter.ts.trap
@@ -425,146 +425,146 @@ hasLocation(#20001,#20158)
variables(#20159,"declaration",#20000)
#20160=@"var;{f};{#20000}"
variables(#20160,"f",#20000)
-#20161=@"var;{C};{#20000}"
-variables(#20161,"C",#20000)
-#20162=@"local_type_name;{C};{#20000}"
-local_type_names(#20162,"C",#20000)
-#20163=@"local_type_name;{I};{#20000}"
-local_type_names(#20163,"I",#20000)
-#20164=*
-stmts(#20164,17,#20001,0,"functio ... ber) {}")
-hasLocation(#20164,#20003)
-stmt_containers(#20164,#20001)
+#20161=@"var;{ambient};{#20000}"
+variables(#20161,"ambient",#20000)
+#20162=@"var;{C};{#20000}"
+variables(#20162,"C",#20000)
+#20163=@"local_type_name;{C};{#20000}"
+local_type_names(#20163,"C",#20000)
+#20164=@"local_type_name;{I};{#20000}"
+local_type_names(#20164,"I",#20000)
#20165=*
-exprs(#20165,78,#20164,-1,"declaration")
-hasLocation(#20165,#20033)
-expr_containers(#20165,#20164)
-literals("declaration","declaration",#20165)
-decl(#20165,#20159)
+stmts(#20165,17,#20001,0,"functio ... ber) {}")
+hasLocation(#20165,#20003)
+stmt_containers(#20165,#20001)
#20166=*
-scopes(#20166,1)
-scopenodes(#20164,#20166)
-scopenesting(#20166,#20000)
-#20167=@"var;{x};{#20166}"
-variables(#20167,"x",#20166)
-#20168=*
-exprs(#20168,78,#20164,0,"x")
-hasLocation(#20168,#20045)
-expr_containers(#20168,#20164)
-literals("x","x",#20168)
-decl(#20168,#20167)
-#20169=@"var;{arguments};{#20166}"
-variables(#20169,"arguments",#20166)
-is_arguments_object(#20169)
-#20170=*
-typeexprs(#20170,2,#20164,-4,"void")
-hasLocation(#20170,#20041)
-expr_containers(#20170,#20164)
-literals("void","void",#20170)
+exprs(#20166,78,#20165,-1,"declaration")
+hasLocation(#20166,#20033)
+expr_containers(#20166,#20165)
+literals("declaration","declaration",#20166)
+decl(#20166,#20159)
+#20167=*
+scopes(#20167,1)
+scopenodes(#20165,#20167)
+scopenesting(#20167,#20000)
+#20168=@"var;{x};{#20167}"
+variables(#20168,"x",#20167)
+#20169=*
+exprs(#20169,78,#20165,0,"x")
+hasLocation(#20169,#20045)
+expr_containers(#20169,#20165)
+literals("x","x",#20169)
+decl(#20169,#20168)
+#20170=@"var;{arguments};{#20167}"
+variables(#20170,"arguments",#20167)
+is_arguments_object(#20170)
#20171=*
-typeexprs(#20171,2,#20164,-6,"number")
-hasLocation(#20171,#20049)
-expr_containers(#20171,#20164)
-literals("number","number",#20171)
+typeexprs(#20171,2,#20165,-4,"void")
+hasLocation(#20171,#20041)
+expr_containers(#20171,#20165)
+literals("void","void",#20171)
#20172=*
-stmts(#20172,1,#20164,-2,"{}")
-#20173=@"loc,{#10000},1,45,1,46"
-locations_default(#20173,#10000,1,45,1,46)
-hasLocation(#20172,#20173)
-stmt_containers(#20172,#20164)
-#20174=*
-stmts(#20174,18,#20001,1,"var f = ... ber) {}")
-hasLocation(#20174,#20007)
-stmt_containers(#20174,#20001)
+typeexprs(#20172,2,#20165,-6,"number")
+hasLocation(#20172,#20049)
+expr_containers(#20172,#20165)
+literals("number","number",#20172)
+#20173=*
+stmts(#20173,1,#20165,-2,"{}")
+#20174=@"loc,{#10000},1,45,1,46"
+locations_default(#20174,#10000,1,45,1,46)
+hasLocation(#20173,#20174)
+stmt_containers(#20173,#20165)
#20175=*
-exprs(#20175,64,#20174,0,"f = fun ... ber) {}")
-#20176=@"loc,{#10000},3,5,3,44"
-locations_default(#20176,#10000,3,5,3,44)
-hasLocation(#20175,#20176)
-enclosing_stmt(#20175,#20174)
-expr_containers(#20175,#20001)
-#20177=*
-exprs(#20177,78,#20175,0,"f")
-hasLocation(#20177,#20059)
-enclosing_stmt(#20177,#20174)
-expr_containers(#20177,#20001)
-literals("f","f",#20177)
-decl(#20177,#20160)
+stmts(#20175,18,#20001,1,"var f = ... ber) {}")
+hasLocation(#20175,#20007)
+stmt_containers(#20175,#20001)
+#20176=*
+exprs(#20176,64,#20175,0,"f = fun ... ber) {}")
+#20177=@"loc,{#10000},3,5,3,44"
+locations_default(#20177,#10000,3,5,3,44)
+hasLocation(#20176,#20177)
+enclosing_stmt(#20176,#20175)
+expr_containers(#20176,#20001)
#20178=*
-exprs(#20178,9,#20175,1,"functio ... ber) {}")
-#20179=@"loc,{#10000},3,9,3,44"
-locations_default(#20179,#10000,3,9,3,44)
-hasLocation(#20178,#20179)
-enclosing_stmt(#20178,#20174)
+exprs(#20178,78,#20176,0,"f")
+hasLocation(#20178,#20059)
+enclosing_stmt(#20178,#20175)
expr_containers(#20178,#20001)
-#20180=*
-scopes(#20180,1)
-scopenodes(#20178,#20180)
-scopenesting(#20180,#20000)
-#20181=@"var;{x};{#20180}"
-variables(#20181,"x",#20180)
-#20182=*
-exprs(#20182,78,#20178,0,"x")
-hasLocation(#20182,#20075)
-expr_containers(#20182,#20178)
-literals("x","x",#20182)
-decl(#20182,#20181)
-#20183=@"var;{arguments};{#20180}"
-variables(#20183,"arguments",#20180)
-is_arguments_object(#20183)
-#20184=*
-typeexprs(#20184,2,#20178,-4,"string")
-hasLocation(#20184,#20071)
-expr_containers(#20184,#20178)
-literals("string","string",#20184)
+literals("f","f",#20178)
+decl(#20178,#20160)
+#20179=*
+exprs(#20179,9,#20176,1,"functio ... ber) {}")
+#20180=@"loc,{#10000},3,9,3,44"
+locations_default(#20180,#10000,3,9,3,44)
+hasLocation(#20179,#20180)
+enclosing_stmt(#20179,#20175)
+expr_containers(#20179,#20001)
+#20181=*
+scopes(#20181,1)
+scopenodes(#20179,#20181)
+scopenesting(#20181,#20000)
+#20182=@"var;{x};{#20181}"
+variables(#20182,"x",#20181)
+#20183=*
+exprs(#20183,78,#20179,0,"x")
+hasLocation(#20183,#20075)
+expr_containers(#20183,#20179)
+literals("x","x",#20183)
+decl(#20183,#20182)
+#20184=@"var;{arguments};{#20181}"
+variables(#20184,"arguments",#20181)
+is_arguments_object(#20184)
#20185=*
-typeexprs(#20185,2,#20178,-6,"number")
-hasLocation(#20185,#20079)
-expr_containers(#20185,#20178)
-literals("number","number",#20185)
+typeexprs(#20185,2,#20179,-4,"string")
+hasLocation(#20185,#20071)
+expr_containers(#20185,#20179)
+literals("string","string",#20185)
#20186=*
-stmts(#20186,1,#20178,-2,"{}")
-#20187=@"loc,{#10000},3,43,3,44"
-locations_default(#20187,#10000,3,43,3,44)
-hasLocation(#20186,#20187)
-stmt_containers(#20186,#20178)
-#20188=*
-stmts(#20188,17,#20001,2,"declare ... umber);")
-hasLocation(#20188,#20011)
-stmt_containers(#20188,#20001)
-has_declare_keyword(#20188)
+typeexprs(#20186,2,#20179,-6,"number")
+hasLocation(#20186,#20079)
+expr_containers(#20186,#20179)
+literals("number","number",#20186)
+#20187=*
+stmts(#20187,1,#20179,-2,"{}")
+#20188=@"loc,{#10000},3,43,3,44"
+locations_default(#20188,#10000,3,43,3,44)
+hasLocation(#20187,#20188)
+stmt_containers(#20187,#20179)
#20189=*
-exprs(#20189,78,#20188,-1,"ambient")
-hasLocation(#20189,#20091)
-expr_containers(#20189,#20188)
-literals("ambient","ambient",#20189)
-#20190=@"var;{ambient};{#20000}"
-variables(#20190,"ambient",#20000)
-decl(#20189,#20190)
+stmts(#20189,17,#20001,2,"declare ... umber);")
+hasLocation(#20189,#20011)
+stmt_containers(#20189,#20001)
+has_declare_keyword(#20189)
+#20190=*
+exprs(#20190,78,#20189,-1,"ambient")
+hasLocation(#20190,#20091)
+expr_containers(#20190,#20189)
+literals("ambient","ambient",#20190)
+decl(#20190,#20161)
#20191=*
scopes(#20191,1)
-scopenodes(#20188,#20191)
+scopenodes(#20189,#20191)
scopenesting(#20191,#20000)
#20192=@"var;{x};{#20191}"
variables(#20192,"x",#20191)
#20193=*
-exprs(#20193,78,#20188,0,"x")
+exprs(#20193,78,#20189,0,"x")
hasLocation(#20193,#20103)
-expr_containers(#20193,#20188)
+expr_containers(#20193,#20189)
literals("x","x",#20193)
decl(#20193,#20192)
#20194=@"var;{arguments};{#20191}"
variables(#20194,"arguments",#20191)
is_arguments_object(#20194)
#20195=*
-typeexprs(#20195,2,#20188,-4,"string")
+typeexprs(#20195,2,#20189,-4,"string")
hasLocation(#20195,#20099)
-expr_containers(#20195,#20188)
+expr_containers(#20195,#20189)
literals("string","string",#20195)
#20196=*
-typeexprs(#20196,2,#20188,-6,"number")
+typeexprs(#20196,2,#20189,-6,"number")
hasLocation(#20196,#20107)
-expr_containers(#20196,#20188)
+expr_containers(#20196,#20189)
literals("number","number",#20196)
#20197=*
stmts(#20197,26,#20001,3,"class C ... C) {}\n}")
@@ -578,8 +578,8 @@ hasLocation(#20199,#20115)
enclosing_stmt(#20199,#20197)
expr_containers(#20199,#20001)
literals("C","C",#20199)
-decl(#20199,#20161)
-typedecl(#20199,#20162)
+decl(#20199,#20162)
+typedecl(#20199,#20163)
#20200=*
scopes(#20200,10)
scopenodes(#20197,#20200)
@@ -612,7 +612,7 @@ typeexprs(#20207,0,#20204,-4,"C")
hasLocation(#20207,#20127)
expr_containers(#20207,#20204)
literals("C","C",#20207)
-typebind(#20207,#20162)
+typebind(#20207,#20163)
#20208=*
stmts(#20208,1,#20204,-2,"{}")
#20209=@"loc,{#10000},8,19,8,20"
@@ -660,7 +660,7 @@ hasLocation(#20219,#20138)
enclosing_stmt(#20219,#20217)
expr_containers(#20219,#20001)
literals("I","I",#20219)
-typedecl(#20219,#20163)
+typedecl(#20219,#20164)
#20220=*
properties(#20220,#20217,2,0,"method(this: I);")
#20221=@"loc,{#10000},12,3,12,18"
@@ -689,7 +689,7 @@ typeexprs(#20226,0,#20223,-4,"I")
hasLocation(#20226,#20150)
expr_containers(#20226,#20223)
literals("I","I",#20226)
-typebind(#20226,#20163)
+typebind(#20226,#20164)
is_method(#20220)
is_abstract_member(#20220)
#20227=*
@@ -729,37 +729,37 @@ successor(#20203,#20204)
successor(#20201,#20212)
successor(#20199,#20203)
successor(#20197,#20217)
-successor(#20188,#20199)
-successor(#20174,#20177)
-successor(#20178,#20175)
+successor(#20189,#20199)
+successor(#20175,#20178)
+successor(#20179,#20176)
#20236=*
-entry_cfg_node(#20236,#20178)
+entry_cfg_node(#20236,#20179)
#20237=@"loc,{#10000},3,9,3,8"
locations_default(#20237,#10000,3,9,3,8)
hasLocation(#20236,#20237)
#20238=*
-exit_cfg_node(#20238,#20178)
+exit_cfg_node(#20238,#20179)
#20239=@"loc,{#10000},3,45,3,44"
locations_default(#20239,#10000,3,45,3,44)
hasLocation(#20238,#20239)
-successor(#20186,#20238)
-successor(#20182,#20186)
-successor(#20236,#20182)
-successor(#20177,#20178)
-successor(#20175,#20188)
-successor(#20164,#20174)
+successor(#20187,#20238)
+successor(#20183,#20187)
+successor(#20236,#20183)
+successor(#20178,#20179)
+successor(#20176,#20189)
+successor(#20165,#20175)
#20240=*
-entry_cfg_node(#20240,#20164)
+entry_cfg_node(#20240,#20165)
hasLocation(#20240,#20228)
#20241=*
-exit_cfg_node(#20241,#20164)
+exit_cfg_node(#20241,#20165)
#20242=@"loc,{#10000},1,47,1,46"
locations_default(#20242,#10000,1,47,1,46)
hasLocation(#20241,#20242)
-successor(#20172,#20241)
-successor(#20168,#20172)
-successor(#20240,#20168)
-successor(#20165,#20164)
-successor(#20227,#20165)
+successor(#20173,#20241)
+successor(#20169,#20173)
+successor(#20240,#20169)
+successor(#20166,#20165)
+successor(#20227,#20166)
numlines(#10000,14,9,0)
filetype(#10000,"typescript")
diff --git a/javascript/ql/integration-tests/query-suite/javascript-code-quality.qls.expected b/javascript/ql/integration-tests/query-suite/javascript-code-quality.qls.expected
index 876b5f25fa28..bf646822ddc4 100644
--- a/javascript/ql/integration-tests/query-suite/javascript-code-quality.qls.expected
+++ b/javascript/ql/integration-tests/query-suite/javascript-code-quality.qls.expected
@@ -1,6 +1,9 @@
ql/javascript/ql/src/Declarations/IneffectiveParameterType.ql
+ql/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.ql
ql/javascript/ql/src/Expressions/ExprHasNoEffect.ql
ql/javascript/ql/src/Expressions/MissingAwait.ql
ql/javascript/ql/src/LanguageFeatures/SpuriousArguments.ql
+ql/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
ql/javascript/ql/src/Quality/UnhandledErrorInStreamPipeline.ql
+ql/javascript/ql/src/RegExp/DuplicateCharacterInCharacterClass.ql
ql/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql
diff --git a/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected b/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected
index 34c4df3d6fae..c80c3fc76da1 100644
--- a/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected
+++ b/javascript/ql/integration-tests/query-suite/not_included_in_qls.expected
@@ -147,4 +147,3 @@ ql/javascript/ql/src/meta/extraction-metrics/FileData.ql
ql/javascript/ql/src/meta/extraction-metrics/MissingMetrics.ql
ql/javascript/ql/src/meta/extraction-metrics/PhaseTimings.ql
ql/javascript/ql/src/meta/types/TypedExprs.ql
-ql/javascript/ql/src/meta/types/TypesWithQualifiedName.ql
diff --git a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll
index eff5fa7fc989..9813d9b32ed9 100644
--- a/javascript/ql/lib/Expressions/ExprHasNoEffect.qll
+++ b/javascript/ql/lib/Expressions/ExprHasNoEffect.qll
@@ -22,6 +22,9 @@ predicate inVoidContext(Expr e) {
)
)
or
+ // propagate void context through parenthesized expressions
+ inVoidContext(e.getParent().(ParExpr))
+ or
exists(SeqExpr seq, int i, int n |
e = seq.getOperand(i) and
n = seq.getNumOperands()
@@ -129,6 +132,19 @@ predicate noSideEffects(Expr e) {
)
}
+/**
+ * Holds if `e` is a compound expression that may contain sub-expressions with side effects.
+ * We should not flag these directly as useless since we want to flag only the innermost
+ * expressions that actually have no effect.
+ */
+predicate isCompoundExpression(Expr e) {
+ e instanceof LogicalBinaryExpr
+ or
+ e instanceof SeqExpr
+ or
+ e instanceof ParExpr
+}
+
/**
* Holds if the expression `e` should be reported as having no effect.
*/
@@ -145,6 +161,7 @@ predicate hasNoEffect(Expr e) {
not isDeclaration(e) and
// exclude DOM properties, which sometimes have magical auto-update properties
not isDomProperty(e.(PropAccess).getPropertyName()) and
+ not isCompoundExpression(e) and
// exclude xUnit.js annotations
not e instanceof XUnitAnnotation and
// exclude common patterns that are most likely intentional
@@ -157,7 +174,17 @@ predicate hasNoEffect(Expr e) {
not exists(fe.getName())
) and
// exclude block-level flow type annotations. For example: `(name: empty)`.
- not e.(ParExpr).getExpression().getLastToken().getNextToken().getValue() = ":" and
+ not exists(ParExpr parent |
+ e.getParent() = parent and
+ e.getLastToken().getNextToken().getValue() = ":"
+ ) and
+ // exclude expressions that are part of a conditional expression
+ not exists(ConditionalExpr cond | e = cond.getABranch() |
+ e instanceof NullLiteral or
+ e.(GlobalVarAccess).getName() = "undefined" or
+ e.(NumberLiteral).getIntValue() = 0 or
+ e instanceof VoidExpr
+ ) and
// exclude the first statement of a try block
not e = any(TryStmt stmt).getBody().getStmt(0).(ExprStmt).getExpr() and
// exclude expressions that are alone in a file, and file doesn't contain a function.
diff --git a/javascript/ql/lib/definitions.qll b/javascript/ql/lib/definitions.qll
index 2cc9313d3132..2f1c99b7c606 100644
--- a/javascript/ql/lib/definitions.qll
+++ b/javascript/ql/lib/definitions.qll
@@ -153,17 +153,7 @@ private predicate jsdocTypeLookup(JSDocNamedTypeExpr ref, AstNode decl, string k
kind = "T"
}
-/**
- * Gets an element, of kind `kind`, that element `e` uses, if any.
- *
- * The `kind` is a string representing what kind of use it is:
- * - `"M"` for function and method calls
- * - `"T"` for uses of types
- * - `"V"` for variable accesses
- * - `"I"` for imports
- */
-cached
-AstNode definitionOf(Locatable e, string kind) {
+private AstNode definitionOfRaw(Locatable e, string kind) {
variableDefLookup(e, result, kind)
or
// prefer definitions over declarations
@@ -179,3 +169,46 @@ AstNode definitionOf(Locatable e, string kind) {
or
jsdocTypeLookup(e, result, kind)
}
+
+/** Gets a more useful node to show for something that resolves to `node`. */
+private AstNode redirectOnce(AstNode node) {
+ exists(ConstructorDeclaration ctor |
+ ctor.isSynthetic() and
+ node = ctor.getBody() and
+ result = ctor.getDeclaringClass()
+ )
+ or
+ exists(ClassDefinition cls |
+ node = cls and
+ result = cls.getIdentifier()
+ )
+ or
+ exists(FunctionDeclStmt decl |
+ node = decl and
+ result = decl.getIdentifier()
+ )
+ or
+ exists(MethodDeclaration member |
+ not member instanceof ConstructorDeclaration and
+ node = member.getBody() and
+ result = member.getNameExpr()
+ )
+}
+
+private AstNode redirect(AstNode node) {
+ node = definitionOfRaw(_, _) and
+ result = redirectOnce*(node) and
+ not exists(redirectOnce(result))
+}
+
+/**
+ * Gets an element, of kind `kind`, that element `e` uses, if any.
+ *
+ * The `kind` is a string representing what kind of use it is:
+ * - `"M"` for function and method calls
+ * - `"T"` for uses of types
+ * - `"V"` for variable accesses
+ * - `"I"` for imports
+ */
+cached
+AstNode definitionOf(Locatable e, string kind) { result = redirect(definitionOfRaw(e, kind)) }
diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml
index c015b3679f16..b367ab885490 100644
--- a/javascript/ql/lib/qlpack.yml
+++ b/javascript/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/javascript-all
-version: 2.6.5
+version: 2.6.6-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript
diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll
index 3e882251cbf7..3bb04f2686be 100644
--- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll
+++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll
@@ -649,11 +649,13 @@ module API {
/** Gets a node corresponding to an import of module `m` without taking into account types from models. */
Node getAModuleImportRaw(string m) {
result = Impl::MkModuleImport(m) or
- result = Impl::MkModuleImport(m).(Node).getMember("default")
+ result = Impl::MkModuleImport(m).(Node).getMember("default") or
+ result = Impl::MkTypeUse(m, "")
}
/** Gets a node whose type has the given qualified name, not including types from models. */
Node getANodeOfTypeRaw(string moduleName, string exportedName) {
+ exportedName != "" and
result = Impl::MkTypeUse(moduleName, exportedName).(Node).getInstance()
or
exportedName = "" and
@@ -749,18 +751,14 @@ module API {
MkModuleImport(string m) {
imports(_, m)
or
- any(TypeAnnotation n).hasQualifiedName(m, _)
- or
- any(Type t).hasUnderlyingType(m, _)
+ any(TypeAnnotation n).hasUnderlyingType(m, _)
} or
MkClassInstance(DataFlow::ClassNode cls) { needsDefNode(cls) } or
MkDef(DataFlow::Node nd) { rhs(_, _, nd) } or
MkUse(DataFlow::Node nd) { use(_, _, nd) } or
/** A use of a TypeScript type. */
MkTypeUse(string moduleName, string exportName) {
- any(TypeAnnotation n).hasQualifiedName(moduleName, exportName)
- or
- any(Type t).hasUnderlyingType(moduleName, exportName)
+ any(TypeAnnotation n).hasUnderlyingType(moduleName, exportName)
} or
MkSyntheticCallbackArg(DataFlow::Node src, int bound, DataFlow::InvokeNode nd) {
trackUseNode(src, true, bound, "").flowsTo(nd.getCalleeNode())
diff --git a/javascript/ql/lib/semmle/javascript/Closure.qll b/javascript/ql/lib/semmle/javascript/Closure.qll
index 40aee266379c..c31698333393 100644
--- a/javascript/ql/lib/semmle/javascript/Closure.qll
+++ b/javascript/ql/lib/semmle/javascript/Closure.qll
@@ -5,17 +5,49 @@
import javascript
module Closure {
+ /** A call to `goog.require` */
+ class RequireCallExpr extends CallExpr {
+ RequireCallExpr() { this.getCallee().(PropAccess).getQualifiedName() = "goog.require" }
+
+ /** Gets the imported namespace name. */
+ string getClosureNamespace() { result = this.getArgument(0).getStringValue() }
+ }
+
+ /** A call to `goog.provide` */
+ class ProvideCallExpr extends CallExpr {
+ ProvideCallExpr() { this.getCallee().(PropAccess).getQualifiedName() = "goog.provide" }
+
+ /** Gets the imported namespace name. */
+ string getClosureNamespace() { result = this.getArgument(0).getStringValue() }
+ }
+
+ /** A call to `goog.module` or `goog.declareModuleId`. */
+ private class ModuleDeclarationCall extends CallExpr {
+ private string kind;
+
+ ModuleDeclarationCall() {
+ this.getCallee().(PropAccess).getQualifiedName() = kind and
+ kind = ["goog.module", "goog.declareModuleId"]
+ }
+
+ /** Gets the declared namespace. */
+ string getClosureNamespace() { result = this.getArgument(0).getStringValue() }
+
+ /** Gets the string `goog.module` or `goog.declareModuleId` depending on which method is being called. */
+ string getModuleKind() { result = kind }
+ }
+
/**
* A reference to a Closure namespace.
*/
- class ClosureNamespaceRef extends DataFlow::Node instanceof ClosureNamespaceRef::Range {
+ deprecated class ClosureNamespaceRef extends DataFlow::Node instanceof ClosureNamespaceRef::Range {
/**
* Gets the namespace being referenced.
*/
string getClosureNamespace() { result = super.getClosureNamespace() }
}
- module ClosureNamespaceRef {
+ deprecated module ClosureNamespaceRef {
/**
* A reference to a Closure namespace.
*
@@ -32,10 +64,10 @@ module Closure {
/**
* A data flow node that returns the value of a closure namespace.
*/
- class ClosureNamespaceAccess extends ClosureNamespaceRef instanceof ClosureNamespaceAccess::Range {
- }
+ deprecated class ClosureNamespaceAccess extends ClosureNamespaceRef instanceof ClosureNamespaceAccess::Range
+ { }
- module ClosureNamespaceAccess {
+ deprecated module ClosureNamespaceAccess {
/**
* A data flow node that returns the value of a closure namespace.
*
@@ -47,7 +79,7 @@ module Closure {
/**
* A call to a method on the `goog.` namespace, as a closure reference.
*/
- abstract private class DefaultNamespaceRef extends DataFlow::MethodCallNode,
+ abstract deprecated private class DefaultNamespaceRef extends DataFlow::MethodCallNode,
ClosureNamespaceRef::Range
{
DefaultNamespaceRef() { this = DataFlow::globalVarRef("goog").getAMethodCall() }
@@ -59,14 +91,14 @@ module Closure {
* Holds if `node` is the data flow node corresponding to the expression in
* a top-level expression statement.
*/
- private predicate isTopLevelExpr(DataFlow::Node node) {
+ deprecated private predicate isTopLevelExpr(DataFlow::Node node) {
any(TopLevel tl).getAChildStmt().(ExprStmt).getExpr().flow() = node
}
/**
* A top-level call to `goog.provide`.
*/
- private class DefaultClosureProvideCall extends DefaultNamespaceRef {
+ deprecated private class DefaultClosureProvideCall extends DefaultNamespaceRef {
DefaultClosureProvideCall() {
this.getMethodName() = "provide" and
isTopLevelExpr(this)
@@ -76,13 +108,14 @@ module Closure {
/**
* A top-level call to `goog.provide`.
*/
- class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureProvideCall
+ deprecated class ClosureProvideCall extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureProvideCall
{ }
/**
* A call to `goog.require`.
*/
- private class DefaultClosureRequireCall extends DefaultNamespaceRef, ClosureNamespaceAccess::Range
+ deprecated private class DefaultClosureRequireCall extends DefaultNamespaceRef,
+ ClosureNamespaceAccess::Range
{
DefaultClosureRequireCall() { this.getMethodName() = "require" }
}
@@ -90,13 +123,13 @@ module Closure {
/**
* A call to `goog.require`.
*/
- class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode instanceof DefaultClosureRequireCall
+ deprecated class ClosureRequireCall extends ClosureNamespaceAccess, DataFlow::MethodCallNode instanceof DefaultClosureRequireCall
{ }
/**
* A top-level call to `goog.module` or `goog.declareModuleId`.
*/
- private class DefaultClosureModuleDeclaration extends DefaultNamespaceRef {
+ deprecated private class DefaultClosureModuleDeclaration extends DefaultNamespaceRef {
DefaultClosureModuleDeclaration() {
(this.getMethodName() = "module" or this.getMethodName() = "declareModuleId") and
isTopLevelExpr(this)
@@ -106,41 +139,29 @@ module Closure {
/**
* A top-level call to `goog.module` or `goog.declareModuleId`.
*/
- class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureModuleDeclaration
+ deprecated class ClosureModuleDeclaration extends ClosureNamespaceRef, DataFlow::MethodCallNode instanceof DefaultClosureModuleDeclaration
{ }
- private GlobalVariable googVariable() { variables(result, "goog", any(GlobalScope sc)) }
-
- pragma[nomagic]
- private MethodCallExpr googModuleDeclExpr() {
- result.getReceiver() = googVariable().getAnAccess() and
- result.getMethodName() = ["module", "declareModuleId"]
- }
-
- pragma[nomagic]
- private MethodCallExpr googModuleDeclExprInContainer(StmtContainer container) {
- result = googModuleDeclExpr() and
- container = result.getContainer()
- }
-
pragma[noinline]
- private ClosureRequireCall getARequireInTopLevel(ClosureModule m) { result.getTopLevel() = m }
+ private RequireCallExpr getARequireInTopLevel(ClosureModule m) { result.getTopLevel() = m }
/**
* A module using the Closure module system, declared using `goog.module()` or `goog.declareModuleId()`.
*/
class ClosureModule extends Module {
- ClosureModule() { exists(googModuleDeclExprInContainer(this)) }
+ private ModuleDeclarationCall decl;
+
+ ClosureModule() { decl.getTopLevel() = this }
/**
* Gets the call to `goog.module` or `goog.declareModuleId` in this module.
*/
- ClosureModuleDeclaration getModuleDeclaration() { result.getTopLevel() = this }
+ deprecated ClosureModuleDeclaration getModuleDeclaration() { result.getTopLevel() = this }
/**
* Gets the namespace of this module.
*/
- string getClosureNamespace() { result = this.getModuleDeclaration().getClosureNamespace() }
+ string getClosureNamespace() { result = decl.getClosureNamespace() }
override Module getAnImportedModule() {
result.(ClosureModule).getClosureNamespace() =
@@ -156,7 +177,7 @@ module Closure {
* Has no result for ES6 modules using `goog.declareModuleId`.
*/
Variable getExportsVariable() {
- this.getModuleDeclaration().getMethodName() = "module" and
+ decl.getModuleKind() = "goog.module" and
result = this.getScope().getVariable("exports")
}
@@ -185,15 +206,15 @@ module Closure {
ClosureScript() {
not this instanceof ClosureModule and
(
- any(ClosureProvideCall provide).getTopLevel() = this
+ any(ProvideCallExpr provide).getTopLevel() = this
or
- any(ClosureRequireCall require).getTopLevel() = this
+ any(RequireCallExpr require).getTopLevel() = this
)
}
/** Gets the identifier of a namespace required by this module. */
string getARequiredNamespace() {
- exists(ClosureRequireCall require |
+ exists(RequireCallExpr require |
require.getTopLevel() = this and
result = require.getClosureNamespace()
)
@@ -201,7 +222,7 @@ module Closure {
/** Gets the identifer of a namespace provided by this module. */
string getAProvidedNamespace() {
- exists(ClosureProvideCall require |
+ exists(ProvideCallExpr require |
require.getTopLevel() = this and
result = require.getClosureNamespace()
)
@@ -213,7 +234,13 @@ module Closure {
*/
pragma[noinline]
predicate isClosureNamespace(string name) {
- exists(string namespace | namespace = any(ClosureNamespaceRef ref).getClosureNamespace() |
+ exists(string namespace |
+ namespace =
+ [
+ any(RequireCallExpr ref).getClosureNamespace(),
+ any(ModuleDeclarationCall c).getClosureNamespace()
+ ]
+ |
name = namespace.substring(0, namespace.indexOf("."))
or
name = namespace
diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
index 379403eb0ee7..e7534449f55b 100644
--- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
+++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll
@@ -180,6 +180,9 @@ deprecated private class LiteralImportPath extends PathExpr, ConstantString {
* ```
*/
class ImportSpecifier extends Expr, @import_specifier {
+ /** Gets the import declaration in which this specifier appears. */
+ ImportDeclaration getImportDeclaration() { result.getASpecifier() = this }
+
/** Gets the imported symbol; undefined for default and namespace import specifiers. */
Identifier getImported() { result = this.getChildExpr(0) }
diff --git a/javascript/ql/lib/semmle/javascript/Expr.qll b/javascript/ql/lib/semmle/javascript/Expr.qll
index 8695c893f815..d7fe610b4f11 100644
--- a/javascript/ql/lib/semmle/javascript/Expr.qll
+++ b/javascript/ql/lib/semmle/javascript/Expr.qll
@@ -4,6 +4,7 @@
import javascript
private import semmle.javascript.internal.CachedStages
+private import semmle.javascript.internal.TypeResolution
/**
* A program element that is either an expression or a type annotation.
@@ -1017,7 +1018,11 @@ class InvokeExpr extends @invokeexpr, Expr {
* Note that the resolved function may be overridden in a subclass and thus is not
* necessarily the actual target of this invocation at runtime.
*/
- Function getResolvedCallee() { result = this.getResolvedCalleeName().getImplementation() }
+ Function getResolvedCallee() {
+ TypeResolution::callTarget(this, result)
+ or
+ result = this.getResolvedCalleeName().getImplementation()
+ }
}
/**
diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll
index 35ba8cfe601a..4a461961f8af 100644
--- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll
+++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll
@@ -34,7 +34,7 @@ module AccessPath {
not this.accessesGlobal(_) and
not this instanceof DataFlow::PropRead and
not this instanceof PropertyProjection and
- not this instanceof Closure::ClosureNamespaceAccess and
+ not this.asExpr() instanceof Closure::RequireCallExpr and
not this = DataFlow::parameterNode(any(ImmediatelyInvokedFunctionExpr iife).getAParameter()) and
not FlowSteps::identityFunctionStep(_, this)
}
@@ -139,8 +139,8 @@ module AccessPath {
result = join(fromReference(prop.getBase(), root), "[number]")
)
or
- exists(Closure::ClosureNamespaceAccess acc | node = acc |
- result = acc.getClosureNamespace() and
+ exists(Closure::RequireCallExpr req | node = req.flow() |
+ result = req.getClosureNamespace() and
root.isGlobal()
)
or
diff --git a/javascript/ql/lib/semmle/javascript/JSDoc.qll b/javascript/ql/lib/semmle/javascript/JSDoc.qll
index 10970a2e8b04..85b7695cd70e 100644
--- a/javascript/ql/lib/semmle/javascript/JSDoc.qll
+++ b/javascript/ql/lib/semmle/javascript/JSDoc.qll
@@ -33,6 +33,9 @@ class JSDoc extends @jsdoc, Locatable {
result.getTitle() = title
}
+ /** Gets the element to which this JSDoc comment is attached */
+ Documentable getDocumentedElement() { result.getDocumentation() = this }
+
override string toString() { result = this.getComment().toString() }
}
@@ -299,6 +302,41 @@ class JSDocIdentifierTypeExpr extends @jsdoc_identifier_type_expr, JSDocTypeExpr
override predicate isRawFunction() { this.getName() = "Function" }
}
+private AstNode getAncestorInScope(Documentable doc) {
+ any(JSDocLocalTypeAccess t).getJSDocComment() = doc.getDocumentation() and // restrict to cases where we need this
+ result = doc.getParent()
+ or
+ exists(AstNode mid |
+ mid = getAncestorInScope(doc) and
+ not mid = any(Scope s).getScopeElement() and
+ result = mid.getParent()
+ )
+}
+
+private Scope getScope(Documentable doc) { result.getScopeElement() = getAncestorInScope(doc) }
+
+pragma[nomagic]
+private predicate shouldResolveName(TopLevel top, string name) {
+ exists(JSDocLocalTypeAccess access |
+ access.getName() = name and
+ access.getTopLevel() = top
+ )
+}
+
+private LexicalName getOwnLocal(Scope scope, string name, DeclarationSpace space) {
+ scope = result.getScope() and
+ name = result.getName() and
+ space = result.getDeclarationSpace() and
+ shouldResolveName(scope.getScopeElement().getTopLevel(), name) // restrict size of predicate
+}
+
+private LexicalName resolveLocal(Scope scope, string name, DeclarationSpace space) {
+ result = getOwnLocal(scope, name, space)
+ or
+ result = resolveLocal(scope.getOuterScope(), name, space) and
+ not exists(getOwnLocal(scope, name, space))
+}
+
/**
* An unqualified identifier in a JSDoc type expression.
*
@@ -311,6 +349,12 @@ class JSDocIdentifierTypeExpr extends @jsdoc_identifier_type_expr, JSDocTypeExpr
*/
class JSDocLocalTypeAccess extends JSDocIdentifierTypeExpr {
JSDocLocalTypeAccess() { not this = any(JSDocQualifiedTypeAccess a).getNameNode() }
+
+ /** Gets a variable, type-name, or namespace that this expression may resolve to. */
+ LexicalName getALexicalName() {
+ result =
+ resolveLocal(getScope(this.getJSDocComment().getDocumentedElement()), this.getName(), _)
+ }
}
/**
@@ -371,7 +415,7 @@ class JSDocNamedTypeExpr extends JSDocTypeExpr {
* - `foo.bar.Baz` has prefix `foo` and suffix `.bar.Baz`.
* - `Baz` has prefix `Baz` and an empty suffix.
*/
- predicate hasNameParts(string prefix, string suffix) {
+ deprecated predicate hasNameParts(string prefix, string suffix) {
not this = any(JSDocQualifiedTypeAccess a).getBase() and // restrict size of predicate
exists(string regex, string name | regex = "([^.]+)(.*)" |
name = this.getRawName() and
@@ -379,46 +423,6 @@ class JSDocNamedTypeExpr extends JSDocTypeExpr {
suffix = name.regexpCapture(regex, 2)
)
}
-
- pragma[noinline]
- pragma[nomagic]
- private predicate hasNamePartsAndEnv(string prefix, string suffix, JSDoc::Environment env) {
- // Force join ordering
- this.hasNameParts(prefix, suffix) and
- env.isContainerInScope(this.getContainer())
- }
-
- /**
- * Gets the qualified name of this name by resolving its prefix, if any.
- */
- cached
- private string resolvedName() {
- exists(string prefix, string suffix, JSDoc::Environment env |
- this.hasNamePartsAndEnv(prefix, suffix, env) and
- result = env.resolveAlias(prefix) + suffix
- )
- }
-
- override predicate hasQualifiedName(string globalName) {
- globalName = this.resolvedName()
- or
- not exists(this.resolvedName()) and
- globalName = this.getRawName()
- }
-
- override DataFlow::ClassNode getClass() {
- exists(string name |
- this.hasQualifiedName(name) and
- result.hasQualifiedName(name)
- )
- or
- // Handle case where a local variable has a reference to the class,
- // but the class doesn't have a globally qualified name.
- exists(string alias, JSDoc::Environment env |
- this.hasNamePartsAndEnv(alias, "", env) and
- result.getAClassReference().flowsTo(env.getNodeFromAlias(alias))
- )
- }
}
/**
@@ -447,12 +451,6 @@ class JSDocAppliedTypeExpr extends @jsdoc_applied_type_expr, JSDocTypeExpr {
* For example, in `Array`, `string` is the only argument type.
*/
JSDocTypeExpr getAnArgument() { result = this.getArgument(_) }
-
- override predicate hasQualifiedName(string globalName) {
- this.getHead().hasQualifiedName(globalName)
- }
-
- override DataFlow::ClassNode getClass() { result = this.getHead().getClass() }
}
/**
@@ -472,8 +470,6 @@ class JSDocNullableTypeExpr extends @jsdoc_nullable_type_expr, JSDocTypeExpr {
predicate isPrefix() { jsdoc_prefix_qualifier(this) }
override JSDocTypeExpr getAnUnderlyingType() { result = this.getTypeExpr().getAnUnderlyingType() }
-
- override DataFlow::ClassNode getClass() { result = this.getTypeExpr().getClass() }
}
/**
@@ -493,8 +489,6 @@ class JSDocNonNullableTypeExpr extends @jsdoc_non_nullable_type_expr, JSDocTypeE
predicate isPrefix() { jsdoc_prefix_qualifier(this) }
override JSDocTypeExpr getAnUnderlyingType() { result = this.getTypeExpr().getAnUnderlyingType() }
-
- override DataFlow::ClassNode getClass() { result = this.getTypeExpr().getClass() }
}
/**
@@ -599,8 +593,6 @@ class JSDocOptionalParameterTypeExpr extends @jsdoc_optional_type_expr, JSDocTyp
override JSDocTypeExpr getAnUnderlyingType() {
result = this.getUnderlyingType().getAnUnderlyingType()
}
-
- override DataFlow::ClassNode getClass() { result = this.getUnderlyingType().getClass() }
}
/**
@@ -635,7 +627,7 @@ module JSDoc {
/**
* A statement container which may declare JSDoc name aliases.
*/
- class Environment extends StmtContainer {
+ deprecated class Environment extends StmtContainer {
/**
* Gets the fully qualified name aliased by the given unqualified name
* within this container.
@@ -685,7 +677,7 @@ module JSDoc {
}
pragma[noinline]
- private predicate isTypenamePrefix(string name) {
+ deprecated private predicate isTypenamePrefix(string name) {
any(JSDocNamedTypeExpr expr).hasNameParts(name, _)
}
}
diff --git a/javascript/ql/lib/semmle/javascript/TypeAnnotations.qll b/javascript/ql/lib/semmle/javascript/TypeAnnotations.qll
index d10b60b92b5b..318ad2f8873e 100644
--- a/javascript/ql/lib/semmle/javascript/TypeAnnotations.qll
+++ b/javascript/ql/lib/semmle/javascript/TypeAnnotations.qll
@@ -4,6 +4,8 @@
import javascript
private import internal.StmtContainers
+private import internal.NameResolution
+private import internal.UnderlyingTypes
/**
* A type annotation, either in the form of a TypeScript type or a JSDoc comment.
@@ -75,14 +77,38 @@ class TypeAnnotation extends @type_annotation, NodeInStmtContainer {
TypeAnnotation getAnUnderlyingType() { result = this }
/**
+ * DEPRECATED. Use `hasUnderlyingType` instead.
+ *
* Holds if this is a reference to the type with qualified name `globalName` relative to the global scope.
*/
- predicate hasQualifiedName(string globalName) { none() }
+ deprecated predicate hasQualifiedName(string globalName) {
+ UnderlyingTypes::nodeHasUnderlyingType(this, globalName)
+ }
/**
+ * DEPRECATED. Use `hasUnderlyingType` instead.
+ *
* Holds if this is a reference to the type exported from `moduleName` under the name `exportedName`.
*/
- predicate hasQualifiedName(string moduleName, string exportedName) { none() }
+ deprecated predicate hasQualifiedName(string moduleName, string exportedName) {
+ UnderlyingTypes::nodeHasUnderlyingType(this, moduleName, exportedName)
+ }
+
+ /**
+ * Holds if this is a reference to the type with qualified name `globalName` relative to the global scope,
+ * or is declared as a subtype thereof, or is a union or intersection containing such a type.
+ */
+ final predicate hasUnderlyingType(string globalName) {
+ UnderlyingTypes::nodeHasUnderlyingType(this, globalName)
+ }
+
+ /**
+ * Holds if this is a reference to the type exported from `moduleName` under the name `exportedName`,
+ * or is declared as a subtype thereof, or is a union or intersection containing such a type.
+ */
+ final predicate hasUnderlyingType(string moduleName, string exportedName) {
+ UnderlyingTypes::nodeHasUnderlyingType(this, moduleName, exportedName)
+ }
/** Gets the statement in which this type appears. */
Stmt getEnclosingStmt() { none() }
@@ -107,5 +133,5 @@ class TypeAnnotation extends @type_annotation, NodeInStmtContainer {
*
* This unfolds nullability modifiers and generic type applications.
*/
- DataFlow::ClassNode getClass() { none() }
+ final DataFlow::ClassNode getClass() { UnderlyingTypes::nodeHasUnderlyingClassType(this, result) }
}
diff --git a/javascript/ql/lib/semmle/javascript/TypeScript.qll b/javascript/ql/lib/semmle/javascript/TypeScript.qll
index 4be331ed6a50..ab670700c24b 100644
--- a/javascript/ql/lib/semmle/javascript/TypeScript.qll
+++ b/javascript/ql/lib/semmle/javascript/TypeScript.qll
@@ -1,4 +1,5 @@
import javascript
+private import semmle.javascript.internal.UnderlyingTypes
/**
* A statement that defines a namespace, that is, a namespace declaration or enum declaration.
@@ -575,10 +576,6 @@ class TypeExpr extends ExprOrType, @typeexpr, TypeAnnotation {
override Function getEnclosingFunction() { result = ExprOrType.super.getEnclosingFunction() }
override TopLevel getTopLevel() { result = ExprOrType.super.getTopLevel() }
-
- override DataFlow::ClassNode getClass() {
- result.getAstNode() = this.getType().(ClassType).getClass()
- }
}
/**
@@ -698,58 +695,9 @@ class TypeAccess extends @typeaccess, TypeExpr, TypeRef {
*/
TypeName getTypeName() { ast_node_symbol(this, result) }
- override predicate hasQualifiedName(string globalName) {
- this.getTypeName().hasQualifiedName(globalName)
- or
- exists(LocalTypeAccess local | local = this |
- not exists(local.getLocalTypeName()) and // Without a local type name, the type is looked up in the global scope.
- globalName = local.getName()
- )
- }
-
- override predicate hasQualifiedName(string moduleName, string exportedName) {
- this.getTypeName().hasQualifiedName(moduleName, exportedName)
- or
- exists(ImportDeclaration imprt, ImportSpecifier spec |
- moduleName = getImportName(imprt) and
- spec = imprt.getASpecifier()
- |
- spec.getImportedName() = exportedName and
- this = spec.getLocal().(TypeDecl).getLocalTypeName().getAnAccess()
- or
- (spec instanceof ImportNamespaceSpecifier or spec instanceof ImportDefaultSpecifier) and
- this =
- spec.getLocal().(LocalNamespaceDecl).getLocalNamespaceName().getAMemberAccess(exportedName)
- )
- or
- exists(ImportEqualsDeclaration imprt |
- moduleName = getImportName(imprt.getImportedEntity()) and
- this =
- imprt
- .getIdentifier()
- .(LocalNamespaceDecl)
- .getLocalNamespaceName()
- .getAMemberAccess(exportedName)
- )
- }
-
override string getAPrimaryQlClass() { result = "TypeAccess" }
}
-/**
- * Gets a suitable name for the library imported by `imprt`.
- *
- * For relative imports, this is the snapshot-relative path to the imported module.
- * For non-relative imports, it is the import path itself.
- */
-private string getImportName(Import imprt) {
- exists(string path | path = imprt.getImportedPathString() |
- if path.regexpMatch("[./].*")
- then result = imprt.getImportedModule().getFile().getRelativePath()
- else result = path
- )
-}
-
/** An identifier that is used as part of a type, such as `Date`. */
class LocalTypeAccess extends @local_type_access, TypeAccess, Identifier, LexicalAccess {
override predicate isStringy() { this.getName() = "String" }
@@ -822,14 +770,6 @@ class GenericTypeExpr extends @generic_typeexpr, TypeExpr {
/** Gets the number of type arguments. This is always at least one. */
int getNumTypeArgument() { result = count(this.getATypeArgument()) }
- override predicate hasQualifiedName(string globalName) {
- this.getTypeAccess().hasQualifiedName(globalName)
- }
-
- override predicate hasQualifiedName(string moduleName, string exportedName) {
- this.getTypeAccess().hasQualifiedName(moduleName, exportedName)
- }
-
override string getAPrimaryQlClass() { result = "GenericTypeExpr" }
}
diff --git a/javascript/ql/lib/semmle/javascript/Variables.qll b/javascript/ql/lib/semmle/javascript/Variables.qll
index 1eeb735124b5..2f9905f86e17 100644
--- a/javascript/ql/lib/semmle/javascript/Variables.qll
+++ b/javascript/ql/lib/semmle/javascript/Variables.qll
@@ -27,6 +27,12 @@ class Scope extends @scope {
result = this.getAVariable() and
result.getName() = name
}
+
+ /** Gets the local type name with the given name declared in this scope. */
+ LocalTypeName getLocalTypeName(string name) {
+ result.getScope() = this and
+ result.getName() = name
+ }
}
/**
@@ -128,8 +134,26 @@ class Variable extends @variable, LexicalName {
/** Gets the scope this variable is declared in. */
override Scope getScope() { variables(this, _, result) }
+ /**
+ * Holds if this variable is declared in the top-level of a module using a `declare` statement.
+ *
+ * For example:
+ * ```js
+ * declare var $: any;
+ * ```
+ *
+ * Such variables are generally treated as a global variables, except for type-checking related purposes.
+ */
+ pragma[nomagic]
+ predicate isTopLevelWithAmbientDeclaration() {
+ this.getScope() instanceof ModuleScope and
+ forex(VarDecl decl | decl = this.getADeclaration() | decl.isAmbient())
+ }
+
/** Holds if this is a global variable. */
- predicate isGlobal() { this.getScope() instanceof GlobalScope }
+ predicate isGlobal() {
+ this.getScope() instanceof GlobalScope or this.isTopLevelWithAmbientDeclaration()
+ }
/**
* Holds if this is a variable exported from a TypeScript namespace.
diff --git a/javascript/ql/lib/semmle/javascript/ViewComponentInput.qll b/javascript/ql/lib/semmle/javascript/ViewComponentInput.qll
index bc80826de5c9..7ab04ad5bd26 100644
--- a/javascript/ql/lib/semmle/javascript/ViewComponentInput.qll
+++ b/javascript/ql/lib/semmle/javascript/ViewComponentInput.qll
@@ -3,6 +3,7 @@
*/
private import javascript
+private import semmle.javascript.internal.TypeResolution
/**
* An input to a view component, such as React props.
@@ -14,34 +15,11 @@ abstract class ViewComponentInput extends DataFlow::Node {
private class ViewComponentInputAsThreatModelSource extends ThreatModelSource::Range instanceof ViewComponentInput
{
- ViewComponentInputAsThreatModelSource() { not isSafeType(this.asExpr().getType()) }
+ ViewComponentInputAsThreatModelSource() {
+ not TypeResolution::valueHasSanitizingPrimitiveType(this.asExpr())
+ }
final override string getThreatModel() { result = "view-component-input" }
final override string getSourceType() { result = ViewComponentInput.super.getSourceType() }
}
-
-private predicate isSafeType(Type t) {
- t instanceof NumberLikeType
- or
- t instanceof BooleanLikeType
- or
- t instanceof UndefinedType
- or
- t instanceof NullType
- or
- t instanceof VoidType
- or
- hasSafeTypes(t, t.(UnionType).getNumElementType())
- or
- isSafeType(t.(IntersectionType).getAnElementType())
-}
-
-/** Hold if the first `n` components of `t` are safe types. */
-private predicate hasSafeTypes(UnionType t, int n) {
- isSafeType(t.getElementType(0)) and
- n = 1
- or
- isSafeType(t.getElementType(n - 1)) and
- hasSafeTypes(t, n - 1)
-}
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
index 46801bd1ad7e..df3d0d5ff8ba 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
@@ -27,6 +27,9 @@ private import internal.PreCallGraphStep
private import semmle.javascript.internal.CachedStages
private import semmle.javascript.dataflow.internal.DataFlowPrivate as Private
private import semmle.javascript.dataflow.internal.VariableOrThis
+private import semmle.javascript.internal.NameResolution
+private import semmle.javascript.internal.UnderlyingTypes
+private import semmle.javascript.internal.TypeResolution
module DataFlow {
/**
@@ -189,26 +192,6 @@ module DataFlow {
FlowSteps::identityFunctionStep(result, this)
}
- /**
- * Gets the static type of this node as determined by the TypeScript type system.
- */
- private Type getType() {
- exists(AST::ValueNode node |
- this = TValueNode(node) and
- ast_node_type(node, result)
- )
- or
- exists(BindingPattern pattern |
- this = lvalueNode(pattern) and
- ast_node_type(pattern, result)
- )
- or
- exists(MethodDefinition def |
- this = TThisNode(def.getInit()) and
- ast_node_type(def.getDeclaringClass(), result)
- )
- }
-
/**
* Gets the type annotation describing the type of this node,
* provided that a static type could not be found.
@@ -229,6 +212,15 @@ module DataFlow {
)
}
+ private NameResolution::Node getNameResolutionNode() {
+ this = valueNode(result)
+ or
+ exists(PropertyPattern pattern |
+ result = pattern.getValuePattern() and
+ this = TPropNode(pattern)
+ )
+ }
+
/**
* Holds if this node is annotated with the given named type,
* or is declared as a subtype thereof, or is a union or intersection containing such a type.
@@ -236,9 +228,10 @@ module DataFlow {
cached
predicate hasUnderlyingType(string globalName) {
Stages::TypeTracking::ref() and
- this.getType().hasUnderlyingType(globalName)
- or
- this.getFallbackTypeAnnotation().getAnUnderlyingType().hasQualifiedName(globalName)
+ exists(NameResolution::Node type |
+ TypeResolution::valueHasType(this.getNameResolutionNode(), type) and
+ UnderlyingTypes::nodeHasUnderlyingType(type, globalName)
+ )
}
/**
@@ -248,9 +241,11 @@ module DataFlow {
cached
predicate hasUnderlyingType(string moduleName, string typeName) {
Stages::TypeTracking::ref() and
- this.getType().hasUnderlyingType(moduleName, typeName)
- or
- this.getFallbackTypeAnnotation().getAnUnderlyingType().hasQualifiedName(moduleName, typeName)
+ moduleName != "global" and
+ exists(NameResolution::Node type |
+ TypeResolution::valueHasType(this.getNameResolutionNode(), type) and
+ UnderlyingTypes::nodeHasUnderlyingType(type, moduleName, typeName)
+ )
}
/**
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll b/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll
index 06729815e9a4..f861488a046c 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/Sources.qll
@@ -333,7 +333,14 @@ module SourceNode {
astNode instanceof TaggedTemplateExpr or
astNode instanceof Templating::PipeRefExpr or
astNode instanceof Templating::TemplateVarRefExpr or
- astNode instanceof StringLiteral
+ astNode instanceof StringLiteral or
+ astNode instanceof TypeAssertion or
+ astNode instanceof SatisfiesExpr
+ )
+ or
+ exists(VariableDeclarator decl |
+ exists(decl.getTypeAnnotation()) and
+ this = DataFlow::valueNode(decl.getBindingPattern())
)
or
DataFlow::parameterNode(this, _)
diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll
index 5cf5bf1e48eb..a5af2737c186 100644
--- a/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll
+++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/Contents.qll
@@ -179,6 +179,9 @@ module Public {
/** Holds if this represents values stored at an unknown array index. */
predicate isUnknownArrayElement() { this = MkArrayElementUnknown() }
+ /** Holds if this represents the value of a resolved promise. */
+ predicate isPromiseValue() { this = MkPromiseValue() }
+
/** Holds if this represents values stored in a `Map` at an unknown key. */
predicate isMapValueWithUnknownKey() { this = MkMapValueWithUnknownKey() }
@@ -266,6 +269,11 @@ module Public {
or
this = ContentSet::anyCapturedContent() and
result instanceof Private::MkCapturedContent
+ or
+ // Although data flow will never use the special `Awaited` ContentSet in a read or store step,
+ // it may appear in type-tracking and type resolution, and here it helps to treat is as `Awaited[value]`.
+ this = MkAwaited() and
+ result = MkPromiseValue()
}
/** Gets the singleton content to be accessed. */
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll
index dd6e1a7d9159..d6bcb9ddd400 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/Nest.qll
@@ -5,6 +5,8 @@
import javascript
private import semmle.javascript.security.dataflow.ServerSideUrlRedirectCustomizations
private import semmle.javascript.dataflow.internal.PreCallGraphStep
+private import semmle.javascript.internal.NameResolution
+private import semmle.javascript.internal.TypeResolution
/**
* Provides classes and predicates for reasoning about [Nest](https://nestjs.com/).
@@ -133,7 +135,9 @@ module NestJS {
hasSanitizingPipe(this, false)
or
hasSanitizingPipe(this, true) and
- isSanitizingType(this.getParameter().getType().unfold())
+ // Note: we could consider types with class-validator decorators to be sanitized here, but instead we consider the root
+ // object to be tainted, but omit taint steps for the individual properties names that have sanitizing decorators. See ClassValidator.qll.
+ TypeResolution::isSanitizingPrimitiveType(this.getParameter().getTypeAnnotation())
}
}
@@ -209,19 +213,6 @@ module NestJS {
dependsOnType = true
}
- /**
- * Holds if a parameter of type `t` is considered sanitized, provided it has been checked by `ValidationPipe`
- * (which relies on metadata emitted by the TypeScript compiler).
- */
- private predicate isSanitizingType(Type t) {
- t instanceof NumberType
- or
- t instanceof BooleanType
- //
- // Note: we could consider types with class-validator decorators to be sanitized here, but instead we consider the root
- // object to be tainted, but omit taint steps for the individual properties names that have sanitizing decorators. See ClassValidator.qll.
- }
-
/**
* A user-defined pipe class, for example:
* ```js
@@ -237,7 +228,7 @@ module NestJS {
CustomPipeClass() {
exists(ClassDefinition cls |
this = cls.flow() and
- cls.getASuperInterface().hasQualifiedName("@nestjs/common", "PipeTransform")
+ cls.getASuperInterface().hasUnderlyingType("@nestjs/common", "PipeTransform")
)
}
@@ -327,14 +318,6 @@ module NestJS {
}
}
- private predicate isStringType(Type type) {
- type instanceof StringType
- or
- type instanceof AnyType
- or
- isStringType(type.(PromiseType).getElementType().unfold())
- }
-
/**
* A return value from a route handler, seen as an argument to `res.send()`.
*
@@ -353,10 +336,10 @@ module NestJS {
ReturnValueAsResponseSend() {
handler.isReturnValueReflected() and
this = handler.getAReturn() and
- // Only returned strings are sinks
- not exists(Type type |
- type = this.asExpr().getType() and
- not isStringType(type.unfold())
+ // Only returned strings are sinks. If we can find a type for the return value, it must be string-like.
+ not exists(NameResolution::Node type |
+ TypeResolution::valueHasType(this.asExpr(), type) and
+ not TypeResolution::hasUnderlyingStringOrAnyType(type)
)
}
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll
index c06490b84368..5e9846e9ad55 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll
@@ -60,9 +60,7 @@ predicate isPackageUsed(string package) {
or
package = any(JS::Import imp).getImportedPathString()
or
- any(JS::TypeName t).hasQualifiedName(package, _)
- or
- any(JS::TypeAnnotation t).hasQualifiedName(package, _)
+ any(JS::TypeAnnotation t).hasUnderlyingType(package, _)
or
exists(JS::PackageJson json | json.getPackageName() = package)
}
@@ -138,7 +136,7 @@ API::Node getExtraNodeFromType(string type) {
parseRelevantTypeString(type, package, qualifiedName)
|
qualifiedName = "" and
- result = [API::moduleImport(package), API::moduleExport(package)]
+ result = [API::Internal::getAModuleImportRaw(package), API::moduleExport(package)]
or
// Access instance of a type based on type annotations
result = API::Internal::getANodeOfTypeRaw(package, qualifiedName)
diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
index 4fad4ae1b059..70beadbfa573 100644
--- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
+++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll
@@ -60,11 +60,7 @@ private predicate neverReturnsJQuery(string name) {
decl.getBaseName() = "jQuery" and
decl.getName() = name
|
- not decl.getDocumentation()
- .getATagByTitle("return")
- .getType()
- .getAnUnderlyingType()
- .hasQualifiedName("jQuery")
+ not decl.getDocumentation().getATagByTitle("return").getType().hasUnderlyingType("jQuery")
)
}
@@ -414,6 +410,8 @@ module JQuery {
this = DataFlow::moduleImport(["jquery", "zepto", "cash-dom"])
or
this.hasUnderlyingType("JQueryStatic")
+ or
+ this.hasUnderlyingType("jquery", "")
}
}
}
diff --git a/javascript/ql/lib/semmle/javascript/internal/NameResolution.qll b/javascript/ql/lib/semmle/javascript/internal/NameResolution.qll
new file mode 100644
index 000000000000..96e72108e2ec
--- /dev/null
+++ b/javascript/ql/lib/semmle/javascript/internal/NameResolution.qll
@@ -0,0 +1,512 @@
+/**
+ * Provides name resolution and propagates type information.
+ */
+
+private import javascript
+
+/**
+ * Provides name resolution and propagates type information.
+ */
+module NameResolution {
+ private class NodeBase =
+ @expr or @typeexpr or @lexical_name or @toplevel or @function_decl_stmt or @class_decl_stmt or
+ @namespace_declaration or @enum_declaration or @interface_declaration or
+ @type_alias_declaration or @jsdoc_type_expr;
+
+ /**
+ * A node in a graph which we use to perform name and type resolution.
+ */
+ class Node extends NodeBase {
+ string toString() {
+ result = this.(AstNode).toString()
+ or
+ result = this.(LexicalName).toString()
+ or
+ result = this.(JSDocTypeExpr).toString()
+ }
+
+ Location getLocation() {
+ result = this.(AstNode).getLocation()
+ or
+ result = this.(LocalVariableLike).getLocation()
+ or
+ result = this.(JSDocTypeExpr).getLocation()
+ }
+ }
+
+ private signature predicate nodeSig(Node node);
+
+ /**
+ * A module top-level, or a `module {}` or `enum {}` statement.
+ */
+ private class ModuleLike extends AstNode {
+ ModuleLike() {
+ this instanceof Module
+ or
+ this instanceof NamespaceDefinition // `module {}` or `enum {}` statement
+ }
+ }
+
+ /**
+ * A local variable, or a top-level variable that acts as a global variable due to an ambient declaration.
+ */
+ class LocalVariableLike extends Variable {
+ LocalVariableLike() { this.isLocal() or this.isTopLevelWithAmbientDeclaration() }
+
+ Location getLocation() {
+ result =
+ min(Location loc |
+ loc = this.getADeclaration().getLocation()
+ |
+ loc order by loc.getStartLine(), loc.getStartColumn()
+ )
+ }
+ }
+
+ /**
+ * Holds if values/namespaces/types in `node1` can flow to values/namespaces/types in `node2`.
+ *
+ * May also include some type-specific steps in cases where this is harmless when tracking values.
+ */
+ private predicate commonStep(Node node1, Node node2) {
+ // Import paths are part of the graph and has an incoming edge from the imported module, if found.
+ // This ensures we can also use the PathExpr as a source when working with external (unresolved) modules.
+ exists(Import imprt |
+ node1 = imprt.getImportedModule() and
+ node2 = imprt.getImportedPathExpr()
+ )
+ or
+ exists(ImportNamespaceSpecifier spec |
+ node1 = spec.getImportDeclaration().getImportedPathExpr() and
+ node2 = spec.getLocal()
+ )
+ or
+ exists(ExportNamespaceSpecifier spec |
+ node1 = spec.getExportDeclaration().(ReExportDeclaration).getImportedPath() and
+ node2 = spec
+ )
+ or
+ exists(ExportAssignDeclaration assign |
+ node1 = assign.getExpression() and
+ node2 = assign.getContainer()
+ )
+ or
+ exists(ImportEqualsDeclaration imprt |
+ node1 = imprt.getImportedEntity() and
+ node2 = imprt.getIdentifier()
+ )
+ or
+ exists(ExternalModuleReference ref |
+ node1 = ref.getImportedPathExpr() and
+ node2 = ref
+ )
+ or
+ exists(ImportTypeExpr imprt |
+ node1 = imprt.getPathExpr() and // TODO: ImportTypeExpr does not seem to be resolved to a Module
+ node2 = imprt
+ )
+ or
+ exists(ClassOrInterface cls |
+ node1 = cls and
+ node2 = cls.getIdentifier()
+ )
+ or
+ exists(NamespaceDefinition def |
+ node1 = def and
+ node2 = def.getIdentifier()
+ )
+ or
+ exists(Function fun |
+ node1 = fun and
+ node2 = fun.getIdentifier()
+ )
+ or
+ exists(EnumMember def |
+ node1 = def.getInitializer() and
+ node2 = def.getIdentifier()
+ )
+ or
+ exists(TypeAliasDeclaration alias |
+ node1 = alias.getDefinition() and
+ node2 = alias.getIdentifier()
+ )
+ or
+ exists(VariableDeclarator decl |
+ node1 = decl.getInit() and
+ node2 = decl.getBindingPattern()
+ )
+ or
+ exists(ParenthesizedTypeExpr type |
+ node1 = type.getElementType() and
+ node2 = type
+ )
+ or
+ exists(ParenthesisExpr expr |
+ node1 = expr.getExpression() and
+ node2 = expr
+ )
+ or
+ exists(NonNullAssertion assertion |
+ // For the time being we don't use this for nullness analysis, so just
+ // propagate through these assertions.
+ node1 = assertion.getExpression() and
+ node2 = assertion
+ )
+ or
+ exists(FunctionTypeExpr fun |
+ node1 = fun.getFunction() and
+ node2 = fun
+ )
+ or
+ exists(TypeofTypeExpr type |
+ node1 = type.getExpressionName() and
+ node2 = type
+ )
+ or
+ exists(Closure::RequireCallExpr req |
+ node1.(Closure::ClosureModule).getClosureNamespace() = req.getClosureNamespace() and
+ node2 = req
+ )
+ or
+ exists(Closure::ClosureModule mod |
+ node1 = mod.getExportsVariable() and
+ node2 = mod
+ )
+ or
+ exists(ImmediatelyInvokedFunctionExpr fun, int i |
+ node1 = fun.getArgument(i) and
+ node2 = fun.getParameter(i)
+ )
+ }
+
+ /**
+ * Holds if there is a read from `node1` to `node2` that accesses the member `name`.
+ */
+ predicate readStep(Node node1, string name, Node node2) {
+ exists(QualifiedTypeAccess access |
+ node1 = access.getQualifier() and
+ name = access.getIdentifier().getName() and
+ node2 = access
+ )
+ or
+ exists(QualifiedNamespaceAccess access |
+ node1 = access.getQualifier() and
+ name = access.getIdentifier().getName() and
+ node2 = access
+ )
+ or
+ exists(QualifiedVarTypeAccess access |
+ node1 = access.getQualifier() and
+ name = access.getIdentifier().getName() and
+ node2 = access
+ )
+ or
+ exists(PropAccess access |
+ node1 = access.getBase() and
+ name = access.getPropertyName() and
+ node2 = access
+ )
+ or
+ exists(ObjectPattern pattern |
+ node1 = pattern and
+ node2 = pattern.getPropertyPatternByName(name).getValuePattern()
+ )
+ or
+ exists(ImportSpecifier spec |
+ node1 = spec.getImportDeclaration().getImportedPathExpr() and
+ name = spec.getImportedName() and
+ node2 = spec.getLocal()
+ )
+ or
+ exists(SelectiveReExportDeclaration exprt, ExportSpecifier spec |
+ spec = exprt.getASpecifier() and
+ node1 = exprt.getImportedPath() and
+ name = spec.getLocalName() and
+ node2 = spec.getLocal()
+ )
+ or
+ exists(JSDocQualifiedTypeAccess expr |
+ node1 = expr.getBase() and
+ name = expr.getName() and
+ node2 = expr
+ )
+ }
+
+ private signature module TypeResolutionInputSig {
+ /**
+ * Holds if flow is permitted through the given variable.
+ */
+ predicate isRelevantVariable(LexicalName var);
+ }
+
+ /**
+ * A local variable with exactly one definition, not counting implicit initialization.
+ */
+ private class EffectivelyConstantVariable extends LocalVariableLike {
+ EffectivelyConstantVariable() {
+ count(SsaExplicitDefinition ssa | ssa.getSourceVariable() = this) <= 1 // count may be zero if ambient
+ }
+ }
+
+ /** Configuration for propagating values and namespaces */
+ private module ValueConfig implements TypeResolutionInputSig {
+ predicate isRelevantVariable(LexicalName var) {
+ var instanceof EffectivelyConstantVariable
+ or
+ // We merge the namespace and value declaration spaces as it seems there is
+ // no need to distinguish them in practice.
+ var instanceof LocalNamespaceName
+ }
+ }
+
+ /**
+ * Associates information about values, such as references to a class, module, or namespace.
+ */
+ module ValueFlow = FlowImpl;
+
+ private module TypeConfig implements TypeResolutionInputSig {
+ predicate isRelevantVariable(LexicalName var) { var instanceof LocalTypeName }
+ }
+
+ /**
+ * Associates nodes with information about types.
+ */
+ module TypeFlow = FlowImpl;
+
+ /**
+ * Generates a directed graph for tracking type names or value names back toward their definition.
+ * The ultimate definition might not be in the database, but the graph lets us track as far as we can.
+ *
+ * The module parameter determines whether types or values should be tracked.
+ *
+ * The example below illustrates the need for two separate instantiations of this module.
+ * When tracking through the nodes corresponding to `X`, we need to remember whether a type or value was tracked.
+ *
+ * ```ts
+ * // lib.ts
+ * class C1 {}
+ * class C2 {}
+ *
+ * const X = C1;
+ * type X = C2;
+ *
+ * export { X }
+ *
+ * // use.ts
+ * import { X } from "./lib"
+ *
+ * var x1 = X // should refer to C1
+ * var x2: X; // should refer to C2
+ * ```
+ */
+ private module FlowImpl {
+ /**
+ * Gets the exported member of `mod` named `name`.
+ */
+ Node getModuleExport(ModuleLike mod, string name) {
+ exists(ExportDeclaration exprt |
+ mod = exprt.getContainer() and
+ exprt.exportsAs(result, name) and
+ S::isRelevantVariable(result)
+ )
+ or
+ exists(ExportNamespaceSpecifier spec |
+ result = spec and
+ mod = spec.getContainer() and
+ name = spec.getExportedName()
+ )
+ or
+ exists(SelectiveReExportDeclaration exprt, ExportSpecifier spec |
+ // `export { A as B } from 'blah'`
+ // This is not covered by `exportsAs` above because neither A or B is a LexicalName
+ // (both are property names) so it doesn't fit the interface of `exportsAs`.
+ spec = exprt.getASpecifier() and
+ mod = exprt.getContainer() and
+ name = spec.getExportedName() and
+ result = spec.getLocal()
+ )
+ or
+ exists(EnumDeclaration enum |
+ mod = enum and
+ result = enum.getMemberByName(name).getIdentifier()
+ )
+ or
+ storeToVariable(result, name, mod.(Closure::ClosureModule).getExportsVariable())
+ }
+
+ /**
+ * Holds if `value` is stored in `target.prop`. Only needs to recognise assignments
+ * that are also recognised by JSDoc tooling such as the Closure compiler.
+ */
+ private predicate storeToVariable(Expr value, string prop, LocalVariableLike target) {
+ exists(AssignExpr assign |
+ // target.name = value
+ assign.getLhs().(PropAccess).accesses(target.getAnAccess(), prop) and
+ value = assign.getRhs()
+ )
+ or
+ // target = { name: value }
+ value = target.getAnAssignedExpr().(ObjectExpr).getPropertyByName(prop).getInit()
+ }
+
+ /** Steps that only apply for this configuration. */
+ private predicate specificStep(Node node1, Node node2) {
+ exists(LexicalName var | S::isRelevantVariable(var) |
+ node1.(LexicalDecl).getALexicalName() = var and
+ node2 = var
+ or
+ node1 = var and
+ node2.(LexicalAccess).getALexicalName() = var
+ or
+ node1 = var and
+ node2.(JSDocLocalTypeAccess).getALexicalName() = var
+ )
+ or
+ exists(Node base, string name, ModuleLike mod |
+ readStep(base, name, node2) and
+ base = trackModule(mod) and
+ node1 = getModuleExport(mod, name)
+ )
+ }
+
+ /**
+ * Holds if data should propagate from `node1` to `node2`.
+ */
+ pragma[inline]
+ predicate step(Node node1, Node node2) {
+ commonStep(node1, node2)
+ or
+ specificStep(node1, node2)
+ }
+
+ /** Helps track flow from a particular set of source nodes. */
+ module Track {
+ /** Gets the set of nodes reachable from `source`. */
+ Node track(Node source) {
+ isSource(source) and
+ result = source
+ or
+ step(track(source), result)
+ }
+ }
+
+ signature class AstNodeSig extends AstNode;
+
+ /** Helps track flow from a particular set of source nodes. */
+ module TrackNode {
+ /** Gets the set of nodes reachable from `source`. */
+ Node track(Source source) {
+ result = source
+ or
+ step(track(source), result)
+ }
+ }
+ }
+
+ /**
+ * Gets a node to which the given module flows.
+ */
+ predicate trackModule = ValueFlow::TrackNode::track/1;
+
+ /**
+ * Holds if `moduleName` appears to start with a package name, as opposed to a relative file import.
+ */
+ bindingset[moduleName]
+ private predicate isExternalModuleName(string moduleName) {
+ not moduleName.regexpMatch("^(\\.|/).*")
+ }
+
+ bindingset[name]
+ private string normalizeModuleName(string name) {
+ result =
+ name.regexpReplaceAll("^node:", "")
+ .regexpReplaceAll("\\.[cm]?[jt]sx?$", "")
+ .regexpReplaceAll("/(index)?$", "")
+ }
+
+ /** Appends a name onto a qualified name */
+ bindingset[a, b]
+ string append(string a, string b) {
+ if b = "default"
+ then result = a
+ else (
+ (if a = "" or b = "" then result = a + b else result = a + "." + b) and
+ result.length() < 100
+ )
+ }
+
+ private predicate needsQualifiedName(Node node) {
+ node = any(JSDocLocalTypeAccess t).getALexicalName().(Variable)
+ or
+ exists(Node prev | needsQualifiedName(prev) |
+ ValueFlow::step(node, prev)
+ or
+ readStep(node, _, prev)
+ )
+ }
+
+ /**
+ * Holds if `node` is a reference to the given module, or a qualified name rooted in that module.
+ *
+ * If `qualifiedName` is empty, `node` refers to the module itself.
+ *
+ * If `mod` is the string `"global"`, `node` refers to a global access path.
+ *
+ * Unlike `trackModule`, this is intended to track uses of external packages.
+ */
+ predicate nodeRefersToModule(Node node, string mod, string qualifiedName) {
+ exists(Expr path |
+ path = any(Import imprt).getImportedPathExpr() or
+ path = any(ReExportDeclaration e).getImportedPath()
+ |
+ node = path and
+ mod = normalizeModuleName(path.getStringValue()) and
+ isExternalModuleName(mod) and
+ qualifiedName = ""
+ )
+ or
+ mod = "global" and
+ exists(LocalNamespaceAccess access |
+ node = access and
+ not exists(access.getLocalNamespaceName()) and
+ access.getName() = qualifiedName
+ )
+ or
+ mod = "global" and
+ exists(JSDocLocalTypeAccess access |
+ node = access and
+ not exists(access.getALexicalName()) and
+ access.getName() = qualifiedName
+ )
+ or
+ mod = "global" and
+ exists(GlobalVarAccess access |
+ node = access and
+ needsQualifiedName(access) and // restrict number of qualified names we generate
+ access.getName() = qualifiedName
+ )
+ or
+ mod = "global" and
+ qualifiedName = node.(Closure::RequireCallExpr).getClosureNamespace()
+ or
+ // Additionally track through bulk re-exports (`export * from 'mod`).
+ // These are normally handled by 'exportAs' which supports various shadowing rules,
+ // but has no effect when the ultimate re-exported module is not resolved to a Module.
+ // We propagate external module refs through bulk re-exports and ignore shadowing rules.
+ exists(BulkReExportDeclaration reExport |
+ nodeRefersToModule(reExport.getImportedPath(), mod, qualifiedName) and
+ node = reExport.getContainer()
+ )
+ or
+ exists(Node mid |
+ nodeRefersToModule(mid, mod, qualifiedName) and
+ ValueFlow::step(mid, node)
+ )
+ or
+ exists(Node mid, string prefix, string step |
+ nodeRefersToModule(mid, mod, prefix) and
+ readStep(mid, step, node) and
+ qualifiedName = append(prefix, step)
+ )
+ }
+}
diff --git a/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll b/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll
new file mode 100644
index 000000000000..ddf5757a38cc
--- /dev/null
+++ b/javascript/ql/lib/semmle/javascript/internal/TypeResolution.qll
@@ -0,0 +1,422 @@
+private import javascript
+private import semmle.javascript.internal.NameResolution::NameResolution
+private import semmle.javascript.internal.UnderlyingTypes
+private import semmle.javascript.dataflow.internal.sharedlib.SummaryTypeTracker as SummaryTypeTracker
+
+module TypeResolution {
+ predicate trackClassValue = ValueFlow::TrackNode::track/1;
+
+ predicate trackType = TypeFlow::TrackNode::track/1;
+
+ /**
+ * Gets a node that has `fun` as an underlying type.
+ *
+ * We track through underlying types as an approximate way to handle calls to a type
+ * that is a union/intersection involving functions.
+ */
+ Node trackUnderlyingFunctionType(Function fun) {
+ result = fun
+ or
+ exists(Node mid | mid = trackUnderlyingFunctionType(fun) |
+ TypeFlow::step(mid, result)
+ or
+ UnderlyingTypes::underlyingTypeStep(mid, result)
+ )
+ }
+
+ predicate trackFunctionValue = ValueFlow::TrackNode::track/1;
+
+ /**
+ * Gets the representative for the type containing the given member.
+ *
+ * For non-static members this is simply the enclosing type declaration.
+ *
+ * For static members we use the class's `Variable` as representative for the type of the class object.
+ */
+ private Node getMemberBase(MemberDeclaration member) {
+ if member.isStatic()
+ then result = member.getDeclaringClass().getVariable()
+ else result = member.getDeclaringType()
+ }
+
+ /**
+ * Holds if `host` is a type with a `content` of type `memberType`, not counting inherited members.
+ */
+ private predicate typeOwnMember(Node host, DataFlow::Content content, Node memberType) {
+ exists(MemberDeclaration decl | host = getMemberBase(decl) |
+ exists(FieldDeclaration field |
+ decl = field and
+ content.asPropertyName() = field.getName() and
+ memberType = field.getTypeAnnotation()
+ )
+ or
+ exists(MethodDeclaration method |
+ decl = method and
+ content.asPropertyName() = method.getName()
+ |
+ not method instanceof AccessorMethodDeclaration and
+ memberType = method.getBody() // use the Function as representative for the function type
+ or
+ method instanceof GetterMethodDeclaration and
+ memberType = method.getBody().getReturnTypeAnnotation()
+ )
+ or
+ decl instanceof IndexSignature and
+ memberType = decl.(IndexSignature).getBody().getReturnTypeAnnotation() and
+ content.isUnknownArrayElement()
+ )
+ or
+ // Ad-hoc support for array types. We don't support generics in general currently, we just special-case arrays and promises.
+ content.isUnknownArrayElement() and
+ (
+ memberType = host.(ArrayTypeExpr).getElementType()
+ or
+ exists(GenericTypeExpr type |
+ host = type and
+ type.getTypeAccess().(LocalTypeAccess).getName() = ["Array", "ReadonlyArray"] and
+ memberType = type.getTypeArgument(0)
+ )
+ or
+ exists(JSDocAppliedTypeExpr type |
+ host = type and
+ type.getHead().(JSDocLocalTypeAccess).getName() = "Array" and
+ memberType = type.getArgument(0)
+ )
+ )
+ or
+ content.isPromiseValue() and
+ memberType = unwrapPromiseType(host)
+ }
+
+ /**
+ * Holds if `host` is a type with a `content` of type `memberType`, possible due to inheritance.
+ */
+ private predicate typeMember(Node host, DataFlow::Content content, Node memberType) {
+ typeOwnMember(host, content, memberType)
+ or
+ // Inherit members from base types
+ not typeOwnMember(host, content, _) and
+ exists(ClassOrInterface baseType | typeMember(baseType, content, memberType) |
+ host.(ClassDefinition).getSuperClass() = trackClassValue(baseType)
+ or
+ host.(ClassOrInterface).getASuperInterface() = trackType(baseType)
+ )
+ }
+
+ /**
+ * Holds `use` refers to `host`, and `host` has type members.
+ *
+ * Currently steps through unions and intersections, which acts as a basic
+ * approximation to the unions/intersection of objects.
+ */
+ private predicate typeMemberHostReaches(Node host, Node use) {
+ typeMember(host, _, _) and
+ use = host
+ or
+ exists(Node mid | typeMemberHostReaches(host, mid) |
+ TypeFlow::step(mid, use)
+ or
+ UnderlyingTypes::underlyingTypeStep(mid, use)
+ )
+ }
+
+ /**
+ * Holds if there is a read from from `object` to `member` that reads `contents`.
+ */
+ private predicate valueReadStep(Node object, DataFlow::ContentSet contents, Node member) {
+ member.(PropAccess).accesses(object, contents.asPropertyName())
+ or
+ object.(ObjectPattern).getPropertyPatternByName(contents.asPropertyName()).getValuePattern() =
+ member
+ or
+ member.(AwaitExpr).getOperand() = object and
+ contents = DataFlow::ContentSet::promiseValue()
+ or
+ SummaryTypeTracker::basicLoadStep(object.(AST::ValueNode).flow(),
+ member.(AST::ValueNode).flow(), contents)
+ }
+
+ predicate callTarget(InvokeExpr call, Function target) {
+ exists(ClassDefinition cls |
+ valueHasType(call.(NewExpr).getCallee(), trackClassValue(cls)) and
+ target = cls.getConstructor().getBody()
+ )
+ or
+ valueHasType(call.getCallee(), trackFunctionValue(target))
+ or
+ valueHasType(call.getCallee(), trackUnderlyingFunctionType(target)) and
+ (
+ call instanceof NewExpr and
+ target = any(ConstructorTypeExpr t).getFunction()
+ or
+ call instanceof CallExpr and
+ target = any(PlainFunctionTypeExpr t).getFunction()
+ )
+ or
+ exists(InterfaceDefinition interface, CallSignature sig |
+ valueHasType(call.getCallee(), trackType(interface)) and
+ sig = interface.getACallSignature() and
+ target = sig.getBody()
+ |
+ call instanceof NewExpr and
+ sig instanceof ConstructorCallSignature
+ or
+ call instanceof CallExpr and
+ sig instanceof FunctionCallSignature
+ )
+ }
+
+ private predicate functionReturnType(Function func, Node returnType) {
+ returnType = func.getReturnTypeAnnotation()
+ or
+ not exists(func.getReturnTypeAnnotation()) and
+ exists(Function functionType |
+ contextualType(func, trackUnderlyingFunctionType(functionType)) and
+ returnType = functionType.getReturnTypeAnnotation()
+ )
+ }
+
+ bindingset[name]
+ private predicate isPromiseTypeName(string name) {
+ name.regexpMatch(".?(Promise|Thenable)(Like)?")
+ }
+
+ private Node unwrapPromiseType(Node promiseType) {
+ exists(GenericTypeExpr type |
+ promiseType = type and
+ isPromiseTypeName(type.getTypeAccess().(LocalTypeAccess).getName()) and
+ result = type.getTypeArgument(0)
+ )
+ or
+ exists(JSDocAppliedTypeExpr type |
+ promiseType = type and
+ isPromiseTypeName(type.getHead().(JSDocLocalTypeAccess).getName()) and
+ result = type.getArgument(0)
+ )
+ }
+
+ predicate contextualType(Node value, Node type) {
+ exists(LocalVariableLike v |
+ type = v.getADeclaration().getTypeAnnotation() and
+ value = v.getAnAssignedExpr()
+ )
+ or
+ exists(InvokeExpr call, Function target, int i |
+ callTarget(call, target) and
+ value = call.getArgument(i) and
+ type = target.getParameter(i).getTypeAnnotation()
+ )
+ or
+ exists(Function lambda, Node returnType |
+ value = lambda.getAReturnedExpr() and
+ functionReturnType(lambda, returnType)
+ |
+ not lambda.isAsyncOrGenerator() and
+ type = returnType
+ or
+ lambda.isAsync() and
+ type = unwrapPromiseType(returnType)
+ )
+ or
+ exists(ObjectExpr object, Node objectType, Node host, string name |
+ contextualType(object, objectType) and
+ typeMemberHostReaches(host, objectType) and
+ typeMember(host, any(DataFlow::Content c | c.asPropertyName() = name), type) and
+ value = object.getPropertyByName(name).getInit()
+ )
+ or
+ exists(ArrayExpr array, Node arrayType, Node host |
+ contextualType(array, arrayType) and
+ typeMemberHostReaches(host, arrayType) and
+ typeMember(host, any(DataFlow::Content c | c.isUnknownArrayElement()), type) and
+ value = array.getAnElement()
+ )
+ }
+
+ /**
+ * Holds if `value` has the given `type`.
+ */
+ predicate valueHasType(Node value, Node type) {
+ value.(BindingPattern).getTypeAnnotation() = type
+ or
+ value.(TypeAssertion).getTypeAnnotation() = type
+ or
+ value.(SatisfiesExpr).getTypeAnnotation() = type
+ or
+ exists(VarDecl decl |
+ // ValueFlow::step is restricted to variables with at most one assignment. Allow the type annotation
+ // of a variable to propagate to its uses, even if the variable has multiple assignments.
+ type = decl.getTypeAnnotation() and
+ value = decl.getVariable().(LocalVariableLike).getAnAccess()
+ )
+ or
+ exists(MemberDeclaration member |
+ value.(ThisExpr).getBindingContainer() = member.getInit() and
+ type = getMemberBase(member)
+ )
+ or
+ exists(ClassDefinition cls |
+ value = cls and
+ type = cls.getVariable()
+ )
+ or
+ exists(FunctionDeclStmt fun |
+ value = fun and
+ type = fun.getVariable()
+ )
+ or
+ exists(Function target | callTarget(value, target) |
+ type = target.getReturnTypeAnnotation()
+ or
+ exists(ClassDefinition cls |
+ target = cls.getConstructor().getBody() and
+ type = cls
+ )
+ )
+ or
+ // Contextual typing for parameters
+ exists(Function lambda, Function functionType, int i |
+ contextualType(lambda, trackUnderlyingFunctionType(functionType))
+ or
+ exists(InterfaceDefinition interface |
+ contextualType(lambda, trackType(interface)) and
+ functionType = interface.getACallSignature().getBody()
+ )
+ |
+ value = lambda.getParameter(i) and
+ not exists(value.(Parameter).getTypeAnnotation()) and
+ type = functionType.getParameter(i).getTypeAnnotation()
+ )
+ or
+ exists(Node mid | valueHasType(mid, type) | ValueFlow::step(mid, value))
+ or
+ exists(Node mid, Node midType, DataFlow::ContentSet contents, Node host |
+ valueReadStep(mid, contents, value) and
+ valueHasType(mid, midType) and
+ typeMemberHostReaches(host, midType) and
+ typeMember(host, contents.getAReadContent(), type)
+ )
+ }
+
+ signature predicate nodeSig(Node node);
+
+ /**
+ * Tracks types that have a certain property, in the sense that:
+ * - an intersection type has the property if any member has the property
+ * - a union type has the property if all its members have the property
+ */
+ module TrackMustProp {
+ predicate hasProperty(Node node) {
+ directlyHasProperty(node)
+ or
+ exists(Node mid |
+ hasProperty(mid) and
+ TypeFlow::step(mid, node)
+ )
+ or
+ unionHasProp(node)
+ or
+ hasProperty(node.(IntersectionTypeExpr).getAnElementType())
+ or
+ exists(ConditionalTypeExpr cond |
+ node = cond and
+ hasProperty(cond.getTrueType()) and
+ hasProperty(cond.getFalseType())
+ )
+ }
+
+ private predicate unionHasProp(UnionTypeExpr node, int n) {
+ hasProperty(node.getElementType(0)) and n = 1
+ or
+ unionHasProp(node, n - 1) and
+ hasProperty(node.getElementType(n - 1))
+ }
+
+ private predicate unionHasProp(UnionTypeExpr node) {
+ unionHasProp(node, node.getNumElementType())
+ }
+ }
+
+ module ValueHasProperty {
+ predicate valueHasProperty(Node value) {
+ exists(Node type |
+ valueHasType(value, type) and
+ typeHasProperty(type)
+ )
+ }
+ }
+
+ private predicate isSanitizingPrimitiveTypeBase(Node node) {
+ node.(TypeExpr).isNumbery()
+ or
+ node.(TypeExpr).isBooleany()
+ or
+ node.(TypeExpr).isNull()
+ or
+ node.(TypeExpr).isUndefined()
+ or
+ node.(TypeExpr).isVoid()
+ or
+ node.(TypeExpr).isNever()
+ or
+ node.(TypeExpr).isBigInt()
+ or
+ node.(TypeExpr).isSymbol()
+ or
+ node instanceof LiteralTypeExpr
+ or
+ node = any(EnumMember m).getIdentifier() // enum members are constant
+ or
+ node instanceof EnumDeclaration // enums are unions of constants
+ }
+
+ /**
+ * Holds if `node` refers to a type that is considered untaintable (if actually enforced at runtime).
+ *
+ * Specifically, the types `number`, `boolean`, `null`, `undefined`, `void`, `never`, as well as literal types (`"foo"`)
+ * and enums and enum members have this property.
+ */
+ predicate isSanitizingPrimitiveType =
+ TrackMustProp::hasProperty/1;
+
+ /**
+ * Holds if `value` has a type that is considered untaintable (if actually enforced at runtime).
+ *
+ * See `isSanitizingPrimitiveType`.
+ */
+ predicate valueHasSanitizingPrimitiveType =
+ ValueHasProperty::valueHasProperty/1;
+
+ private predicate isPromiseBase(Node node) { exists(unwrapPromiseType(node)) }
+
+ /**
+ * Holds if the given type is a Promise object. Does not hold for unions unless all parts of the union are promises.
+ */
+ predicate isPromiseType = TrackMustProp::hasProperty/1;
+
+ /**
+ * Holds if the given value has a type that implied it is a Promise object. Does not hold for unions unless all parts of the union are promises.
+ */
+ predicate valueHasPromiseType = ValueHasProperty::valueHasProperty/1;
+
+ /**
+ * Holds if `type` contains `string` or `any`, possibly wrapped in a promise.
+ */
+ predicate hasUnderlyingStringOrAnyType(Node type) {
+ type.(TypeAnnotation).isStringy()
+ or
+ type.(TypeAnnotation).isAny()
+ or
+ type instanceof StringLiteralTypeExpr
+ or
+ type instanceof TemplateLiteralTypeExpr
+ or
+ exists(Node mid | hasUnderlyingStringOrAnyType(mid) |
+ TypeFlow::step(mid, type)
+ or
+ UnderlyingTypes::underlyingTypeStep(mid, type)
+ or
+ type = unwrapPromiseType(mid)
+ )
+ }
+}
diff --git a/javascript/ql/lib/semmle/javascript/internal/UnderlyingTypes.qll b/javascript/ql/lib/semmle/javascript/internal/UnderlyingTypes.qll
new file mode 100644
index 000000000000..8f6628278c4f
--- /dev/null
+++ b/javascript/ql/lib/semmle/javascript/internal/UnderlyingTypes.qll
@@ -0,0 +1,128 @@
+/**
+ * Provides name resolution and propagates type information.
+ */
+
+private import javascript
+private import semmle.javascript.internal.NameResolution::NameResolution
+
+/**
+ * Provides name resolution and propagates type information.
+ */
+module UnderlyingTypes {
+ private predicate subtypeStep(Node node1, Node node2) {
+ exists(ClassOrInterface cls |
+ (
+ node1 = cls.getSuperClass() or
+ node1 = cls.getASuperInterface()
+ ) and
+ node2 = cls
+ )
+ }
+
+ predicate underlyingTypeStep(Node node1, Node node2) {
+ exists(UnionOrIntersectionTypeExpr type |
+ node1 = type.getAnElementType() and
+ node2 = type
+ )
+ or
+ exists(ReadonlyTypeExpr type |
+ node1 = type.getElementType() and
+ node2 = type
+ )
+ or
+ exists(OptionalTypeExpr type |
+ node1 = type.getElementType() and
+ node2 = type
+ )
+ or
+ exists(GenericTypeExpr type |
+ node1 = type.getTypeAccess() and
+ node2 = type
+ )
+ or
+ exists(ExpressionWithTypeArguments e |
+ node1 = e.getExpression() and
+ node2 = e
+ )
+ or
+ exists(JSDocUnionTypeExpr type |
+ node1 = type.getAnAlternative() and
+ node2 = type
+ )
+ or
+ exists(JSDocNonNullableTypeExpr type |
+ node1 = type.getTypeExpr() and
+ node2 = type
+ )
+ or
+ exists(JSDocNullableTypeExpr type |
+ node1 = type.getTypeExpr() and
+ node2 = type
+ )
+ or
+ exists(JSDocAppliedTypeExpr type |
+ node1 = type.getHead() and
+ node2 = type
+ )
+ or
+ exists(JSDocOptionalParameterTypeExpr type |
+ node1 = type.getUnderlyingType() and
+ node2 = type
+ )
+ }
+
+ predicate nodeHasUnderlyingType(Node node, string mod, string name) {
+ nodeRefersToModule(node, mod, name)
+ or
+ exists(JSDocLocalTypeAccess type |
+ node = type and
+ not exists(type.getALexicalName()) and
+ not type = any(JSDocQualifiedTypeAccess t).getBase() and
+ name = type.getName() and
+ mod = "global"
+ )
+ or
+ exists(LocalTypeAccess type |
+ node = type and
+ not exists(type.getLocalTypeName()) and
+ name = type.getName() and
+ mod = "global"
+ )
+ or
+ exists(Node mid | nodeHasUnderlyingType(mid, mod, name) |
+ TypeFlow::step(mid, node)
+ or
+ underlyingTypeStep(mid, node)
+ or
+ subtypeStep(mid, node)
+ )
+ }
+
+ pragma[nomagic]
+ predicate nodeHasUnderlyingType(Node node, string name) {
+ nodeHasUnderlyingType(node, "global", name)
+ }
+
+ predicate nodeHasUnderlyingClassType(Node node, DataFlow::ClassNode cls) {
+ node = cls.getAstNode()
+ or
+ exists(string name |
+ classHasGlobalName(cls, name) and
+ nodeHasUnderlyingType(node, name)
+ )
+ or
+ exists(Node mid | nodeHasUnderlyingClassType(mid, cls) |
+ TypeFlow::step(mid, node)
+ or
+ underlyingTypeStep(mid, node)
+ // Note: unlike for external types, we do not use subtype steps here.
+ // The caller is responsible for handling the class hierarchy.
+ )
+ }
+
+ pragma[nomagic]
+ private predicate classHasGlobalName(DataFlow::ClassNode cls, string name) {
+ cls.flowsTo(AccessPath::getAnAssignmentTo(name)) and
+ not cls.getTopLevel().isExterns() // don't propagate externs classes
+ }
+}
diff --git a/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.qhelp b/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.qhelp
index e59f290ae6df..652d8b544d0f 100644
--- a/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.qhelp
+++ b/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.qhelp
@@ -4,50 +4,73 @@
-In TypeScript the keywords constructor and new for
-member declarations are used to declare constructors in classes and interfaces
-respectively.
-However, a member declaration with the name new in an interface
-or constructor in a class, will declare an ordinary method named
-new or constructor rather than a constructor.
-Similarly, the keyword function is used to declare functions in
-some contexts. However, using the name function for a class
-or interface member declaration declares a method named function.
+In TypeScript, certain keywords have special meanings for member declarations, and misusing them can create confusion:
+
+
+
+
In classes, use constructor rather than new to declare constructors. Using new within a class creates a method named "new" and not a constructor signature.
+
In interfaces, use new rather than constructor to declare constructor signatures. Using constructor within an interface creates a method named "constructor" and not a constructor signature.
+
Similarly, the keyword function is used to declare functions in some contexts. However, using the name function for a class or interface member declaration declares a method named "function".
+
+
+
+When these keywords are misused, TypeScript will interpret them as regular method names rather than their intended special syntax, leading to code that may not work as expected.
-Declare classes as classes and not as interfaces.
-Use the keyword constructor to declare constructors in a class,
-use the keyword new to declare constructors inside interfaces,
-and don't use function when declaring a call signature in an
-interface.
+Consider following these guidelines for clearer code:
+
+
For classes, use constructor to declare constructors.
+
For interfaces, use new to declare constructor signatures (call signatures that create new instances).
+
Avoid accidentally creating methods named function by misusing the function keyword within class or interface declarations.
+
+
-The below example declares an interface Point with 2 fields
-and a method called constructor. The interface does not declare
-a class Point with a constructor, which was likely what the
-developer meant to create.
+The following examples show common mistakes when using these keywords:
-
-The below example is a fixed version of the above, where the interface is
-instead declared as a class, thereby describing the type the developer meant
-in the first place.
+This interface mistakenly uses constructor, which creates a method named "constructor" instead of a constructor signature:
+
+
+Use new for constructor signatures in interfaces:
+
+
+This class mistakenly uses new, which creates a method named "new" instead of a constructor:
+
+
+
+
+Use constructor for constructors in classes:
+
+
+
+
+This interface uses function as a method name, which declares a method named "function" rather than declaring a function:
+
diff --git a/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.ql b/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.ql
index c185e5c4d04e..fafa234f5f78 100644
--- a/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.ql
+++ b/javascript/ql/src/Declarations/SuspiciousMethodNameDeclaration.ql
@@ -6,7 +6,9 @@
* @problem.severity warning
* @id js/suspicious-method-name-declaration
* @precision high
- * @tags correctness
+ * @tags quality
+ * reliability
+ * correctness
* typescript
* methods
*/
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclaration.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclaration.ts
index b7b925aa15a9..6558267cef4b 100644
--- a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclaration.ts
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclaration.ts
@@ -1,6 +1,6 @@
-declare class Point {
+// BAD: Using 'constructor' in an interface creates a method, not a constructor signature
+interface Point {
x: number;
y: number;
- constructor(x : number, y: number);
+ constructor(x: number, y: number); // This is just a method named "constructor"
}
-
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClass.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClass.ts
new file mode 100644
index 000000000000..2a078c8b468b
--- /dev/null
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClass.ts
@@ -0,0 +1,6 @@
+// BAD: Using 'new' in a class creates a method, not a constructor
+class Point {
+ x: number;
+ y: number;
+ new(x: number, y: number) {}; // This is just a method named "new"
+}
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClassFixed.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClassFixed.ts
new file mode 100644
index 000000000000..0e072a4e0316
--- /dev/null
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationClassFixed.ts
@@ -0,0 +1,9 @@
+// GOOD: Using 'constructor' for constructors in classes
+class Point {
+ x: number;
+ y: number;
+ constructor(x: number, y: number) { // This is a proper constructor
+ this.x = x;
+ this.y = y;
+ }
+}
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFixed.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFixed.ts
index 850038f4dbfe..d5dacdbb9515 100644
--- a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFixed.ts
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFixed.ts
@@ -1,4 +1,6 @@
+// GOOD: Using 'new' for constructor signatures in interfaces
interface Point {
x: number;
y: number;
+ new(x: number, y: number): Point; // This is a proper constructor signature
}
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunction.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunction.ts
new file mode 100644
index 000000000000..37749d4ff85b
--- /dev/null
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunction.ts
@@ -0,0 +1,4 @@
+// BAD: Using 'function' as a method name is confusing
+interface Calculator {
+ function(a: number, b: number): number; // This is just a method named "function"
+}
diff --git a/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunctionFixed.ts b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunctionFixed.ts
new file mode 100644
index 000000000000..a5b3b747faa4
--- /dev/null
+++ b/javascript/ql/src/Declarations/examples/SuspiciousMethodNameDeclarationFunctionFixed.ts
@@ -0,0 +1,4 @@
+// GOOD: Using descriptive method names instead of 'function'
+interface Calculator {
+ calculate(a: number, b: number): number; // Clear, descriptive method name
+}
diff --git a/javascript/ql/src/Expressions/MissingAwait.ql b/javascript/ql/src/Expressions/MissingAwait.ql
index d97c006a7bd1..a16d31ee2a57 100644
--- a/javascript/ql/src/Expressions/MissingAwait.ql
+++ b/javascript/ql/src/Expressions/MissingAwait.ql
@@ -10,6 +10,7 @@
*/
import javascript
+private import semmle.javascript.internal.TypeResolution
/**
* Holds if `call` is a call to an `async` function.
@@ -28,7 +29,7 @@ predicate isPromise(DataFlow::SourceNode node, boolean nullable) {
isAsyncCall(node, nullable)
or
not isAsyncCall(node, _) and
- node.asExpr().getType() instanceof PromiseType and
+ TypeResolution::valueHasPromiseType(node.asExpr()) and
nullable = true
}
diff --git a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
index f22b97795607..f6824cfd9587 100644
--- a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
+++ b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql
@@ -5,7 +5,10 @@
* @problem.severity warning
* @id js/template-syntax-in-string-literal
* @precision high
- * @tags correctness
+ * @tags quality
+ * reliability
+ * correctness
+ * language-features
*/
import javascript
@@ -74,8 +77,8 @@ class CandidateStringLiteral extends StringLiteral {
*/
predicate hasObjectProvidingTemplateVariables(CandidateStringLiteral lit) {
exists(DataFlow::CallNode call, DataFlow::ObjectLiteralNode obj |
- call.getAnArgument().getALocalSource() = obj and
- call.getAnArgument().asExpr() = lit and
+ call.getAnArgument() = [lit.flow(), StringConcatenation::getRoot(lit.flow())] and
+ obj.flowsTo(call.getAnArgument()) and
forex(string name | name = lit.getAReferencedVariable() | exists(obj.getAPropertyWrite(name)))
)
}
@@ -91,12 +94,38 @@ VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) {
result.getTopLevel() = tl
}
+/**
+ * Tracks data flow from a string literal that may flow to a replace operation.
+ */
+DataFlow::SourceNode trackStringWithTemplateSyntax(
+ CandidateStringLiteral lit, DataFlow::TypeTracker t
+) {
+ t.start() and result = lit.flow() and exists(lit.getAReferencedVariable())
+ or
+ exists(DataFlow::TypeTracker t2 | result = trackStringWithTemplateSyntax(lit, t2).track(t2, t))
+}
+
+/**
+ * Gets a string literal that flows to a replace operation.
+ */
+DataFlow::SourceNode trackStringWithTemplateSyntax(CandidateStringLiteral lit) {
+ result = trackStringWithTemplateSyntax(lit, DataFlow::TypeTracker::end())
+}
+
+/**
+ * Holds if the string literal flows to a replace method call.
+ */
+predicate hasReplaceMethodCall(CandidateStringLiteral lit) {
+ trackStringWithTemplateSyntax(lit).getAMethodCall() instanceof StringReplaceCall
+}
+
from CandidateStringLiteral lit, Variable v, Scope s, string name, VarDecl decl
where
decl = getDeclIn(v, s, name, lit.getTopLevel()) and
lit.getAReferencedVariable() = name and
lit.isInScope(s) and
not hasObjectProvidingTemplateVariables(lit) and
- not lit.getStringValue() = "${" + name + "}"
+ not lit.getStringValue() = "${" + name + "}" and
+ not hasReplaceMethodCall(lit)
select lit, "This string is not a template literal, but appears to reference the variable $@.",
decl, v.getName()
diff --git a/javascript/ql/src/RegExp/DuplicateCharacterInCharacterClass.qhelp b/javascript/ql/src/RegExp/DuplicateCharacterInCharacterClass.qhelp
index 30ef990ec0cd..f94cced3d09a 100644
--- a/javascript/ql/src/RegExp/DuplicateCharacterInCharacterClass.qhelp
+++ b/javascript/ql/src/RegExp/DuplicateCharacterInCharacterClass.qhelp
@@ -5,26 +5,42 @@
-Character classes in regular expressions represent sets of characters, so there is no need to specify
-the same character twice in one character class. Duplicate characters in character classes are at best
-useless, and may even indicate a latent bug.
+Character classes in regular expressions (denoted by square brackets []) represent sets of characters where the pattern matches any single character from that set. Since character classes are sets, specifying the same character multiple times is redundant and often indicates a programming error.
+
+Common mistakes include:
+
+
+
Using square brackets [] instead of parentheses () for grouping alternatives
+
Misunderstanding that special regex characters like |, *, +, (), and - work differently when appearing inside a character class
+
Accidentally duplicating characters or escape sequences that represent the same character
+
+
-
If the character was accidentally duplicated, remove it. If the character class was meant to be a
-group, replace the brackets with parentheses.
+
+Examine each duplicate character to determine the intended behavior:
+
+
+
If you see | inside square brackets (e.g., [a|b|c]): This is usually a mistake. The author likely intended alternation. Replace the character class with a group: (a|b|c)
+
If trying to match alternative strings, use parentheses () for grouping instead of square brackets
+
If the duplicate was truly accidental, remove the redundant characters
+
If trying to use special regex operators inside square brackets, note that most operators (like |) are treated as literal characters
+
+
+Note that simply removing | characters from character classes is rarely the correct fix. Instead, analyze the pattern to understand what the author intended to match.
+
-In the following example, the character class [password|pwd] contains two instances each
-of the characters d, p, s, and w. The programmer
-most likely meant to write (password|pwd) (a pattern that matches either the string
-"password" or the string "pwd"), and accidentally mistyped the enclosing
-brackets.
+Example 1: Confusing character classes with groups
+
+
+The pattern [password|pwd] does not match "password" or "pwd" as intended. Instead, it matches any single character from the set {p, a, s, w, o, r, d, |}. Note that | has no special meaning inside character classes.
@@ -33,10 +49,23 @@ brackets.
To fix this problem, the regular expression should be rewritten to /(password|pwd) =/.
+
+Example 2: CSS unit matching
+
+
+The pattern r?e[m|x] appears to be trying to match "rem" or "rex", but actually matches "re" followed by any of the characters {m, |, x}. The correct pattern should be r?e(m|x) or r?e[mx].
+
+
+
+Similarly, v[h|w|min|max] should be v(h|w|min|max) to properly match "vh", "vw", "vmin", or "vmax".
+
' |
| event-handler-receiver.js:2:49:2:61 | location.href | semmle.label | location.href |
| express.js:6:15:6:33 | req.param("wobble") | semmle.label | req.param("wobble") |
+| jquery-declare-any.ts:6:7:6:17 | window.name | semmle.label | window.name |
+| jquery-declare-type.ts:6:7:6:17 | window.name | semmle.label | window.name |
| jquery.js:2:7:2:40 | tainted | semmle.label | tainted |
| jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search |
| jquery.js:4:5:4:11 | tainted | semmle.label | tainted |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected
index 0ed15b8d92ab..c031b7c1810c 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected
@@ -182,6 +182,8 @@ nodes
| hana.js:85:35:85:54 | tableRows[0].comment | semmle.label | tableRows[0].comment |
| hana.js:90:33:90:34 | rs | semmle.label | rs |
| hana.js:90:33:90:45 | rs[0].comment | semmle.label | rs[0].comment |
+| jquery-declare-any.ts:6:7:6:17 | window.name | semmle.label | window.name |
+| jquery-declare-type.ts:6:7:6:17 | window.name | semmle.label | window.name |
| jquery.js:2:7:2:40 | tainted | semmle.label | tainted |
| jquery.js:2:17:2:40 | documen ... .search | semmle.label | documen ... .search |
| jquery.js:4:5:4:11 | tainted | semmle.label | tainted |
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-any.ts b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-any.ts
new file mode 100644
index 000000000000..df8267bba306
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-any.ts
@@ -0,0 +1,7 @@
+import 'dummy';
+
+declare var $: any;
+
+function t() {
+ $(window.name); // $ Alert
+}
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-type.ts b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-type.ts
new file mode 100644
index 000000000000..c866f71a1eb9
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery-declare-type.ts
@@ -0,0 +1,7 @@
+import 'dummy';
+
+declare var $: JQueryStatic;
+
+function t() {
+ $(window.name); // $ Alert
+}
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected
index 499cf6cce49d..4f757d1a9313 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected
@@ -22,7 +22,6 @@
| main.js:111:37:111:37 | x | main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | This markdown rendering which depends on $@ might later allow $@. | main.js:98:43:98:43 | x | library input | main.js:112:24:112:26 | svg | cross-site scripting |
| main.js:117:34:117:34 | s | main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | This markdown rendering which depends on $@ might later allow $@. | main.js:116:47:116:47 | s | library input | main.js:118:53:118:56 | html | cross-site scripting |
| typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | This HTML construction which depends on $@ might later allow $@. | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting |
-| typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | This HTML construction which depends on $@ might later allow $@. | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | " ... /span>" | cross-site scripting |
edges
| jquery-plugin.js:11:27:11:31 | stuff | jquery-plugin.js:14:31:14:35 | stuff | provenance | |
| jquery-plugin.js:11:34:11:40 | options | jquery-plugin.js:12:31:12:37 | options | provenance | |
@@ -69,7 +68,6 @@ edges
| main.js:98:43:98:43 | x | main.js:111:37:111:37 | x | provenance | |
| main.js:116:47:116:47 | s | main.js:117:34:117:34 | s | provenance | |
| typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | provenance | |
-| typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | provenance | |
nodes
| jquery-plugin.js:11:27:11:31 | stuff | semmle.label | stuff |
| jquery-plugin.js:11:34:11:40 | options | semmle.label | options |
@@ -128,6 +126,4 @@ nodes
| main.js:117:34:117:34 | s | semmle.label | s |
| typed.ts:1:39:1:39 | s | semmle.label | s |
| typed.ts:2:29:2:29 | s | semmle.label | s |
-| typed.ts:6:43:6:43 | s | semmle.label | s |
-| typed.ts:8:40:8:40 | s | semmle.label | s |
subpaths
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/typed.ts b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/typed.ts
index 1c50460050cf..8c166fb243ff 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/typed.ts
+++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/typed.ts
@@ -3,9 +3,9 @@ export function basicHtmlConstruction(s: string) { // $ Source
document.body.innerHTML = html;
}
-export function insertIntoCreatedDocument(s: string) { // $ Source
+export function insertIntoCreatedDocument(s: string) {
const newDoc = document.implementation.createHTMLDocument("");
- newDoc.body.innerHTML = "" + s + ""; // $ SPURIOUS: Alert - inserted into document disconnected from the main DOM.
+ newDoc.body.innerHTML = "" + s + ""; // OK - inserted into document disconnected from the main DOM.
}
export function id(s: string) {
@@ -17,4 +17,3 @@ export function notVulnerable() {
const html = "" + s + "";
document.body.innerHTML = html;
}
-
\ No newline at end of file
diff --git a/javascript/ql/test/query-tests/definitions/definitions.expected b/javascript/ql/test/query-tests/definitions/definitions.expected
index 081db47c3faa..cb91ac6e37ce 100644
--- a/javascript/ql/test/query-tests/definitions/definitions.expected
+++ b/javascript/ql/test/query-tests/definitions/definitions.expected
@@ -1,36 +1,36 @@
| b.js:3:3:3:3 | x | b.js:2:7:2:7 | x | V |
-| b.js:7:1:7:1 | f | b.js:1:1:5:1 | functio ... ar x;\\n} | M |
-| b.js:8:1:8:1 | g | a.js:2:1:2:15 | function g() {} | M |
+| b.js:7:1:7:1 | f | b.js:1:10:1:10 | f | M |
+| b.js:8:1:8:1 | g | a.js:2:10:2:10 | g | M |
| client.ts:1:22:1:30 | "./tslib" | tslib.ts:1:1:10:0 | | I |
-| client.ts:7:19:7:19 | C | tslib.ts:1:8:3:1 | class C {\\n m() {}\\n} | T |
-| client.ts:8:10:8:10 | C | client.ts:3:1:5:1 | class C {\\n m() {}\\n} | T |
-| client.ts:9:16:9:16 | C | client.ts:3:1:5:1 | class C {\\n m() {}\\n} | T |
-| client.ts:10:16:10:16 | C | tslib.ts:6:10:8:3 | class C ... {}\\n } | T |
-| client.ts:13:25:13:25 | C | client.ts:3:1:5:1 | class C {\\n m() {}\\n} | T |
-| client.ts:13:35:13:35 | C | tslib.ts:1:8:3:1 | class C {\\n m() {}\\n} | T |
-| client.ts:13:47:13:47 | C | tslib.ts:6:10:8:3 | class C ... {}\\n } | T |
+| client.ts:7:19:7:19 | C | tslib.ts:1:14:1:14 | C | T |
+| client.ts:8:10:8:10 | C | client.ts:3:7:3:7 | C | T |
+| client.ts:9:16:9:16 | C | client.ts:3:7:3:7 | C | T |
+| client.ts:10:16:10:16 | C | tslib.ts:6:16:6:16 | C | T |
+| client.ts:13:25:13:25 | C | client.ts:3:7:3:7 | C | T |
+| client.ts:13:35:13:35 | C | tslib.ts:1:14:1:14 | C | T |
+| client.ts:13:47:13:47 | C | tslib.ts:6:16:6:16 | C | T |
| client.ts:14:3:14:3 | x | client.ts:13:22:13:22 | x | V |
-| client.ts:14:5:14:5 | m | client.ts:4:3:4:8 | m() {} | M |
+| client.ts:14:5:14:5 | m | client.ts:4:3:4:3 | m | M |
| client.ts:15:3:15:3 | y | client.ts:13:28:13:28 | y | V |
-| client.ts:15:5:15:5 | m | tslib.ts:2:3:2:8 | m() {} | M |
+| client.ts:15:5:15:5 | m | tslib.ts:2:3:2:3 | m | M |
| client.ts:16:3:16:3 | z | client.ts:13:38:13:38 | z | V |
-| client.ts:16:5:16:5 | m | tslib.ts:7:5:7:10 | m() {} | M |
+| client.ts:16:5:16:5 | m | tslib.ts:7:5:7:5 | m | M |
| d.js:1:17:1:21 | './c' | c.js:1:1:1:20 | | I |
-| d.js:10:1:10:1 | A | d.js:7:1:9:1 | functio ... = 42;\\n} | V |
-| d.js:16:19:16:23 | Super | d.js:12:1:14:1 | class S ... () {}\\n} | V |
+| d.js:10:1:10:1 | A | d.js:7:10:7:10 | A | V |
+| d.js:16:19:16:23 | Super | d.js:12:7:12:11 | Super | V |
| d.js:16:25:16:24 | args | d.js:16:25:16:24 | args | V |
| d.js:20:1:20:1 | o | d.js:3:9:5:1 | {\\n f: ... () {}\\n} | V |
| d.js:20:3:20:3 | f | d.js:4:3:4:18 | f: function() {} | M |
-| d.js:22:13:22:13 | A | d.js:7:1:9:1 | functio ... = 42;\\n} | M |
+| d.js:22:13:22:13 | A | d.js:7:10:7:10 | A | M |
| d.js:23:1:23:1 | a | d.js:22:5:22:5 | a | V |
| d.js:23:3:23:3 | x | d.js:8:3:8:8 | this.x | M |
| d.js:24:1:24:1 | a | d.js:22:5:22:5 | a | V |
| d.js:24:3:24:3 | g | d.js:10:1:10:13 | A.prototype.g | M |
-| d.js:26:13:26:15 | Sub | d.js:16:1:18:1 | class S ... () {}\\n} | M |
+| d.js:26:13:26:15 | Sub | d.js:16:7:16:9 | Sub | M |
| d.js:27:1:27:1 | x | d.js:26:5:26:5 | x | V |
| d.js:27:3:27:3 | m | d.js:13:3:13:3 | m | M |
| d.js:28:1:28:1 | x | d.js:26:5:26:5 | x | V |
| d.js:28:3:28:3 | n | d.js:17:3:17:3 | n | M |
| tst.js:1:19:1:23 | './m' | m.js:1:1:2:0 | | I |
-| tst.js:3:5:3:5 | A | m.js:1:8:1:17 | class A {} | M |
+| tst.js:3:5:3:5 | A | m.js:1:14:1:14 | A | M |
| tst.js:5:15:5:19 | './m' | m.js:1:1:2:0 | | I |
diff --git a/misc/codegen/codegen.py b/misc/codegen/codegen.py
index ae3a67d3fba6..7510405cd7fb 100755
--- a/misc/codegen/codegen.py
+++ b/misc/codegen/codegen.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-""" Driver script to run all code generation """
+"""Driver script to run all code generation"""
import argparse
import logging
@@ -9,7 +9,7 @@
import typing
import shlex
-if 'BUILD_WORKSPACE_DIRECTORY' not in os.environ:
+if "BUILD_WORKSPACE_DIRECTORY" not in os.environ:
# we are not running with `bazel run`, set up module search path
_repo_root = pathlib.Path(__file__).resolve().parents[2]
sys.path.append(str(_repo_root))
@@ -29,57 +29,105 @@ def _parse_args() -> argparse.Namespace:
conf = None
p = argparse.ArgumentParser(description="Code generation suite")
- p.add_argument("--generate", type=lambda x: x.split(","),
- help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, "
- "trap, cpp and rust")
- p.add_argument("--verbose", "-v", action="store_true", help="print more information")
+ p.add_argument(
+ "--generate",
+ type=lambda x: x.split(","),
+ help="specify what targets to generate as a comma separated list, choosing among dbscheme, ql, "
+ "trap, cpp and rust",
+ )
+ p.add_argument(
+ "--verbose", "-v", action="store_true", help="print more information"
+ )
p.add_argument("--quiet", "-q", action="store_true", help="only print errors")
- p.add_argument("--configuration-file", "-c", type=_abspath, default=conf,
- help="A configuration file to load options from. By default, the first codegen.conf file found by "
- "going up directories from the current location. If present all paths provided in options are "
- "considered relative to its directory")
- p.add_argument("--root-dir", type=_abspath,
- help="the directory that should be regarded as the root of the language pack codebase. Used to "
- "compute QL imports and in some comments and as root for relative paths provided as options. "
- "If not provided it defaults to the directory of the configuration file, if any")
+ p.add_argument(
+ "--configuration-file",
+ "-c",
+ type=_abspath,
+ default=conf,
+ help="A configuration file to load options from. By default, the first codegen.conf file found by "
+ "going up directories from the current location. If present all paths provided in options are "
+ "considered relative to its directory",
+ )
+ p.add_argument(
+ "--root-dir",
+ type=_abspath,
+ help="the directory that should be regarded as the root of the language pack codebase. Used to "
+ "compute QL imports and in some comments and as root for relative paths provided as options. "
+ "If not provided it defaults to the directory of the configuration file, if any",
+ )
path_arguments = [
- p.add_argument("--schema",
- help="input schema file (default schema.py)"),
- p.add_argument("--dbscheme",
- help="output file for dbscheme generation, input file for trap generation"),
- p.add_argument("--ql-output",
- help="output directory for generated QL files"),
- p.add_argument("--ql-stub-output",
- help="output directory for QL stub/customization files. Defines also the "
- "generated qll file importing every class file"),
- p.add_argument("--ql-test-output",
- help="output directory for QL generated extractor test files"),
- p.add_argument("--ql-cfg-output",
- help="output directory for QL CFG layer (optional)."),
- p.add_argument("--cpp-output",
- help="output directory for generated C++ files, required if trap or cpp is provided to "
- "--generate"),
- p.add_argument("--rust-output",
- help="output directory for generated Rust files, required if rust is provided to "
- "--generate"),
- p.add_argument("--generated-registry",
- help="registry file containing information about checked-in generated code. A .gitattributes"
- "file is generated besides it to mark those files with linguist-generated=true. Must"
- "be in a directory containing all generated code."),
+ p.add_argument("--schema", help="input schema file (default schema.py)"),
+ p.add_argument(
+ "--dbscheme",
+ help="output file for dbscheme generation, input file for trap generation",
+ ),
+ p.add_argument("--ql-output", help="output directory for generated QL files"),
+ p.add_argument(
+ "--ql-stub-output",
+ help="output directory for QL stub/customization files. Defines also the "
+ "generated qll file importing every class file",
+ ),
+ p.add_argument(
+ "--ql-test-output",
+ help="output directory for QL generated extractor test files",
+ ),
+ p.add_argument(
+ "--ql-cfg-output", help="output directory for QL CFG layer (optional)."
+ ),
+ p.add_argument(
+ "--cpp-output",
+ help="output directory for generated C++ files, required if trap or cpp is provided to "
+ "--generate",
+ ),
+ p.add_argument(
+ "--rust-output",
+ help="output directory for generated Rust files, required if rust is provided to "
+ "--generate",
+ ),
+ p.add_argument(
+ "--generated-registry",
+ help="registry file containing information about checked-in generated code. A .gitattributes"
+ "file is generated besides it to mark those files with linguist-generated=true. Must"
+ "be in a directory containing all generated code.",
+ ),
]
- p.add_argument("--script-name",
- help="script name to put in header comments of generated files. By default, the path of this "
- "script relative to the root directory")
- p.add_argument("--trap-library",
- help="path to the trap library from an include directory, required if generating C++ trap bindings"),
- p.add_argument("--ql-format", action="store_true", default=True,
- help="use codeql to autoformat QL files (which is the default)")
- p.add_argument("--no-ql-format", action="store_false", dest="ql_format", help="do not format QL files")
- p.add_argument("--codeql-binary", default="codeql", help="command to use for QL formatting (default %(default)s)")
- p.add_argument("--force", "-f", action="store_true",
- help="generate all files without skipping unchanged files and overwriting modified ones")
- p.add_argument("--use-current-directory", action="store_true",
- help="do not consider paths as relative to --root-dir or the configuration directory")
+ p.add_argument(
+ "--script-name",
+ help="script name to put in header comments of generated files. By default, the path of this "
+ "script relative to the root directory",
+ )
+ p.add_argument(
+ "--trap-library",
+ help="path to the trap library from an include directory, required if generating C++ trap bindings",
+ ),
+ p.add_argument(
+ "--ql-format",
+ action="store_true",
+ default=True,
+ help="use codeql to autoformat QL files (which is the default)",
+ )
+ p.add_argument(
+ "--no-ql-format",
+ action="store_false",
+ dest="ql_format",
+ help="do not format QL files",
+ )
+ p.add_argument(
+ "--codeql-binary",
+ default="codeql",
+ help="command to use for QL formatting (default %(default)s)",
+ )
+ p.add_argument(
+ "--force",
+ "-f",
+ action="store_true",
+ help="generate all files without skipping unchanged files and overwriting modified ones",
+ )
+ p.add_argument(
+ "--use-current-directory",
+ action="store_true",
+ help="do not consider paths as relative to --root-dir or the configuration directory",
+ )
opts = p.parse_args()
if opts.configuration_file is not None:
with open(opts.configuration_file) as config:
@@ -97,7 +145,15 @@ def _parse_args() -> argparse.Namespace:
for arg in path_arguments:
path = getattr(opts, arg.dest)
if path is not None:
- setattr(opts, arg.dest, _abspath(path) if opts.use_current_directory else (opts.root_dir / path))
+ setattr(
+ opts,
+ arg.dest,
+ (
+ _abspath(path)
+ if opts.use_current_directory
+ else (opts.root_dir / path)
+ ),
+ )
if not opts.script_name:
opts.script_name = paths.exe_file.relative_to(opts.root_dir)
return opts
@@ -115,7 +171,7 @@ def run():
log_level = logging.ERROR
else:
log_level = logging.INFO
- logging.basicConfig(format="{levelname} {message}", style='{', level=log_level)
+ logging.basicConfig(format="{levelname} {message}", style="{", level=log_level)
for target in opts.generate:
generate(target, opts, render.Renderer(opts.script_name))
diff --git a/misc/codegen/generators/cppgen.py b/misc/codegen/generators/cppgen.py
index 1a9a64663c19..cf99167fa46d 100644
--- a/misc/codegen/generators/cppgen.py
+++ b/misc/codegen/generators/cppgen.py
@@ -49,7 +49,11 @@ def _get_trap_name(cls: schema.Class, p: schema.Property) -> str | None:
return inflection.pluralize(trap_name)
-def _get_field(cls: schema.Class, p: schema.Property, add_or_none_except: typing.Optional[str] = None) -> cpp.Field:
+def _get_field(
+ cls: schema.Class,
+ p: schema.Property,
+ add_or_none_except: typing.Optional[str] = None,
+) -> cpp.Field:
args = dict(
field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""),
base_type=_get_type(p.type, add_or_none_except),
@@ -83,14 +87,15 @@ def _get_class(self, name: str) -> cpp.Class:
bases=[self._get_class(b) for b in cls.bases],
fields=[
_get_field(cls, p, self._add_or_none_except)
- for p in cls.properties if "cpp_skip" not in p.pragmas and not p.synth
+ for p in cls.properties
+ if "cpp_skip" not in p.pragmas and not p.synth
],
final=not cls.derived,
trap_name=trap_name,
)
def get_classes(self):
- ret = {'': []}
+ ret = {"": []}
for k, cls in self._classmap.items():
if not cls.synth:
ret.setdefault(cls.group, []).append(self._get_class(cls.name))
@@ -102,6 +107,12 @@ def generate(opts, renderer):
processor = Processor(schemaloader.load_file(opts.schema))
out = opts.cpp_output
for dir, classes in processor.get_classes().items():
- renderer.render(cpp.ClassList(classes, opts.schema,
- include_parent=bool(dir),
- trap_library=opts.trap_library), out / dir / "TrapClasses")
+ renderer.render(
+ cpp.ClassList(
+ classes,
+ opts.schema,
+ include_parent=bool(dir),
+ trap_library=opts.trap_library,
+ ),
+ out / dir / "TrapClasses",
+ )
diff --git a/misc/codegen/generators/dbschemegen.py b/misc/codegen/generators/dbschemegen.py
index f861972cdd68..c28fce746b97 100755
--- a/misc/codegen/generators/dbschemegen.py
+++ b/misc/codegen/generators/dbschemegen.py
@@ -13,6 +13,7 @@
as columns
The type hierarchy will be translated to corresponding `union` declarations.
"""
+
import typing
import inflection
@@ -29,7 +30,7 @@ class Error(Exception):
def dbtype(typename: str, add_or_none_except: typing.Optional[str] = None) -> str:
- """ translate a type to a dbscheme counterpart, using `@lower_underscore` format for classes.
+ """translate a type to a dbscheme counterpart, using `@lower_underscore` format for classes.
For class types, appends an underscore followed by `null` if provided
"""
if typename[0].isupper():
@@ -42,12 +43,18 @@ def dbtype(typename: str, add_or_none_except: typing.Optional[str] = None) -> st
return typename
-def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], add_or_none_except: typing.Optional[str] = None):
- """ Yield all dbscheme entities needed to model class `cls` """
+def cls_to_dbscheme(
+ cls: schema.Class,
+ lookup: typing.Dict[str, schema.Class],
+ add_or_none_except: typing.Optional[str] = None,
+):
+ """Yield all dbscheme entities needed to model class `cls`"""
if cls.synth:
return
if cls.derived:
- yield Union(dbtype(cls.name), (dbtype(c) for c in cls.derived if not lookup[c].synth))
+ yield Union(
+ dbtype(cls.name), (dbtype(c) for c in cls.derived if not lookup[c].synth)
+ )
dir = pathlib.Path(cls.group) if cls.group else None
# output a table specific to a class only if it is a leaf class or it has 1-to-1 properties
# Leaf classes need a table to bind the `@` ids
@@ -61,9 +68,11 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a
name=inflection.tableize(cls.name),
columns=[
Column("id", type=dbtype(cls.name), binding=binding),
- ] + [
+ ]
+ + [
Column(f.name, dbtype(f.type, add_or_none_except))
- for f in cls.properties if f.is_single and not f.synth
+ for f in cls.properties
+ if f.is_single and not f.synth
],
dir=dir,
)
@@ -74,28 +83,37 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a
continue
if f.is_unordered:
yield Table(
- name=overridden_table_name or inflection.tableize(f"{cls.name}_{f.name}"),
+ name=overridden_table_name
+ or inflection.tableize(f"{cls.name}_{f.name}"),
columns=[
Column("id", type=dbtype(cls.name)),
- Column(inflection.singularize(f.name), dbtype(f.type, add_or_none_except)),
+ Column(
+ inflection.singularize(f.name),
+ dbtype(f.type, add_or_none_except),
+ ),
],
dir=dir,
)
elif f.is_repeated:
yield Table(
keyset=KeySet(["id", "index"]),
- name=overridden_table_name or inflection.tableize(f"{cls.name}_{f.name}"),
+ name=overridden_table_name
+ or inflection.tableize(f"{cls.name}_{f.name}"),
columns=[
Column("id", type=dbtype(cls.name)),
Column("index", type="int"),
- Column(inflection.singularize(f.name), dbtype(f.type, add_or_none_except)),
+ Column(
+ inflection.singularize(f.name),
+ dbtype(f.type, add_or_none_except),
+ ),
],
dir=dir,
)
elif f.is_optional:
yield Table(
keyset=KeySet(["id"]),
- name=overridden_table_name or inflection.tableize(f"{cls.name}_{f.name}"),
+ name=overridden_table_name
+ or inflection.tableize(f"{cls.name}_{f.name}"),
columns=[
Column("id", type=dbtype(cls.name)),
Column(f.name, dbtype(f.type, add_or_none_except)),
@@ -105,7 +123,8 @@ def cls_to_dbscheme(cls: schema.Class, lookup: typing.Dict[str, schema.Class], a
elif f.is_predicate:
yield Table(
keyset=KeySet(["id"]),
- name=overridden_table_name or inflection.underscore(f"{cls.name}_{f.name}"),
+ name=overridden_table_name
+ or inflection.underscore(f"{cls.name}_{f.name}"),
columns=[
Column("id", type=dbtype(cls.name)),
],
@@ -119,33 +138,46 @@ def check_name_conflicts(decls: list[Table | Union]):
match decl:
case Table(name=name):
if name in names:
- raise Error(f"Duplicate table name: {
- name}, you can use `@ql.db_table_name` on a property to resolve this")
+ raise Error(
+ f"Duplicate table name: {
+ name}, you can use `@ql.db_table_name` on a property to resolve this"
+ )
names.add(name)
def get_declarations(data: schema.Schema):
add_or_none_except = data.root_class.name if data.null else None
- declarations = [d for cls in data.classes.values() if not cls.imported for d in cls_to_dbscheme(cls,
- data.classes, add_or_none_except)]
+ declarations = [
+ d
+ for cls in data.classes.values()
+ if not cls.imported
+ for d in cls_to_dbscheme(cls, data.classes, add_or_none_except)
+ ]
if data.null:
property_classes = {
- prop.type for cls in data.classes.values() for prop in cls.properties
+ prop.type
+ for cls in data.classes.values()
+ for prop in cls.properties
if cls.name != data.null and prop.type and prop.type[0].isupper()
}
declarations += [
- Union(dbtype(t, data.null), [dbtype(t), dbtype(data.null)]) for t in sorted(property_classes)
+ Union(dbtype(t, data.null), [dbtype(t), dbtype(data.null)])
+ for t in sorted(property_classes)
]
check_name_conflicts(declarations)
return declarations
-def get_includes(data: schema.Schema, include_dir: pathlib.Path, root_dir: pathlib.Path):
+def get_includes(
+ data: schema.Schema, include_dir: pathlib.Path, root_dir: pathlib.Path
+):
includes = []
for inc in data.includes:
inc = include_dir / inc
with open(inc) as inclusion:
- includes.append(SchemeInclude(src=inc.relative_to(root_dir), data=inclusion.read()))
+ includes.append(
+ SchemeInclude(src=inc.relative_to(root_dir), data=inclusion.read())
+ )
return includes
@@ -155,8 +187,10 @@ def generate(opts, renderer):
data = schemaloader.load_file(input)
- dbscheme = Scheme(src=input.name,
- includes=get_includes(data, include_dir=input.parent, root_dir=input.parent),
- declarations=get_declarations(data))
+ dbscheme = Scheme(
+ src=input.name,
+ includes=get_includes(data, include_dir=input.parent, root_dir=input.parent),
+ declarations=get_declarations(data),
+ )
renderer.render(dbscheme, out)
diff --git a/misc/codegen/generators/qlgen.py b/misc/codegen/generators/qlgen.py
index 7e898135d01f..991c21990d46 100755
--- a/misc/codegen/generators/qlgen.py
+++ b/misc/codegen/generators/qlgen.py
@@ -19,6 +19,7 @@
* one `.ql` test query for all single properties and on `_.ql` test query for each optional or
repeated property
"""
+
# TODO this should probably be split in different generators now: ql, qltest, maybe qlsynth
import logging
@@ -70,7 +71,7 @@ class NoClasses(Error):
abbreviations.update({f"{k}s": f"{v}s" for k, v in abbreviations.items()})
-_abbreviations_re = re.compile("|".join(fr"\b{abbr}\b" for abbr in abbreviations))
+_abbreviations_re = re.compile("|".join(rf"\b{abbr}\b" for abbr in abbreviations))
def _humanize(s: str) -> str:
@@ -98,11 +99,17 @@ def _get_doc(cls: schema.Class, prop: schema.Property, plural=None):
return format.format(**{noun: transform(noun) for noun in nouns})
prop_name = _humanize(prop.name)
- class_name = cls.pragmas.get("ql_default_doc_name", _humanize(inflection.underscore(cls.name)))
+ class_name = cls.pragmas.get(
+ "ql_default_doc_name", _humanize(inflection.underscore(cls.name))
+ )
if prop.is_predicate:
return f"this {class_name} {prop_name}"
if plural is not None:
- prop_name = inflection.pluralize(prop_name) if plural else inflection.singularize(prop_name)
+ prop_name = (
+ inflection.pluralize(prop_name)
+ if plural
+ else inflection.singularize(prop_name)
+ )
return f"{prop_name} of this {class_name}"
@@ -114,8 +121,12 @@ def _type_is_hideable(t: str, lookup: typing.Dict[str, schema.ClassBase]) -> boo
return False
-def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dict[str, schema.ClassBase],
- prev_child: str = "") -> ql.Property:
+def get_ql_property(
+ cls: schema.Class,
+ prop: schema.Property,
+ lookup: typing.Dict[str, schema.ClassBase],
+ prev_child: str = "",
+) -> ql.Property:
args = dict(
type=prop.type if not prop.is_predicate else "predicate",
@@ -133,12 +144,15 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
ql_name = prop.pragmas.get("ql_name", prop.name)
db_table_name = prop.pragmas.get("ql_db_table_name")
if db_table_name and prop.is_single:
- raise Error(f"`db_table_name` pragma is not supported for single properties, but {cls.name}.{prop.name} has it")
+ raise Error(
+ f"`db_table_name` pragma is not supported for single properties, but {cls.name}.{prop.name} has it"
+ )
if prop.is_single:
args.update(
singular=inflection.camelize(ql_name),
tablename=inflection.tableize(cls.name),
- tableparams=["this"] + ["result" if p is prop else "_" for p in cls.properties if p.is_single],
+ tableparams=["this"]
+ + ["result" if p is prop else "_" for p in cls.properties if p.is_single],
doc=_get_doc(cls, prop),
)
elif prop.is_repeated:
@@ -146,7 +160,11 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
singular=inflection.singularize(inflection.camelize(ql_name)),
plural=inflection.pluralize(inflection.camelize(ql_name)),
tablename=db_table_name or inflection.tableize(f"{cls.name}_{prop.name}"),
- tableparams=["this", "index", "result"] if not prop.is_unordered else ["this", "result"],
+ tableparams=(
+ ["this", "index", "result"]
+ if not prop.is_unordered
+ else ["this", "result"]
+ ),
doc=_get_doc(cls, prop, plural=False),
doc_plural=_get_doc(cls, prop, plural=True),
)
@@ -169,7 +187,9 @@ def get_ql_property(cls: schema.Class, prop: schema.Property, lookup: typing.Dic
return ql.Property(**args)
-def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.ClassBase]) -> ql.Class:
+def get_ql_class(
+ cls: schema.Class, lookup: typing.Dict[str, schema.ClassBase]
+) -> ql.Class:
if "ql_name" in cls.pragmas:
raise Error("ql_name is not supported yet for classes, only for properties")
prev_child = ""
@@ -195,12 +215,14 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.ClassBase])
)
-def get_ql_cfg_class(cls: schema.Class, lookup: typing.Dict[str, ql.Class]) -> ql.CfgClass:
+def get_ql_cfg_class(
+ cls: schema.Class, lookup: typing.Dict[str, ql.Class]
+) -> ql.CfgClass:
return ql.CfgClass(
name=cls.name,
bases=[base for base in cls.bases if lookup[base.base].cfg],
properties=cls.properties,
- doc=cls.doc
+ doc=cls.doc,
)
@@ -214,24 +236,33 @@ def _to_db_type(x: str) -> str:
def get_ql_synth_class_db(name: str) -> ql.Synth.FinalClassDb:
- return _final_db_class_lookup.setdefault(name, ql.Synth.FinalClassDb(name=name,
- params=[
- ql.Synth.Param("id", _to_db_type(name))]))
+ return _final_db_class_lookup.setdefault(
+ name,
+ ql.Synth.FinalClassDb(
+ name=name, params=[ql.Synth.Param("id", _to_db_type(name))]
+ ),
+ )
def get_ql_synth_class(cls: schema.Class):
if cls.derived:
- return ql.Synth.NonFinalClass(name=cls.name, derived=sorted(cls.derived),
- root=not cls.bases)
+ return ql.Synth.NonFinalClass(
+ name=cls.name, derived=sorted(cls.derived), root=not cls.bases
+ )
if cls.synth and cls.synth.from_class is not None:
source = cls.synth.from_class
get_ql_synth_class_db(source).subtract_type(cls.name)
- return ql.Synth.FinalClassDerivedSynth(name=cls.name,
- params=[ql.Synth.Param("id", _to_db_type(source))])
+ return ql.Synth.FinalClassDerivedSynth(
+ name=cls.name, params=[ql.Synth.Param("id", _to_db_type(source))]
+ )
if cls.synth and cls.synth.on_arguments is not None:
- return ql.Synth.FinalClassFreshSynth(name=cls.name,
- params=[ql.Synth.Param(k, _to_db_type(v))
- for k, v in cls.synth.on_arguments.items()])
+ return ql.Synth.FinalClassFreshSynth(
+ name=cls.name,
+ params=[
+ ql.Synth.Param(k, _to_db_type(v))
+ for k, v in cls.synth.on_arguments.items()
+ ],
+ )
return get_ql_synth_class_db(cls.name)
@@ -250,7 +281,13 @@ def get_types_used_by(cls: ql.Class, is_impl: bool) -> typing.Iterable[str]:
def get_classes_used_by(cls: ql.Class, is_impl: bool) -> typing.List[str]:
- return sorted(set(t for t in get_types_used_by(cls, is_impl) if t[0].isupper() and (is_impl or t != cls.name)))
+ return sorted(
+ set(
+ t
+ for t in get_types_used_by(cls, is_impl)
+ if t[0].isupper() and (is_impl or t != cls.name)
+ )
+ )
def format(codeql, files):
@@ -265,7 +302,8 @@ def format(codeql, files):
codeql_path = shutil.which(codeql)
if not codeql_path:
raise FormatError(
- f"`{codeql}` not found in PATH. Either install it, or pass `-- --codeql-binary` with a full path")
+ f"`{codeql}` not found in PATH. Either install it, or pass `-- --codeql-binary` with a full path"
+ )
codeql = codeql_path
res = subprocess.run(format_cmd, stderr=subprocess.PIPE, text=True)
if res.returncode:
@@ -281,16 +319,22 @@ def _get_path(cls: schema.Class) -> pathlib.Path:
def _get_path_impl(cls: schema.Class) -> pathlib.Path:
- return pathlib.Path(cls.group or "", "internal", cls.name+"Impl").with_suffix(".qll")
+ return pathlib.Path(cls.group or "", "internal", cls.name + "Impl").with_suffix(
+ ".qll"
+ )
def _get_path_public(cls: schema.Class) -> pathlib.Path:
- return pathlib.Path(cls.group or "", "internal" if "ql_internal" in cls.pragmas else "", cls.name).with_suffix(".qll")
+ return pathlib.Path(
+ cls.group or "", "internal" if "ql_internal" in cls.pragmas else "", cls.name
+ ).with_suffix(".qll")
-def _get_all_properties(cls: schema.Class, lookup: typing.Dict[str, schema.Class],
- already_seen: typing.Optional[typing.Set[int]] = None) -> \
- typing.Iterable[typing.Tuple[schema.Class, schema.Property]]:
+def _get_all_properties(
+ cls: schema.Class,
+ lookup: typing.Dict[str, schema.Class],
+ already_seen: typing.Optional[typing.Set[int]] = None,
+) -> typing.Iterable[typing.Tuple[schema.Class, schema.Property]]:
# deduplicate using ids
if already_seen is None:
already_seen = set()
@@ -304,14 +348,19 @@ def _get_all_properties(cls: schema.Class, lookup: typing.Dict[str, schema.Class
yield cls, p
-def _get_all_properties_to_be_tested(cls: schema.Class, lookup: typing.Dict[str, schema.Class]) -> \
- typing.Iterable[ql.PropertyForTest]:
+def _get_all_properties_to_be_tested(
+ cls: schema.Class, lookup: typing.Dict[str, schema.Class]
+) -> typing.Iterable[ql.PropertyForTest]:
for c, p in _get_all_properties(cls, lookup):
if not ("qltest_skip" in c.pragmas or "qltest_skip" in p.pragmas):
# TODO here operations are duplicated, but should be better if we split ql and qltest generation
p = get_ql_property(c, p, lookup)
- yield ql.PropertyForTest(p.getter, is_total=p.is_single or p.is_predicate,
- type=p.type if not p.is_predicate else None, is_indexed=p.is_indexed)
+ yield ql.PropertyForTest(
+ p.getter,
+ is_total=p.is_single or p.is_predicate,
+ type=p.type if not p.is_predicate else None,
+ is_indexed=p.is_indexed,
+ )
if p.is_repeated and not p.is_optional:
yield ql.PropertyForTest(f"getNumberOf{p.plural}", type="int")
elif p.is_optional and not p.is_repeated:
@@ -324,33 +373,45 @@ def _partition_iter(x, pred):
def _partition(l, pred):
- """ partitions a list according to boolean predicate """
+ """partitions a list according to boolean predicate"""
return map(list, _partition_iter(l, pred))
-def _is_in_qltest_collapsed_hierarchy(cls: schema.Class, lookup: typing.Dict[str, schema.Class]):
- return "qltest_collapse_hierarchy" in cls.pragmas or _is_under_qltest_collapsed_hierarchy(cls, lookup)
+def _is_in_qltest_collapsed_hierarchy(
+ cls: schema.Class, lookup: typing.Dict[str, schema.Class]
+):
+ return (
+ "qltest_collapse_hierarchy" in cls.pragmas
+ or _is_under_qltest_collapsed_hierarchy(cls, lookup)
+ )
-def _is_under_qltest_collapsed_hierarchy(cls: schema.Class, lookup: typing.Dict[str, schema.Class]):
+def _is_under_qltest_collapsed_hierarchy(
+ cls: schema.Class, lookup: typing.Dict[str, schema.Class]
+):
return "qltest_uncollapse_hierarchy" not in cls.pragmas and any(
- _is_in_qltest_collapsed_hierarchy(lookup[b], lookup) for b in cls.bases)
+ _is_in_qltest_collapsed_hierarchy(lookup[b], lookup) for b in cls.bases
+ )
def should_skip_qltest(cls: schema.Class, lookup: typing.Dict[str, schema.Class]):
- return "qltest_skip" in cls.pragmas or not (
- cls.final or "qltest_collapse_hierarchy" in cls.pragmas) or _is_under_qltest_collapsed_hierarchy(
- cls, lookup)
+ return (
+ "qltest_skip" in cls.pragmas
+ or not (cls.final or "qltest_collapse_hierarchy" in cls.pragmas)
+ or _is_under_qltest_collapsed_hierarchy(cls, lookup)
+ )
-def _get_stub(cls: schema.Class, base_import: str, generated_import_prefix: str) -> ql.Stub:
+def _get_stub(
+ cls: schema.Class, base_import: str, generated_import_prefix: str
+) -> ql.Stub:
if isinstance(cls.synth, schema.SynthInfo):
if cls.synth.from_class is not None:
accessors = [
ql.SynthUnderlyingAccessor(
argument="Entity",
type=_to_db_type(cls.synth.from_class),
- constructorparams=["result"]
+ constructorparams=["result"],
)
]
elif cls.synth.on_arguments is not None:
@@ -358,28 +419,39 @@ def _get_stub(cls: schema.Class, base_import: str, generated_import_prefix: str)
ql.SynthUnderlyingAccessor(
argument=inflection.camelize(arg),
type=_to_db_type(type),
- constructorparams=["result" if a == arg else "_" for a in cls.synth.on_arguments]
- ) for arg, type in cls.synth.on_arguments.items()
+ constructorparams=[
+ "result" if a == arg else "_" for a in cls.synth.on_arguments
+ ],
+ )
+ for arg, type in cls.synth.on_arguments.items()
]
else:
accessors = []
- return ql.Stub(name=cls.name, base_import=base_import, import_prefix=generated_import_prefix,
- doc=cls.doc, synth_accessors=accessors)
+ return ql.Stub(
+ name=cls.name,
+ base_import=base_import,
+ import_prefix=generated_import_prefix,
+ doc=cls.doc,
+ synth_accessors=accessors,
+ )
def _get_class_public(cls: schema.Class) -> ql.ClassPublic:
- return ql.ClassPublic(name=cls.name, doc=cls.doc, internal="ql_internal" in cls.pragmas)
+ return ql.ClassPublic(
+ name=cls.name, doc=cls.doc, internal="ql_internal" in cls.pragmas
+ )
_stub_qldoc_header = "// the following QLdoc is generated: if you need to edit it, do it in the schema file\n "
_class_qldoc_re = re.compile(
rf"(?P(?:{re.escape(_stub_qldoc_header)})?/\*\*.*?\*/\s*|^\s*)(?:class\s+(?P\w+))?",
- re.MULTILINE | re.DOTALL)
+ re.MULTILINE | re.DOTALL,
+)
def _patch_class_qldoc(cls: str, qldoc: str, stub_file: pathlib.Path):
- """ Replace or insert `qldoc` as the QLdoc of class `cls` in `stub_file` """
+ """Replace or insert `qldoc` as the QLdoc of class `cls` in `stub_file`"""
if not qldoc or not stub_file.exists():
return
qldoc = "\n ".join(l.rstrip() for l in qldoc.splitlines())
@@ -415,7 +487,11 @@ def generate(opts, renderer):
data = schemaloader.load_file(input)
- classes = {name: get_ql_class(cls, data.classes) for name, cls in data.classes.items() if not cls.imported}
+ classes = {
+ name: get_ql_class(cls, data.classes)
+ for name, cls in data.classes.items()
+ if not cls.imported
+ }
if not classes:
raise NoClasses
root = next(iter(classes.values()))
@@ -429,28 +505,47 @@ def generate(opts, renderer):
cfg_classes = []
generated_import_prefix = get_import(out, opts.root_dir)
registry = opts.generated_registry or pathlib.Path(
- os.path.commonpath((out, stub_out, test_out)), ".generated.list")
+ os.path.commonpath((out, stub_out, test_out)), ".generated.list"
+ )
- with renderer.manage(generated=generated, stubs=stubs, registry=registry,
- force=opts.force) as renderer:
+ with renderer.manage(
+ generated=generated, stubs=stubs, registry=registry, force=opts.force
+ ) as renderer:
- db_classes = [cls for name, cls in classes.items() if not data.classes[name].synth]
- renderer.render(ql.DbClasses(classes=db_classes, imports=sorted(set(pre_imports.values()))), out / "Raw.qll")
+ db_classes = [
+ cls for name, cls in classes.items() if not data.classes[name].synth
+ ]
+ renderer.render(
+ ql.DbClasses(classes=db_classes, imports=sorted(set(pre_imports.values()))),
+ out / "Raw.qll",
+ )
- classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name))
+ classes_by_dir_and_name = sorted(
+ classes.values(), key=lambda cls: (cls.dir, cls.name)
+ )
for c in classes_by_dir_and_name:
- path = get_import(stub_out / c.dir / "internal" /
- c.name if c.internal else stub_out / c.path, opts.root_dir)
+ path = get_import(
+ (
+ stub_out / c.dir / "internal" / c.name
+ if c.internal
+ else stub_out / c.path
+ ),
+ opts.root_dir,
+ )
imports[c.name] = path
- path_impl = get_import(stub_out / c.dir / "internal" / c.name, opts.root_dir)
+ path_impl = get_import(
+ stub_out / c.dir / "internal" / c.name, opts.root_dir
+ )
imports_impl[c.name + "Impl"] = path_impl + "Impl"
if c.cfg:
cfg_classes.append(get_ql_cfg_class(c, classes))
for c in classes.values():
qll = out / c.path.with_suffix(".qll")
- c.imports = [imports[t] if t in imports else imports_impl[t] +
- "::Impl as " + t for t in get_classes_used_by(c, is_impl=True)]
+ c.imports = [
+ imports[t] if t in imports else imports_impl[t] + "::Impl as " + t
+ for t in get_classes_used_by(c, is_impl=True)
+ ]
classes_used_by[c.name] = get_classes_used_by(c, is_impl=False)
c.import_prefix = generated_import_prefix
renderer.render(c, qll)
@@ -458,7 +553,7 @@ def generate(opts, renderer):
if cfg_out:
cfg_classes_val = ql.CfgClasses(
include_file_import=get_import(include_file, opts.root_dir),
- classes=cfg_classes
+ classes=cfg_classes,
)
cfg_qll = cfg_out / "CfgNodes.qll"
renderer.render(cfg_classes_val, cfg_qll)
@@ -475,7 +570,7 @@ def generate(opts, renderer):
if not renderer.is_customized_stub(stub_file):
renderer.render(stub, stub_file)
else:
- qldoc = renderer.render_str(stub, template='ql_stub_class_qldoc')
+ qldoc = renderer.render_str(stub, template="ql_stub_class_qldoc")
_patch_class_qldoc(c.name, qldoc, stub_file)
class_public = _get_class_public(c)
path_public = _get_path_public(c)
@@ -484,18 +579,31 @@ def generate(opts, renderer):
renderer.render(class_public, class_public_file)
# for example path/to/elements -> path/to/elements.qll
- renderer.render(ql.ImportList([i for name, i in imports.items() if name not in classes or not classes[name].internal]),
- include_file)
+ renderer.render(
+ ql.ImportList(
+ [
+ i
+ for name, i in imports.items()
+ if name not in classes or not classes[name].internal
+ ]
+ ),
+ include_file,
+ )
elements_module = get_import(include_file, opts.root_dir)
renderer.render(
ql.GetParentImplementation(
classes=list(classes.values()),
- imports=[elements_module] + [i for name,
- i in imports.items() if name in classes and classes[name].internal],
+ imports=[elements_module]
+ + [
+ i
+ for name, i in imports.items()
+ if name in classes and classes[name].internal
+ ],
),
- out / 'ParentChild.qll')
+ out / "ParentChild.qll",
+ )
if test_out:
for c in data.classes.values():
@@ -507,39 +615,61 @@ def generate(opts, renderer):
test_with = data.classes[test_with_name] if test_with_name else c
test_dir = test_out / test_with.group / test_with.name
test_dir.mkdir(parents=True, exist_ok=True)
- if all(f.suffix in (".txt", ".ql", ".actual", ".expected") for f in test_dir.glob("*.*")):
+ if all(
+ f.suffix in (".txt", ".ql", ".actual", ".expected")
+ for f in test_dir.glob("*.*")
+ ):
log.warning(f"no test source in {test_dir.relative_to(test_out)}")
- renderer.render(ql.MissingTestInstructions(),
- test_dir / missing_test_source_filename)
+ renderer.render(
+ ql.MissingTestInstructions(),
+ test_dir / missing_test_source_filename,
+ )
continue
- total_props, partial_props = _partition(_get_all_properties_to_be_tested(c, data.classes),
- lambda p: p.is_total)
- renderer.render(ql.ClassTester(class_name=c.name,
- properties=total_props,
- elements_module=elements_module,
- # in case of collapsed hierarchies we want to see the actual QL class in results
- show_ql_class="qltest_collapse_hierarchy" in c.pragmas),
- test_dir / f"{c.name}.ql")
+ total_props, partial_props = _partition(
+ _get_all_properties_to_be_tested(c, data.classes),
+ lambda p: p.is_total,
+ )
+ renderer.render(
+ ql.ClassTester(
+ class_name=c.name,
+ properties=total_props,
+ elements_module=elements_module,
+ # in case of collapsed hierarchies we want to see the actual QL class in results
+ show_ql_class="qltest_collapse_hierarchy" in c.pragmas,
+ ),
+ test_dir / f"{c.name}.ql",
+ )
for p in partial_props:
- renderer.render(ql.PropertyTester(class_name=c.name,
- elements_module=elements_module,
- property=p), test_dir / f"{c.name}_{p.getter}.ql")
+ renderer.render(
+ ql.PropertyTester(
+ class_name=c.name,
+ elements_module=elements_module,
+ property=p,
+ ),
+ test_dir / f"{c.name}_{p.getter}.ql",
+ )
final_synth_types = []
non_final_synth_types = []
constructor_imports = []
synth_constructor_imports = []
stubs = {}
- for cls in sorted((cls for cls in data.classes.values() if not cls.imported),
- key=lambda cls: (cls.group, cls.name)):
+ for cls in sorted(
+ (cls for cls in data.classes.values() if not cls.imported),
+ key=lambda cls: (cls.group, cls.name),
+ ):
synth_type = get_ql_synth_class(cls)
if synth_type.is_final:
final_synth_types.append(synth_type)
if synth_type.has_params:
- stub_file = stub_out / cls.group / "internal" / f"{cls.name}Constructor.qll"
+ stub_file = (
+ stub_out / cls.group / "internal" / f"{cls.name}Constructor.qll"
+ )
if not renderer.is_customized_stub(stub_file):
# stub rendering must be postponed as we might not have yet all subtracted synth types in `synth_type`
- stubs[stub_file] = ql.Synth.ConstructorStub(synth_type, import_prefix=generated_import_prefix)
+ stubs[stub_file] = ql.Synth.ConstructorStub(
+ synth_type, import_prefix=generated_import_prefix
+ )
constructor_import = get_import(stub_file, opts.root_dir)
constructor_imports.append(constructor_import)
if synth_type.is_synth:
@@ -549,9 +679,20 @@ def generate(opts, renderer):
for stub_file, data in stubs.items():
renderer.render(data, stub_file)
- renderer.render(ql.Synth.Types(root.name, generated_import_prefix,
- final_synth_types, non_final_synth_types), out / "Synth.qll")
- renderer.render(ql.ImportList(constructor_imports), out / "SynthConstructors.qll")
- renderer.render(ql.ImportList(synth_constructor_imports), out / "PureSynthConstructors.qll")
+ renderer.render(
+ ql.Synth.Types(
+ root.name,
+ generated_import_prefix,
+ final_synth_types,
+ non_final_synth_types,
+ ),
+ out / "Synth.qll",
+ )
+ renderer.render(
+ ql.ImportList(constructor_imports), out / "SynthConstructors.qll"
+ )
+ renderer.render(
+ ql.ImportList(synth_constructor_imports), out / "PureSynthConstructors.qll"
+ )
if opts.ql_format:
format(opts.codeql_binary, renderer.written)
diff --git a/misc/codegen/generators/rustgen.py b/misc/codegen/generators/rustgen.py
index d7025830bcbd..1f373151d6ad 100644
--- a/misc/codegen/generators/rustgen.py
+++ b/misc/codegen/generators/rustgen.py
@@ -55,7 +55,8 @@ def _get_field(cls: schema.Class, p: schema.Property) -> rust.Field:
def _get_properties(
- cls: schema.Class, lookup: dict[str, schema.ClassBase],
+ cls: schema.Class,
+ lookup: dict[str, schema.ClassBase],
) -> typing.Iterable[tuple[schema.Class, schema.Property]]:
for b in cls.bases:
yield from _get_properties(lookup[b], lookup)
@@ -92,8 +93,9 @@ def _get_class(self, name: str) -> rust.Class:
# only generate detached fields in the actual class defining them, not the derived ones
if c is cls:
# TODO lift this restriction if required (requires change in dbschemegen as well)
- assert c.derived or not p.is_single, \
- f"property {p.name} in concrete class marked as detached but not optional"
+ assert (
+ c.derived or not p.is_single
+ ), f"property {p.name} in concrete class marked as detached but not optional"
detached_fields.append(_get_field(c, p))
elif not cls.derived:
# for non-detached ones, only generate fields in the concrete classes
@@ -123,10 +125,12 @@ def generate(opts, renderer):
processor = Processor(schemaloader.load_file(opts.schema))
out = opts.rust_output
groups = set()
- with renderer.manage(generated=out.rglob("*.rs"),
- stubs=(),
- registry=out / ".generated.list",
- force=opts.force) as renderer:
+ with renderer.manage(
+ generated=out.rglob("*.rs"),
+ stubs=(),
+ registry=out / ".generated.list",
+ force=opts.force,
+ ) as renderer:
for group, classes in processor.get_classes().items():
group = group or "top"
groups.add(group)
diff --git a/misc/codegen/generators/rusttestgen.py b/misc/codegen/generators/rusttestgen.py
index e7a23fedacdc..a46d2584127b 100644
--- a/misc/codegen/generators/rusttestgen.py
+++ b/misc/codegen/generators/rusttestgen.py
@@ -42,7 +42,9 @@ def _get_code(doc: list[str]) -> list[str]:
code.append(f"// {line}")
case _, True:
code.append(line)
- assert not adding_code, "Unterminated code block in docstring:\n " + "\n ".join(doc)
+ assert not adding_code, "Unterminated code block in docstring:\n " + "\n ".join(
+ doc
+ )
if has_code:
return code
return []
@@ -51,15 +53,19 @@ def _get_code(doc: list[str]) -> list[str]:
def generate(opts, renderer):
assert opts.ql_test_output
schema = schemaloader.load_file(opts.schema)
- with renderer.manage(generated=opts.ql_test_output.rglob("gen_*.rs"),
- stubs=(),
- registry=opts.ql_test_output / ".generated_tests.list",
- force=opts.force) as renderer:
+ with renderer.manage(
+ generated=opts.ql_test_output.rglob("gen_*.rs"),
+ stubs=(),
+ registry=opts.ql_test_output / ".generated_tests.list",
+ force=opts.force,
+ ) as renderer:
for cls in schema.classes.values():
if cls.imported:
continue
- if (qlgen.should_skip_qltest(cls, schema.classes) or
- "rust_skip_doc_test" in cls.pragmas):
+ if (
+ qlgen.should_skip_qltest(cls, schema.classes)
+ or "rust_skip_doc_test" in cls.pragmas
+ ):
continue
code = _get_code(cls.doc)
for p in schema.iter_properties(cls.name):
@@ -79,5 +85,10 @@ def generate(opts, renderer):
code = [indent + l for l in code]
test_with_name = typing.cast(str, cls.pragmas.get("qltest_test_with"))
test_with = schema.classes[test_with_name] if test_with_name else cls
- test = opts.ql_test_output / test_with.group / test_with.name / f"gen_{test_name}.rs"
+ test = (
+ opts.ql_test_output
+ / test_with.group
+ / test_with.name
+ / f"gen_{test_name}.rs"
+ )
renderer.render(TestCode(code="\n".join(code), function=fn), test)
diff --git a/misc/codegen/generators/trapgen.py b/misc/codegen/generators/trapgen.py
index e22b3e4e0e73..1f33fd4a0ff8 100755
--- a/misc/codegen/generators/trapgen.py
+++ b/misc/codegen/generators/trapgen.py
@@ -86,13 +86,18 @@ def generate(opts, renderer):
for dir, entries in traps.items():
dir = dir or pathlib.Path()
relative_gen_dir = pathlib.Path(*[".." for _ in dir.parents])
- renderer.render(cpp.TrapList(entries, opts.dbscheme, trap_library, relative_gen_dir), out / dir / "TrapEntries")
+ renderer.render(
+ cpp.TrapList(entries, opts.dbscheme, trap_library, relative_gen_dir),
+ out / dir / "TrapEntries",
+ )
tags = []
for tag in toposort_flatten(tag_graph):
- tags.append(cpp.Tag(
- name=get_tag_name(tag),
- bases=[get_tag_name(b) for b in sorted(tag_graph[tag])],
- id=tag,
- ))
+ tags.append(
+ cpp.Tag(
+ name=get_tag_name(tag),
+ bases=[get_tag_name(b) for b in sorted(tag_graph[tag])],
+ id=tag,
+ )
+ )
renderer.render(cpp.TagList(tags, opts.dbscheme), out / "TrapTags")
diff --git a/misc/codegen/lib/cpp.py b/misc/codegen/lib/cpp.py
index eed7aba045cb..2b8c504caacd 100644
--- a/misc/codegen/lib/cpp.py
+++ b/misc/codegen/lib/cpp.py
@@ -4,20 +4,111 @@
from typing import List, ClassVar
# taken from https://en.cppreference.com/w/cpp/keyword
-cpp_keywords = {"alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept",
- "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t",
- "class", "compl", "concept", "const", "consteval", "constexpr", "constinit", "const_cast", "continue",
- "co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast",
- "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if",
- "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr",
- "operator", "or", "or_eq", "private", "protected", "public", "reflexpr", "register", "reinterpret_cast",
- "requires", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
- "switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try", "typedef",
- "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while",
- "xor", "xor_eq"}
+cpp_keywords = {
+ "alignas",
+ "alignof",
+ "and",
+ "and_eq",
+ "asm",
+ "atomic_cancel",
+ "atomic_commit",
+ "atomic_noexcept",
+ "auto",
+ "bitand",
+ "bitor",
+ "bool",
+ "break",
+ "case",
+ "catch",
+ "char",
+ "char8_t",
+ "char16_t",
+ "char32_t",
+ "class",
+ "compl",
+ "concept",
+ "const",
+ "consteval",
+ "constexpr",
+ "constinit",
+ "const_cast",
+ "continue",
+ "co_await",
+ "co_return",
+ "co_yield",
+ "decltype",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "dynamic_cast",
+ "else",
+ "enum",
+ "explicit",
+ "export",
+ "extern",
+ "false",
+ "float",
+ "for",
+ "friend",
+ "goto",
+ "if",
+ "inline",
+ "int",
+ "long",
+ "mutable",
+ "namespace",
+ "new",
+ "noexcept",
+ "not",
+ "not_eq",
+ "nullptr",
+ "operator",
+ "or",
+ "or_eq",
+ "private",
+ "protected",
+ "public",
+ "reflexpr",
+ "register",
+ "reinterpret_cast",
+ "requires",
+ "return",
+ "short",
+ "signed",
+ "sizeof",
+ "static",
+ "static_assert",
+ "static_cast",
+ "struct",
+ "switch",
+ "synchronized",
+ "template",
+ "this",
+ "thread_local",
+ "throw",
+ "true",
+ "try",
+ "typedef",
+ "typeid",
+ "typename",
+ "union",
+ "unsigned",
+ "using",
+ "virtual",
+ "void",
+ "volatile",
+ "wchar_t",
+ "while",
+ "xor",
+ "xor_eq",
+}
_field_overrides = [
- (re.compile(r"(start|end)_(line|column)|(.*_)?index|width|num_.*"), {"base_type": "unsigned"}),
+ (
+ re.compile(r"(start|end)_(line|column)|(.*_)?index|width|num_.*"),
+ {"base_type": "unsigned"},
+ ),
(re.compile(r"(.*)_"), lambda m: {"field_name": m[1]}),
]
@@ -108,7 +199,7 @@ def has_bases(self):
@dataclass
class TrapList:
- template: ClassVar = 'trap_traps'
+ template: ClassVar = "trap_traps"
extensions = ["h", "cpp"]
traps: List[Trap]
source: str
@@ -118,7 +209,7 @@ class TrapList:
@dataclass
class TagList:
- template: ClassVar = 'trap_tags'
+ template: ClassVar = "trap_tags"
extensions = ["h"]
tags: List[Tag]
@@ -127,7 +218,7 @@ class TagList:
@dataclass
class ClassBase:
- ref: 'Class'
+ ref: "Class"
first: bool = False
@@ -140,7 +231,9 @@ class Class:
trap_name: str = None
def __post_init__(self):
- self.bases = [ClassBase(c) for c in sorted(self.bases, key=lambda cls: cls.name)]
+ self.bases = [
+ ClassBase(c) for c in sorted(self.bases, key=lambda cls: cls.name)
+ ]
if self.bases:
self.bases[0].first = True
diff --git a/misc/codegen/lib/dbscheme.py b/misc/codegen/lib/dbscheme.py
index eee0191b6788..03c9878d7f11 100644
--- a/misc/codegen/lib/dbscheme.py
+++ b/misc/codegen/lib/dbscheme.py
@@ -1,4 +1,4 @@
-""" dbscheme format representation """
+"""dbscheme format representation"""
import logging
import pathlib
@@ -100,7 +100,7 @@ class SchemeInclude:
@dataclass
class Scheme:
- template: ClassVar = 'dbscheme'
+ template: ClassVar = "dbscheme"
src: str
includes: List[SchemeInclude]
diff --git a/misc/codegen/lib/paths.py b/misc/codegen/lib/paths.py
index b102987a2267..f56bbb9d8171 100644
--- a/misc/codegen/lib/paths.py
+++ b/misc/codegen/lib/paths.py
@@ -1,4 +1,4 @@
-""" module providing useful filesystem paths """
+"""module providing useful filesystem paths"""
import pathlib
import sys
@@ -7,13 +7,15 @@
_this_file = pathlib.Path(__file__).resolve()
try:
- workspace_dir = pathlib.Path(os.environ['BUILD_WORKSPACE_DIRECTORY']).resolve() # <- means we are using bazel run
- root_dir = workspace_dir / 'swift'
+ workspace_dir = pathlib.Path(
+ os.environ["BUILD_WORKSPACE_DIRECTORY"]
+ ).resolve() # <- means we are using bazel run
+ root_dir = workspace_dir / "swift"
except KeyError:
root_dir = _this_file.parents[2]
workspace_dir = root_dir.parent
-lib_dir = _this_file.parents[2] / 'codegen' / 'lib'
-templates_dir = _this_file.parents[2] / 'codegen' / 'templates'
+lib_dir = _this_file.parents[2] / "codegen" / "lib"
+templates_dir = _this_file.parents[2] / "codegen" / "templates"
exe_file = pathlib.Path(sys.argv[0]).resolve()
diff --git a/misc/codegen/lib/ql.py b/misc/codegen/lib/ql.py
index 0200477eb32c..7537aac995c5 100644
--- a/misc/codegen/lib/ql.py
+++ b/misc/codegen/lib/ql.py
@@ -100,7 +100,7 @@ def __str__(self):
@dataclass
class Class:
- template: ClassVar = 'ql_class'
+ template: ClassVar = "ql_class"
name: str
bases: List[Base] = field(default_factory=list)
@@ -116,7 +116,12 @@ class Class:
cfg: bool = False
def __post_init__(self):
- def get_bases(bases): return [Base(str(b), str(prev)) for b, prev in zip(bases, itertools.chain([""], bases))]
+ def get_bases(bases):
+ return [
+ Base(str(b), str(prev))
+ for b, prev in zip(bases, itertools.chain([""], bases))
+ ]
+
self.bases = get_bases(self.bases)
self.bases_impl = get_bases(self.bases_impl)
if self.properties:
@@ -164,7 +169,7 @@ def __post_init__(self):
@dataclass
class Stub:
- template: ClassVar = 'ql_stub'
+ template: ClassVar = "ql_stub"
name: str
base_import: str
@@ -183,7 +188,7 @@ def has_qldoc(self) -> bool:
@dataclass
class ClassPublic:
- template: ClassVar = 'ql_class_public'
+ template: ClassVar = "ql_class_public"
name: str
imports: List[str] = field(default_factory=list)
@@ -197,7 +202,7 @@ def has_qldoc(self) -> bool:
@dataclass
class DbClasses:
- template: ClassVar = 'ql_db'
+ template: ClassVar = "ql_db"
classes: List[Class] = field(default_factory=list)
imports: List[str] = field(default_factory=list)
@@ -205,14 +210,14 @@ class DbClasses:
@dataclass
class ImportList:
- template: ClassVar = 'ql_imports'
+ template: ClassVar = "ql_imports"
imports: List[str] = field(default_factory=list)
@dataclass
class GetParentImplementation:
- template: ClassVar = 'ql_parent'
+ template: ClassVar = "ql_parent"
classes: List[Class] = field(default_factory=list)
imports: List[str] = field(default_factory=list)
@@ -234,7 +239,7 @@ class TesterBase:
@dataclass
class ClassTester(TesterBase):
- template: ClassVar = 'ql_test_class'
+ template: ClassVar = "ql_test_class"
properties: List[PropertyForTest] = field(default_factory=list)
show_ql_class: bool = False
@@ -242,14 +247,14 @@ class ClassTester(TesterBase):
@dataclass
class PropertyTester(TesterBase):
- template: ClassVar = 'ql_test_property'
+ template: ClassVar = "ql_test_property"
property: PropertyForTest
@dataclass
class MissingTestInstructions:
- template: ClassVar = 'ql_test_missing'
+ template: ClassVar = "ql_test_missing"
class Synth:
@@ -306,7 +311,9 @@ class FinalClassDb(FinalClass):
subtracted_synth_types: List["Synth.Class"] = field(default_factory=list)
def subtract_type(self, type: str):
- self.subtracted_synth_types.append(Synth.Class(type, first=not self.subtracted_synth_types))
+ self.subtracted_synth_types.append(
+ Synth.Class(type, first=not self.subtracted_synth_types)
+ )
@property
def has_subtracted_synth_types(self) -> bool:
@@ -357,6 +364,6 @@ class CfgClass:
@dataclass
class CfgClasses:
- template: ClassVar = 'ql_cfg_nodes'
+ template: ClassVar = "ql_cfg_nodes"
include_file_import: Optional[str] = None
classes: List[CfgClass] = field(default_factory=list)
diff --git a/misc/codegen/lib/render.py b/misc/codegen/lib/render.py
index ac43a515de10..5ab746107ee7 100644
--- a/misc/codegen/lib/render.py
+++ b/misc/codegen/lib/render.py
@@ -1,4 +1,4 @@
-""" template renderer module, wrapping around `pystache.Renderer`
+"""template renderer module, wrapping around `pystache.Renderer`
`pystache` is a python mustache engine, and mustache is a template language. More information on
@@ -23,14 +23,21 @@ class Error(Exception):
class Renderer:
- """ Template renderer using mustache templates in the `templates` directory """
+ """Template renderer using mustache templates in the `templates` directory"""
def __init__(self, generator: pathlib.Path):
- self._r = pystache.Renderer(search_dirs=str(paths.templates_dir), escape=lambda u: u)
+ self._r = pystache.Renderer(
+ search_dirs=str(paths.templates_dir), escape=lambda u: u
+ )
self._generator = generator
- def render(self, data: object, output: typing.Optional[pathlib.Path], template: typing.Optional[str] = None):
- """ Render `data` to `output`.
+ def render(
+ self,
+ data: object,
+ output: typing.Optional[pathlib.Path],
+ template: typing.Optional[str] = None,
+ ):
+ """Render `data` to `output`.
`data` must have a `template` attribute denoting which template to use from the template directory.
@@ -58,13 +65,18 @@ def _do_write(self, mnemonic: str, contents: str, output: pathlib.Path):
out.write(contents)
log.debug(f"{mnemonic}: generated {output.name}")
- def manage(self, generated: typing.Iterable[pathlib.Path], stubs: typing.Iterable[pathlib.Path],
- registry: pathlib.Path, force: bool = False) -> "RenderManager":
+ def manage(
+ self,
+ generated: typing.Iterable[pathlib.Path],
+ stubs: typing.Iterable[pathlib.Path],
+ registry: pathlib.Path,
+ force: bool = False,
+ ) -> "RenderManager":
return RenderManager(self._generator, generated, stubs, registry, force)
class RenderManager(Renderer):
- """ A context manager allowing to manage checked in generated files and their cleanup, able
+ """A context manager allowing to manage checked in generated files and their cleanup, able
to skip unneeded writes.
This is done by using and updating a checked in list of generated files that assigns two
@@ -74,6 +86,7 @@ class RenderManager(Renderer):
* the other is the hash of the actual file after code generation has finished. This will be
different from the above because of post-processing like QL formatting. This hash is used
to detect invalid modification of generated files"""
+
written: typing.Set[pathlib.Path]
@dataclass
@@ -82,12 +95,18 @@ class Hashes:
pre contains the hash of a file as rendered, post is the hash after
postprocessing (for example QL formatting)
"""
+
pre: str
post: typing.Optional[str] = None
- def __init__(self, generator: pathlib.Path, generated: typing.Iterable[pathlib.Path],
- stubs: typing.Iterable[pathlib.Path],
- registry: pathlib.Path, force: bool = False):
+ def __init__(
+ self,
+ generator: pathlib.Path,
+ generated: typing.Iterable[pathlib.Path],
+ stubs: typing.Iterable[pathlib.Path],
+ registry: pathlib.Path,
+ force: bool = False,
+ ):
super().__init__(generator)
self._registry_path = registry
self._force = force
@@ -142,10 +161,14 @@ def _process_generated(self, generated: typing.Iterable[pathlib.Path]):
if self._force:
pass
elif rel_path not in self._hashes:
- log.warning(f"{rel_path} marked as generated but absent from the registry")
+ log.warning(
+ f"{rel_path} marked as generated but absent from the registry"
+ )
elif self._hashes[rel_path].post != self._hash_file(f):
- raise Error(f"{rel_path} is generated but was modified, please revert the file "
- "or pass --force to overwrite")
+ raise Error(
+ f"{rel_path} is generated but was modified, please revert the file "
+ "or pass --force to overwrite"
+ )
def _process_stubs(self, stubs: typing.Iterable[pathlib.Path]):
for f in stubs:
@@ -159,8 +182,10 @@ def _process_stubs(self, stubs: typing.Iterable[pathlib.Path]):
elif rel_path not in self._hashes:
log.warning(f"{rel_path} marked as stub but absent from the registry")
elif self._hashes[rel_path].post != self._hash_file(f):
- raise Error(f"{rel_path} is a stub marked as generated, but it was modified, "
- "please remove the `// generated` header, revert the file or pass --force to overwrite it")
+ raise Error(
+ f"{rel_path} is a stub marked as generated, but it was modified, "
+ "please remove the `// generated` header, revert the file or pass --force to overwrite it"
+ )
@staticmethod
def is_customized_stub(file: pathlib.Path) -> bool:
@@ -191,13 +216,17 @@ def _load_registry(self):
for line in reg:
if line.strip():
filename, prehash, posthash = line.split()
- self._hashes[pathlib.Path(filename)] = self.Hashes(prehash, posthash)
+ self._hashes[pathlib.Path(filename)] = self.Hashes(
+ prehash, posthash
+ )
except FileNotFoundError:
pass
def _dump_registry(self):
self._registry_path.parent.mkdir(parents=True, exist_ok=True)
- with open(self._registry_path, 'w') as out, open(self._registry_path.parent / ".gitattributes", "w") as attrs:
+ with open(self._registry_path, "w") as out, open(
+ self._registry_path.parent / ".gitattributes", "w"
+ ) as attrs:
print(f"/{self._registry_path.name}", "linguist-generated", file=attrs)
print("/.gitattributes", "linguist-generated", file=attrs)
for f, hashes in sorted(self._hashes.items()):
diff --git a/misc/codegen/lib/schema.py b/misc/codegen/lib/schema.py
index 5178e61d3844..efcfb5c5fc2e 100644
--- a/misc/codegen/lib/schema.py
+++ b/misc/codegen/lib/schema.py
@@ -1,4 +1,5 @@
-""" schema format representation """
+"""schema format representation"""
+
import abc
import typing
from collections.abc import Iterable
@@ -52,7 +53,11 @@ def is_optional(self) -> bool:
@property
def is_repeated(self) -> bool:
- return self.kind in (self.Kind.REPEATED, self.Kind.REPEATED_OPTIONAL, self.Kind.REPEATED_UNORDERED)
+ return self.kind in (
+ self.Kind.REPEATED,
+ self.Kind.REPEATED_OPTIONAL,
+ self.Kind.REPEATED_UNORDERED,
+ )
@property
def is_unordered(self) -> bool:
@@ -74,10 +79,11 @@ def has_builtin_type(self) -> bool:
SingleProperty = functools.partial(Property, Property.Kind.SINGLE)
OptionalProperty = functools.partial(Property, Property.Kind.OPTIONAL)
RepeatedProperty = functools.partial(Property, Property.Kind.REPEATED)
-RepeatedOptionalProperty = functools.partial(
- Property, Property.Kind.REPEATED_OPTIONAL)
+RepeatedOptionalProperty = functools.partial(Property, Property.Kind.REPEATED_OPTIONAL)
PredicateProperty = functools.partial(Property, Property.Kind.PREDICATE)
-RepeatedUnorderedProperty = functools.partial(Property, Property.Kind.REPEATED_UNORDERED)
+RepeatedUnorderedProperty = functools.partial(
+ Property, Property.Kind.REPEATED_UNORDERED
+)
@dataclass
@@ -197,9 +203,9 @@ def _make_property(arg: object) -> Property:
class PropertyModifier(abc.ABC):
- """ Modifier of `Property` objects.
- Being on the right of `|` it will trigger construction of a `Property` from
- the left operand.
+ """Modifier of `Property` objects.
+ Being on the right of `|` it will trigger construction of a `Property` from
+ the left operand.
"""
def __ror__(self, other: object) -> Property:
@@ -210,11 +216,9 @@ def __ror__(self, other: object) -> Property:
def __invert__(self) -> "PropertyModifier":
return self.negate()
- def modify(self, prop: Property):
- ...
+ def modify(self, prop: Property): ...
- def negate(self) -> "PropertyModifier":
- ...
+ def negate(self) -> "PropertyModifier": ...
def split_doc(doc):
@@ -224,7 +228,11 @@ def split_doc(doc):
lines = doc.splitlines()
# Determine minimum indentation (first line doesn't count):
strippedlines = (line.lstrip() for line in lines[1:])
- indents = [len(line) - len(stripped) for line, stripped in zip(lines[1:], strippedlines) if stripped]
+ indents = [
+ len(line) - len(stripped)
+ for line, stripped in zip(lines[1:], strippedlines)
+ if stripped
+ ]
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indents:
diff --git a/misc/codegen/lib/schemadefs.py b/misc/codegen/lib/schemadefs.py
index b0cf2b038a8d..5841b9ac874d 100644
--- a/misc/codegen/lib/schemadefs.py
+++ b/misc/codegen/lib/schemadefs.py
@@ -39,7 +39,9 @@ class _DocModifier(_schema.PropertyModifier, metaclass=_DocModifierMetaclass):
def modify(self, prop: _schema.Property):
if self.doc and ("\n" in self.doc or self.doc[-1] == "."):
- raise _schema.Error("No newlines or trailing dots are allowed in doc, did you intend to use desc?")
+ raise _schema.Error(
+ "No newlines or trailing dots are allowed in doc, did you intend to use desc?"
+ )
prop.doc = self.doc
def negate(self) -> _schema.PropertyModifier:
@@ -73,10 +75,13 @@ def include(source: str):
@_dataclass
class _Namespace:
- """ simple namespacing mechanism """
+ """simple namespacing mechanism"""
+
_name: str
- def add(self, pragma: _Union["_PragmaBase", "_Parametrized"], key: str | None = None):
+ def add(
+ self, pragma: _Union["_PragmaBase", "_Parametrized"], key: str | None = None
+ ):
self.__dict__[pragma.pragma] = pragma
pragma.pragma = key or f"{self._name}_{pragma.pragma}"
@@ -110,15 +115,18 @@ def _apply(self, pragmas: _Dict[str, object]) -> None:
@_dataclass
class _ClassPragma(_PragmaBase):
- """ A class pragma.
+ """A class pragma.
For schema classes it acts as a python decorator with `@`.
"""
+
inherited: bool = False
def __call__(self, cls: type) -> type:
- """ use this pragma as a decorator on classes """
+ """use this pragma as a decorator on classes"""
if self.inherited:
- setattr(cls, f"{_schema.inheritable_pragma_prefix}{self.pragma}", self.value)
+ setattr(
+ cls, f"{_schema.inheritable_pragma_prefix}{self.pragma}", self.value
+ )
else:
# not using hasattr as we don't want to land on inherited pragmas
if "_pragmas" not in cls.__dict__:
@@ -129,9 +137,10 @@ def __call__(self, cls: type) -> type:
@_dataclass
class _PropertyPragma(_PragmaBase, _schema.PropertyModifier):
- """ A property pragma.
+ """A property pragma.
It functions similarly to a `_PropertyModifier` with `|`, adding the pragma.
"""
+
remove: bool = False
def modify(self, prop: _schema.Property):
@@ -149,21 +158,23 @@ def _apply(self, pragmas: _Dict[str, object]) -> None:
@_dataclass
class _Pragma(_ClassPragma, _PropertyPragma):
- """ A class or property pragma.
+ """A class or property pragma.
For properties, it functions similarly to a `_PropertyModifier` with `|`, adding the pragma.
For schema classes it acts as a python decorator with `@`.
"""
class _Parametrized[P, **Q, T]:
- """ A parametrized pragma.
+ """A parametrized pragma.
Needs to be applied to a parameter to give a pragma.
"""
def __init__(self, pragma_instance: P, factory: _Callable[Q, T]):
self.pragma_instance = pragma_instance
self.factory = factory
- self.__signature__ = _inspect.signature(self.factory).replace(return_annotation=type(self.pragma_instance))
+ self.__signature__ = _inspect.signature(self.factory).replace(
+ return_annotation=type(self.pragma_instance)
+ )
@property
def pragma(self):
@@ -187,7 +198,8 @@ def modify(self, prop: _schema.Property):
K = _schema.Property.Kind
if prop.kind != K.SINGLE:
raise _schema.Error(
- "optional should only be applied to simple property types")
+ "optional should only be applied to simple property types"
+ )
prop.kind = K.OPTIONAL
@@ -200,7 +212,8 @@ def modify(self, prop: _schema.Property):
prop.kind = K.REPEATED_OPTIONAL
else:
raise _schema.Error(
- "list should only be applied to simple or optional property types")
+ "list should only be applied to simple or optional property types"
+ )
class _Setifier(_schema.PropertyModifier):
@@ -212,7 +225,7 @@ def modify(self, prop: _schema.Property):
class _TypeModifier:
- """ Modifies types using get item notation """
+ """Modifies types using get item notation"""
def __init__(self, modifier: _schema.PropertyModifier):
self.modifier = modifier
@@ -242,7 +255,11 @@ def __getitem__(self, item):
qltest.add(_ClassPragma("skip"))
qltest.add(_ClassPragma("collapse_hierarchy"))
qltest.add(_ClassPragma("uncollapse_hierarchy"))
-qltest.add(_Parametrized(_ClassPragma("test_with", inherited=True), factory=_schema.get_type_name))
+qltest.add(
+ _Parametrized(
+ _ClassPragma("test_with", inherited=True), factory=_schema.get_type_name
+ )
+)
ql.add(_Parametrized(_ClassPragma("default_doc_name"), factory=lambda doc: doc))
ql.add(_ClassPragma("hideable", inherited=True))
@@ -255,15 +272,33 @@ def __getitem__(self, item):
rust.add(_PropertyPragma("detach"))
rust.add(_Pragma("skip_doc_test"))
-rust.add(_Parametrized(_ClassPragma("doc_test_signature"), factory=lambda signature: signature))
+rust.add(
+ _Parametrized(
+ _ClassPragma("doc_test_signature"), factory=lambda signature: signature
+ )
+)
-group = _Parametrized(_ClassPragma("group", inherited=True), factory=lambda group: group)
+group = _Parametrized(
+ _ClassPragma("group", inherited=True), factory=lambda group: group
+)
-synth.add(_Parametrized(_ClassPragma("from_class"), factory=lambda ref: _schema.SynthInfo(
- from_class=_schema.get_type_name(ref))), key="synth")
-synth.add(_Parametrized(_ClassPragma("on_arguments"), factory=lambda **kwargs:
- _schema.SynthInfo(on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()})), key="synth")
+synth.add(
+ _Parametrized(
+ _ClassPragma("from_class"),
+ factory=lambda ref: _schema.SynthInfo(from_class=_schema.get_type_name(ref)),
+ ),
+ key="synth",
+)
+synth.add(
+ _Parametrized(
+ _ClassPragma("on_arguments"),
+ factory=lambda **kwargs: _schema.SynthInfo(
+ on_arguments={k: _schema.get_type_name(t) for k, t in kwargs.items()}
+ ),
+ ),
+ key="synth",
+)
@_dataclass(frozen=True)
@@ -283,7 +318,12 @@ def modify(self, prop: _schema.Property):
drop = object()
-def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, replace_bases: _Dict[type, type] | None = None, cfg: bool = False) -> _Callable[[type], _PropertyModifierList]:
+def annotate(
+ annotated_cls: type,
+ add_bases: _Iterable[type] | None = None,
+ replace_bases: _Dict[type, type] | None = None,
+ cfg: bool = False,
+) -> _Callable[[type], _PropertyModifierList]:
"""
Add or modify schema annotations after a class has been defined previously.
@@ -291,6 +331,7 @@ def annotate(annotated_cls: type, add_bases: _Iterable[type] | None = None, repl
`replace_bases` can be used to replace bases on the annotated class.
"""
+
def decorator(cls: type) -> _PropertyModifierList:
if cls.__name__ != "_":
raise _schema.Error("Annotation classes must be named _")
@@ -299,7 +340,9 @@ def decorator(cls: type) -> _PropertyModifierList:
for p, v in cls.__dict__.get("_pragmas", {}).items():
_ClassPragma(p, value=v)(annotated_cls)
if replace_bases:
- annotated_cls.__bases__ = tuple(replace_bases.get(b, b) for b in annotated_cls.__bases__)
+ annotated_cls.__bases__ = tuple(
+ replace_bases.get(b, b) for b in annotated_cls.__bases__
+ )
if add_bases:
annotated_cls.__bases__ += tuple(add_bases)
annotated_cls.__cfg__ = cfg
@@ -312,9 +355,12 @@ def decorator(cls: type) -> _PropertyModifierList:
elif p in annotated_cls.__annotations__:
annotated_cls.__annotations__[p] |= a
elif isinstance(a, (_PropertyModifierList, _PropertyModifierList)):
- raise _schema.Error(f"annotated property {p} not present in annotated class "
- f"{annotated_cls.__name__}")
+ raise _schema.Error(
+ f"annotated property {p} not present in annotated class "
+ f"{annotated_cls.__name__}"
+ )
else:
annotated_cls.__annotations__[p] = a
return _
+
return decorator
diff --git a/misc/codegen/loaders/dbschemeloader.py b/misc/codegen/loaders/dbschemeloader.py
index f6fbab50499c..a9b599ef0c3c 100644
--- a/misc/codegen/loaders/dbschemeloader.py
+++ b/misc/codegen/loaders/dbschemeloader.py
@@ -12,9 +12,13 @@ class _Re:
"|"
r"^(?P@\w+)\s*=\s*(?P@\w+(?:\s*\|\s*@\w+)*)\s*;?"
)
- field = re.compile(r"(?m)[\w\s]*\s(?P\w+)\s*:\s*(?P@?\w+)(?P\s+ref)?")
+ field = re.compile(
+ r"(?m)[\w\s]*\s(?P\w+)\s*:\s*(?P@?\w+)(?P\s+ref)?"
+ )
key = re.compile(r"@\w+")
- comment = re.compile(r"(?m)(?s)/\*.*?\*/|//(?!dir=)[^\n]*$") # lookahead avoid ignoring metadata like //dir=foo
+ comment = re.compile(
+ r"(?m)(?s)/\*.*?\*/|//(?!dir=)[^\n]*$"
+ ) # lookahead avoid ignoring metadata like //dir=foo
def _get_column(match):
diff --git a/misc/codegen/loaders/schemaloader.py b/misc/codegen/loaders/schemaloader.py
index 3b5f20cbbede..eaf08a04f571 100644
--- a/misc/codegen/loaders/schemaloader.py
+++ b/misc/codegen/loaders/schemaloader.py
@@ -1,4 +1,5 @@
-""" schema loader """
+"""schema loader"""
+
import sys
import inflection
@@ -33,37 +34,56 @@ def _get_class(cls: type) -> schema.Class:
raise schema.Error(f"Only class definitions allowed in schema, found {cls}")
# we must check that going to dbscheme names and back is preserved
# In particular this will not happen if uppercase acronyms are included in the name
- to_underscore_and_back = inflection.camelize(inflection.underscore(cls.__name__), uppercase_first_letter=True)
+ to_underscore_and_back = inflection.camelize(
+ inflection.underscore(cls.__name__), uppercase_first_letter=True
+ )
if cls.__name__ != to_underscore_and_back:
- raise schema.Error(f"Class name must be upper camel-case, without capitalized acronyms, found {cls.__name__} "
- f"instead of {to_underscore_and_back}")
- if len({g for g in (getattr(b, f"{schema.inheritable_pragma_prefix}group", None)
- for b in cls.__bases__) if g}) > 1:
+ raise schema.Error(
+ f"Class name must be upper camel-case, without capitalized acronyms, found {cls.__name__} "
+ f"instead of {to_underscore_and_back}"
+ )
+ if (
+ len(
+ {
+ g
+ for g in (
+ getattr(b, f"{schema.inheritable_pragma_prefix}group", None)
+ for b in cls.__bases__
+ )
+ if g
+ }
+ )
+ > 1
+ ):
raise schema.Error(f"Bases with mixed groups for {cls.__name__}")
pragmas = {
# dir and getattr inherit from bases
- a[len(schema.inheritable_pragma_prefix):]: getattr(cls, a)
- for a in dir(cls) if a.startswith(schema.inheritable_pragma_prefix)
+ a[len(schema.inheritable_pragma_prefix) :]: getattr(cls, a)
+ for a in dir(cls)
+ if a.startswith(schema.inheritable_pragma_prefix)
}
pragmas |= cls.__dict__.get("_pragmas", {})
derived = {d.__name__ for d in cls.__subclasses__()}
if "null" in pragmas and derived:
raise schema.Error(f"Null class cannot be derived")
- return schema.Class(name=cls.__name__,
- bases=[b.__name__ for b in cls.__bases__ if b is not object],
- derived=derived,
- pragmas=pragmas,
- cfg=cls.__cfg__ if hasattr(cls, "__cfg__") else False,
- # in the following we don't use `getattr` to avoid inheriting
- properties=[
- a | _PropertyNamer(n)
- for n, a in cls.__dict__.get("__annotations__", {}).items()
- ],
- doc=schema.split_doc(cls.__doc__),
- )
-
-
-def _toposort_classes_by_group(classes: typing.Dict[str, schema.Class]) -> typing.Dict[str, schema.Class]:
+ return schema.Class(
+ name=cls.__name__,
+ bases=[b.__name__ for b in cls.__bases__ if b is not object],
+ derived=derived,
+ pragmas=pragmas,
+ cfg=cls.__cfg__ if hasattr(cls, "__cfg__") else False,
+ # in the following we don't use `getattr` to avoid inheriting
+ properties=[
+ a | _PropertyNamer(n)
+ for n, a in cls.__dict__.get("__annotations__", {}).items()
+ ],
+ doc=schema.split_doc(cls.__doc__),
+ )
+
+
+def _toposort_classes_by_group(
+ classes: typing.Dict[str, schema.Class],
+) -> typing.Dict[str, schema.Class]:
groups = {}
ret = {}
@@ -79,7 +99,7 @@ def _toposort_classes_by_group(classes: typing.Dict[str, schema.Class]) -> typin
def _fill_synth_information(classes: typing.Dict[str, schema.Class]):
- """ Take a dictionary where the `synth` field is filled for all explicitly synthesized classes
+ """Take a dictionary where the `synth` field is filled for all explicitly synthesized classes
and update it so that all non-final classes that have only synthesized final descendants
get `True` as` value for the `synth` field
"""
@@ -109,7 +129,7 @@ def fill_is_synth(name: str):
def _fill_hideable_information(classes: typing.Dict[str, schema.Class]):
- """ Update the class map propagating the `hideable` attribute upwards in the hierarchy """
+ """Update the class map propagating the `hideable` attribute upwards in the hierarchy"""
todo = [cls for cls in classes.values() if "ql_hideable" in cls.pragmas]
while todo:
cls = todo.pop()
@@ -123,10 +143,14 @@ def _fill_hideable_information(classes: typing.Dict[str, schema.Class]):
def _check_test_with(classes: typing.Dict[str, schema.Class]):
for cls in classes.values():
test_with = typing.cast(str, cls.pragmas.get("qltest_test_with"))
- transitive_test_with = test_with and classes[test_with].pragmas.get("qltest_test_with")
+ transitive_test_with = test_with and classes[test_with].pragmas.get(
+ "qltest_test_with"
+ )
if test_with and transitive_test_with:
- raise schema.Error(f"{cls.name} has test_with {test_with} which in turn "
- f"has test_with {transitive_test_with}, use that directly")
+ raise schema.Error(
+ f"{cls.name} has test_with {test_with} which in turn "
+ f"has test_with {transitive_test_with}, use that directly"
+ )
def load(m: types.ModuleType) -> schema.Schema:
@@ -136,6 +160,7 @@ def load(m: types.ModuleType) -> schema.Schema:
known = {"int", "string", "boolean"}
known.update(n for n in m.__dict__ if not n.startswith("__"))
import misc.codegen.lib.schemadefs as defs
+
null = None
for name, data in m.__dict__.items():
if hasattr(defs, name):
@@ -152,21 +177,26 @@ def load(m: types.ModuleType) -> schema.Schema:
continue
cls = _get_class(data)
if classes and not cls.bases:
- raise schema.Error(
- f"Only one root class allowed, found second root {name}")
+ raise schema.Error(f"Only one root class allowed, found second root {name}")
cls.check_types(known)
classes[name] = cls
if "null" in cls.pragmas:
del cls.pragmas["null"]
if null is not None:
- raise schema.Error(f"Null class {null} already defined, second null class {name} not allowed")
+ raise schema.Error(
+ f"Null class {null} already defined, second null class {name} not allowed"
+ )
null = name
_fill_synth_information(classes)
_fill_hideable_information(classes)
_check_test_with(classes)
- return schema.Schema(includes=includes, classes=imported_classes | _toposort_classes_by_group(classes), null=null)
+ return schema.Schema(
+ includes=includes,
+ classes=imported_classes | _toposort_classes_by_group(classes),
+ null=null,
+ )
def load_file(path: pathlib.Path) -> schema.Schema:
diff --git a/misc/codegen/templates/rust_classes.mustache b/misc/codegen/templates/rust_classes.mustache
index 0fa29b1eb690..77a0335da518 100644
--- a/misc/codegen/templates/rust_classes.mustache
+++ b/misc/codegen/templates/rust_classes.mustache
@@ -63,8 +63,8 @@ pub struct {{name}} {
impl {{name}} {
{{#detached_fields}}
- pub fn emit_{{singular_field_name}}(id: trap::Label, {{#is_repeated}}{{^is_unordered}}i: usize, {{/is_unordered}}{{/is_repeated}}value: {{base_type}}, out: &mut trap::Writer) {
- out.add_tuple("{{table_name}}", vec![id.into(), {{#is_repeated}}{{^is_unordered}}i.into(), {{/is_unordered}}{{/is_repeated}}value.into()]);
+ pub fn emit_{{singular_field_name}}(id: trap::Label{{^is_predicate}}{{#is_repeated}}{{^is_unordered}}, i: usize{{/is_unordered}}{{/is_repeated}}, value: {{base_type}}{{/is_predicate}}, out: &mut trap::Writer) {
+ out.add_tuple("{{table_name}}", vec![id.into(){{^is_predicate}}{{#is_repeated}}{{^is_unordered}}, i.into(){{/is_unordered}}{{/is_repeated}}, value.into(){{/is_predicate}}]);
}
{{/detached_fields}}
}
diff --git a/misc/codegen/test/test_cpp.py b/misc/codegen/test/test_cpp.py
index c4bee337a4f7..77295bb0d828 100644
--- a/misc/codegen/test/test_cpp.py
+++ b/misc/codegen/test/test_cpp.py
@@ -17,34 +17,49 @@ def test_field_name():
assert f.field_name == "foo"
-@pytest.mark.parametrize("type,expected", [
- ("std::string", "trapQuoted(value)"),
- ("bool", '(value ? "true" : "false")'),
- ("something_else", "value"),
-])
+@pytest.mark.parametrize(
+ "type,expected",
+ [
+ ("std::string", "trapQuoted(value)"),
+ ("bool", '(value ? "true" : "false")'),
+ ("something_else", "value"),
+ ],
+)
def test_field_get_streamer(type, expected):
f = cpp.Field("name", type)
assert f.get_streamer()("value") == expected
-@pytest.mark.parametrize("is_optional,is_repeated,is_predicate,expected", [
- (False, False, False, True),
- (True, False, False, False),
- (False, True, False, False),
- (True, True, False, False),
- (False, False, True, False),
-])
+@pytest.mark.parametrize(
+ "is_optional,is_repeated,is_predicate,expected",
+ [
+ (False, False, False, True),
+ (True, False, False, False),
+ (False, True, False, False),
+ (True, True, False, False),
+ (False, False, True, False),
+ ],
+)
def test_field_is_single(is_optional, is_repeated, is_predicate, expected):
- f = cpp.Field("name", "type", is_optional=is_optional, is_repeated=is_repeated, is_predicate=is_predicate)
+ f = cpp.Field(
+ "name",
+ "type",
+ is_optional=is_optional,
+ is_repeated=is_repeated,
+ is_predicate=is_predicate,
+ )
assert f.is_single is expected
-@pytest.mark.parametrize("is_optional,is_repeated,expected", [
- (False, False, "bar"),
- (True, False, "std::optional"),
- (False, True, "std::vector"),
- (True, True, "std::vector>"),
-])
+@pytest.mark.parametrize(
+ "is_optional,is_repeated,expected",
+ [
+ (False, False, "bar"),
+ (True, False, "std::optional"),
+ (False, True, "std::vector"),
+ (True, True, "std::vector>"),
+ ],
+)
def test_field_modal_types(is_optional, is_repeated, expected):
f = cpp.Field("name", "bar", is_optional=is_optional, is_repeated=is_repeated)
assert f.type == expected
@@ -69,11 +84,9 @@ def test_tag_has_first_base_marked():
assert t.bases == expected
-@pytest.mark.parametrize("bases,expected", [
- ([], False),
- (["a"], True),
- (["a", "b"], True)
-])
+@pytest.mark.parametrize(
+ "bases,expected", [([], False), (["a"], True), (["a", "b"], True)]
+)
def test_tag_has_bases(bases, expected):
t = cpp.Tag("name", bases, "id")
assert t.has_bases is expected
@@ -91,11 +104,9 @@ def test_class_has_first_base_marked():
assert c.bases == expected
-@pytest.mark.parametrize("bases,expected", [
- ([], False),
- (["a"], True),
- (["a", "b"], True)
-])
+@pytest.mark.parametrize(
+ "bases,expected", [([], False), (["a"], True), (["a", "b"], True)]
+)
def test_class_has_bases(bases, expected):
t = cpp.Class("name", [cpp.Class(b) for b in bases])
assert t.has_bases is expected
@@ -113,5 +124,5 @@ def test_class_single_fields():
assert c.single_fields == fields[::2]
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_cppgen.py b/misc/codegen/test/test_cppgen.py
index 063940322412..8d0d4605b052 100644
--- a/misc/codegen/test/test_cppgen.py
+++ b/misc/codegen/test/test_cppgen.py
@@ -18,7 +18,10 @@ def ret(classes):
assert isinstance(g, cpp.ClassList), f
assert g.include_parent is (f.parent != output_dir)
assert f.name == "TrapClasses", f
- return {str(f.parent.relative_to(output_dir)): g.classes for f, g in generated.items()}
+ return {
+ str(f.parent.relative_to(output_dir)): g.classes
+ for f, g in generated.items()
+ }
return ret
@@ -38,129 +41,193 @@ def test_empty(generate):
def test_empty_class(generate):
- assert generate([
- schema.Class(name="MyClass"),
- ]) == [
- cpp.Class(name="MyClass", final=True, trap_name="MyClasses")
- ]
+ assert generate(
+ [
+ schema.Class(name="MyClass"),
+ ]
+ ) == [cpp.Class(name="MyClass", final=True, trap_name="MyClasses")]
def test_two_class_hierarchy(generate):
base = cpp.Class(name="A")
- assert generate([
- schema.Class(name="A", derived={"B"}),
- schema.Class(name="B", bases=["A"]),
- ]) == [
+ assert generate(
+ [
+ schema.Class(name="A", derived={"B"}),
+ schema.Class(name="B", bases=["A"]),
+ ]
+ ) == [
base,
cpp.Class(name="B", bases=[base], final=True, trap_name="Bs"),
]
-@pytest.mark.parametrize("type,expected", [
- ("a", "a"),
- ("string", "std::string"),
- ("boolean", "bool"),
- ("MyClass", "TrapLabel"),
-])
-@pytest.mark.parametrize("property_cls,optional,repeated,unordered,trap_name", [
- (schema.SingleProperty, False, False, False, None),
- (schema.OptionalProperty, True, False, False, "MyClassProps"),
- (schema.RepeatedProperty, False, True, False, "MyClassProps"),
- (schema.RepeatedOptionalProperty, True, True, False, "MyClassProps"),
- (schema.RepeatedUnorderedProperty, False, True, True, "MyClassProps"),
-])
-def test_class_with_field(generate, type, expected, property_cls, optional, repeated, unordered, trap_name):
- assert generate([
- schema.Class(name="MyClass", properties=[property_cls("prop", type)]),
- ]) == [
- cpp.Class(name="MyClass",
- fields=[cpp.Field("prop", expected, is_optional=optional,
- is_repeated=repeated, is_unordered=unordered, trap_name=trap_name)],
- trap_name="MyClasses",
- final=True)
+@pytest.mark.parametrize(
+ "type,expected",
+ [
+ ("a", "a"),
+ ("string", "std::string"),
+ ("boolean", "bool"),
+ ("MyClass", "TrapLabel"),
+ ],
+)
+@pytest.mark.parametrize(
+ "property_cls,optional,repeated,unordered,trap_name",
+ [
+ (schema.SingleProperty, False, False, False, None),
+ (schema.OptionalProperty, True, False, False, "MyClassProps"),
+ (schema.RepeatedProperty, False, True, False, "MyClassProps"),
+ (schema.RepeatedOptionalProperty, True, True, False, "MyClassProps"),
+ (schema.RepeatedUnorderedProperty, False, True, True, "MyClassProps"),
+ ],
+)
+def test_class_with_field(
+ generate, type, expected, property_cls, optional, repeated, unordered, trap_name
+):
+ assert generate(
+ [
+ schema.Class(name="MyClass", properties=[property_cls("prop", type)]),
+ ]
+ ) == [
+ cpp.Class(
+ name="MyClass",
+ fields=[
+ cpp.Field(
+ "prop",
+ expected,
+ is_optional=optional,
+ is_repeated=repeated,
+ is_unordered=unordered,
+ trap_name=trap_name,
+ )
+ ],
+ trap_name="MyClasses",
+ final=True,
+ )
]
def test_class_field_with_null(generate, input):
input.null = "Null"
a = cpp.Class(name="A")
- assert generate([
- schema.Class(name="A", derived={"B"}),
- schema.Class(name="B", bases=["A"], properties=[
- schema.SingleProperty("x", "A"),
- schema.SingleProperty("y", "B"),
- ])
- ]) == [
+ assert generate(
+ [
+ schema.Class(name="A", derived={"B"}),
+ schema.Class(
+ name="B",
+ bases=["A"],
+ properties=[
+ schema.SingleProperty("x", "A"),
+ schema.SingleProperty("y", "B"),
+ ],
+ ),
+ ]
+ ) == [
a,
- cpp.Class(name="B", bases=[a], final=True, trap_name="Bs",
- fields=[
- cpp.Field("x", "TrapLabel"),
- cpp.Field("y", "TrapLabel"),
- ]),
+ cpp.Class(
+ name="B",
+ bases=[a],
+ final=True,
+ trap_name="Bs",
+ fields=[
+ cpp.Field("x", "TrapLabel"),
+ cpp.Field("y", "TrapLabel"),
+ ],
+ ),
]
def test_class_with_predicate(generate):
- assert generate([
- schema.Class(name="MyClass", properties=[
- schema.PredicateProperty("prop")]),
- ]) == [
- cpp.Class(name="MyClass",
- fields=[
- cpp.Field("prop", "bool", trap_name="MyClassProp", is_predicate=True)],
- trap_name="MyClasses",
- final=True)
+ assert generate(
+ [
+ schema.Class(name="MyClass", properties=[schema.PredicateProperty("prop")]),
+ ]
+ ) == [
+ cpp.Class(
+ name="MyClass",
+ fields=[
+ cpp.Field("prop", "bool", trap_name="MyClassProp", is_predicate=True)
+ ],
+ trap_name="MyClasses",
+ final=True,
+ )
]
-@pytest.mark.parametrize("name",
- ["start_line", "start_column", "end_line", "end_column", "index", "num_whatever", "width"])
+@pytest.mark.parametrize(
+ "name",
+ [
+ "start_line",
+ "start_column",
+ "end_line",
+ "end_column",
+ "index",
+ "num_whatever",
+ "width",
+ ],
+)
def test_class_with_overridden_unsigned_field(generate, name):
- assert generate([
- schema.Class(name="MyClass", properties=[
- schema.SingleProperty(name, "bar")]),
- ]) == [
- cpp.Class(name="MyClass",
- fields=[cpp.Field(name, "unsigned")],
- trap_name="MyClasses",
- final=True)
+ assert generate(
+ [
+ schema.Class(
+ name="MyClass", properties=[schema.SingleProperty(name, "bar")]
+ ),
+ ]
+ ) == [
+ cpp.Class(
+ name="MyClass",
+ fields=[cpp.Field(name, "unsigned")],
+ trap_name="MyClasses",
+ final=True,
+ )
]
def test_class_with_overridden_underscore_field(generate):
- assert generate([
- schema.Class(name="MyClass", properties=[
- schema.SingleProperty("something_", "bar")]),
- ]) == [
- cpp.Class(name="MyClass",
- fields=[cpp.Field("something", "bar")],
- trap_name="MyClasses",
- final=True)
+ assert generate(
+ [
+ schema.Class(
+ name="MyClass", properties=[schema.SingleProperty("something_", "bar")]
+ ),
+ ]
+ ) == [
+ cpp.Class(
+ name="MyClass",
+ fields=[cpp.Field("something", "bar")],
+ trap_name="MyClasses",
+ final=True,
+ )
]
@pytest.mark.parametrize("name", cpp.cpp_keywords)
def test_class_with_keyword_field(generate, name):
- assert generate([
- schema.Class(name="MyClass", properties=[
- schema.SingleProperty(name, "bar")]),
- ]) == [
- cpp.Class(name="MyClass",
- fields=[cpp.Field(name + "_", "bar")],
- trap_name="MyClasses",
- final=True)
+ assert generate(
+ [
+ schema.Class(
+ name="MyClass", properties=[schema.SingleProperty(name, "bar")]
+ ),
+ ]
+ ) == [
+ cpp.Class(
+ name="MyClass",
+ fields=[cpp.Field(name + "_", "bar")],
+ trap_name="MyClasses",
+ final=True,
+ )
]
def test_classes_with_dirs(generate_grouped):
cbase = cpp.Class(name="CBase")
- assert generate_grouped([
- schema.Class(name="A"),
- schema.Class(name="B", pragmas={"group": "foo"}),
- schema.Class(name="CBase", derived={"C"}, pragmas={"group": "bar"}),
- schema.Class(name="C", bases=["CBase"], pragmas={"group": "bar"}),
- schema.Class(name="D", pragmas={"group": "foo/bar/baz"}),
- ]) == {
+ assert generate_grouped(
+ [
+ schema.Class(name="A"),
+ schema.Class(name="B", pragmas={"group": "foo"}),
+ schema.Class(name="CBase", derived={"C"}, pragmas={"group": "bar"}),
+ schema.Class(name="C", bases=["CBase"], pragmas={"group": "bar"}),
+ schema.Class(name="D", pragmas={"group": "foo/bar/baz"}),
+ ]
+ ) == {
".": [cpp.Class(name="A", trap_name="As", final=True)],
"foo": [cpp.Class(name="B", trap_name="Bs", final=True)],
"bar": [cbase, cpp.Class(name="C", bases=[cbase], trap_name="Cs", final=True)],
@@ -169,81 +236,126 @@ def test_classes_with_dirs(generate_grouped):
def test_cpp_skip_pragma(generate):
- assert generate([
- schema.Class(name="A", properties=[
- schema.SingleProperty("x", "foo"),
- schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]),
- ])
- ]) == [
- cpp.Class(name="A", final=True, trap_name="As", fields=[
- cpp.Field("x", "foo"),
- ]),
+ assert generate(
+ [
+ schema.Class(
+ name="A",
+ properties=[
+ schema.SingleProperty("x", "foo"),
+ schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]),
+ ],
+ )
+ ]
+ ) == [
+ cpp.Class(
+ name="A",
+ final=True,
+ trap_name="As",
+ fields=[
+ cpp.Field("x", "foo"),
+ ],
+ ),
]
def test_synth_classes_ignored(generate):
- assert generate([
- schema.Class(
- name="W",
- pragmas={"synth": schema.SynthInfo()},
- ),
- schema.Class(
- name="X",
- pragmas={"synth": schema.SynthInfo(from_class="A")},
- ),
- schema.Class(
- name="Y",
- pragmas={"synth": schema.SynthInfo(on_arguments={"a": "A", "b": "int"})},
- ),
- schema.Class(
- name="Z",
- ),
- ]) == [
+ assert generate(
+ [
+ schema.Class(
+ name="W",
+ pragmas={"synth": schema.SynthInfo()},
+ ),
+ schema.Class(
+ name="X",
+ pragmas={"synth": schema.SynthInfo(from_class="A")},
+ ),
+ schema.Class(
+ name="Y",
+ pragmas={
+ "synth": schema.SynthInfo(on_arguments={"a": "A", "b": "int"})
+ },
+ ),
+ schema.Class(
+ name="Z",
+ ),
+ ]
+ ) == [
cpp.Class(name="Z", final=True, trap_name="Zs"),
]
def test_synth_properties_ignored(generate):
- assert generate([
- schema.Class(
+ assert generate(
+ [
+ schema.Class(
+ name="X",
+ properties=[
+ schema.SingleProperty("x", "a"),
+ schema.SingleProperty("y", "b", synth=True),
+ schema.SingleProperty("z", "c"),
+ schema.OptionalProperty("foo", "bar", synth=True),
+ schema.RepeatedProperty("baz", "bazz", synth=True),
+ schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True),
+ schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True),
+ ],
+ ),
+ ]
+ ) == [
+ cpp.Class(
name="X",
- properties=[
- schema.SingleProperty("x", "a"),
- schema.SingleProperty("y", "b", synth=True),
- schema.SingleProperty("z", "c"),
- schema.OptionalProperty("foo", "bar", synth=True),
- schema.RepeatedProperty("baz", "bazz", synth=True),
- schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True),
- schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True),
+ final=True,
+ trap_name="Xes",
+ fields=[
+ cpp.Field("x", "a"),
+ cpp.Field("z", "c"),
],
),
- ]) == [
- cpp.Class(name="X", final=True, trap_name="Xes", fields=[
- cpp.Field("x", "a"),
- cpp.Field("z", "c"),
- ]),
]
def test_properties_with_custom_db_table_names(generate):
- assert generate([
- schema.Class("Obj", properties=[
- schema.OptionalProperty("x", "a", pragmas={"ql_db_table_name": "foo"}),
- schema.RepeatedProperty("y", "b", pragmas={"ql_db_table_name": "bar"}),
- schema.RepeatedOptionalProperty("z", "c", pragmas={"ql_db_table_name": "baz"}),
- schema.PredicateProperty("p", pragmas={"ql_db_table_name": "hello"}),
- schema.RepeatedUnorderedProperty("q", "d", pragmas={"ql_db_table_name": "world"}),
- ]),
- ]) == [
- cpp.Class(name="Obj", final=True, trap_name="Objs", fields=[
- cpp.Field("x", "a", is_optional=True, trap_name="Foo"),
- cpp.Field("y", "b", is_repeated=True, trap_name="Bar"),
- cpp.Field("z", "c", is_repeated=True, is_optional=True, trap_name="Baz"),
- cpp.Field("p", "bool", is_predicate=True, trap_name="Hello"),
- cpp.Field("q", "d", is_repeated=True, is_unordered=True, trap_name="World"),
- ]),
+ assert generate(
+ [
+ schema.Class(
+ "Obj",
+ properties=[
+ schema.OptionalProperty(
+ "x", "a", pragmas={"ql_db_table_name": "foo"}
+ ),
+ schema.RepeatedProperty(
+ "y", "b", pragmas={"ql_db_table_name": "bar"}
+ ),
+ schema.RepeatedOptionalProperty(
+ "z", "c", pragmas={"ql_db_table_name": "baz"}
+ ),
+ schema.PredicateProperty(
+ "p", pragmas={"ql_db_table_name": "hello"}
+ ),
+ schema.RepeatedUnorderedProperty(
+ "q", "d", pragmas={"ql_db_table_name": "world"}
+ ),
+ ],
+ ),
+ ]
+ ) == [
+ cpp.Class(
+ name="Obj",
+ final=True,
+ trap_name="Objs",
+ fields=[
+ cpp.Field("x", "a", is_optional=True, trap_name="Foo"),
+ cpp.Field("y", "b", is_repeated=True, trap_name="Bar"),
+ cpp.Field(
+ "z", "c", is_repeated=True, is_optional=True, trap_name="Baz"
+ ),
+ cpp.Field("p", "bool", is_predicate=True, trap_name="Hello"),
+ cpp.Field(
+ "q", "d", is_repeated=True, is_unordered=True, trap_name="World"
+ ),
+ ],
+ ),
]
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_dbscheme.py b/misc/codegen/test/test_dbscheme.py
index e2635ecee5ac..2ba7a269c6e8 100644
--- a/misc/codegen/test/test_dbscheme.py
+++ b/misc/codegen/test/test_dbscheme.py
@@ -14,12 +14,15 @@ def test_dbcolumn_keyword_name(keyword):
assert dbscheme.Column(keyword, "some_type").name == keyword + "_"
-@pytest.mark.parametrize("type,binding,lhstype,rhstype", [
- ("builtin_type", False, "builtin_type", "builtin_type ref"),
- ("builtin_type", True, "builtin_type", "builtin_type ref"),
- ("@at_type", False, "int", "@at_type ref"),
- ("@at_type", True, "unique int", "@at_type"),
-])
+@pytest.mark.parametrize(
+ "type,binding,lhstype,rhstype",
+ [
+ ("builtin_type", False, "builtin_type", "builtin_type ref"),
+ ("builtin_type", True, "builtin_type", "builtin_type ref"),
+ ("@at_type", False, "int", "@at_type ref"),
+ ("@at_type", True, "unique int", "@at_type"),
+ ],
+)
def test_dbcolumn_types(type, binding, lhstype, rhstype):
col = dbscheme.Column("foo", type, binding)
assert col.lhstype == lhstype
@@ -34,7 +37,11 @@ def test_keyset_has_first_id_marked():
def test_table_has_first_column_marked():
- columns = [dbscheme.Column("a", "x"), dbscheme.Column("b", "y", binding=True), dbscheme.Column("c", "z")]
+ columns = [
+ dbscheme.Column("a", "x"),
+ dbscheme.Column("b", "y", binding=True),
+ dbscheme.Column("c", "z"),
+ ]
expected = deepcopy(columns)
table = dbscheme.Table("foo", columns)
expected[0].first = True
@@ -48,5 +55,5 @@ def test_union_has_first_case_marked():
assert [c.type for c in u.rhs] == rhs
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_dbschemegen.py b/misc/codegen/test/test_dbschemegen.py
index 653ad7fc8a39..7ae1941fe8d1 100644
--- a/misc/codegen/test/test_dbschemegen.py
+++ b/misc/codegen/test/test_dbschemegen.py
@@ -8,10 +8,12 @@
InputExpectedPair = collections.namedtuple("InputExpectedPair", ("input", "expected"))
-@pytest.fixture(params=[
- InputExpectedPair(None, None),
- InputExpectedPair("foodir", pathlib.Path("foodir")),
-])
+@pytest.fixture(
+ params=[
+ InputExpectedPair(None, None),
+ InputExpectedPair("foodir", pathlib.Path("foodir")),
+ ]
+)
def dir_param(request):
return request.param
@@ -21,7 +23,7 @@ def generate(opts, input, renderer):
def func(classes, null=None):
input.classes = {cls.name: cls for cls in classes}
input.null = null
- (out, data), = run_generation(dbschemegen.generate, opts, renderer).items()
+ ((out, data),) = run_generation(dbschemegen.generate, opts, renderer).items()
assert out is opts.dbscheme
return data
@@ -48,23 +50,26 @@ def test_includes(input, opts, generate):
dbscheme.SchemeInclude(
src=pathlib.Path(i),
data=i + " data",
- ) for i in includes
+ )
+ for i in includes
],
declarations=[],
)
def test_empty_final_class(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class("Object", pragmas={"group": dir_param.input}),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
+ dbscheme.Column("id", "@object", binding=True),
],
dir=dir_param.expected,
)
@@ -73,218 +78,279 @@ def test_empty_final_class(generate, dir_param):
def test_final_class_with_single_scalar_field(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.SingleProperty("foo", "bar"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.SingleProperty("foo", "bar"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- dbscheme.Column('foo', 'bar'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ dbscheme.Column("foo", "bar"),
+ ],
+ dir=dir_param.expected,
)
],
)
def test_final_class_with_single_class_field(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.SingleProperty("foo", "Bar"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.SingleProperty("foo", "Bar"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- dbscheme.Column('foo', '@bar'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ dbscheme.Column("foo", "@bar"),
+ ],
+ dir=dir_param.expected,
)
],
)
def test_final_class_with_optional_field(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.OptionalProperty("foo", "bar"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.OptionalProperty("foo", "bar"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_foos",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('foo', 'bar'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("foo", "bar"),
+ ],
+ dir=dir_param.expected,
),
],
)
-@pytest.mark.parametrize("property_cls", [schema.RepeatedProperty, schema.RepeatedOptionalProperty])
+@pytest.mark.parametrize(
+ "property_cls", [schema.RepeatedProperty, schema.RepeatedOptionalProperty]
+)
def test_final_class_with_repeated_field(generate, property_cls, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- property_cls("foo", "bar"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ property_cls("foo", "bar"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_foos",
keyset=dbscheme.KeySet(["id", "index"]),
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('index', 'int'),
- dbscheme.Column('foo', 'bar'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("index", "int"),
+ dbscheme.Column("foo", "bar"),
+ ],
+ dir=dir_param.expected,
),
],
)
def test_final_class_with_repeated_unordered_field(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.RepeatedUnorderedProperty("foo", "bar"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.RepeatedUnorderedProperty("foo", "bar"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_foos",
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('foo', 'bar'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("foo", "bar"),
+ ],
+ dir=dir_param.expected,
),
],
)
def test_final_class_with_predicate_field(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.PredicateProperty("foo"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.PredicateProperty("foo"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_foo",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@object'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ ],
+ dir=dir_param.expected,
),
],
)
def test_final_class_with_more_fields(generate, dir_param):
- assert generate([
- schema.Class("Object", pragmas={"group": dir_param.input}, properties=[
- schema.SingleProperty("one", "x"),
- schema.SingleProperty("two", "y"),
- schema.OptionalProperty("three", "z"),
- schema.RepeatedProperty("four", "u"),
- schema.RepeatedOptionalProperty("five", "v"),
- schema.PredicateProperty("six"),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Object",
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.SingleProperty("one", "x"),
+ schema.SingleProperty("two", "y"),
+ schema.OptionalProperty("three", "z"),
+ schema.RepeatedProperty("four", "u"),
+ schema.RepeatedOptionalProperty("five", "v"),
+ schema.PredicateProperty("six"),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
dbscheme.Table(
name="objects",
columns=[
- dbscheme.Column('id', '@object', binding=True),
- dbscheme.Column('one', 'x'),
- dbscheme.Column('two', 'y'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object", binding=True),
+ dbscheme.Column("one", "x"),
+ dbscheme.Column("two", "y"),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_threes",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('three', 'z'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("three", "z"),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_fours",
keyset=dbscheme.KeySet(["id", "index"]),
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('index', 'int'),
- dbscheme.Column('four', 'u'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("index", "int"),
+ dbscheme.Column("four", "u"),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_fives",
keyset=dbscheme.KeySet(["id", "index"]),
columns=[
- dbscheme.Column('id', '@object'),
- dbscheme.Column('index', 'int'),
- dbscheme.Column('five', 'v'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ dbscheme.Column("index", "int"),
+ dbscheme.Column("five", "v"),
+ ],
+ dir=dir_param.expected,
),
dbscheme.Table(
name="object_six",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@object'),
- ], dir=dir_param.expected,
+ dbscheme.Column("id", "@object"),
+ ],
+ dir=dir_param.expected,
),
],
)
def test_empty_class_with_derived(generate):
- assert generate([
- schema.Class(name="Base", derived={"Left", "Right"}),
- schema.Class(name="Left", bases=["Base"]),
- schema.Class(name="Right", bases=["Base"]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(name="Base", derived={"Left", "Right"}),
+ schema.Class(name="Left", bases=["Base"]),
+ schema.Class(name="Right", bases=["Base"]),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -305,17 +371,20 @@ def test_empty_class_with_derived(generate):
def test_class_with_derived_and_single_property(generate, dir_param):
- assert generate([
- schema.Class(
- name="Base",
- derived={"Left", "Right"},
- pragmas={"group": dir_param.input},
- properties=[
- schema.SingleProperty("single", "Prop"),
- ]),
- schema.Class(name="Left", bases=["Base"]),
- schema.Class(name="Right", bases=["Base"]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ name="Base",
+ derived={"Left", "Right"},
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.SingleProperty("single", "Prop"),
+ ],
+ ),
+ schema.Class(name="Left", bases=["Base"]),
+ schema.Class(name="Right", bases=["Base"]),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -327,8 +396,8 @@ def test_class_with_derived_and_single_property(generate, dir_param):
name="bases",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@base'),
- dbscheme.Column('single', '@prop'),
+ dbscheme.Column("id", "@base"),
+ dbscheme.Column("single", "@prop"),
],
dir=dir_param.expected,
),
@@ -345,17 +414,20 @@ def test_class_with_derived_and_single_property(generate, dir_param):
def test_class_with_derived_and_optional_property(generate, dir_param):
- assert generate([
- schema.Class(
- name="Base",
- derived={"Left", "Right"},
- pragmas={"group": dir_param.input},
- properties=[
- schema.OptionalProperty("opt", "Prop"),
- ]),
- schema.Class(name="Left", bases=["Base"]),
- schema.Class(name="Right", bases=["Base"]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ name="Base",
+ derived={"Left", "Right"},
+ pragmas={"group": dir_param.input},
+ properties=[
+ schema.OptionalProperty("opt", "Prop"),
+ ],
+ ),
+ schema.Class(name="Left", bases=["Base"]),
+ schema.Class(name="Right", bases=["Base"]),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -367,8 +439,8 @@ def test_class_with_derived_and_optional_property(generate, dir_param):
name="base_opts",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@base'),
- dbscheme.Column('opt', '@prop'),
+ dbscheme.Column("id", "@base"),
+ dbscheme.Column("opt", "@prop"),
],
dir=dir_param.expected,
),
@@ -385,17 +457,20 @@ def test_class_with_derived_and_optional_property(generate, dir_param):
def test_class_with_derived_and_repeated_property(generate, dir_param):
- assert generate([
- schema.Class(
- name="Base",
- pragmas={"group": dir_param.input},
- derived={"Left", "Right"},
- properties=[
- schema.RepeatedProperty("rep", "Prop"),
- ]),
- schema.Class(name="Left", bases=["Base"]),
- schema.Class(name="Right", bases=["Base"]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ name="Base",
+ pragmas={"group": dir_param.input},
+ derived={"Left", "Right"},
+ properties=[
+ schema.RepeatedProperty("rep", "Prop"),
+ ],
+ ),
+ schema.Class(name="Left", bases=["Base"]),
+ schema.Class(name="Right", bases=["Base"]),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -407,9 +482,9 @@ def test_class_with_derived_and_repeated_property(generate, dir_param):
name="base_reps",
keyset=dbscheme.KeySet(["id", "index"]),
columns=[
- dbscheme.Column('id', '@base'),
- dbscheme.Column('index', 'int'),
- dbscheme.Column('rep', '@prop'),
+ dbscheme.Column("id", "@base"),
+ dbscheme.Column("index", "int"),
+ dbscheme.Column("rep", "@prop"),
],
dir=dir_param.expected,
),
@@ -426,38 +501,41 @@ def test_class_with_derived_and_repeated_property(generate, dir_param):
def test_null_class(generate):
- assert generate([
- schema.Class(
- name="Base",
- derived={"W", "X", "Y", "Z", "Null"},
- ),
- schema.Class(
- name="W",
- bases=["Base"],
- properties=[
- schema.SingleProperty("w", "W"),
- schema.SingleProperty("x", "X"),
- schema.OptionalProperty("y", "Y"),
- schema.RepeatedProperty("z", "Z"),
- ]
- ),
- schema.Class(
- name="X",
- bases=["Base"],
- ),
- schema.Class(
- name="Y",
- bases=["Base"],
- ),
- schema.Class(
- name="Z",
- bases=["Base"],
- ),
- schema.Class(
- name="Null",
- bases=["Base"],
- ),
- ], null="Null") == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ name="Base",
+ derived={"W", "X", "Y", "Z", "Null"},
+ ),
+ schema.Class(
+ name="W",
+ bases=["Base"],
+ properties=[
+ schema.SingleProperty("w", "W"),
+ schema.SingleProperty("x", "X"),
+ schema.OptionalProperty("y", "Y"),
+ schema.RepeatedProperty("z", "Z"),
+ ],
+ ),
+ schema.Class(
+ name="X",
+ bases=["Base"],
+ ),
+ schema.Class(
+ name="Y",
+ bases=["Base"],
+ ),
+ schema.Class(
+ name="Z",
+ bases=["Base"],
+ ),
+ schema.Class(
+ name="Null",
+ bases=["Base"],
+ ),
+ ],
+ null="Null",
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -468,50 +546,50 @@ def test_null_class(generate):
dbscheme.Table(
name="ws",
columns=[
- dbscheme.Column('id', '@w', binding=True),
- dbscheme.Column('w', '@w_or_none'),
- dbscheme.Column('x', '@x_or_none'),
+ dbscheme.Column("id", "@w", binding=True),
+ dbscheme.Column("w", "@w_or_none"),
+ dbscheme.Column("x", "@x_or_none"),
],
),
dbscheme.Table(
name="w_ies",
keyset=dbscheme.KeySet(["id"]),
columns=[
- dbscheme.Column('id', '@w'),
- dbscheme.Column('y', '@y_or_none'),
+ dbscheme.Column("id", "@w"),
+ dbscheme.Column("y", "@y_or_none"),
],
),
dbscheme.Table(
name="w_zs",
keyset=dbscheme.KeySet(["id", "index"]),
columns=[
- dbscheme.Column('id', '@w'),
- dbscheme.Column('index', 'int'),
- dbscheme.Column('z', '@z_or_none'),
+ dbscheme.Column("id", "@w"),
+ dbscheme.Column("index", "int"),
+ dbscheme.Column("z", "@z_or_none"),
],
),
dbscheme.Table(
name="xes",
columns=[
- dbscheme.Column('id', '@x', binding=True),
+ dbscheme.Column("id", "@x", binding=True),
],
),
dbscheme.Table(
name="ys",
columns=[
- dbscheme.Column('id', '@y', binding=True),
+ dbscheme.Column("id", "@y", binding=True),
],
),
dbscheme.Table(
name="zs",
columns=[
- dbscheme.Column('id', '@z', binding=True),
+ dbscheme.Column("id", "@z", binding=True),
],
),
dbscheme.Table(
name="nulls",
columns=[
- dbscheme.Column('id', '@null', binding=True),
+ dbscheme.Column("id", "@null", binding=True),
],
),
dbscheme.Union(
@@ -535,11 +613,15 @@ def test_null_class(generate):
def test_synth_classes_ignored(generate):
- assert generate([
- schema.Class(name="A", pragmas={"synth": schema.SynthInfo()}),
- schema.Class(name="B", pragmas={"synth": schema.SynthInfo(from_class="A")}),
- schema.Class(name="C", pragmas={"synth": schema.SynthInfo(on_arguments={"x": "A"})}),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(name="A", pragmas={"synth": schema.SynthInfo()}),
+ schema.Class(name="B", pragmas={"synth": schema.SynthInfo(from_class="A")}),
+ schema.Class(
+ name="C", pragmas={"synth": schema.SynthInfo(on_arguments={"x": "A"})}
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[],
@@ -547,11 +629,13 @@ def test_synth_classes_ignored(generate):
def test_synth_derived_classes_ignored(generate):
- assert generate([
- schema.Class(name="A", derived={"B", "C"}),
- schema.Class(name="B", bases=["A"], pragmas={"synth": schema.SynthInfo()}),
- schema.Class(name="C", bases=["A"]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(name="A", derived={"B", "C"}),
+ schema.Class(name="B", bases=["A"], pragmas={"synth": schema.SynthInfo()}),
+ schema.Class(name="C", bases=["A"]),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -561,23 +645,28 @@ def test_synth_derived_classes_ignored(generate):
columns=[
dbscheme.Column("id", "@c", binding=True),
],
- )
+ ),
],
)
def test_synth_properties_ignored(generate):
- assert generate([
- schema.Class(name="A", properties=[
- schema.SingleProperty("x", "a"),
- schema.SingleProperty("y", "b", synth=True),
- schema.SingleProperty("z", "c"),
- schema.OptionalProperty("foo", "bar", synth=True),
- schema.RepeatedProperty("baz", "bazz", synth=True),
- schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True),
- schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ name="A",
+ properties=[
+ schema.SingleProperty("x", "a"),
+ schema.SingleProperty("y", "b", synth=True),
+ schema.SingleProperty("z", "c"),
+ schema.OptionalProperty("foo", "bar", synth=True),
+ schema.RepeatedProperty("baz", "bazz", synth=True),
+ schema.RepeatedOptionalProperty("bazzz", "bazzzz", synth=True),
+ schema.RepeatedUnorderedProperty("bazzzzz", "bazzzzzz", synth=True),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -595,24 +684,44 @@ def test_synth_properties_ignored(generate):
def test_table_conflict(generate):
with pytest.raises(dbschemegen.Error):
- generate([
- schema.Class("Foo", properties=[
- schema.OptionalProperty("bar", "FooBar"),
- ]),
- schema.Class("FooBar"),
- ])
+ generate(
+ [
+ schema.Class(
+ "Foo",
+ properties=[
+ schema.OptionalProperty("bar", "FooBar"),
+ ],
+ ),
+ schema.Class("FooBar"),
+ ]
+ )
def test_table_name_overrides(generate):
- assert generate([
- schema.Class("Obj", properties=[
- schema.OptionalProperty("x", "a", pragmas={"ql_db_table_name": "foo"}),
- schema.RepeatedProperty("y", "b", pragmas={"ql_db_table_name": "bar"}),
- schema.RepeatedOptionalProperty("z", "c", pragmas={"ql_db_table_name": "baz"}),
- schema.PredicateProperty("p", pragmas={"ql_db_table_name": "hello"}),
- schema.RepeatedUnorderedProperty("q", "d", pragmas={"ql_db_table_name": "world"}),
- ]),
- ]) == dbscheme.Scheme(
+ assert generate(
+ [
+ schema.Class(
+ "Obj",
+ properties=[
+ schema.OptionalProperty(
+ "x", "a", pragmas={"ql_db_table_name": "foo"}
+ ),
+ schema.RepeatedProperty(
+ "y", "b", pragmas={"ql_db_table_name": "bar"}
+ ),
+ schema.RepeatedOptionalProperty(
+ "z", "c", pragmas={"ql_db_table_name": "baz"}
+ ),
+ schema.PredicateProperty(
+ "p", pragmas={"ql_db_table_name": "hello"}
+ ),
+ schema.RepeatedUnorderedProperty(
+ "q", "d", pragmas={"ql_db_table_name": "world"}
+ ),
+ ],
+ ),
+ ]
+ ) == dbscheme.Scheme(
src=schema_file.name,
includes=[],
declarations=[
@@ -666,5 +775,5 @@ def test_table_name_overrides(generate):
)
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_dbschemelaoder.py b/misc/codegen/test/test_dbschemelaoder.py
index ab4efbff75a1..e9079b699b93 100644
--- a/misc/codegen/test/test_dbschemelaoder.py
+++ b/misc/codegen/test/test_dbschemelaoder.py
@@ -22,26 +22,42 @@ def test_load_empty(load):
def test_load_one_empty_table(load):
- assert load("""
+ assert (
+ load(
+ """
test_foos();
-""") == [
- dbscheme.Table(name="test_foos", columns=[])
- ]
+"""
+ )
+ == [dbscheme.Table(name="test_foos", columns=[])]
+ )
def test_load_table_with_keyset(load):
- assert load("""
+ assert (
+ load(
+ """
#keyset[x, y,z]
test_foos();
-""") == [
- dbscheme.Table(name="test_foos", columns=[], keyset=dbscheme.KeySet(["x", "y", "z"]))
- ]
+"""
+ )
+ == [
+ dbscheme.Table(
+ name="test_foos", columns=[], keyset=dbscheme.KeySet(["x", "y", "z"])
+ )
+ ]
+ )
expected_columns = [
("int foo: int ref", dbscheme.Column(schema_name="foo", type="int", binding=False)),
- (" int bar : int ref", dbscheme.Column(schema_name="bar", type="int", binding=False)),
- ("str baz_: str ref", dbscheme.Column(schema_name="baz", type="str", binding=False)),
+ (
+ " int bar : int ref",
+ dbscheme.Column(schema_name="bar", type="int", binding=False),
+ ),
+ (
+ "str baz_: str ref",
+ dbscheme.Column(schema_name="baz", type="str", binding=False),
+ ),
("int x: @foo ref", dbscheme.Column(schema_name="x", type="@foo", binding=False)),
("int y: @foo", dbscheme.Column(schema_name="y", type="@foo", binding=True)),
("unique int z: @foo", dbscheme.Column(schema_name="z", type="@foo", binding=True)),
@@ -50,42 +66,58 @@ def test_load_table_with_keyset(load):
@pytest.mark.parametrize("column,expected", expected_columns)
def test_load_table_with_column(load, column, expected):
- assert load(f"""
+ assert (
+ load(
+ f"""
foos(
{column}
);
-""") == [
- dbscheme.Table(name="foos", columns=[deepcopy(expected)])
- ]
+"""
+ )
+ == [dbscheme.Table(name="foos", columns=[deepcopy(expected)])]
+ )
def test_load_table_with_multiple_columns(load):
columns = ",\n".join(c for c, _ in expected_columns)
expected = [deepcopy(e) for _, e in expected_columns]
- assert load(f"""
+ assert (
+ load(
+ f"""
foos(
{columns}
);
-""") == [
- dbscheme.Table(name="foos", columns=expected)
- ]
+"""
+ )
+ == [dbscheme.Table(name="foos", columns=expected)]
+ )
def test_load_table_with_multiple_columns_and_dir(load):
columns = ",\n".join(c for c, _ in expected_columns)
expected = [deepcopy(e) for _, e in expected_columns]
- assert load(f"""
+ assert (
+ load(
+ f"""
foos( //dir=foo/bar/baz
{columns}
);
-""") == [
- dbscheme.Table(name="foos", columns=expected, dir=pathlib.Path("foo/bar/baz"))
- ]
+"""
+ )
+ == [
+ dbscheme.Table(
+ name="foos", columns=expected, dir=pathlib.Path("foo/bar/baz")
+ )
+ ]
+ )
def test_load_multiple_table_with_columns(load):
tables = [f"table{i}({col});" for i, (col, _) in enumerate(expected_columns)]
- expected = [dbscheme.Table(name=f"table{i}", columns=[deepcopy(e)]) for i, (_, e) in enumerate(expected_columns)]
+ expected = [
+ dbscheme.Table(name=f"table{i}", columns=[deepcopy(e)])
+ for i, (_, e) in enumerate(expected_columns)
+ ]
assert load("\n".join(tables)) == expected
@@ -96,28 +128,41 @@ def test_union(load):
def test_table_and_union(load):
- assert load("""
+ assert (
+ load(
+ """
foos();
-@foo = @bar | @baz | @bla;""") == [
- dbscheme.Table(name="foos", columns=[]),
- dbscheme.Union(lhs="@foo", rhs=["@bar", "@baz", "@bla"]),
- ]
+@foo = @bar | @baz | @bla;"""
+ )
+ == [
+ dbscheme.Table(name="foos", columns=[]),
+ dbscheme.Union(lhs="@foo", rhs=["@bar", "@baz", "@bla"]),
+ ]
+ )
def test_comments_ignored(load):
- assert load("""
+ assert (
+ load(
+ """
// fake_table();
foos(/* x */unique /*y*/int/*
z
*/ id/* */: /* * */ @bar/*,
int ignored: int ref*/);
-@foo = @bar | @baz | @bla; // | @xxx""") == [
- dbscheme.Table(name="foos", columns=[dbscheme.Column(schema_name="id", type="@bar", binding=True)]),
- dbscheme.Union(lhs="@foo", rhs=["@bar", "@baz", "@bla"]),
- ]
-
-
-if __name__ == '__main__':
+@foo = @bar | @baz | @bla; // | @xxx"""
+ )
+ == [
+ dbscheme.Table(
+ name="foos",
+ columns=[dbscheme.Column(schema_name="id", type="@bar", binding=True)],
+ ),
+ dbscheme.Union(lhs="@foo", rhs=["@bar", "@baz", "@bla"]),
+ ]
+ )
+
+
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_ql.py b/misc/codegen/test/test_ql.py
index e326e65a9e4f..406c6134a477 100644
--- a/misc/codegen/test/test_ql.py
+++ b/misc/codegen/test/test_ql.py
@@ -34,37 +34,55 @@ def test_property_unordered_getter(name, expected_getter):
assert prop.getter == expected_getter
-@pytest.mark.parametrize("plural,expected", [
- (None, False),
- ("", False),
- ("X", True),
-])
+@pytest.mark.parametrize(
+ "plural,expected",
+ [
+ (None, False),
+ ("", False),
+ ("X", True),
+ ],
+)
def test_property_is_repeated(plural, expected):
prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural)
assert prop.is_repeated is expected
-@pytest.mark.parametrize("plural,unordered,expected", [
- (None, False, False),
- ("", False, False),
- ("X", False, True),
- ("X", True, False),
-])
+@pytest.mark.parametrize(
+ "plural,unordered,expected",
+ [
+ (None, False, False),
+ ("", False, False),
+ ("X", False, True),
+ ("X", True, False),
+ ],
+)
def test_property_is_indexed(plural, unordered, expected):
- prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural, is_unordered=unordered)
+ prop = ql.Property(
+ "foo", "Foo", "props", ["result"], plural=plural, is_unordered=unordered
+ )
assert prop.is_indexed is expected
-@pytest.mark.parametrize("is_optional,is_predicate,plural,expected", [
- (False, False, None, True),
- (False, False, "", True),
- (False, False, "X", False),
- (True, False, None, False),
- (False, True, None, False),
-])
+@pytest.mark.parametrize(
+ "is_optional,is_predicate,plural,expected",
+ [
+ (False, False, None, True),
+ (False, False, "", True),
+ (False, False, "X", False),
+ (True, False, None, False),
+ (False, True, None, False),
+ ],
+)
def test_property_is_single(is_optional, is_predicate, plural, expected):
- prop = ql.Property("foo", "Foo", "props", ["result"], plural=plural,
- is_predicate=is_predicate, is_optional=is_optional)
+ prop = ql.Property(
+ "foo",
+ "Foo",
+ "props",
+ ["result"],
+ plural=plural,
+ is_predicate=is_predicate,
+ is_optional=is_optional,
+ )
assert prop.is_single is expected
@@ -85,7 +103,12 @@ def test_property_predicate_getter():
def test_class_processes_bases():
bases = ["B", "Ab", "C", "Aa"]
- expected = [ql.Base("B"), ql.Base("Ab", prev="B"), ql.Base("C", prev="Ab"), ql.Base("Aa", prev="C")]
+ expected = [
+ ql.Base("B"),
+ ql.Base("Ab", prev="B"),
+ ql.Base("C", prev="Ab"),
+ ql.Base("Aa", prev="C"),
+ ]
cls = ql.Class("Foo", bases=bases)
assert cls.bases == expected
@@ -110,7 +133,9 @@ def test_non_root_class():
assert not cls.root
-@pytest.mark.parametrize("prev_child,is_child", [(None, False), ("", True), ("x", True)])
+@pytest.mark.parametrize(
+ "prev_child,is_child", [(None, False), ("", True), ("x", True)]
+)
def test_is_child(prev_child, is_child):
p = ql.Property("Foo", "int", prev_child=prev_child)
assert p.is_child is is_child
@@ -122,22 +147,27 @@ def test_empty_class_no_children():
def test_class_no_children():
- cls = ql.Class("Class", properties=[ql.Property("Foo", "int"), ql.Property("Bar", "string")])
+ cls = ql.Class(
+ "Class", properties=[ql.Property("Foo", "int"), ql.Property("Bar", "string")]
+ )
assert cls.has_children is False
def test_class_with_children():
- cls = ql.Class("Class", properties=[ql.Property("Foo", "int"), ql.Property("Child", "x", prev_child=""),
- ql.Property("Bar", "string")])
+ cls = ql.Class(
+ "Class",
+ properties=[
+ ql.Property("Foo", "int"),
+ ql.Property("Child", "x", prev_child=""),
+ ql.Property("Bar", "string"),
+ ],
+ )
assert cls.has_children is True
-@pytest.mark.parametrize("doc,expected",
- [
- (["foo", "bar"], True),
- (["foo", "bar"], True),
- ([], False)
- ])
+@pytest.mark.parametrize(
+ "doc,expected", [(["foo", "bar"], True), (["foo", "bar"], True), ([], False)]
+)
def test_has_doc(doc, expected):
stub = ql.Stub("Class", base_import="foo", import_prefix="bar", doc=doc)
assert stub.has_qldoc is expected
@@ -150,5 +180,5 @@ def test_synth_accessor_has_first_constructor_param_marked():
assert [p.param for p in x.constructorparams] == params
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_qlgen.py b/misc/codegen/test/test_qlgen.py
index 75e587fbd5eb..43617d5f9e42 100644
--- a/misc/codegen/test/test_qlgen.py
+++ b/misc/codegen/test/test_qlgen.py
@@ -17,22 +17,28 @@ def run_mock():
# these are lambdas so that they will use patched paths when called
-def stub_path(): return paths.root_dir / "ql/lib/stub/path"
+def stub_path():
+ return paths.root_dir / "ql/lib/stub/path"
-def ql_output_path(): return paths.root_dir / "ql/lib/other/path"
+def ql_output_path():
+ return paths.root_dir / "ql/lib/other/path"
-def ql_test_output_path(): return paths.root_dir / "ql/test/path"
+def ql_test_output_path():
+ return paths.root_dir / "ql/test/path"
-def generated_registry_path(): return paths.root_dir / "ql/registry.list"
+def generated_registry_path():
+ return paths.root_dir / "ql/registry.list"
-def import_file(): return stub_path().with_suffix(".qll")
+def import_file():
+ return stub_path().with_suffix(".qll")
-def children_file(): return ql_output_path() / "ParentChild.qll"
+def children_file():
+ return ql_output_path() / "ParentChild.qll"
stub_import = "stub.path"
@@ -63,7 +69,9 @@ def generate(input, qlgen_opts, renderer, render_manager):
def func(classes):
input.classes = {cls.name: cls for cls in classes}
- return run_managed_generation(qlgen.generate, qlgen_opts, renderer, render_manager)
+ return run_managed_generation(
+ qlgen.generate, qlgen_opts, renderer, render_manager
+ )
return func
@@ -109,20 +117,38 @@ def _filter_generated_classes(ret, output_test_files=False):
except ValueError:
assert False, f"{f} is in wrong directory"
if output_test_files:
- return {
- str(f): ret[ql_test_output_path() / f]
- for f in test_files
- }
- base_files -= {pathlib.Path(f"{name}.qll") for name in
- ("Raw", "Synth", "SynthConstructors", "PureSynthConstructors")}
- stub_files = {pathlib.Path(f.parent.parent, f.stem + ".qll") if f.parent.name ==
- "internal" and pathlib.Path(f.parent.parent, f.stem + ".qll") in base_files else f for f in stub_files}
+ return {str(f): ret[ql_test_output_path() / f] for f in test_files}
+ base_files -= {
+ pathlib.Path(f"{name}.qll")
+ for name in ("Raw", "Synth", "SynthConstructors", "PureSynthConstructors")
+ }
+ stub_files = {
+ (
+ pathlib.Path(f.parent.parent, f.stem + ".qll")
+ if f.parent.name == "internal"
+ and pathlib.Path(f.parent.parent, f.stem + ".qll") in base_files
+ else f
+ )
+ for f in stub_files
+ }
assert base_files <= stub_files
return {
- str(f): (ret[stub_path() / "internal" / f] if stub_path() / "internal" / f in ret else ret[stub_path() / f],
- ret[stub_path() / pathlib.Path(f.parent, "internal" if not f.parent.name ==
- "internal" else "", f.stem + "Impl.qll")],
- ret[ql_output_path() / f])
+ str(f): (
+ (
+ ret[stub_path() / "internal" / f]
+ if stub_path() / "internal" / f in ret
+ else ret[stub_path() / f]
+ ),
+ ret[
+ stub_path()
+ / pathlib.Path(
+ f.parent,
+ "internal" if not f.parent.name == "internal" else "",
+ f.stem + "Impl.qll",
+ )
+ ],
+ ret[ql_output_path() / f],
+ )
for f in base_files
}
@@ -148,8 +174,12 @@ def a_ql_class(**kwargs):
def a_ql_stub(*, name, import_prefix="", **kwargs):
- return ql.Stub(name=name, **kwargs, import_prefix=gen_import,
- base_import=f"{gen_import_prefix}{import_prefix}{name}")
+ return ql.Stub(
+ name=name,
+ **kwargs,
+ import_prefix=gen_import,
+ base_import=f"{gen_import_prefix}{import_prefix}{name}",
+ )
def a_ql_class_public(*, name, **kwargs):
@@ -157,347 +187,674 @@ def a_ql_class_public(*, name, **kwargs):
def test_one_empty_class(generate_classes):
- assert generate_classes([
- schema.Class("A")
- ]) == {
- "A.qll": (a_ql_class_public(name="A"),
- a_ql_stub(name="A"),
- a_ql_class(name="A", final=True, imports=[stub_import_prefix + "A"]))
+ assert generate_classes([schema.Class("A")]) == {
+ "A.qll": (
+ a_ql_class_public(name="A"),
+ a_ql_stub(name="A"),
+ a_ql_class(name="A", final=True, imports=[stub_import_prefix + "A"]),
+ )
}
def test_one_empty_internal_class(generate_classes):
- assert generate_classes([
- schema.Class("A", pragmas=["ql_internal"])
- ]) == {
- "A.qll": (a_ql_class_public(name="A", internal=True),
- a_ql_stub(name="A"),
- a_ql_class(name="A", final=True, internal=True, imports=[stub_import_prefix_internal + "A"])),
+ assert generate_classes([schema.Class("A", pragmas=["ql_internal"])]) == {
+ "A.qll": (
+ a_ql_class_public(name="A", internal=True),
+ a_ql_stub(name="A"),
+ a_ql_class(
+ name="A",
+ final=True,
+ internal=True,
+ imports=[stub_import_prefix_internal + "A"],
+ ),
+ ),
}
def test_hierarchy(generate_classes):
- assert generate_classes([
- schema.Class("D", bases=["B", "C"]),
- schema.Class("C", bases=["A"], derived={"D"}),
- schema.Class("B", bases=["A"], derived={"D"}),
- schema.Class("A", derived={"B", "C"}),
- ]) == {
- "A.qll": (a_ql_class_public(name="A"), a_ql_stub(name="A"), a_ql_class(name="A", imports=[stub_import_prefix + "A"])),
- "B.qll": (a_ql_class_public(name="B", imports=[stub_import_prefix + "A"]), a_ql_stub(name="B"), a_ql_class(name="B", bases=["A"], bases_impl=["AImpl::A"], imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"])),
- "C.qll": (a_ql_class_public(name="C", imports=[stub_import_prefix + "A"]), a_ql_stub(name="C"), a_ql_class(name="C", bases=["A"], bases_impl=["AImpl::A"], imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"])),
- "D.qll": (a_ql_class_public(name="D", imports=[stub_import_prefix + "B", stub_import_prefix + "C"]), a_ql_stub(name="D"), a_ql_class(name="D", final=True, bases=["B", "C"], bases_impl=["BImpl::B", "CImpl::C"],
- imports=[stub_import_prefix_internal + cls + "Impl::Impl as " + cls + "Impl" for cls in "BC"])),
+ assert generate_classes(
+ [
+ schema.Class("D", bases=["B", "C"]),
+ schema.Class("C", bases=["A"], derived={"D"}),
+ schema.Class("B", bases=["A"], derived={"D"}),
+ schema.Class("A", derived={"B", "C"}),
+ ]
+ ) == {
+ "A.qll": (
+ a_ql_class_public(name="A"),
+ a_ql_stub(name="A"),
+ a_ql_class(name="A", imports=[stub_import_prefix + "A"]),
+ ),
+ "B.qll": (
+ a_ql_class_public(name="B", imports=[stub_import_prefix + "A"]),
+ a_ql_stub(name="B"),
+ a_ql_class(
+ name="B",
+ bases=["A"],
+ bases_impl=["AImpl::A"],
+ imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"],
+ ),
+ ),
+ "C.qll": (
+ a_ql_class_public(name="C", imports=[stub_import_prefix + "A"]),
+ a_ql_stub(name="C"),
+ a_ql_class(
+ name="C",
+ bases=["A"],
+ bases_impl=["AImpl::A"],
+ imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"],
+ ),
+ ),
+ "D.qll": (
+ a_ql_class_public(
+ name="D", imports=[stub_import_prefix + "B", stub_import_prefix + "C"]
+ ),
+ a_ql_stub(name="D"),
+ a_ql_class(
+ name="D",
+ final=True,
+ bases=["B", "C"],
+ bases_impl=["BImpl::B", "CImpl::C"],
+ imports=[
+ stub_import_prefix_internal + cls + "Impl::Impl as " + cls + "Impl"
+ for cls in "BC"
+ ],
+ ),
+ ),
}
def test_hierarchy_imports(generate_import_list):
- assert generate_import_list([
- schema.Class("D", bases=["B", "C"]),
- schema.Class("C", bases=["A"], derived={"D"}),
- schema.Class("B", bases=["A"], derived={"D"}),
- schema.Class("A", derived={"B", "C"}),
- ]) == ql.ImportList([stub_import_prefix + cls for cls in "ABCD"])
+ assert generate_import_list(
+ [
+ schema.Class("D", bases=["B", "C"]),
+ schema.Class("C", bases=["A"], derived={"D"}),
+ schema.Class("B", bases=["A"], derived={"D"}),
+ schema.Class("A", derived={"B", "C"}),
+ ]
+ ) == ql.ImportList([stub_import_prefix + cls for cls in "ABCD"])
def test_internal_not_in_import_list(generate_import_list):
- assert generate_import_list([
- schema.Class("D", bases=["B", "C"]),
- schema.Class("C", bases=["A"], derived={"D"}, pragmas=["ql_internal"]),
- schema.Class("B", bases=["A"], derived={"D"}),
- schema.Class("A", derived={"B", "C"}, pragmas=["ql_internal"]),
- ]) == ql.ImportList([stub_import_prefix + cls for cls in "BD"])
+ assert generate_import_list(
+ [
+ schema.Class("D", bases=["B", "C"]),
+ schema.Class("C", bases=["A"], derived={"D"}, pragmas=["ql_internal"]),
+ schema.Class("B", bases=["A"], derived={"D"}),
+ schema.Class("A", derived={"B", "C"}, pragmas=["ql_internal"]),
+ ]
+ ) == ql.ImportList([stub_import_prefix + cls for cls in "BD"])
def test_hierarchy_children(generate_children_implementations):
- assert generate_children_implementations([
- schema.Class("A", derived={"B", "C"}, pragmas=["ql_internal"]),
- schema.Class("B", bases=["A"], derived={"D"}),
- schema.Class("C", bases=["A"], derived={"D"}, pragmas=["ql_internal"]),
- schema.Class("D", bases=["B", "C"]),
- ]) == ql.GetParentImplementation(
- classes=[a_ql_class(name="A", internal=True, imports=[stub_import_prefix_internal + "A"]),
- a_ql_class(name="B", bases=["A"], bases_impl=["AImpl::A"], imports=[
- stub_import_prefix_internal + "AImpl::Impl as AImpl"]),
- a_ql_class(name="C", bases=["A"], bases_impl=["AImpl::A"], imports=[
- stub_import_prefix_internal + "AImpl::Impl as AImpl"], internal=True),
- a_ql_class(name="D", final=True, bases=["B", "C"], bases_impl=["BImpl::B", "CImpl::C"],
- imports=[stub_import_prefix_internal + cls + "Impl::Impl as " + cls + "Impl" for cls in "BC"]),
- ],
+ assert generate_children_implementations(
+ [
+ schema.Class("A", derived={"B", "C"}, pragmas=["ql_internal"]),
+ schema.Class("B", bases=["A"], derived={"D"}),
+ schema.Class("C", bases=["A"], derived={"D"}, pragmas=["ql_internal"]),
+ schema.Class("D", bases=["B", "C"]),
+ ]
+ ) == ql.GetParentImplementation(
+ classes=[
+ a_ql_class(
+ name="A", internal=True, imports=[stub_import_prefix_internal + "A"]
+ ),
+ a_ql_class(
+ name="B",
+ bases=["A"],
+ bases_impl=["AImpl::A"],
+ imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"],
+ ),
+ a_ql_class(
+ name="C",
+ bases=["A"],
+ bases_impl=["AImpl::A"],
+ imports=[stub_import_prefix_internal + "AImpl::Impl as AImpl"],
+ internal=True,
+ ),
+ a_ql_class(
+ name="D",
+ final=True,
+ bases=["B", "C"],
+ bases_impl=["BImpl::B", "CImpl::C"],
+ imports=[
+ stub_import_prefix_internal + cls + "Impl::Impl as " + cls + "Impl"
+ for cls in "BC"
+ ],
+ ),
+ ],
imports=[stub_import] + [stub_import_prefix_internal + cls for cls in "AC"],
)
def test_single_property(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"], doc="foo of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("MyObject", properties=[schema.SingleProperty("foo", "bar")]),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_internal_property(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar", pragmas=["ql_internal"])]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"], doc="foo of this my object",
- internal=True),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.SingleProperty("foo", "bar", pragmas=["ql_internal"])
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ internal=True,
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_children(generate_classes):
- assert generate_classes([
- schema.Class("FakeRoot"),
- schema.Class("MyObject", properties=[
- schema.SingleProperty("a", "int"),
- schema.SingleProperty("child_1", "int", is_child=True),
- schema.RepeatedProperty("bs", "int"),
- schema.RepeatedProperty("children", "int", is_child=True),
- schema.OptionalProperty("c", "int"),
- schema.OptionalProperty("child_3", "int", is_child=True),
- schema.RepeatedOptionalProperty("d", "int"),
- schema.RepeatedOptionalProperty("child_4", "int", is_child=True),
- ]),
- ]) == {
- "FakeRoot.qll": (a_ql_class_public(name="FakeRoot"), a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"])),
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="A", type="int", tablename="my_objects",
- tableparams=["this", "result", "_"],
- doc="a of this my object"),
- ql.Property(singular="Child1", type="int", tablename="my_objects",
- tableparams=["this", "_", "result"], prev_child="",
- doc="child 1 of this my object"),
- ql.Property(singular="B", plural="Bs", type="int",
- tablename="my_object_bs",
- tableparams=["this", "index", "result"],
- doc="b of this my object",
- doc_plural="bs of this my object"),
- ql.Property(singular="Child", plural="Children", type="int",
- tablename="my_object_children",
- tableparams=["this", "index", "result"], prev_child="Child1",
- doc="child of this my object",
- doc_plural="children of this my object"),
- ql.Property(singular="C", type="int", tablename="my_object_cs",
- tableparams=["this", "result"], is_optional=True,
- doc="c of this my object"),
- ql.Property(singular="Child3", type="int",
- tablename="my_object_child_3s",
- tableparams=["this", "result"], is_optional=True,
- prev_child="Child", doc="child 3 of this my object"),
- ql.Property(singular="D", plural="Ds", type="int",
- tablename="my_object_ds",
- tableparams=["this", "index", "result"], is_optional=True,
- doc="d of this my object",
- doc_plural="ds of this my object"),
- ql.Property(singular="Child4", plural="Child4s", type="int",
- tablename="my_object_child_4s",
- tableparams=["this", "index", "result"], is_optional=True,
- prev_child="Child3", doc="child 4 of this my object",
- doc_plural="child 4s of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("FakeRoot"),
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.SingleProperty("a", "int"),
+ schema.SingleProperty("child_1", "int", is_child=True),
+ schema.RepeatedProperty("bs", "int"),
+ schema.RepeatedProperty("children", "int", is_child=True),
+ schema.OptionalProperty("c", "int"),
+ schema.OptionalProperty("child_3", "int", is_child=True),
+ schema.RepeatedOptionalProperty("d", "int"),
+ schema.RepeatedOptionalProperty("child_4", "int", is_child=True),
+ ],
+ ),
+ ]
+ ) == {
+ "FakeRoot.qll": (
+ a_ql_class_public(name="FakeRoot"),
+ a_ql_stub(name="FakeRoot"),
+ a_ql_class(
+ name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"]
+ ),
+ ),
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="A",
+ type="int",
+ tablename="my_objects",
+ tableparams=["this", "result", "_"],
+ doc="a of this my object",
+ ),
+ ql.Property(
+ singular="Child1",
+ type="int",
+ tablename="my_objects",
+ tableparams=["this", "_", "result"],
+ prev_child="",
+ doc="child 1 of this my object",
+ ),
+ ql.Property(
+ singular="B",
+ plural="Bs",
+ type="int",
+ tablename="my_object_bs",
+ tableparams=["this", "index", "result"],
+ doc="b of this my object",
+ doc_plural="bs of this my object",
+ ),
+ ql.Property(
+ singular="Child",
+ plural="Children",
+ type="int",
+ tablename="my_object_children",
+ tableparams=["this", "index", "result"],
+ prev_child="Child1",
+ doc="child of this my object",
+ doc_plural="children of this my object",
+ ),
+ ql.Property(
+ singular="C",
+ type="int",
+ tablename="my_object_cs",
+ tableparams=["this", "result"],
+ is_optional=True,
+ doc="c of this my object",
+ ),
+ ql.Property(
+ singular="Child3",
+ type="int",
+ tablename="my_object_child_3s",
+ tableparams=["this", "result"],
+ is_optional=True,
+ prev_child="Child",
+ doc="child 3 of this my object",
+ ),
+ ql.Property(
+ singular="D",
+ plural="Ds",
+ type="int",
+ tablename="my_object_ds",
+ tableparams=["this", "index", "result"],
+ is_optional=True,
+ doc="d of this my object",
+ doc_plural="ds of this my object",
+ ),
+ ql.Property(
+ singular="Child4",
+ plural="Child4s",
+ type="int",
+ tablename="my_object_child_4s",
+ tableparams=["this", "index", "result"],
+ is_optional=True,
+ prev_child="Child3",
+ doc="child 4 of this my object",
+ doc_plural="child 4s of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_single_properties(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("one", "x"),
- schema.SingleProperty("two", "y"),
- schema.SingleProperty("three", "z"),
- ]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="One", type="x", tablename="my_objects",
- tableparams=["this", "result", "_", "_"],
- doc="one of this my object"),
- ql.Property(singular="Two", type="y", tablename="my_objects",
- tableparams=["this", "_", "result", "_"],
- doc="two of this my object"),
- ql.Property(singular="Three", type="z", tablename="my_objects",
- tableparams=["this", "_", "_", "result"],
- doc="three of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.SingleProperty("one", "x"),
+ schema.SingleProperty("two", "y"),
+ schema.SingleProperty("three", "z"),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="One",
+ type="x",
+ tablename="my_objects",
+ tableparams=["this", "result", "_", "_"],
+ doc="one of this my object",
+ ),
+ ql.Property(
+ singular="Two",
+ type="y",
+ tablename="my_objects",
+ tableparams=["this", "_", "result", "_"],
+ doc="two of this my object",
+ ),
+ ql.Property(
+ singular="Three",
+ type="z",
+ tablename="my_objects",
+ tableparams=["this", "_", "_", "result"],
+ doc="three of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
@pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")])
def test_optional_property(generate_classes, is_child, prev_child):
- assert generate_classes([
- schema.Class("FakeRoot"),
- schema.Class("MyObject", properties=[
- schema.OptionalProperty("foo", "bar", is_child=is_child)]),
- ]) == {
- "FakeRoot.qll": (a_ql_class_public(name="FakeRoot"), a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"])),
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_object_foos",
- tableparams=["this", "result"],
- is_optional=True, prev_child=prev_child, doc="foo of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("FakeRoot"),
+ schema.Class(
+ "MyObject",
+ properties=[schema.OptionalProperty("foo", "bar", is_child=is_child)],
+ ),
+ ]
+ ) == {
+ "FakeRoot.qll": (
+ a_ql_class_public(name="FakeRoot"),
+ a_ql_stub(name="FakeRoot"),
+ a_ql_class(
+ name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"]
+ ),
+ ),
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_object_foos",
+ tableparams=["this", "result"],
+ is_optional=True,
+ prev_child=prev_child,
+ doc="foo of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
@pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")])
def test_repeated_property(generate_classes, is_child, prev_child):
- assert generate_classes([
- schema.Class("FakeRoot"),
- schema.Class("MyObject", properties=[
- schema.RepeatedProperty("foo", "bar", is_child=is_child)]),
- ]) == {
- "FakeRoot.qll": (a_ql_class_public(name="FakeRoot"), a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"])),
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos",
- tableparams=["this", "index", "result"], prev_child=prev_child,
- doc="foo of this my object", doc_plural="foos of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("FakeRoot"),
+ schema.Class(
+ "MyObject",
+ properties=[schema.RepeatedProperty("foo", "bar", is_child=is_child)],
+ ),
+ ]
+ ) == {
+ "FakeRoot.qll": (
+ a_ql_class_public(name="FakeRoot"),
+ a_ql_stub(name="FakeRoot"),
+ a_ql_class(
+ name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"]
+ ),
+ ),
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ plural="Foos",
+ type="bar",
+ tablename="my_object_foos",
+ tableparams=["this", "index", "result"],
+ prev_child=prev_child,
+ doc="foo of this my object",
+ doc_plural="foos of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_repeated_unordered_property(generate_classes):
- assert generate_classes([
- schema.Class("FakeRoot"),
- schema.Class("MyObject", properties=[
- schema.RepeatedUnorderedProperty("foo", "bar")]),
- ]) == {
- "FakeRoot.qll": (a_ql_class_public(name="FakeRoot"), a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"])),
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos",
- tableparams=["this", "result"], is_unordered=True,
- doc="foo of this my object", doc_plural="foos of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("FakeRoot"),
+ schema.Class(
+ "MyObject", properties=[schema.RepeatedUnorderedProperty("foo", "bar")]
+ ),
+ ]
+ ) == {
+ "FakeRoot.qll": (
+ a_ql_class_public(name="FakeRoot"),
+ a_ql_stub(name="FakeRoot"),
+ a_ql_class(
+ name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"]
+ ),
+ ),
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ plural="Foos",
+ type="bar",
+ tablename="my_object_foos",
+ tableparams=["this", "result"],
+ is_unordered=True,
+ doc="foo of this my object",
+ doc_plural="foos of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
@pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")])
def test_repeated_optional_property(generate_classes, is_child, prev_child):
- assert generate_classes([
- schema.Class("FakeRoot"),
- schema.Class("MyObject", properties=[
- schema.RepeatedOptionalProperty("foo", "bar", is_child=is_child)]),
- ]) == {
-
- "FakeRoot.qll": (a_ql_class_public(name="FakeRoot"), a_ql_stub(name="FakeRoot"), a_ql_class(name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"])),
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", plural="Foos", type="bar", tablename="my_object_foos",
- tableparams=["this", "index", "result"], is_optional=True,
- prev_child=prev_child, doc="foo of this my object",
- doc_plural="foos of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("FakeRoot"),
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.RepeatedOptionalProperty("foo", "bar", is_child=is_child)
+ ],
+ ),
+ ]
+ ) == {
+ "FakeRoot.qll": (
+ a_ql_class_public(name="FakeRoot"),
+ a_ql_stub(name="FakeRoot"),
+ a_ql_class(
+ name="FakeRoot", final=True, imports=[stub_import_prefix + "FakeRoot"]
+ ),
+ ),
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ plural="Foos",
+ type="bar",
+ tablename="my_object_foos",
+ tableparams=["this", "index", "result"],
+ is_optional=True,
+ prev_child=prev_child,
+ doc="foo of this my object",
+ doc_plural="foos of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_predicate_property(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.PredicateProperty("is_foo")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="isFoo", type="predicate", tablename="my_object_is_foo",
- tableparams=["this"], is_predicate=True, doc="this my object is foo"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("MyObject", properties=[schema.PredicateProperty("is_foo")]),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="isFoo",
+ type="predicate",
+ tablename="my_object_is_foo",
+ tableparams=["this"],
+ is_predicate=True,
+ doc="this my object is foo",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
@pytest.mark.parametrize("is_child,prev_child", [(False, None), (True, "")])
def test_single_class_property(generate_classes, is_child, prev_child):
- assert generate_classes([
- schema.Class("Bar"),
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "Bar", is_child=is_child)]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject", imports=[stub_import_prefix + "Bar"]),
- a_ql_stub(name="MyObject"),
- a_ql_class(
- name="MyObject", final=True, imports=[stub_import_prefix + "Bar", stub_import_prefix + "MyObject"], properties=[
- ql.Property(singular="Foo", type="Bar", tablename="my_objects",
- tableparams=[
- "this", "result"],
- prev_child=prev_child, doc="foo of this my object",
- type_is_codegen_class=True),
- ],
- )),
- "Bar.qll": (a_ql_class_public(name="Bar"), a_ql_stub(name="Bar"), a_ql_class(name="Bar", final=True, imports=[stub_import_prefix + "Bar"])),
+ assert generate_classes(
+ [
+ schema.Class("Bar"),
+ schema.Class(
+ "MyObject",
+ properties=[schema.SingleProperty("foo", "Bar", is_child=is_child)],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject", imports=[stub_import_prefix + "Bar"]),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ imports=[stub_import_prefix + "Bar", stub_import_prefix + "MyObject"],
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="Bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ prev_child=prev_child,
+ doc="foo of this my object",
+ type_is_codegen_class=True,
+ ),
+ ],
+ ),
+ ),
+ "Bar.qll": (
+ a_ql_class_public(name="Bar"),
+ a_ql_stub(name="Bar"),
+ a_ql_class(name="Bar", final=True, imports=[stub_import_prefix + "Bar"]),
+ ),
}
def test_class_with_doc(generate_classes):
doc = ["Very important class.", "Very."]
- assert generate_classes([
- schema.Class("A", doc=doc),
- ]) == {
- "A.qll": (a_ql_class_public(name="A", doc=doc), a_ql_stub(name="A", doc=doc), a_ql_class(name="A", final=True, doc=doc, imports=[stub_import_prefix + "A"])),
+ assert generate_classes(
+ [
+ schema.Class("A", doc=doc),
+ ]
+ ) == {
+ "A.qll": (
+ a_ql_class_public(name="A", doc=doc),
+ a_ql_stub(name="A", doc=doc),
+ a_ql_class(
+ name="A", final=True, doc=doc, imports=[stub_import_prefix + "A"]
+ ),
+ ),
}
def test_class_dir(generate_classes):
dir = "another/rel/path"
- assert generate_classes([
- schema.Class("A", derived={"B"}, pragmas={"group": dir}),
- schema.Class("B", bases=["A"]),
- ]) == {
+ assert generate_classes(
+ [
+ schema.Class("A", derived={"B"}, pragmas={"group": dir}),
+ schema.Class("B", bases=["A"]),
+ ]
+ ) == {
f"{dir}/A.qll": (
- a_ql_class_public(name="A"), a_ql_stub(name="A", import_prefix="another.rel.path."), a_ql_class(name="A", dir=pathlib.Path(dir), imports=[stub_import_prefix + "another.rel.path.A"])),
- "B.qll": (a_ql_class_public(name="B", imports=[stub_import_prefix + "another.rel.path.A"]),
- a_ql_stub(name="B"),
- a_ql_class(name="B", final=True, bases=["A"], bases_impl=["AImpl::A"],
- imports=[stub_import_prefix + "another.rel.path.internal.AImpl::Impl as AImpl"])),
+ a_ql_class_public(name="A"),
+ a_ql_stub(name="A", import_prefix="another.rel.path."),
+ a_ql_class(
+ name="A",
+ dir=pathlib.Path(dir),
+ imports=[stub_import_prefix + "another.rel.path.A"],
+ ),
+ ),
+ "B.qll": (
+ a_ql_class_public(
+ name="B", imports=[stub_import_prefix + "another.rel.path.A"]
+ ),
+ a_ql_stub(name="B"),
+ a_ql_class(
+ name="B",
+ final=True,
+ bases=["A"],
+ bases_impl=["AImpl::A"],
+ imports=[
+ stub_import_prefix
+ + "another.rel.path.internal.AImpl::Impl as AImpl"
+ ],
+ ),
+ ),
}
def test_root_element_cannot_have_children(generate_classes):
with pytest.raises(qlgen.RootElementHasChildren):
- generate_classes([
- schema.Class('A', properties=[schema.SingleProperty("x", is_child=True)])
- ])
+ generate_classes(
+ [schema.Class("A", properties=[schema.SingleProperty("x", is_child=True)])]
+ )
def test_class_dir_imports(generate_import_list):
dir = "another/rel/path"
- assert generate_import_list([
- schema.Class("A", derived={"B"}, pragmas={"group": dir}),
- schema.Class("B", bases=["A"]),
- ]) == ql.ImportList([
- stub_import_prefix + "B",
- stub_import_prefix + "another.rel.path.A",
- ])
+ assert generate_import_list(
+ [
+ schema.Class("A", derived={"B"}, pragmas={"group": dir}),
+ schema.Class("B", bases=["A"]),
+ ]
+ ) == ql.ImportList(
+ [
+ stub_import_prefix + "B",
+ stub_import_prefix + "another.rel.path.A",
+ ]
+ )
def test_format(opts, generate, render_manager, run_mock):
@@ -507,10 +864,21 @@ def test_format(opts, generate, render_manager, run_mock):
pathlib.Path("bar.qll"),
pathlib.Path("y", "baz.txt"),
]
- generate([schema.Class('A')])
+ generate([schema.Class("A")])
assert run_mock.mock_calls == [
- mock.call([opts.codeql_binary, "query", "format", "--in-place", "--", "x/foo.ql", "bar.qll"],
- stderr=subprocess.PIPE, text=True),
+ mock.call(
+ [
+ opts.codeql_binary,
+ "query",
+ "format",
+ "--in-place",
+ "--",
+ "x/foo.ql",
+ "bar.qll",
+ ],
+ stderr=subprocess.PIPE,
+ text=True,
+ ),
]
@@ -523,7 +891,7 @@ def test_format_error(opts, generate, render_manager, run_mock):
pathlib.Path("y", "baz.txt"),
]
with pytest.raises(qlgen.FormatError):
- generate([schema.Class('A')])
+ generate([schema.Class("A")])
def test_format_no_codeql(opts, generate, render_manager, run_mock):
@@ -532,7 +900,7 @@ def test_format_no_codeql(opts, generate, render_manager, run_mock):
pathlib.Path("bar.qll"),
]
with pytest.raises(qlgen.FormatError):
- generate([schema.Class('A')])
+ generate([schema.Class("A")])
def test_format_no_codeql_in_path(opts, generate, render_manager, run_mock):
@@ -541,7 +909,7 @@ def test_format_no_codeql_in_path(opts, generate, render_manager, run_mock):
pathlib.Path("bar.qll"),
]
with pytest.raises(qlgen.FormatError):
- generate([schema.Class('A')])
+ generate([schema.Class("A")])
@pytest.mark.parametrize("force", [False, True])
@@ -561,23 +929,29 @@ def test_manage_parameters(opts, generate, renderer, force):
write(test_a)
write(test_b)
write(test_c)
- generate([schema.Class('A')])
+ generate([schema.Class("A")])
assert renderer.mock_calls == [
- mock.call.manage(generated={ql_a, ql_b, test_a, test_b, import_file()}, stubs={stub_a, stub_b},
- registry=opts.generated_registry, force=force)
+ mock.call.manage(
+ generated={ql_a, ql_b, test_a, test_b, import_file()},
+ stubs={stub_a, stub_b},
+ registry=opts.generated_registry,
+ force=force,
+ )
]
def test_modified_stub_skipped(qlgen_opts, generate, render_manager):
stub = qlgen_opts.ql_stub_output / "AImpl.qll"
render_manager.is_customized_stub.side_effect = lambda f: f == stub
- assert stub not in generate([schema.Class('A')])
+ assert stub not in generate([schema.Class("A")])
def test_test_missing_source(generate_tests):
- generate_tests([
- schema.Class("A"),
- ]) == {
+ generate_tests(
+ [
+ schema.Class("A"),
+ ]
+ ) == {
"A/MISSING_SOURCE.txt": ql.MissingTestInstructions(),
}
@@ -592,144 +966,236 @@ def a_ql_property_tester(**kwargs):
def test_test_source_present(opts, generate_tests):
write(opts.ql_test_output / "A" / "test.swift")
- assert generate_tests([
- schema.Class("A"),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class("A"),
+ ]
+ ) == {
"A/A.ql": a_ql_class_tester(class_name="A"),
}
def test_test_source_present_with_dir(opts, generate_tests):
write(opts.ql_test_output / "foo" / "A" / "test.swift")
- assert generate_tests([
- schema.Class("A", pragmas={"group": "foo"}),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class("A", pragmas={"group": "foo"}),
+ ]
+ ) == {
"foo/A/A.ql": a_ql_class_tester(class_name="A"),
}
def test_test_total_properties(opts, generate_tests):
write(opts.ql_test_output / "B" / "test.swift")
- assert generate_tests([
- schema.Class("A", derived={"B"}, properties=[
- schema.SingleProperty("x", "string"),
- ]),
- schema.Class("B", bases=["A"], properties=[
- schema.PredicateProperty("y", "int"),
- ]),
- ]) == {
- "B/B.ql": a_ql_class_tester(class_name="B", properties=[
- ql.PropertyForTest(getter="getX", type="string"),
- ql.PropertyForTest(getter="y"),
- ])
+ assert generate_tests(
+ [
+ schema.Class(
+ "A",
+ derived={"B"},
+ properties=[
+ schema.SingleProperty("x", "string"),
+ ],
+ ),
+ schema.Class(
+ "B",
+ bases=["A"],
+ properties=[
+ schema.PredicateProperty("y", "int"),
+ ],
+ ),
+ ]
+ ) == {
+ "B/B.ql": a_ql_class_tester(
+ class_name="B",
+ properties=[
+ ql.PropertyForTest(getter="getX", type="string"),
+ ql.PropertyForTest(getter="y"),
+ ],
+ )
}
def test_test_partial_properties(opts, generate_tests):
write(opts.ql_test_output / "B" / "test.swift")
- assert generate_tests([
- schema.Class("A", derived={"B", "C"}, properties=[
- schema.OptionalProperty("x", "string"),
- ]),
- schema.Class("B", bases=["A"], properties=[
- schema.RepeatedProperty("y", "bool"),
- schema.RepeatedOptionalProperty("z", "int"),
- schema.RepeatedUnorderedProperty("w", "string"),
- ]),
- ]) == {
- "B/B.ql": a_ql_class_tester(class_name="B", properties=[
- ql.PropertyForTest(getter="hasX"),
- ql.PropertyForTest(getter="getNumberOfYs", type="int"),
- ql.PropertyForTest(getter="getNumberOfWs", type="int"),
- ]),
- "B/B_getX.ql": a_ql_property_tester(class_name="B",
- property=ql.PropertyForTest(getter="getX", is_total=False,
- type="string")),
- "B/B_getY.ql": a_ql_property_tester(class_name="B",
- property=ql.PropertyForTest(getter="getY", is_total=False,
- is_indexed=True,
- type="bool")),
- "B/B_getZ.ql": a_ql_property_tester(class_name="B",
- property=ql.PropertyForTest(getter="getZ", is_total=False,
- is_indexed=True,
- type="int")),
- "B/B_getAW.ql": a_ql_property_tester(class_name="B",
- property=ql.PropertyForTest(getter="getAW", is_total=False,
- type="string")),
+ assert generate_tests(
+ [
+ schema.Class(
+ "A",
+ derived={"B", "C"},
+ properties=[
+ schema.OptionalProperty("x", "string"),
+ ],
+ ),
+ schema.Class(
+ "B",
+ bases=["A"],
+ properties=[
+ schema.RepeatedProperty("y", "bool"),
+ schema.RepeatedOptionalProperty("z", "int"),
+ schema.RepeatedUnorderedProperty("w", "string"),
+ ],
+ ),
+ ]
+ ) == {
+ "B/B.ql": a_ql_class_tester(
+ class_name="B",
+ properties=[
+ ql.PropertyForTest(getter="hasX"),
+ ql.PropertyForTest(getter="getNumberOfYs", type="int"),
+ ql.PropertyForTest(getter="getNumberOfWs", type="int"),
+ ],
+ ),
+ "B/B_getX.ql": a_ql_property_tester(
+ class_name="B",
+ property=ql.PropertyForTest(getter="getX", is_total=False, type="string"),
+ ),
+ "B/B_getY.ql": a_ql_property_tester(
+ class_name="B",
+ property=ql.PropertyForTest(
+ getter="getY", is_total=False, is_indexed=True, type="bool"
+ ),
+ ),
+ "B/B_getZ.ql": a_ql_property_tester(
+ class_name="B",
+ property=ql.PropertyForTest(
+ getter="getZ", is_total=False, is_indexed=True, type="int"
+ ),
+ ),
+ "B/B_getAW.ql": a_ql_property_tester(
+ class_name="B",
+ property=ql.PropertyForTest(getter="getAW", is_total=False, type="string"),
+ ),
}
def test_test_properties_deduplicated(opts, generate_tests):
write(opts.ql_test_output / "Final" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"A", "B"}, properties=[
- schema.SingleProperty("x", "string"),
- schema.RepeatedProperty("y", "bool"),
- ]),
- schema.Class("A", bases=["Base"], derived={"Final"}),
- schema.Class("B", bases=["Base"], derived={"Final"}),
- schema.Class("Final", bases=["A", "B"]),
- ]) == {
- "Final/Final.ql": a_ql_class_tester(class_name="Final", properties=[
- ql.PropertyForTest(getter="getX", type="string"),
- ql.PropertyForTest(getter="getNumberOfYs", type="int"),
- ]),
- "Final/Final_getY.ql": a_ql_property_tester(class_name="Final",
- property=ql.PropertyForTest(getter="getY", is_total=False,
- is_indexed=True,
- type="bool")),
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"A", "B"},
+ properties=[
+ schema.SingleProperty("x", "string"),
+ schema.RepeatedProperty("y", "bool"),
+ ],
+ ),
+ schema.Class("A", bases=["Base"], derived={"Final"}),
+ schema.Class("B", bases=["Base"], derived={"Final"}),
+ schema.Class("Final", bases=["A", "B"]),
+ ]
+ ) == {
+ "Final/Final.ql": a_ql_class_tester(
+ class_name="Final",
+ properties=[
+ ql.PropertyForTest(getter="getX", type="string"),
+ ql.PropertyForTest(getter="getNumberOfYs", type="int"),
+ ],
+ ),
+ "Final/Final_getY.ql": a_ql_property_tester(
+ class_name="Final",
+ property=ql.PropertyForTest(
+ getter="getY", is_total=False, is_indexed=True, type="bool"
+ ),
+ ),
}
def test_test_properties_skipped(opts, generate_tests):
write(opts.ql_test_output / "Derived" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"Derived"}, properties=[
- schema.SingleProperty("x", "string", pragmas=["qltest_skip", "foo"]),
- schema.RepeatedProperty("y", "int", pragmas=["bar", "qltest_skip"]),
- ]),
- schema.Class("Derived", bases=["Base"], properties=[
- schema.PredicateProperty("a", pragmas=["qltest_skip"]),
- schema.OptionalProperty(
- "b", "int", pragmas=["bar", "qltest_skip", "baz"]),
- ]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"Derived"},
+ properties=[
+ schema.SingleProperty(
+ "x", "string", pragmas=["qltest_skip", "foo"]
+ ),
+ schema.RepeatedProperty("y", "int", pragmas=["bar", "qltest_skip"]),
+ ],
+ ),
+ schema.Class(
+ "Derived",
+ bases=["Base"],
+ properties=[
+ schema.PredicateProperty("a", pragmas=["qltest_skip"]),
+ schema.OptionalProperty(
+ "b", "int", pragmas=["bar", "qltest_skip", "baz"]
+ ),
+ ],
+ ),
+ ]
+ ) == {
"Derived/Derived.ql": a_ql_class_tester(class_name="Derived"),
}
def test_test_base_class_skipped(opts, generate_tests):
write(opts.ql_test_output / "Derived" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"Derived"}, pragmas=["qltest_skip", "foo"], properties=[
- schema.SingleProperty("x", "string"),
- schema.RepeatedProperty("y", "int"),
- ]),
- schema.Class("Derived", bases=["Base"]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"Derived"},
+ pragmas=["qltest_skip", "foo"],
+ properties=[
+ schema.SingleProperty("x", "string"),
+ schema.RepeatedProperty("y", "int"),
+ ],
+ ),
+ schema.Class("Derived", bases=["Base"]),
+ ]
+ ) == {
"Derived/Derived.ql": a_ql_class_tester(class_name="Derived"),
}
def test_test_final_class_skipped(opts, generate_tests):
write(opts.ql_test_output / "Derived" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"Derived"}),
- schema.Class("Derived", bases=["Base"], pragmas=["qltest_skip", "foo"], properties=[
- schema.SingleProperty("x", "string"),
- schema.RepeatedProperty("y", "int"),
- ]),
- ]) == {}
+ assert (
+ generate_tests(
+ [
+ schema.Class("Base", derived={"Derived"}),
+ schema.Class(
+ "Derived",
+ bases=["Base"],
+ pragmas=["qltest_skip", "foo"],
+ properties=[
+ schema.SingleProperty("x", "string"),
+ schema.RepeatedProperty("y", "int"),
+ ],
+ ),
+ ]
+ )
+ == {}
+ )
def test_test_class_hierarchy_collapse(opts, generate_tests):
write(opts.ql_test_output / "Base" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]),
- schema.Class("D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]),
- schema.Class("D2", bases=["Base"], derived={"D3"}, properties=[schema.SingleProperty("y", "string")]),
- schema.Class("D3", bases=["D2"], properties=[schema.SingleProperty("z", "string")]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"D1", "D2"},
+ pragmas=["foo", "qltest_collapse_hierarchy"],
+ ),
+ schema.Class(
+ "D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]
+ ),
+ schema.Class(
+ "D2",
+ bases=["Base"],
+ derived={"D3"},
+ properties=[schema.SingleProperty("y", "string")],
+ ),
+ schema.Class(
+ "D3", bases=["D2"], properties=[schema.SingleProperty("z", "string")]
+ ),
+ ]
+ ) == {
"Base/Base.ql": a_ql_class_tester(class_name="Base", show_ql_class=True),
}
@@ -737,13 +1203,26 @@ def test_test_class_hierarchy_collapse(opts, generate_tests):
def test_test_class_hierarchy_uncollapse(opts, generate_tests):
for d in ("Base", "D3", "D4"):
write(opts.ql_test_output / d / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]),
- schema.Class("D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]),
- schema.Class("D2", bases=["Base"], derived={"D3", "D4"}, pragmas=["qltest_uncollapse_hierarchy", "bar"]),
- schema.Class("D3", bases=["D2"]),
- schema.Class("D4", bases=["D2"]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"D1", "D2"},
+ pragmas=["foo", "qltest_collapse_hierarchy"],
+ ),
+ schema.Class(
+ "D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]
+ ),
+ schema.Class(
+ "D2",
+ bases=["Base"],
+ derived={"D3", "D4"},
+ pragmas=["qltest_uncollapse_hierarchy", "bar"],
+ ),
+ schema.Class("D3", bases=["D2"]),
+ schema.Class("D4", bases=["D2"]),
+ ]
+ ) == {
"Base/Base.ql": a_ql_class_tester(class_name="Base", show_ql_class=True),
"D3/D3.ql": a_ql_class_tester(class_name="D3"),
"D4/D4.ql": a_ql_class_tester(class_name="D4"),
@@ -753,12 +1232,22 @@ def test_test_class_hierarchy_uncollapse(opts, generate_tests):
def test_test_class_hierarchy_uncollapse_at_final(opts, generate_tests):
for d in ("Base", "D3"):
write(opts.ql_test_output / d / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]),
- schema.Class("D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]),
- schema.Class("D2", bases=["Base"], derived={"D3"}),
- schema.Class("D3", bases=["D2"], pragmas=["qltest_uncollapse_hierarchy", "bar"]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class(
+ "Base",
+ derived={"D1", "D2"},
+ pragmas=["foo", "qltest_collapse_hierarchy"],
+ ),
+ schema.Class(
+ "D1", bases=["Base"], properties=[schema.SingleProperty("x", "string")]
+ ),
+ schema.Class("D2", bases=["Base"], derived={"D3"}),
+ schema.Class(
+ "D3", bases=["D2"], pragmas=["qltest_uncollapse_hierarchy", "bar"]
+ ),
+ ]
+ ) == {
"Base/Base.ql": a_ql_class_tester(class_name="Base", show_ql_class=True),
"D3/D3.ql": a_ql_class_tester(class_name="D3"),
}
@@ -766,11 +1255,13 @@ def test_test_class_hierarchy_uncollapse_at_final(opts, generate_tests):
def test_test_with(opts, generate_tests):
write(opts.ql_test_output / "B" / "test.swift")
- assert generate_tests([
- schema.Class("Base", derived={"A", "B"}),
- schema.Class("A", bases=["Base"], pragmas={"qltest_test_with": "B"}),
- schema.Class("B", bases=["Base"]),
- ]) == {
+ assert generate_tests(
+ [
+ schema.Class("Base", derived={"A", "B"}),
+ schema.Class("A", bases=["Base"], pragmas={"qltest_test_with": "B"}),
+ schema.Class("B", bases=["Base"]),
+ ]
+ ) == {
"B/A.ql": a_ql_class_tester(class_name="A"),
"B/B.ql": a_ql_class_tester(class_name="B"),
}
@@ -778,291 +1269,605 @@ def test_test_with(opts, generate_tests):
def test_property_description(generate_classes):
description = ["Lorem", "Ipsum"]
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar", description=description),
- ]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"],
- doc="foo of this my object",
- description=description),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.SingleProperty("foo", "bar", description=description),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ description=description,
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_property_doc_override(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar", doc="baz")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"], doc="baz"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject", properties=[schema.SingleProperty("foo", "bar", doc="baz")]
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="baz",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_repeated_property_doc_override(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.RepeatedProperty("x", "int", doc="children of this"),
- schema.RepeatedOptionalProperty("y", "int", doc="child of this")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="X", plural="Xes", type="int",
- tablename="my_object_xes",
- tableparams=["this", "index", "result"],
- doc="child of this", doc_plural="children of this"),
- ql.Property(singular="Y", plural="Ys", type="int",
- tablename="my_object_ies", is_optional=True,
- tableparams=["this", "index", "result"],
- doc="child of this", doc_plural="children of this"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.RepeatedProperty("x", "int", doc="children of this"),
+ schema.RepeatedOptionalProperty("y", "int", doc="child of this"),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="X",
+ plural="Xes",
+ type="int",
+ tablename="my_object_xes",
+ tableparams=["this", "index", "result"],
+ doc="child of this",
+ doc_plural="children of this",
+ ),
+ ql.Property(
+ singular="Y",
+ plural="Ys",
+ type="int",
+ tablename="my_object_ies",
+ is_optional=True,
+ tableparams=["this", "index", "result"],
+ doc="child of this",
+ doc_plural="children of this",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
@pytest.mark.parametrize("abbr,expected", list(qlgen.abbreviations.items()))
def test_property_doc_abbreviations(generate_classes, abbr, expected):
expected_doc = f"foo {expected} bar of this object"
- assert generate_classes([
- schema.Class("Object", properties=[
- schema.SingleProperty(f"foo_{abbr}_bar", "baz")]),
- ]) == {
- "Object.qll": (a_ql_class_public(name="Object"),
- a_ql_stub(name="Object"),
- a_ql_class(name="Object", final=True,
- properties=[
- ql.Property(singular=f"Foo{abbr.capitalize()}Bar", type="baz",
- tablename="objects",
- tableparams=["this", "result"], doc=expected_doc),
- ],
- imports=[stub_import_prefix + "Object"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "Object", properties=[schema.SingleProperty(f"foo_{abbr}_bar", "baz")]
+ ),
+ ]
+ ) == {
+ "Object.qll": (
+ a_ql_class_public(name="Object"),
+ a_ql_stub(name="Object"),
+ a_ql_class(
+ name="Object",
+ final=True,
+ properties=[
+ ql.Property(
+ singular=f"Foo{abbr.capitalize()}Bar",
+ type="baz",
+ tablename="objects",
+ tableparams=["this", "result"],
+ doc=expected_doc,
+ ),
+ ],
+ imports=[stub_import_prefix + "Object"],
+ ),
+ ),
}
@pytest.mark.parametrize("abbr,expected", list(qlgen.abbreviations.items()))
-def test_property_doc_abbreviations_ignored_if_within_word(generate_classes, abbr, expected):
+def test_property_doc_abbreviations_ignored_if_within_word(
+ generate_classes, abbr, expected
+):
expected_doc = f"foo {abbr}acadabra bar of this object"
- assert generate_classes([
- schema.Class("Object", properties=[
- schema.SingleProperty(f"foo_{abbr}acadabra_bar", "baz")]),
- ]) == {
- "Object.qll": (a_ql_class_public(name="Object"),
- a_ql_stub(name="Object"),
- a_ql_class(name="Object", final=True,
- properties=[
- ql.Property(singular=f"Foo{abbr.capitalize()}acadabraBar", type="baz",
- tablename="objects",
- tableparams=["this", "result"], doc=expected_doc),
- ],
- imports=[stub_import_prefix + "Object"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "Object",
+ properties=[schema.SingleProperty(f"foo_{abbr}acadabra_bar", "baz")],
+ ),
+ ]
+ ) == {
+ "Object.qll": (
+ a_ql_class_public(name="Object"),
+ a_ql_stub(name="Object"),
+ a_ql_class(
+ name="Object",
+ final=True,
+ properties=[
+ ql.Property(
+ singular=f"Foo{abbr.capitalize()}acadabraBar",
+ type="baz",
+ tablename="objects",
+ tableparams=["this", "result"],
+ doc=expected_doc,
+ ),
+ ],
+ imports=[stub_import_prefix + "Object"],
+ ),
+ ),
}
def test_repeated_property_doc_override_with_format(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.RepeatedProperty("x", "int", doc="special {children} of this"),
- schema.RepeatedOptionalProperty("y", "int", doc="special {child} of this")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="X", plural="Xes", type="int",
- tablename="my_object_xes",
- tableparams=["this", "index", "result"],
- doc="special child of this",
- doc_plural="special children of this"),
- ql.Property(singular="Y", plural="Ys", type="int",
- tablename="my_object_ies", is_optional=True,
- tableparams=["this", "index", "result"],
- doc="special child of this",
- doc_plural="special children of this"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.RepeatedProperty(
+ "x", "int", doc="special {children} of this"
+ ),
+ schema.RepeatedOptionalProperty(
+ "y", "int", doc="special {child} of this"
+ ),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="X",
+ plural="Xes",
+ type="int",
+ tablename="my_object_xes",
+ tableparams=["this", "index", "result"],
+ doc="special child of this",
+ doc_plural="special children of this",
+ ),
+ ql.Property(
+ singular="Y",
+ plural="Ys",
+ type="int",
+ tablename="my_object_ies",
+ is_optional=True,
+ tableparams=["this", "index", "result"],
+ doc="special child of this",
+ doc_plural="special children of this",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_repeated_property_doc_override_with_multiple_formats(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.RepeatedProperty("x", "int", doc="{cat} or {dog}"),
- schema.RepeatedOptionalProperty("y", "int", doc="{cats} or {dogs}")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="X", plural="Xes", type="int",
- tablename="my_object_xes",
- tableparams=["this", "index", "result"],
- doc="cat or dog", doc_plural="cats or dogs"),
- ql.Property(singular="Y", plural="Ys", type="int",
- tablename="my_object_ies", is_optional=True,
- tableparams=["this", "index", "result"],
- doc="cat or dog", doc_plural="cats or dogs"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.RepeatedProperty("x", "int", doc="{cat} or {dog}"),
+ schema.RepeatedOptionalProperty("y", "int", doc="{cats} or {dogs}"),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="X",
+ plural="Xes",
+ type="int",
+ tablename="my_object_xes",
+ tableparams=["this", "index", "result"],
+ doc="cat or dog",
+ doc_plural="cats or dogs",
+ ),
+ ql.Property(
+ singular="Y",
+ plural="Ys",
+ type="int",
+ tablename="my_object_ies",
+ is_optional=True,
+ tableparams=["this", "index", "result"],
+ doc="cat or dog",
+ doc_plural="cats or dogs",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_property_doc_override_with_format(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar", doc="special {baz} of this")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"], doc="special baz of this"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[
+ schema.SingleProperty("foo", "bar", doc="special {baz} of this")
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="special baz of this",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_property_on_class_with_default_doc_name(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar")],
- pragmas={"ql_default_doc_name": "baz"}),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- tableparams=["this", "result"], doc="foo of this baz"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ properties=[schema.SingleProperty("foo", "bar")],
+ pragmas={"ql_default_doc_name": "baz"},
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ tableparams=["this", "result"],
+ doc="foo of this baz",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_stub_on_class_with_synth_from_class(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", pragmas={"synth": schema.SynthInfo(from_class="A")},
- properties=[schema.SingleProperty("foo", "bar")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject", synth_accessors=[
- ql.SynthUnderlyingAccessor(argument="Entity", type="Raw::A", constructorparams=["result"]),
- ]),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True,
- tableparams=["this", "result"], doc="foo of this my object"),
- ], imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ pragmas={"synth": schema.SynthInfo(from_class="A")},
+ properties=[schema.SingleProperty("foo", "bar")],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(
+ name="MyObject",
+ synth_accessors=[
+ ql.SynthUnderlyingAccessor(
+ argument="Entity", type="Raw::A", constructorparams=["result"]
+ ),
+ ],
+ ),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ synth=True,
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_stub_on_class_with_synth_on_arguments(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", pragmas={"synth": schema.SynthInfo(on_arguments={"base": "A", "index": "int", "label": "string"})},
- properties=[schema.SingleProperty("foo", "bar")]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject", synth_accessors=[
- ql.SynthUnderlyingAccessor(argument="Base", type="Raw::A", constructorparams=["result", "_", "_"]),
- ql.SynthUnderlyingAccessor(argument="Index", type="int", constructorparams=["_", "result", "_"]),
- ql.SynthUnderlyingAccessor(argument="Label", type="string", constructorparams=["_", "_", "result"]),
- ]),
- a_ql_class(name="MyObject", final=True, properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects", synth=True,
- tableparams=["this", "result"], doc="foo of this my object"),
- ], imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject",
+ pragmas={
+ "synth": schema.SynthInfo(
+ on_arguments={"base": "A", "index": "int", "label": "string"}
+ )
+ },
+ properties=[schema.SingleProperty("foo", "bar")],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(
+ name="MyObject",
+ synth_accessors=[
+ ql.SynthUnderlyingAccessor(
+ argument="Base",
+ type="Raw::A",
+ constructorparams=["result", "_", "_"],
+ ),
+ ql.SynthUnderlyingAccessor(
+ argument="Index",
+ type="int",
+ constructorparams=["_", "result", "_"],
+ ),
+ ql.SynthUnderlyingAccessor(
+ argument="Label",
+ type="string",
+ constructorparams=["_", "_", "result"],
+ ),
+ ],
+ ),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ synth=True,
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_synth_property(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", properties=[
- schema.SingleProperty("foo", "bar", synth=True)]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"),
- a_ql_stub(name="MyObject"),
- a_ql_class(name="MyObject", final=True,
- properties=[
- ql.Property(singular="Foo", type="bar", tablename="my_objects",
- synth=True,
- tableparams=["this", "result"], doc="foo of this my object"),
- ],
- imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "MyObject", properties=[schema.SingleProperty("foo", "bar", synth=True)]
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="Foo",
+ type="bar",
+ tablename="my_objects",
+ synth=True,
+ tableparams=["this", "result"],
+ doc="foo of this my object",
+ ),
+ ],
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_hideable_class(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", pragmas=["ql_hideable"]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable=True, imports=[stub_import_prefix + "MyObject"])),
+ assert generate_classes(
+ [
+ schema.Class("MyObject", pragmas=["ql_hideable"]),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ hideable=True,
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
}
def test_hideable_property(generate_classes):
- assert generate_classes([
- schema.Class("MyObject", pragmas=["ql_hideable"]),
- schema.Class("Other", properties=[
- schema.SingleProperty("x", "MyObject"),
- ]),
- ]) == {
- "MyObject.qll": (a_ql_class_public(name="MyObject"), a_ql_stub(name="MyObject"), a_ql_class(name="MyObject", final=True, hideable=True, imports=[stub_import_prefix + "MyObject"])),
- "Other.qll": (a_ql_class_public(name="Other", imports=[stub_import_prefix + "MyObject"]),
- a_ql_stub(name="Other"),
- a_ql_class(name="Other", imports=[stub_import_prefix + "MyObject", stub_import_prefix + "Other"],
- final=True, properties=[
- ql.Property(singular="X", type="MyObject", tablename="others",
- type_is_hideable=True,
- type_is_codegen_class=True,
- tableparams=["this", "result"], doc="x of this other"),
- ])),
+ assert generate_classes(
+ [
+ schema.Class("MyObject", pragmas=["ql_hideable"]),
+ schema.Class(
+ "Other",
+ properties=[
+ schema.SingleProperty("x", "MyObject"),
+ ],
+ ),
+ ]
+ ) == {
+ "MyObject.qll": (
+ a_ql_class_public(name="MyObject"),
+ a_ql_stub(name="MyObject"),
+ a_ql_class(
+ name="MyObject",
+ final=True,
+ hideable=True,
+ imports=[stub_import_prefix + "MyObject"],
+ ),
+ ),
+ "Other.qll": (
+ a_ql_class_public(name="Other", imports=[stub_import_prefix + "MyObject"]),
+ a_ql_stub(name="Other"),
+ a_ql_class(
+ name="Other",
+ imports=[stub_import_prefix + "MyObject", stub_import_prefix + "Other"],
+ final=True,
+ properties=[
+ ql.Property(
+ singular="X",
+ type="MyObject",
+ tablename="others",
+ type_is_hideable=True,
+ type_is_codegen_class=True,
+ tableparams=["this", "result"],
+ doc="x of this other",
+ ),
+ ],
+ ),
+ ),
}
def test_property_with_custom_db_table_name(generate_classes):
- assert generate_classes([
- schema.Class("Obj", properties=[
- schema.OptionalProperty("x", "a", pragmas={"ql_db_table_name": "foo"}),
- schema.RepeatedProperty("y", "b", pragmas={"ql_db_table_name": "bar"}),
- schema.RepeatedOptionalProperty("z", "c", pragmas={"ql_db_table_name": "baz"}),
- schema.PredicateProperty("p", pragmas={"ql_db_table_name": "hello"}),
- schema.RepeatedUnorderedProperty("q", "d", pragmas={"ql_db_table_name": "world"}),
- ]),
- ]) == {
- "Obj.qll": (a_ql_class_public(name="Obj"),
- a_ql_stub(name="Obj"),
- a_ql_class(name="Obj", final=True, properties=[
- ql.Property(singular="X", type="a", tablename="foo",
- tableparams=["this", "result"],
- is_optional=True, doc="x of this obj"),
- ql.Property(singular="Y", plural="Ys", type="b", tablename="bar",
- tableparams=["this", "index", "result"],
- doc="y of this obj", doc_plural="ys of this obj"),
- ql.Property(singular="Z", plural="Zs", type="c", tablename="baz",
- tableparams=["this", "index", "result"],
- is_optional=True, doc="z of this obj", doc_plural="zs of this obj"),
- ql.Property(singular="p", type="predicate", tablename="hello",
- tableparams=["this"], is_predicate=True,
- doc="this obj p"),
- ql.Property(singular="Q", plural="Qs", type="d", tablename="world",
- tableparams=["this", "result"], is_unordered=True,
- doc="q of this obj", doc_plural="qs of this obj"),
- ],
- imports=[stub_import_prefix + "Obj"])),
+ assert generate_classes(
+ [
+ schema.Class(
+ "Obj",
+ properties=[
+ schema.OptionalProperty(
+ "x", "a", pragmas={"ql_db_table_name": "foo"}
+ ),
+ schema.RepeatedProperty(
+ "y", "b", pragmas={"ql_db_table_name": "bar"}
+ ),
+ schema.RepeatedOptionalProperty(
+ "z", "c", pragmas={"ql_db_table_name": "baz"}
+ ),
+ schema.PredicateProperty(
+ "p", pragmas={"ql_db_table_name": "hello"}
+ ),
+ schema.RepeatedUnorderedProperty(
+ "q", "d", pragmas={"ql_db_table_name": "world"}
+ ),
+ ],
+ ),
+ ]
+ ) == {
+ "Obj.qll": (
+ a_ql_class_public(name="Obj"),
+ a_ql_stub(name="Obj"),
+ a_ql_class(
+ name="Obj",
+ final=True,
+ properties=[
+ ql.Property(
+ singular="X",
+ type="a",
+ tablename="foo",
+ tableparams=["this", "result"],
+ is_optional=True,
+ doc="x of this obj",
+ ),
+ ql.Property(
+ singular="Y",
+ plural="Ys",
+ type="b",
+ tablename="bar",
+ tableparams=["this", "index", "result"],
+ doc="y of this obj",
+ doc_plural="ys of this obj",
+ ),
+ ql.Property(
+ singular="Z",
+ plural="Zs",
+ type="c",
+ tablename="baz",
+ tableparams=["this", "index", "result"],
+ is_optional=True,
+ doc="z of this obj",
+ doc_plural="zs of this obj",
+ ),
+ ql.Property(
+ singular="p",
+ type="predicate",
+ tablename="hello",
+ tableparams=["this"],
+ is_predicate=True,
+ doc="this obj p",
+ ),
+ ql.Property(
+ singular="Q",
+ plural="Qs",
+ type="d",
+ tablename="world",
+ tableparams=["this", "result"],
+ is_unordered=True,
+ doc="q of this obj",
+ doc_plural="qs of this obj",
+ ),
+ ],
+ imports=[stub_import_prefix + "Obj"],
+ ),
+ ),
}
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_render.py b/misc/codegen/test/test_render.py
index 21378e715bb2..74803c2300c4 100644
--- a/misc/codegen/test/test_render.py
+++ b/misc/codegen/test/test_render.py
@@ -46,7 +46,10 @@ def write_registry(file, *files_and_hashes):
def assert_registry(file, *files_and_hashes):
assert_file(file, create_registry(files_and_hashes))
files = [file.name, ".gitattributes"] + [f for f, _, _ in files_and_hashes]
- assert_file(file.parent / ".gitattributes", "\n".join(f"/{f} linguist-generated" for f in files) + "\n")
+ assert_file(
+ file.parent / ".gitattributes",
+ "\n".join(f"/{f} linguist-generated" for f in files) + "\n",
+ )
def hash(text):
@@ -56,11 +59,11 @@ def hash(text):
def test_constructor(pystache_renderer_cls, sut):
- pystache_init, = pystache_renderer_cls.mock_calls
- assert set(pystache_init.kwargs) == {'search_dirs', 'escape'}
- assert pystache_init.kwargs['search_dirs'] == str(paths.templates_dir)
+ (pystache_init,) = pystache_renderer_cls.mock_calls
+ assert set(pystache_init.kwargs) == {"search_dirs", "escape"}
+ assert pystache_init.kwargs["search_dirs"] == str(paths.templates_dir)
an_object = object()
- assert pystache_init.kwargs['escape'](an_object) is an_object
+ assert pystache_init.kwargs["escape"](an_object) is an_object
def test_render(pystache_renderer, sut):
@@ -218,7 +221,9 @@ def test_managed_render_with_skipping_of_stub_file(pystache_renderer, sut):
some_processed_output = "// generated some processed output"
registry = paths.root_dir / "a/registry.list"
write(stub, some_processed_output)
- write_registry(registry, ("some/stub.txt", hash(some_output), hash(some_processed_output)))
+ write_registry(
+ registry, ("some/stub.txt", hash(some_output), hash(some_processed_output))
+ )
pystache_renderer.render_name.side_effect = (some_output,)
@@ -227,7 +232,9 @@ def test_managed_render_with_skipping_of_stub_file(pystache_renderer, sut):
assert renderer.written == set()
assert_file(stub, some_processed_output)
- assert_registry(registry, ("some/stub.txt", hash(some_output), hash(some_processed_output)))
+ assert_registry(
+ registry, ("some/stub.txt", hash(some_output), hash(some_processed_output))
+ )
assert pystache_renderer.mock_calls == [
mock.call.render_name(data.template, data, generator=generator),
]
@@ -238,13 +245,17 @@ def test_managed_render_with_modified_generated_file(pystache_renderer, sut):
some_processed_output = "// some processed output"
registry = paths.root_dir / "a/registry.list"
write(output, "// something else")
- write_registry(registry, ("some/output.txt", "whatever", hash(some_processed_output)))
+ write_registry(
+ registry, ("some/output.txt", "whatever", hash(some_processed_output))
+ )
with pytest.raises(render.Error):
sut.manage(generated=(output,), stubs=(), registry=registry)
-def test_managed_render_with_modified_stub_file_still_marked_as_generated(pystache_renderer, sut):
+def test_managed_render_with_modified_stub_file_still_marked_as_generated(
+ pystache_renderer, sut
+):
stub = paths.root_dir / "a/some/stub.txt"
some_processed_output = "// generated some processed output"
registry = paths.root_dir / "a/registry.list"
@@ -255,7 +266,9 @@ def test_managed_render_with_modified_stub_file_still_marked_as_generated(pystac
sut.manage(generated=(), stubs=(stub,), registry=registry)
-def test_managed_render_with_modified_stub_file_not_marked_as_generated(pystache_renderer, sut):
+def test_managed_render_with_modified_stub_file_not_marked_as_generated(
+ pystache_renderer, sut
+):
stub = paths.root_dir / "a/some/stub.txt"
some_processed_output = "// generated some processed output"
registry = paths.root_dir / "a/registry.list"
@@ -272,7 +285,9 @@ class MyError(Exception):
pass
-def test_managed_render_exception_drops_written_and_inexsistent_from_registry(pystache_renderer, sut):
+def test_managed_render_exception_drops_written_and_inexsistent_from_registry(
+ pystache_renderer, sut
+):
data = mock.Mock(spec=("template",))
text = "some text"
pystache_renderer.render_name.side_effect = (text,)
@@ -281,11 +296,9 @@ def test_managed_render_exception_drops_written_and_inexsistent_from_registry(py
write(output, text)
write(paths.root_dir / "a/a")
write(paths.root_dir / "a/c")
- write_registry(registry,
- "aaa",
- ("some/output.txt", "whatever", hash(text)),
- "bbb",
- "ccc")
+ write_registry(
+ registry, "aaa", ("some/output.txt", "whatever", hash(text)), "bbb", "ccc"
+ )
with pytest.raises(MyError):
with sut.manage(generated=(), stubs=(), registry=registry) as renderer:
@@ -299,17 +312,14 @@ def test_managed_render_drops_inexsistent_from_registry(pystache_renderer, sut):
registry = paths.root_dir / "a/registry.list"
write(paths.root_dir / "a/a")
write(paths.root_dir / "a/c")
- write_registry(registry,
- ("a", hash(''), hash('')),
- "bbb",
- ("c", hash(''), hash('')))
+ write_registry(
+ registry, ("a", hash(""), hash("")), "bbb", ("c", hash(""), hash(""))
+ )
with sut.manage(generated=(), stubs=(), registry=registry):
pass
- assert_registry(registry,
- ("a", hash(''), hash('')),
- ("c", hash(''), hash('')))
+ assert_registry(registry, ("a", hash(""), hash("")), ("c", hash(""), hash("")))
def test_managed_render_exception_does_not_erase(pystache_renderer, sut):
@@ -321,7 +331,9 @@ def test_managed_render_exception_does_not_erase(pystache_renderer, sut):
write_registry(registry)
with pytest.raises(MyError):
- with sut.manage(generated=(output,), stubs=(stub,), registry=registry) as renderer:
+ with sut.manage(
+ generated=(output,), stubs=(stub,), registry=registry
+ ) as renderer:
raise MyError
assert output.is_file()
@@ -333,14 +345,15 @@ def test_render_with_extensions(pystache_renderer, sut):
data.template = "test_template"
data.extensions = ["foo", "bar", "baz"]
output = pathlib.Path("my", "test", "file")
- expected_outputs = [pathlib.Path("my", "test", p) for p in ("file.foo", "file.bar", "file.baz")]
+ expected_outputs = [
+ pathlib.Path("my", "test", p) for p in ("file.foo", "file.bar", "file.baz")
+ ]
rendered = [f"text{i}" for i in range(len(expected_outputs))]
pystache_renderer.render_name.side_effect = rendered
sut.render(data, output)
expected_templates = ["test_template_foo", "test_template_bar", "test_template_baz"]
assert pystache_renderer.mock_calls == [
- mock.call.render_name(t, data, generator=generator)
- for t in expected_templates
+ mock.call.render_name(t, data, generator=generator) for t in expected_templates
]
for expected_output, expected_contents in zip(expected_outputs, rendered):
assert_file(expected_output, expected_contents)
@@ -356,7 +369,9 @@ def test_managed_render_with_force_not_skipping_generated_file(pystache_renderer
pystache_renderer.render_name.side_effect = (some_output,)
- with sut.manage(generated=(output,), stubs=(), registry=registry, force=True) as renderer:
+ with sut.manage(
+ generated=(output,), stubs=(), registry=registry, force=True
+ ) as renderer:
renderer.render(data, output)
assert renderer.written == {output}
assert_file(output, some_output)
@@ -374,11 +389,15 @@ def test_managed_render_with_force_not_skipping_stub_file(pystache_renderer, sut
some_processed_output = "// generated some processed output"
registry = paths.root_dir / "a/registry.list"
write(stub, some_processed_output)
- write_registry(registry, ("some/stub.txt", hash(some_output), hash(some_processed_output)))
+ write_registry(
+ registry, ("some/stub.txt", hash(some_output), hash(some_processed_output))
+ )
pystache_renderer.render_name.side_effect = (some_output,)
- with sut.manage(generated=(), stubs=(stub,), registry=registry, force=True) as renderer:
+ with sut.manage(
+ generated=(), stubs=(stub,), registry=registry, force=True
+ ) as renderer:
renderer.render(data, stub)
assert renderer.written == {stub}
assert_file(stub, some_output)
@@ -394,13 +413,17 @@ def test_managed_render_with_force_ignores_modified_generated_file(sut):
some_processed_output = "// some processed output"
registry = paths.root_dir / "a/registry.list"
write(output, "// something else")
- write_registry(registry, ("some/output.txt", "whatever", hash(some_processed_output)))
+ write_registry(
+ registry, ("some/output.txt", "whatever", hash(some_processed_output))
+ )
with sut.manage(generated=(output,), stubs=(), registry=registry, force=True):
pass
-def test_managed_render_with_force_ignores_modified_stub_file_still_marked_as_generated(sut):
+def test_managed_render_with_force_ignores_modified_stub_file_still_marked_as_generated(
+ sut,
+):
stub = paths.root_dir / "a/some/stub.txt"
some_processed_output = "// generated some processed output"
registry = paths.root_dir / "a/registry.list"
@@ -411,5 +434,5 @@ def test_managed_render_with_force_ignores_modified_stub_file_still_marked_as_ge
pass
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_schemaloader.py b/misc/codegen/test/test_schemaloader.py
index 1c8bfba271b2..5e8ba91b742a 100644
--- a/misc/codegen/test/test_schemaloader.py
+++ b/misc/codegen/test/test_schemaloader.py
@@ -26,9 +26,9 @@ class MyClass:
pass
assert data.classes == {
- 'MyClass': schema.Class('MyClass'),
+ "MyClass": schema.Class("MyClass"),
}
- assert data.root_class is data.classes['MyClass']
+ assert data.root_class is data.classes["MyClass"]
def test_two_empty_classes():
@@ -41,10 +41,10 @@ class MyClass2(MyClass1):
pass
assert data.classes == {
- 'MyClass1': schema.Class('MyClass1', derived={'MyClass2'}),
- 'MyClass2': schema.Class('MyClass2', bases=['MyClass1']),
+ "MyClass1": schema.Class("MyClass1", derived={"MyClass2"}),
+ "MyClass2": schema.Class("MyClass2", bases=["MyClass1"]),
}
- assert data.root_class is data.classes['MyClass1']
+ assert data.root_class is data.classes["MyClass1"]
def test_no_external_bases():
@@ -52,6 +52,7 @@ class A:
pass
with pytest.raises(schema.Error):
+
@load
class data:
class MyClass(A):
@@ -60,6 +61,7 @@ class MyClass(A):
def test_no_multiple_roots():
with pytest.raises(schema.Error):
+
@load
class data:
class MyClass1:
@@ -85,10 +87,10 @@ class D(B, C):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B', 'C'}),
- 'B': schema.Class('B', bases=['A'], derived={'D'}),
- 'C': schema.Class('C', bases=['A'], derived={'D'}),
- 'D': schema.Class('D', bases=['B', 'C']),
+ "A": schema.Class("A", derived={"B", "C"}),
+ "B": schema.Class("B", bases=["A"], derived={"D"}),
+ "C": schema.Class("C", bases=["A"], derived={"D"}),
+ "D": schema.Class("D", bases=["B", "C"]),
}
@@ -101,7 +103,7 @@ class A:
pass
assert data.classes == {
- 'A': schema.Class('A', pragmas={"group": "xxx"}),
+ "A": schema.Class("A", pragmas={"group": "xxx"}),
}
@@ -114,7 +116,7 @@ class A:
class B(A):
pass
- @defs.group('xxx')
+ @defs.group("xxx")
class C(A):
pass
@@ -122,25 +124,26 @@ class D(B, C):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B', 'C'}),
- 'B': schema.Class('B', bases=['A'], derived={'D'}),
- 'C': schema.Class('C', bases=['A'], derived={'D'}, pragmas={"group": "xxx"}),
- 'D': schema.Class('D', bases=['B', 'C'], pragmas={"group": "xxx"}),
+ "A": schema.Class("A", derived={"B", "C"}),
+ "B": schema.Class("B", bases=["A"], derived={"D"}),
+ "C": schema.Class("C", bases=["A"], derived={"D"}, pragmas={"group": "xxx"}),
+ "D": schema.Class("D", bases=["B", "C"], pragmas={"group": "xxx"}),
}
def test_no_mixed_groups_in_bases():
with pytest.raises(schema.Error):
+
@load
class data:
class A:
pass
- @defs.group('x')
+ @defs.group("x")
class B(A):
pass
- @defs.group('y')
+ @defs.group("y")
class C(A):
pass
@@ -153,6 +156,7 @@ class D(B, C):
def test_lowercase_rejected():
with pytest.raises(schema.Error):
+
@load
class data:
class aLowerCase:
@@ -171,14 +175,17 @@ class A:
six: defs.set[defs.string]
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('one', 'string'),
- schema.OptionalProperty('two', 'int'),
- schema.RepeatedProperty('three', 'boolean'),
- schema.RepeatedOptionalProperty('four', 'string'),
- schema.PredicateProperty('five'),
- schema.RepeatedUnorderedProperty('six', 'string'),
- ]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty("one", "string"),
+ schema.OptionalProperty("two", "int"),
+ schema.RepeatedProperty("three", "boolean"),
+ schema.RepeatedOptionalProperty("four", "string"),
+ schema.PredicateProperty("five"),
+ schema.RepeatedUnorderedProperty("six", "string"),
+ ],
+ ),
}
@@ -199,14 +206,18 @@ class B(A):
five: defs.set[A]
assert data.classes == {
- 'A': schema.Class('A', derived={'B'}),
- 'B': schema.Class('B', bases=['A'], properties=[
- schema.SingleProperty('one', 'A'),
- schema.OptionalProperty('two', 'A'),
- schema.RepeatedProperty('three', 'A'),
- schema.RepeatedOptionalProperty('four', 'A'),
- schema.RepeatedUnorderedProperty('five', 'A'),
- ]),
+ "A": schema.Class("A", derived={"B"}),
+ "B": schema.Class(
+ "B",
+ bases=["A"],
+ properties=[
+ schema.SingleProperty("one", "A"),
+ schema.OptionalProperty("two", "A"),
+ schema.RepeatedProperty("three", "A"),
+ schema.RepeatedOptionalProperty("four", "A"),
+ schema.RepeatedUnorderedProperty("five", "A"),
+ ],
+ ),
}
@@ -221,20 +232,31 @@ class A:
five: defs.set["A"]
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('one', 'A'),
- schema.OptionalProperty('two', 'A'),
- schema.RepeatedProperty('three', 'A'),
- schema.RepeatedOptionalProperty('four', 'A'),
- schema.RepeatedUnorderedProperty('five', 'A'),
- ]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty("one", "A"),
+ schema.OptionalProperty("two", "A"),
+ schema.RepeatedProperty("three", "A"),
+ schema.RepeatedOptionalProperty("four", "A"),
+ schema.RepeatedUnorderedProperty("five", "A"),
+ ],
+ ),
}
-@pytest.mark.parametrize("spec", [lambda t: t, lambda t: defs.optional[t], lambda t: defs.list[t],
- lambda t: defs.list[defs.optional[t]]])
+@pytest.mark.parametrize(
+ "spec",
+ [
+ lambda t: t,
+ lambda t: defs.optional[t],
+ lambda t: defs.list[t],
+ lambda t: defs.list[defs.optional[t]],
+ ],
+)
def test_string_reference_dangling(spec):
with pytest.raises(schema.Error):
+
@load
class data:
class A:
@@ -251,18 +273,24 @@ class A:
four: defs.list[defs.optional["A"]] | defs.child
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('one', 'A', is_child=True),
- schema.OptionalProperty('two', 'A', is_child=True),
- schema.RepeatedProperty('three', 'A', is_child=True),
- schema.RepeatedOptionalProperty('four', 'A', is_child=True),
- ]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty("one", "A", is_child=True),
+ schema.OptionalProperty("two", "A", is_child=True),
+ schema.RepeatedProperty("three", "A", is_child=True),
+ schema.RepeatedOptionalProperty("four", "A", is_child=True),
+ ],
+ ),
}
-@pytest.mark.parametrize("spec", [defs.string, defs.int, defs.boolean, defs.predicate, defs.set["A"]])
+@pytest.mark.parametrize(
+ "spec", [defs.string, defs.int, defs.boolean, defs.predicate, defs.set["A"]]
+)
def test_builtin_predicate_and_set_children_not_allowed(spec):
with pytest.raises(schema.Error):
+
@load
class data:
class A:
@@ -291,9 +319,12 @@ class A:
x: defs.string | pragma
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('x', 'string', pragmas=[expected]),
- ]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty("x", "string", pragmas=[expected]),
+ ],
+ ),
}
@@ -308,9 +339,16 @@ class A:
x: spec
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('x', 'string', pragmas=[expected for _, expected in _property_pragmas]),
- ]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x",
+ "string",
+ pragmas=[expected for _, expected in _property_pragmas],
+ ),
+ ],
+ ),
}
@@ -323,7 +361,7 @@ class A:
pass
assert data.classes == {
- 'A': schema.Class('A', pragmas=[expected]),
+ "A": schema.Class("A", pragmas=[expected]),
}
@@ -340,7 +378,7 @@ class A:
apply_pragmas(A)
assert data.classes == {
- 'A': schema.Class('A', pragmas=[e for _, e in _pragmas]),
+ "A": schema.Class("A", pragmas=[e for _, e in _pragmas]),
}
@@ -355,8 +393,10 @@ class B(A):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B'}, pragmas={"synth": True}),
- 'B': schema.Class('B', bases=['A'], pragmas={"synth": schema.SynthInfo(from_class="A")}),
+ "A": schema.Class("A", derived={"B"}, pragmas={"synth": True}),
+ "B": schema.Class(
+ "B", bases=["A"], pragmas={"synth": schema.SynthInfo(from_class="A")}
+ ),
}
@@ -371,13 +411,16 @@ class B(A):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B'}, pragmas={"synth": schema.SynthInfo(from_class="B")}),
- 'B': schema.Class('B', bases=['A']),
+ "A": schema.Class(
+ "A", derived={"B"}, pragmas={"synth": schema.SynthInfo(from_class="B")}
+ ),
+ "B": schema.Class("B", bases=["A"]),
}
def test_synth_from_class_dangling():
with pytest.raises(schema.Error):
+
@load
class data:
@defs.synth.from_class("X")
@@ -396,8 +439,12 @@ class B(A):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B'}, pragmas={"synth": True}),
- 'B': schema.Class('B', bases=['A'], pragmas={"synth": schema.SynthInfo(on_arguments={'a': 'A', 'i': 'int'})}),
+ "A": schema.Class("A", derived={"B"}, pragmas={"synth": True}),
+ "B": schema.Class(
+ "B",
+ bases=["A"],
+ pragmas={"synth": schema.SynthInfo(on_arguments={"a": "A", "i": "int"})},
+ ),
}
@@ -415,13 +462,18 @@ class B(A):
pass
assert data.classes == {
- 'A': schema.Class('A', derived={'B'}, pragmas={"synth": schema.SynthInfo(on_arguments={'b': 'B', 'i': 'int'})}),
- 'B': schema.Class('B', bases=['A']),
+ "A": schema.Class(
+ "A",
+ derived={"B"},
+ pragmas={"synth": schema.SynthInfo(on_arguments={"b": "B", "i": "int"})},
+ ),
+ "B": schema.Class("B", bases=["A"]),
}
def test_synth_class_on_dangling():
with pytest.raises(schema.Error):
+
@load
class data:
@defs.synth.on_arguments(s=defs.string, a="A", i=defs.int)
@@ -453,12 +505,25 @@ class C(Root):
pass
assert data.classes == {
- 'Root': schema.Class('Root', derived={'Base', 'C'}),
- 'Base': schema.Class('Base', bases=['Root'], derived={'Intermediate', 'B'}, pragmas={"synth": True}),
- 'Intermediate': schema.Class('Intermediate', bases=['Base'], derived={'A'}, pragmas={"synth": True}),
- 'A': schema.Class('A', bases=['Intermediate'], pragmas={"synth": schema.SynthInfo(on_arguments={'a': 'Base', 'i': 'int'})}),
- 'B': schema.Class('B', bases=['Base'], pragmas={"synth": schema.SynthInfo(from_class='Base')}),
- 'C': schema.Class('C', bases=['Root']),
+ "Root": schema.Class("Root", derived={"Base", "C"}),
+ "Base": schema.Class(
+ "Base",
+ bases=["Root"],
+ derived={"Intermediate", "B"},
+ pragmas={"synth": True},
+ ),
+ "Intermediate": schema.Class(
+ "Intermediate", bases=["Base"], derived={"A"}, pragmas={"synth": True}
+ ),
+ "A": schema.Class(
+ "A",
+ bases=["Intermediate"],
+ pragmas={"synth": schema.SynthInfo(on_arguments={"a": "Base", "i": "int"})},
+ ),
+ "B": schema.Class(
+ "B", bases=["Base"], pragmas={"synth": schema.SynthInfo(from_class="Base")}
+ ),
+ "C": schema.Class("C", bases=["Root"]),
}
@@ -479,9 +544,7 @@ class data:
class A:
"""Very important class."""
- assert data.classes == {
- 'A': schema.Class('A', doc=["Very important class."])
- }
+ assert data.classes == {"A": schema.Class("A", doc=["Very important class."])}
def test_property_docstring():
@@ -491,7 +554,14 @@ class A:
x: int | defs.desc("very important property.")
assert data.classes == {
- 'A': schema.Class('A', properties=[schema.SingleProperty('x', 'int', description=["very important property."])])
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x", "int", description=["very important property."]
+ )
+ ],
+ )
}
@@ -502,21 +572,27 @@ class A:
"""Very important
class."""
- assert data.classes == {
- 'A': schema.Class('A', doc=["Very important", "class."])
- }
+ assert data.classes == {"A": schema.Class("A", doc=["Very important", "class."])}
def test_property_docstring_newline():
@load
class data:
class A:
- x: int | defs.desc("""very important
- property.""")
+ x: int | defs.desc(
+ """very important
+ property."""
+ )
assert data.classes == {
- 'A': schema.Class('A',
- properties=[schema.SingleProperty('x', 'int', description=["very important", "property."])])
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x", "int", description=["very important", "property."]
+ )
+ ],
+ )
}
@@ -530,23 +606,30 @@ class A:
"""
- assert data.classes == {
- 'A': schema.Class('A', doc=["Very important class."])
- }
+ assert data.classes == {"A": schema.Class("A", doc=["Very important class."])}
def test_property_docstring_stripped():
@load
class data:
class A:
- x: int | defs.desc("""
+ x: int | defs.desc(
+ """
very important property.
- """)
+ """
+ )
assert data.classes == {
- 'A': schema.Class('A', properties=[schema.SingleProperty('x', 'int', description=["very important property."])])
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x", "int", description=["very important property."]
+ )
+ ],
+ )
}
@@ -559,7 +642,9 @@ class A:
As said, very important."""
assert data.classes == {
- 'A': schema.Class('A', doc=["Very important class.", "", "As said, very important."])
+ "A": schema.Class(
+ "A", doc=["Very important class.", "", "As said, very important."]
+ )
}
@@ -567,13 +652,27 @@ def test_property_docstring_split():
@load
class data:
class A:
- x: int | defs.desc("""very important property.
+ x: int | defs.desc(
+ """very important property.
- Very very important.""")
+ Very very important."""
+ )
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('x', 'int', description=["very important property.", "", "Very very important."])])
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x",
+ "int",
+ description=[
+ "very important property.",
+ "",
+ "Very very important.",
+ ],
+ )
+ ],
+ )
}
@@ -587,7 +686,9 @@ class A:
"""
assert data.classes == {
- 'A': schema.Class('A', doc=["Very important class.", " As said, very important."])
+ "A": schema.Class(
+ "A", doc=["Very important class.", " As said, very important."]
+ )
}
@@ -595,14 +696,24 @@ def test_property_docstring_indent():
@load
class data:
class A:
- x: int | defs.desc("""
+ x: int | defs.desc(
+ """
very important property.
Very very important.
- """)
+ """
+ )
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('x', 'int', description=["very important property.", " Very very important."])])
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.SingleProperty(
+ "x",
+ "int",
+ description=["very important property.", " Very very important."],
+ )
+ ],
+ )
}
@@ -613,13 +724,13 @@ class A:
x: int | defs.doc("y")
assert data.classes == {
- 'A': schema.Class('A', properties=[
- schema.SingleProperty('x', 'int', doc="y")]),
+ "A": schema.Class("A", properties=[schema.SingleProperty("x", "int", doc="y")]),
}
def test_property_doc_override_no_newlines():
with pytest.raises(schema.Error):
+
@load
class data:
class A:
@@ -628,6 +739,7 @@ class A:
def test_property_doc_override_no_trailing_dot():
with pytest.raises(schema.Error):
+
@load
class data:
class A:
@@ -642,7 +754,7 @@ class A:
pass
assert data.classes == {
- 'A': schema.Class('A', pragmas={"ql_default_doc_name": "b"}),
+ "A": schema.Class("A", pragmas={"ql_default_doc_name": "b"}),
}
@@ -653,7 +765,12 @@ class A:
x: optional[int] | defs.ql.db_table_name("foo")
assert data.classes == {
- 'A': schema.Class('A', properties=[schema.OptionalProperty("x", "int", pragmas={"ql_db_table_name": "foo"})]),
+ "A": schema.Class(
+ "A",
+ properties=[
+ schema.OptionalProperty("x", "int", pragmas={"ql_db_table_name": "foo"})
+ ],
+ ),
}
@@ -668,15 +785,16 @@ class Null(Root):
pass
assert data.classes == {
- 'Root': schema.Class('Root', derived={'Null'}),
- 'Null': schema.Class('Null', bases=['Root']),
+ "Root": schema.Class("Root", derived={"Null"}),
+ "Null": schema.Class("Null", bases=["Root"]),
}
- assert data.null == 'Null'
+ assert data.null == "Null"
assert data.null_class is data.classes[data.null]
def test_null_class_cannot_be_derived():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -692,6 +810,7 @@ class Impossible(Null):
def test_null_class_cannot_be_defined_multiple_times():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -708,6 +827,7 @@ class Null2(Root):
def test_uppercase_acronyms_are_rejected():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -737,10 +857,18 @@ class NonHideable(Root):
pass
assert data.classes == {
- "Root": schema.Class("Root", derived={"A", "IndirectlyHideable", "NonHideable"}, pragmas=["ql_hideable"]),
+ "Root": schema.Class(
+ "Root",
+ derived={"A", "IndirectlyHideable", "NonHideable"},
+ pragmas=["ql_hideable"],
+ ),
"A": schema.Class("A", bases=["Root"], derived={"B"}, pragmas=["ql_hideable"]),
- "IndirectlyHideable": schema.Class("IndirectlyHideable", bases=["Root"], derived={"B"}, pragmas=["ql_hideable"]),
- "B": schema.Class("B", bases=["A", "IndirectlyHideable"], pragmas=["ql_hideable"]),
+ "IndirectlyHideable": schema.Class(
+ "IndirectlyHideable", bases=["Root"], derived={"B"}, pragmas=["ql_hideable"]
+ ),
+ "B": schema.Class(
+ "B", bases=["A", "IndirectlyHideable"], pragmas=["ql_hideable"]
+ ),
"NonHideable": schema.Class("NonHideable", bases=["Root"]),
}
@@ -771,7 +899,9 @@ class E(B):
assert data.classes == {
"Root": schema.Class("Root", derived=set("ABCD")),
"A": schema.Class("A", bases=["Root"]),
- "B": schema.Class("B", bases=["Root"], pragmas={"qltest_test_with": "A"}, derived={'E'}),
+ "B": schema.Class(
+ "B", bases=["Root"], pragmas={"qltest_test_with": "A"}, derived={"E"}
+ ),
"C": schema.Class("C", bases=["Root"], pragmas={"qltest_test_with": "D"}),
"D": schema.Class("D", bases=["Root"]),
"E": schema.Class("E", bases=["B"], pragmas={"qltest_test_with": "A"}),
@@ -782,10 +912,10 @@ def test_annotate_docstring():
@load
class data:
class Root:
- """ old docstring """
+ """old docstring"""
class A(Root):
- """ A docstring """
+ """A docstring"""
@defs.annotate(Root)
class _:
@@ -819,7 +949,15 @@ class _:
pass
assert data.classes == {
- "Root": schema.Class("Root", pragmas=["qltest_skip", "cpp_skip", "ql_hideable", "qltest_collapse_hierarchy"]),
+ "Root": schema.Class(
+ "Root",
+ pragmas=[
+ "qltest_skip",
+ "cpp_skip",
+ "ql_hideable",
+ "qltest_collapse_hierarchy",
+ ],
+ ),
}
@@ -837,11 +975,16 @@ class _:
z: defs.string
assert data.classes == {
- "Root": schema.Class("Root", properties=[
- schema.SingleProperty("x", "int", doc="foo"),
- schema.OptionalProperty("y", "Root", pragmas=["ql_internal"], is_child=True),
- schema.SingleProperty("z", "string"),
- ]),
+ "Root": schema.Class(
+ "Root",
+ properties=[
+ schema.SingleProperty("x", "int", doc="foo"),
+ schema.OptionalProperty(
+ "y", "Root", pragmas=["ql_internal"], is_child=True
+ ),
+ schema.SingleProperty("z", "string"),
+ ],
+ ),
}
@@ -860,16 +1003,20 @@ class _:
z: defs._ | ~defs.synth | ~defs.doc
assert data.classes == {
- "Root": schema.Class("Root", properties=[
- schema.SingleProperty("x", "int"),
- schema.OptionalProperty("y", "Root"),
- schema.SingleProperty("z", "string"),
- ]),
+ "Root": schema.Class(
+ "Root",
+ properties=[
+ schema.SingleProperty("x", "int"),
+ schema.OptionalProperty("y", "Root"),
+ schema.SingleProperty("z", "string"),
+ ],
+ ),
}
def test_annotate_non_existing_field():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -882,6 +1029,7 @@ class _:
def test_annotate_not_underscore():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -916,6 +1064,7 @@ class Derived(A, B):
@defs.annotate(Derived, replace_bases={B: C})
class _:
pass
+
assert data.classes == {
"Root": schema.Class("Root", derived={"A", "B"}),
"A": schema.Class("A", bases=["Root"], derived={"Derived"}),
@@ -946,6 +1095,7 @@ class Derived(A):
@defs.annotate(Derived, add_bases=(B, C))
class _:
pass
+
assert data.classes == {
"Root": schema.Class("Root", derived={"A", "B", "C"}),
"A": schema.Class("A", bases=["Root"], derived={"Derived"}),
@@ -968,15 +1118,19 @@ class _:
y: defs.drop
assert data.classes == {
- "Root": schema.Class("Root", properties=[
- schema.SingleProperty("x", "int"),
- schema.SingleProperty("z", "boolean"),
- ]),
+ "Root": schema.Class(
+ "Root",
+ properties=[
+ schema.SingleProperty("x", "int"),
+ schema.SingleProperty("z", "boolean"),
+ ],
+ ),
}
def test_test_with_unknown_string():
with pytest.raises(schema.Error):
+
@load
class data:
class Root:
@@ -989,6 +1143,7 @@ class A(Root):
def test_test_with_unknown_class():
with pytest.raises(schema.Error):
+
class B:
pass
@@ -1004,6 +1159,7 @@ class A(Root):
def test_test_with_double():
with pytest.raises(schema.Error):
+
class B:
pass
@@ -1024,5 +1180,5 @@ class C(Root):
pass
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/test_trapgen.py b/misc/codegen/test/test_trapgen.py
index a81f40e0dd83..590c83aa7347 100644
--- a/misc/codegen/test/test_trapgen.py
+++ b/misc/codegen/test/test_trapgen.py
@@ -17,10 +17,16 @@ def ret(entities):
dirs = {f.parent for f in generated}
assert all(isinstance(f, pathlib.Path) for f in generated)
assert all(f.name in ("TrapEntries", "TrapTags") for f in generated)
- assert set(f for f in generated if f.name == "TrapTags") == {output_dir / "TrapTags"}
- return ({
- str(d.relative_to(output_dir)): generated[d / "TrapEntries"] for d in dirs
- }, generated[output_dir / "TrapTags"])
+ assert set(f for f in generated if f.name == "TrapTags") == {
+ output_dir / "TrapTags"
+ }
+ return (
+ {
+ str(d.relative_to(output_dir)): generated[d / "TrapEntries"]
+ for d in dirs
+ },
+ generated[output_dir / "TrapTags"],
+ )
return ret
@@ -65,87 +71,130 @@ def test_empty_tags(generate_tags):
def test_one_empty_table_rejected(generate_traps):
with pytest.raises(AssertionError):
- generate_traps([
- dbscheme.Table(name="foos", columns=[]),
- ])
+ generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[]),
+ ]
+ )
def test_one_table(generate_traps):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
- ]) == [
+ assert generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
+ ]
+ ) == [
cpp.Trap("foos", name="Foos", fields=[cpp.Field("bla", "int")]),
]
def test_one_table(generate_traps):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
- ]) == [
+ assert generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
+ ]
+ ) == [
cpp.Trap("foos", name="Foos", fields=[cpp.Field("bla", "int")]),
]
def test_one_table_with_id(generate_traps):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[
- dbscheme.Column("bla", "int", binding=True)]),
- ]) == [
- cpp.Trap("foos", name="Foos", fields=[cpp.Field(
- "bla", "int")], id=cpp.Field("bla", "int")),
+ assert generate_traps(
+ [
+ dbscheme.Table(
+ name="foos", columns=[dbscheme.Column("bla", "int", binding=True)]
+ ),
+ ]
+ ) == [
+ cpp.Trap(
+ "foos",
+ name="Foos",
+ fields=[cpp.Field("bla", "int")],
+ id=cpp.Field("bla", "int"),
+ ),
]
def test_one_table_with_two_binding_first_is_id(generate_traps):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[
- dbscheme.Column("x", "a", binding=True),
- dbscheme.Column("y", "b", binding=True),
- ]),
- ]) == [
- cpp.Trap("foos", name="Foos", fields=[
- cpp.Field("x", "a"),
- cpp.Field("y", "b"),
- ], id=cpp.Field("x", "a")),
+ assert generate_traps(
+ [
+ dbscheme.Table(
+ name="foos",
+ columns=[
+ dbscheme.Column("x", "a", binding=True),
+ dbscheme.Column("y", "b", binding=True),
+ ],
+ ),
+ ]
+ ) == [
+ cpp.Trap(
+ "foos",
+ name="Foos",
+ fields=[
+ cpp.Field("x", "a"),
+ cpp.Field("y", "b"),
+ ],
+ id=cpp.Field("x", "a"),
+ ),
]
-@pytest.mark.parametrize("column,field", [
- (dbscheme.Column("x", "string"), cpp.Field("x", "std::string")),
- (dbscheme.Column("y", "boolean"), cpp.Field("y", "bool")),
- (dbscheme.Column("z", "@db_type"), cpp.Field("z", "TrapLabel")),
-])
+@pytest.mark.parametrize(
+ "column,field",
+ [
+ (dbscheme.Column("x", "string"), cpp.Field("x", "std::string")),
+ (dbscheme.Column("y", "boolean"), cpp.Field("y", "bool")),
+ (dbscheme.Column("z", "@db_type"), cpp.Field("z", "TrapLabel")),
+ ],
+)
def test_one_table_special_types(generate_traps, column, field):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[column]),
- ]) == [
+ assert generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[column]),
+ ]
+ ) == [
cpp.Trap("foos", name="Foos", fields=[field]),
]
-@pytest.mark.parametrize("name", ["start_line", "start_column", "end_line", "end_column", "index", "num_whatever"])
+@pytest.mark.parametrize(
+ "name",
+ ["start_line", "start_column", "end_line", "end_column", "index", "num_whatever"],
+)
def test_one_table_overridden_unsigned_field(generate_traps, name):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[dbscheme.Column(name, "bar")]),
- ]) == [
+ assert generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[dbscheme.Column(name, "bar")]),
+ ]
+ ) == [
cpp.Trap("foos", name="Foos", fields=[cpp.Field(name, "unsigned")]),
]
def test_one_table_overridden_underscore_named_field(generate_traps):
- assert generate_traps([
- dbscheme.Table(name="foos", columns=[dbscheme.Column("whatever_", "bar")]),
- ]) == [
+ assert generate_traps(
+ [
+ dbscheme.Table(name="foos", columns=[dbscheme.Column("whatever_", "bar")]),
+ ]
+ ) == [
cpp.Trap("foos", name="Foos", fields=[cpp.Field("whatever", "bar")]),
]
def test_tables_with_dir(generate_grouped_traps):
- assert generate_grouped_traps([
- dbscheme.Table(name="x", columns=[dbscheme.Column("i", "int")]),
- dbscheme.Table(name="y", columns=[dbscheme.Column("i", "int")], dir=pathlib.Path("foo")),
- dbscheme.Table(name="z", columns=[dbscheme.Column("i", "int")], dir=pathlib.Path("foo/bar")),
- ]) == {
+ assert generate_grouped_traps(
+ [
+ dbscheme.Table(name="x", columns=[dbscheme.Column("i", "int")]),
+ dbscheme.Table(
+ name="y", columns=[dbscheme.Column("i", "int")], dir=pathlib.Path("foo")
+ ),
+ dbscheme.Table(
+ name="z",
+ columns=[dbscheme.Column("i", "int")],
+ dir=pathlib.Path("foo/bar"),
+ ),
+ ]
+ ) == {
".": [cpp.Trap("x", name="X", fields=[cpp.Field("i", "int")])],
"foo": [cpp.Trap("y", name="Y", fields=[cpp.Field("i", "int")])],
"foo/bar": [cpp.Trap("z", name="Z", fields=[cpp.Field("i", "int")])],
@@ -153,15 +202,22 @@ def test_tables_with_dir(generate_grouped_traps):
def test_one_table_no_tags(generate_tags):
- assert generate_tags([
- dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
- ]) == []
+ assert (
+ generate_tags(
+ [
+ dbscheme.Table(name="foos", columns=[dbscheme.Column("bla", "int")]),
+ ]
+ )
+ == []
+ )
def test_one_union_tags(generate_tags):
- assert generate_tags([
- dbscheme.Union(lhs="@left_hand_side", rhs=["@b", "@a", "@c"]),
- ]) == [
+ assert generate_tags(
+ [
+ dbscheme.Union(lhs="@left_hand_side", rhs=["@b", "@a", "@c"]),
+ ]
+ ) == [
cpp.Tag(name="LeftHandSide", bases=[], id="@left_hand_side"),
cpp.Tag(name="A", bases=["LeftHandSide"], id="@a"),
cpp.Tag(name="B", bases=["LeftHandSide"], id="@b"),
@@ -170,11 +226,13 @@ def test_one_union_tags(generate_tags):
def test_multiple_union_tags(generate_tags):
- assert generate_tags([
- dbscheme.Union(lhs="@d", rhs=["@a"]),
- dbscheme.Union(lhs="@a", rhs=["@b", "@c"]),
- dbscheme.Union(lhs="@e", rhs=["@c", "@f"]),
- ]) == [
+ assert generate_tags(
+ [
+ dbscheme.Union(lhs="@d", rhs=["@a"]),
+ dbscheme.Union(lhs="@a", rhs=["@b", "@c"]),
+ dbscheme.Union(lhs="@e", rhs=["@c", "@f"]),
+ ]
+ ) == [
cpp.Tag(name="D", bases=[], id="@d"),
cpp.Tag(name="E", bases=[], id="@e"),
cpp.Tag(name="A", bases=["D"], id="@a"),
@@ -184,5 +242,5 @@ def test_multiple_union_tags(generate_tags):
]
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff --git a/misc/codegen/test/utils.py b/misc/codegen/test/utils.py
index e33500711f25..094455d3d14d 100644
--- a/misc/codegen/test/utils.py
+++ b/misc/codegen/test/utils.py
@@ -39,8 +39,9 @@ def opts():
@pytest.fixture(autouse=True)
def override_paths(tmp_path):
- with mock.patch("misc.codegen.lib.paths.root_dir", tmp_path), \
- mock.patch("misc.codegen.lib.paths.exe_file", tmp_path / "exe"):
+ with mock.patch("misc.codegen.lib.paths.root_dir", tmp_path), mock.patch(
+ "misc.codegen.lib.paths.exe_file", tmp_path / "exe"
+ ):
yield
diff --git a/misc/scripts/models-as-data/bulk_generate_mad.py b/misc/scripts/models-as-data/bulk_generate_mad.py
old mode 100644
new mode 100755
index 22a872dc2bf2..a00dc31b05ef
--- a/misc/scripts/models-as-data/bulk_generate_mad.py
+++ b/misc/scripts/models-as-data/bulk_generate_mad.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
"""
Experimental script for bulk generation of MaD models based on a list of projects.
@@ -7,15 +8,31 @@
import os.path
import subprocess
import sys
-from typing import NotRequired, TypedDict, List
+from typing import Required, TypedDict, List, Callable, Optional
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
import argparse
-import json
-import requests
import zipfile
import tarfile
-from functools import cmp_to_key
+import shutil
+
+
+def missing_module(module_name: str) -> None:
+ print(
+ f"ERROR: {module_name} is not installed. Please install it with 'pip install {module_name}'."
+ )
+ sys.exit(1)
+
+
+try:
+ import yaml
+except ImportError:
+ missing_module("pyyaml")
+
+try:
+ import requests
+except ImportError:
+ missing_module("requests")
import generate_mad as mad
@@ -28,22 +45,18 @@
# A project to generate models for
-class Project(TypedDict):
- """
- Type definition for projects (acquired via a GitHub repo) to model.
-
- Attributes:
- name: The name of the project
- git_repo: URL to the git repository
- git_tag: Optional Git tag to check out
- """
-
- name: str
- git_repo: NotRequired[str]
- git_tag: NotRequired[str]
- with_sinks: NotRequired[bool]
- with_sinks: NotRequired[bool]
- with_summaries: NotRequired[bool]
+Project = TypedDict(
+ "Project",
+ {
+ "name": Required[str],
+ "git-repo": str,
+ "git-tag": str,
+ "with-sinks": bool,
+ "with-sources": bool,
+ "with-summaries": bool,
+ },
+ total=False,
+)
def should_generate_sinks(project: Project) -> bool:
@@ -63,14 +76,14 @@ def clone_project(project: Project) -> str:
Shallow clone a project into the build directory.
Args:
- project: A dictionary containing project information with 'name', 'git_repo', and optional 'git_tag' keys.
+ project: A dictionary containing project information with 'name', 'git-repo', and optional 'git-tag' keys.
Returns:
The path to the cloned project directory.
"""
name = project["name"]
- repo_url = project["git_repo"]
- git_tag = project.get("git_tag")
+ repo_url = project["git-repo"]
+ git_tag = project.get("git-tag")
# Determine target directory
target_dir = os.path.join(build_dir, name)
@@ -103,6 +116,39 @@ def clone_project(project: Project) -> str:
return target_dir
+def run_in_parallel[
+ T, U
+](
+ func: Callable[[T], U],
+ items: List[T],
+ *,
+ on_error=lambda item, exc: None,
+ error_summary=lambda failures: None,
+ max_workers=8,
+) -> List[Optional[U]]:
+ if not items:
+ return []
+ max_workers = min(max_workers, len(items))
+ results = [None for _ in range(len(items))]
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
+ # Start cloning tasks and keep track of them
+ futures = {
+ executor.submit(func, item): index for index, item in enumerate(items)
+ }
+ # Process results as they complete
+ for future in as_completed(futures):
+ index = futures[future]
+ try:
+ results[index] = future.result()
+ except Exception as e:
+ on_error(items[index], e)
+ failed = [item for item, result in zip(items, results) if result is None]
+ if failed:
+ error_summary(failed)
+ sys.exit(1)
+ return results
+
+
def clone_projects(projects: List[Project]) -> List[tuple[Project, str]]:
"""
Clone all projects in parallel.
@@ -114,40 +160,19 @@ def clone_projects(projects: List[Project]) -> List[tuple[Project, str]]:
List of (project, project_dir) pairs in the same order as the input projects
"""
start_time = time.time()
- max_workers = min(8, len(projects)) # Use at most 8 threads
- project_dirs_map = {} # Map to store results by project name
-
- with ThreadPoolExecutor(max_workers=max_workers) as executor:
- # Start cloning tasks and keep track of them
- future_to_project = {
- executor.submit(clone_project, project): project for project in projects
- }
-
- # Process results as they complete
- for future in as_completed(future_to_project):
- project = future_to_project[future]
- try:
- project_dir = future.result()
- project_dirs_map[project["name"]] = (project, project_dir)
- except Exception as e:
- print(f"ERROR: Failed to clone {project['name']}: {e}")
-
- if len(project_dirs_map) != len(projects):
- failed_projects = [
- project["name"]
- for project in projects
- if project["name"] not in project_dirs_map
- ]
- print(
- f"ERROR: Only {len(project_dirs_map)} out of {len(projects)} projects were cloned successfully. Failed projects: {', '.join(failed_projects)}"
- )
- sys.exit(1)
-
- project_dirs = [project_dirs_map[project["name"]] for project in projects]
-
+ dirs = run_in_parallel(
+ clone_project,
+ projects,
+ on_error=lambda project, exc: print(
+ f"ERROR: Failed to clone project {project['name']}: {exc}"
+ ),
+ error_summary=lambda failures: print(
+ f"ERROR: Failed to clone {len(failures)} projects: {', '.join(p['name'] for p in failures)}"
+ ),
+ )
clone_time = time.time() - start_time
print(f"Cloning completed in {clone_time:.2f} seconds")
- return project_dirs
+ return list(zip(projects, dirs))
def build_database(
@@ -159,7 +184,7 @@ def build_database(
Args:
language: The language for which to build the database (e.g., "rust").
extractor_options: Additional options for the extractor.
- project: A dictionary containing project information with 'name' and 'git_repo' keys.
+ project: A dictionary containing project information with 'name' and 'git-repo' keys.
project_dir: Path to the CodeQL database.
Returns:
@@ -200,7 +225,7 @@ def build_database(
return database_dir
-def generate_models(config, project: Project, database_dir: str) -> None:
+def generate_models(config, args, project: Project, database_dir: str) -> None:
"""
Generate models for a project.
@@ -218,6 +243,8 @@ def generate_models(config, project: Project, database_dir: str) -> None:
generator.generateSources = should_generate_sources(project)
generator.generateSummaries = should_generate_summaries(project)
generator.setenvironment(database=database_dir, folder=name)
+ generator.threads = args.codeql_threads
+ generator.ram = args.codeql_ram
generator.run()
@@ -307,35 +334,48 @@ def pretty_name_from_artifact_name(artifact_name: str) -> str:
def download_dca_databases(
- experiment_name: str, pat: str, projects: List[Project]
+ language: str,
+ experiment_names: list[str],
+ pat: str,
+ projects: List[Project],
) -> List[tuple[Project, str | None]]:
"""
Download databases from a DCA experiment.
Args:
- experiment_name: The name of the DCA experiment to download databases from.
+ experiment_names: The names of the DCA experiments to download databases from.
pat: Personal Access Token for GitHub API authentication.
projects: List of projects to download databases for.
Returns:
List of (project_name, database_dir) pairs, where database_dir is None if the download failed.
"""
- database_results = {}
print("\n=== Finding projects ===")
- response = get_json_from_github(
- f"https://raw.githubusercontent.com/github/codeql-dca-main/data/{experiment_name}/reports/downloads.json",
- pat,
- )
- targets = response["targets"]
project_map = {project["name"]: project for project in projects}
- for data in targets.values():
- downloads = data["downloads"]
- analyzed_database = downloads["analyzed_database"]
- artifact_name = analyzed_database["artifact_name"]
- pretty_name = pretty_name_from_artifact_name(artifact_name)
+ analyzed_databases = {}
+ for experiment_name in experiment_names:
+ response = get_json_from_github(
+ f"https://raw.githubusercontent.com/github/codeql-dca-main/data/{experiment_name}/reports/downloads.json",
+ pat,
+ )
+ targets = response["targets"]
+ for data in targets.values():
+ downloads = data["downloads"]
+ analyzed_database = downloads["analyzed_database"]
+ artifact_name = analyzed_database["artifact_name"]
+ pretty_name = pretty_name_from_artifact_name(artifact_name)
+
+ if not pretty_name in project_map:
+ print(f"Skipping {pretty_name} as it is not in the list of projects")
+ continue
+
+ if pretty_name in analyzed_databases:
+ print(
+ f"Skipping previous database {analyzed_databases[pretty_name]['artifact_name']} for {pretty_name}"
+ )
- if not pretty_name in project_map:
- print(f"Skipping {pretty_name} as it is not in the list of projects")
- continue
+ analyzed_databases[pretty_name] = analyzed_database
+ def download_and_decompress(analyzed_database: dict) -> str:
+ artifact_name = analyzed_database["artifact_name"]
repository = analyzed_database["repository"]
run_id = analyzed_database["run_id"]
print(f"=== Finding artifact: {artifact_name} ===")
@@ -351,27 +391,40 @@ def download_dca_databases(
artifact_zip_location = download_artifact(
archive_download_url, artifact_name, pat
)
- print(f"=== Extracting artifact: {artifact_name} ===")
+ print(f"=== Decompressing artifact: {artifact_name} ===")
# The database is in a zip file, which contains a tar.gz file with the DB
# First we open the zip file
with zipfile.ZipFile(artifact_zip_location, "r") as zip_ref:
artifact_unzipped_location = os.path.join(build_dir, artifact_name)
+ # clean up any remnants of previous runs
+ shutil.rmtree(artifact_unzipped_location, ignore_errors=True)
# And then we extract it to build_dir/artifact_name
zip_ref.extractall(artifact_unzipped_location)
- # And then we iterate over the contents of the extracted directory
- # and extract the tar.gz files inside it
- for entry in os.listdir(artifact_unzipped_location):
- artifact_tar_location = os.path.join(artifact_unzipped_location, entry)
- with tarfile.open(artifact_tar_location, "r:gz") as tar_ref:
- # And we just untar it to the same directory as the zip file
- tar_ref.extractall(artifact_unzipped_location)
- database_results[pretty_name] = os.path.join(
- artifact_unzipped_location, remove_extension(entry)
- )
+ # And then we extract the language tar.gz file inside it
+ artifact_tar_location = os.path.join(
+ artifact_unzipped_location, f"{language}.tar.gz"
+ )
+ with tarfile.open(artifact_tar_location, "r:gz") as tar_ref:
+ # And we just untar it to the same directory as the zip file
+ tar_ref.extractall(artifact_unzipped_location)
+ ret = os.path.join(artifact_unzipped_location, language)
+ print(f"Decompression complete: {ret}")
+ return ret
+
+ results = run_in_parallel(
+ download_and_decompress,
+ list(analyzed_databases.values()),
+ on_error=lambda db, exc: print(
+ f"ERROR: Failed to download and decompress {db["artifact_name"]}: {exc}"
+ ),
+ error_summary=lambda failures: print(
+ f"ERROR: Failed to download {len(failures)} databases: {', '.join(item[0] for item in failures)}"
+ ),
+ )
- print(f"\n=== Extracted {len(database_results)} databases ===")
+ print(f"\n=== Fetched {len(results)} databases ===")
- return [(project, database_results[project["name"]]) for project in projects]
+ return [(project_map[n], r) for n, r in zip(analyzed_databases, results)]
def get_mad_destination_for_project(config, name: str) -> str:
@@ -400,33 +453,18 @@ def main(config, args) -> None:
if not os.path.exists(build_dir):
os.makedirs(build_dir)
- # Check if any of the MaD directories contain working directory changes in git
- for project in projects:
- mad_dir = get_mad_destination_for_project(config, project["name"])
- if os.path.exists(mad_dir):
- git_status_output = subprocess.check_output(
- ["git", "status", "-s", mad_dir], text=True
- ).strip()
- if git_status_output:
- print(
- f"""ERROR: Working directory changes detected in {mad_dir}.
-
-Before generating new models, the existing models are deleted.
-
-To avoid loss of data, please commit your changes."""
- )
- sys.exit(1)
-
database_results = []
match get_strategy(config):
case "repo":
extractor_options = config.get("extractor_options", [])
database_results = build_databases_from_projects(
- language, extractor_options, projects
+ language,
+ extractor_options,
+ projects,
)
case "dca":
- experiment_name = args.dca
- if experiment_name is None:
+ experiment_names = args.dca
+ if experiment_names is None:
print("ERROR: --dca argument is required for DCA strategy")
sys.exit(1)
@@ -439,7 +477,10 @@ def main(config, args) -> None:
with open(args.pat, "r") as f:
pat = f.read().strip()
database_results = download_dca_databases(
- experiment_name, pat, projects
+ language,
+ experiment_names,
+ pat,
+ projects,
)
# Generate models for all projects
@@ -463,7 +504,7 @@ def main(config, args) -> None:
for project, database_dir in database_results:
if database_dir is not None:
- generate_models(config, project, database_dir)
+ generate_models(config, args, project, database_dir)
if __name__ == "__main__":
@@ -474,14 +515,26 @@ def main(config, args) -> None:
parser.add_argument(
"--dca",
type=str,
- help="Name of a DCA run that built all the projects",
- required=False,
+ help="Name of a DCA run that built all the projects. Can be repeated, with sources taken from all provided runs, "
+ "the last provided ones having priority",
+ action="append",
)
parser.add_argument(
"--pat",
type=str,
help="Path to a file containing the PAT token required to grab DCA databases (the same as the one you use for DCA)",
- required=False,
+ )
+ parser.add_argument(
+ "--codeql-ram",
+ type=int,
+ help="What `--ram` value to pass to `codeql` while generating models (by default the flag is not passed)",
+ default=None,
+ )
+ parser.add_argument(
+ "--codeql-threads",
+ type=int,
+ help="What `--threads` value to pass to `codeql` (default %(default)s)",
+ default=0,
)
args = parser.parse_args()
@@ -492,9 +545,9 @@ def main(config, args) -> None:
sys.exit(1)
try:
with open(args.config, "r") as f:
- config = json.load(f)
- except json.JSONDecodeError as e:
- print(f"ERROR: Failed to parse JSON file {args.config}: {e}")
+ config = yaml.safe_load(f)
+ except yaml.YAMLError as e:
+ print(f"ERROR: Failed to parse YAML file {args.config}: {e}")
sys.exit(1)
main(config, args)
diff --git a/misc/scripts/models-as-data/generate_mad.py b/misc/scripts/models-as-data/generate_mad.py
index a5f8ffc8fa05..818721ed43b6 100755
--- a/misc/scripts/models-as-data/generate_mad.py
+++ b/misc/scripts/models-as-data/generate_mad.py
@@ -62,6 +62,8 @@ def __init__(self, language):
self.generateTypeBasedSummaries = False
self.dryRun = False
self.dirname = "modelgenerator"
+ self.ram = 2**15
+ self.threads = 8
def setenvironment(self, database, folder):
@@ -138,8 +140,12 @@ def runQuery(self, query):
queryFile = os.path.join(self.codeQlRoot, f"{self.language}/ql/src/utils/{self.dirname}", query)
resultBqrs = os.path.join(self.workDir, "out.bqrs")
- helpers.run_cmd(['codeql', 'query', 'run', queryFile, '--database',
- self.database, '--output', resultBqrs, '--threads', '8', '--ram', '32768'], "Failed to generate " + query)
+ cmd = ['codeql', 'query', 'run', queryFile, '--database', self.database, '--output', resultBqrs]
+ if self.threads is not None:
+ cmd += ["--threads", str(self.threads)]
+ if self.ram is not None:
+ cmd += ["--ram", str(self.ram)]
+ helpers.run_cmd(cmd, "Failed to generate " + query)
return helpers.readData(self.workDir, resultBqrs)
@@ -214,4 +220,4 @@ def run(self):
self.save(typeBasedContent, ".typebased.model.yml")
if __name__ == '__main__':
- Generator.make().run()
\ No newline at end of file
+ Generator.make().run()
diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml
index 3ee266732fb6..848e808db344 100644
--- a/misc/suite-helpers/qlpack.yml
+++ b/misc/suite-helpers/qlpack.yml
@@ -1,4 +1,4 @@
name: codeql/suite-helpers
-version: 1.0.25
+version: 1.0.26-dev
groups: shared
warnOnImplicitThis: true
diff --git a/python/ql/integration-tests/query-suite/python-code-quality.qls.expected b/python/ql/integration-tests/query-suite/python-code-quality.qls.expected
index b81d300d0241..c2168cab937b 100644
--- a/python/ql/integration-tests/query-suite/python-code-quality.qls.expected
+++ b/python/ql/integration-tests/query-suite/python-code-quality.qls.expected
@@ -1,3 +1,4 @@
+ql/python/ql/src/Functions/IterReturnsNonSelf.ql
ql/python/ql/src/Functions/NonCls.ql
ql/python/ql/src/Functions/NonSelf.ql
ql/python/ql/src/Functions/ReturnConsistentTupleSizes.ql
diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml
index 4b1d284def3b..ffd394c25441 100644
--- a/python/ql/lib/qlpack.yml
+++ b/python/ql/lib/qlpack.yml
@@ -1,5 +1,5 @@
name: codeql/python-all
-version: 4.0.9
+version: 4.0.10-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python
diff --git a/python/ql/src/Functions/IterReturnsNonSelf.qhelp b/python/ql/src/Functions/IterReturnsNonSelf.qhelp
index f614d912ff0a..0ad5a05fdf48 100644
--- a/python/ql/src/Functions/IterReturnsNonSelf.qhelp
+++ b/python/ql/src/Functions/IterReturnsNonSelf.qhelp
@@ -3,34 +3,27 @@
"qhelp.dtd">
-
The __iter__ method of an iterator should return self.
-This is important so that iterators can be used as sequences in any context
-that expect a sequence. To do so requires that __iter__ is
-idempotent on iterators.
-
-
-Note that sequences and mapping should return a new iterator, it is just the returned
-iterator that must obey this constraint.
+
Iterator classes (classes defining a __next__ method) should have an __iter__ method that returns the iterator itself.
+This ensures that the object is also an iterable; and behaves as expected when used anywhere an iterator or iterable is expected, such as in for loops.
+
+
-
Make the __iter__ return self unless the class should not be an iterator,
-in which case rename the next (Python 2) or __next__ (Python 3)
-to something else.
+
Ensure that the __iter__ method returns self, or is otherwise equivalent as an iterator to self.
-
In this example the Counter class's __iter__ method does not
-return self (or even an iterator). This will cause the program to fail when anyone attempts
-to use the iterator in a for loop or in statement.
-
+
In the following example, the MyRange class's __iter__ method does not return self.
+This would lead to unexpected results when used with a for loop or in statement.