diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml
index f80864ed0199..e701090420dc 100644
--- a/.github/workflows/check-change-note.yml
+++ b/.github/workflows/check-change-note.yml
@@ -9,6 +9,8 @@ on:
- "*/ql/lib/**/*.ql"
- "*/ql/lib/**/*.qll"
- "*/ql/lib/**/*.yml"
+ - "shared/**/*.ql"
+ - "shared/**/*.qll"
- "!**/experimental/**"
- "!ql/**"
- ".github/workflows/check-change-note.yml"
diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml
index 1dc62c49caff..542a230446f9 100644
--- a/.github/workflows/csharp-qltest.yml
+++ b/.github/workflows/csharp-qltest.yml
@@ -91,7 +91,7 @@ jobs:
run: |
# Generate (Asp)NetCore stubs
STUBS_PATH=stubs_output
- python3 ql/src/Stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH"
+ python3 scripts/stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH"
rm -rf ql/test/resources/stubs/_frameworks
# Update existing stubs in the repo with the freshly generated ones
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/
diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml
index 48c55b2a6301..8e2df456260f 100644
--- a/.github/workflows/csv-coverage-pr-artifacts.yml
+++ b/.github/workflows/csv-coverage-pr-artifacts.yml
@@ -89,9 +89,32 @@ jobs:
- name: Save PR number
run: |
mkdir -p pr
- echo ${{ github.event.pull_request.number }} > pr/NR
+ echo ${PR_NUMBER} > pr/NR
+ env:
+ PR_NUMBER: ${{ github.event.pull_request.number }}
- name: Upload PR number
uses: actions/upload-artifact@v3
with:
name: pr
path: pr/
+ - name: Save comment ID (if it exists)
+ run: |
+ # Find the latest comment starting with COMMENT_PREFIX
+ COMMENT_PREFIX=":warning: The head of this PR and the base branch were compared for differences in the framework coverage reports."
+ COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" --paginate | jq --arg prefix "${COMMENT_PREFIX}" 'map(select(.body|startswith($prefix)) | .id) | max // empty')
+ if [[ -z ${COMMENT_ID} ]]
+ then
+ echo "Comment not found. Not uploading 'comment/ID' artifact."
+ else
+ mkdir -p comment
+ echo ${COMMENT_ID} > comment/ID
+ fi
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ - name: Upload comment ID (if it exists)
+ uses: actions/upload-artifact@v3
+ with:
+ name: comment
+ path: comment/
+ if-no-files-found: ignore
diff --git a/codeql-workspace.yml b/codeql-workspace.yml
index 2d86498cbeae..03f5866a0c28 100644
--- a/codeql-workspace.yml
+++ b/codeql-workspace.yml
@@ -6,7 +6,7 @@ provide:
- "*/ql/consistency-queries/qlpack.yml"
- "*/ql/automodel/src/qlpack.yml"
- "*/ql/automodel/test/qlpack.yml"
- - "shared/*/qlpack.yml"
+ - "shared/**/qlpack.yml"
- "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml"
- "go/ql/config/legacy-support/qlpack.yml"
- "go/build/codeql-extractor-go/codeql-extractor.yml"
diff --git a/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme
new file mode 100644
index 000000000000..f79ce79e3b75
--- /dev/null
+++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme
@@ -0,0 +1,2226 @@
+
+/**
+ * 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
+);
+
+/**
+ * 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
+;
+*/
+
+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,
+ int handle: @variable ref,
+ int promise: @variable 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);
+
+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
+);
+
+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_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable 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
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default 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: @functionorblock 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. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this 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.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @usertype.kind of
+ 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+| 5 = @typedef // classic C: typedef typedef type name
+| 6 = @template
+| 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 // a using name = type style typedef
+;
+*/
+
+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
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+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
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype 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
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int 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
+);
+
+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
+;
+
+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_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
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+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;
+
+@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
+ ;
+
+/*
+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
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ 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
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * 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
+);
+
+/*
+ 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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+);
+
+@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
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_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
+;
+
+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
+);
+
+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
+);
+
+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
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_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
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock 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
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+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(
+ unique 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/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..5b388693c66d
--- /dev/null
+++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme
@@ -0,0 +1,2221 @@
+
+/**
+ * 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
+);
+
+/**
+ * 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
+ */
+
+@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
+;
+*/
+
+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,
+ int handle: @variable ref,
+ int promise: @variable 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);
+
+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
+);
+
+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_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable 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
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default 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: @functionorblock 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. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this 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.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @usertype.kind of
+ 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+| 5 = @typedef // classic C: typedef typedef type name
+| 6 = @template
+| 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 // a using name = type style typedef
+;
+*/
+
+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
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+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
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype 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
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int 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
+);
+
+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
+;
+
+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_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
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+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;
+
+@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
+ ;
+
+/*
+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
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ 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
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * 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
+);
+
+/*
+ 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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+);
+
+@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
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_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
+;
+
+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
+);
+
+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
+);
+
+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
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_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
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock 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
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+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(
+ unique 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/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties
new file mode 100644
index 000000000000..2e93d8c4306f
--- /dev/null
+++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties
@@ -0,0 +1,3 @@
+description: Introduce extractor version numbers
+compatibility: breaking
+extractor_version.rel: delete
diff --git a/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md b/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md
new file mode 100644
index 000000000000..f2b168949a6a
--- /dev/null
+++ b/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md
@@ -0,0 +1,4 @@
+---
+category: breaking
+---
+* The `Container` and `Folder` classes now derive from `ElementBase` instead of `Locatable`, and no longer expose the `getLocation` predicate. Use `getURL` instead.
diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml
index cb5488af594a..06ce6589b7b6 100644
--- a/cpp/ql/lib/qlpack.yml
+++ b/cpp/ql/lib/qlpack.yml
@@ -7,6 +7,7 @@ library: true
upgrades: upgrades
dependencies:
codeql/dataflow: ${workspace}
+ codeql/rangeanalysis: ${workspace}
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll
index 55ecd2b46e36..950368bf984a 100644
--- a/cpp/ql/lib/semmle/code/cpp/File.qll
+++ b/cpp/ql/lib/semmle/code/cpp/File.qll
@@ -32,7 +32,7 @@ private module Input implements InputSig {
private module Impl = Make;
/** A file or folder. */
-class Container extends Locatable, Impl::Container {
+class Container extends ElementBase, Impl::Container {
override string toString() { result = Impl::Container.super.toString() }
}
@@ -47,11 +47,6 @@ class Container extends Locatable, Impl::Container {
* To get the full path, use `getAbsolutePath`.
*/
class Folder extends Container, Impl::Folder {
- override Location getLocation() {
- result.getContainer() = this and
- result.hasLocationInfo(_, 0, 0, 0, 0)
- }
-
override string getAPrimaryQlClass() { result = "Folder" }
}
@@ -67,7 +62,7 @@ class Folder extends Container, Impl::Folder {
* The base name further decomposes into the _stem_ and _extension_ -- see
* `getStem` and `getExtension`. To get the full path, use `getAbsolutePath`.
*/
-class File extends Container, Impl::File {
+class File extends Container, Locatable, Impl::File {
override string getAPrimaryQlClass() { result = "File" }
override Location getLocation() {
diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll b/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll
new file mode 100644
index 000000000000..859f0375b364
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll
@@ -0,0 +1,15 @@
+/**
+ * INTERNAL: Do not use. Provides predicates for getting the CodeQL and frontend
+ * version used during database extraction.
+ */
+
+/** Get the extractor CodeQL version */
+string getExtractorCodeQLVersion() { extractor_version(result, _) }
+
+/** Get the extractor frontend version */
+string getExtractorFrontendVersion() { extractor_version(_, result) }
+
+predicate isExtractorFrontendVersion65OrHigher() {
+ // Version numbers we not included in the database before 6.5.
+ exists(getExtractorCodeQLVersion())
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
index cc2a0b01c4d4..055f48c80ec8 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll
@@ -32,25 +32,34 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
}
/**
- * Gets the instruction that holds the `output` for `call`.
+ * Gets the node that represents the output of `call` with kind `output` at
+ * indirection index `indirectionIndex`.
*/
-Node callOutput(CallInstruction call, FunctionOutput output) {
+private Node callOutputWithIndirectionIndex(
+ CallInstruction call, FunctionOutput output, int indirectionIndex
+) {
// The return value
simpleOutNode(result, call) and
- output.isReturnValue()
+ output.isReturnValue() and
+ indirectionIndex = 0
or
// The side effect of a call on the value pointed to by an argument or qualifier
- exists(int index, int indirectionIndex |
+ exists(int index |
result.(IndirectArgumentOutNode).getArgumentIndex() = index and
- result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex and
+ result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex - 1 and
result.(IndirectArgumentOutNode).getCallInstruction() = call and
- output.isParameterDerefOrQualifierObject(index, indirectionIndex)
+ output.isParameterDerefOrQualifierObject(index, indirectionIndex - 1)
)
or
- exists(int ind |
- result = getIndirectReturnOutNode(call, ind) and
- output.isReturnValueDeref(ind)
- )
+ result = getIndirectReturnOutNode(call, indirectionIndex) and
+ output.isReturnValueDeref(indirectionIndex)
+}
+
+/**
+ * Gets the instruction that holds the `output` for `call`.
+ */
+Node callOutput(CallInstruction call, FunctionOutput output) {
+ result = callOutputWithIndirectionIndex(call, output, _)
}
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
@@ -76,19 +85,15 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
*/
bindingset[d]
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
- exists(DataFlow::Node n | n = callOutput(call, output) and d > 0 |
+ exists(DataFlow::Node n, int indirectionIndex |
+ n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
+ |
// The return value
- result = getIndirectReturnOutNode(n.asInstruction(), d)
+ result = callOutputWithIndirectionIndex(call, output, indirectionIndex + d)
or
// If there isn't an indirect out node for the call with indirection `d` then
// we conflate this with the underlying `CallInstruction`.
- not exists(getIndirectReturnOutNode(call, d)) and
+ not exists(getIndirectReturnOutNode(call, indirectionIndex + d)) and
n = result
- or
- // The side effect of a call on the value pointed to by an argument or qualifier
- exists(Operand operand, int indirectionIndex |
- Ssa::outNodeHasAddressAndIndex(n, operand, indirectionIndex) and
- Ssa::outNodeHasAddressAndIndex(result, operand, indirectionIndex + d)
- )
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
index 8d9156502665..fc718693dbdf 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll
@@ -228,7 +228,7 @@ private class PointerWrapperTypeIndirection extends Indirection instanceof Point
override predicate isAdditionalDereference(Instruction deref, Operand address) {
exists(CallInstruction call |
operandForFullyConvertedCall(getAUse(deref), call) and
- this = call.getStaticCallTarget().getClassAndName("operator*") and
+ this = call.getStaticCallTarget().getClassAndName(["operator*", "operator->", "get"]) and
address = call.getThisArgumentOperand()
)
}
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
index 03ef716f4f06..a0967ed9a774 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll
@@ -1,5 +1,6 @@
private import cpp
import semmle.code.cpp.ir.implementation.raw.IR
+private import semmle.code.cpp.internal.ExtractorVersion
private import semmle.code.cpp.ir.IRConfiguration
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -362,10 +363,10 @@ predicate ignoreLoad(Expr expr) {
expr instanceof FunctionAccess
or
// The load is duplicated from the operand.
- expr instanceof ParenthesisExpr
+ isExtractorFrontendVersion65OrHigher() and expr instanceof ParenthesisExpr
or
// The load is duplicated from the right operand.
- expr instanceof CommaExpr
+ isExtractorFrontendVersion65OrHigher() and expr instanceof CommaExpr
or
expr.(PointerDereferenceExpr).getOperand().getFullyConverted().getType().getUnspecifiedType()
instanceof FunctionPointerType
diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
index 2a62d4f1219d..f06579fc4368 100644
--- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
+++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll
@@ -1,4 +1,5 @@
private import cpp
+private import semmle.code.cpp.internal.ExtractorVersion
private import semmle.code.cpp.ir.implementation.IRType
private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -648,7 +649,21 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
class TranslatedPrefixCrementOperation extends TranslatedCrementOperation {
override PrefixCrementOperation expr;
- override Instruction getResult() { result = this.getUnloadedOperand().getResult() }
+ override Instruction getResult() {
+ // The following distinction is needed to work around extractor limitations
+ // in old versions of the extractor.
+ if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher()
+ then
+ // If this is C, then the result of a prefix crement is a prvalue for the
+ // new value assigned to the operand. If this is C++, then the result is
+ // an lvalue, but that lvalue is being loaded as part of this expression.
+ // EDG doesn't mark this as a load.
+ result = this.getInstruction(CrementOpTag())
+ else
+ // This is C++, where the result is an lvalue for the operand, and that
+ // lvalue is not being loaded as part of this expression.
+ result = this.getUnloadedOperand().getResult()
+ }
}
class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
@@ -1491,7 +1506,21 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
result = this.getRightOperand().getFirstInstruction()
}
- final override Instruction getResult() { result = this.getLeftOperand().getResult() }
+ final override Instruction getResult() {
+ // The following distinction is needed to work around extractor limitations
+ // in old versions of the extractor.
+ if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher()
+ then
+ // If this is C, then the result of an assignment is a prvalue for the new
+ // value assigned to the left operand. If this is C++, then the result is
+ // an lvalue, but that lvalue is being loaded as part of this expression.
+ // EDG doesn't mark this as a load.
+ result = this.getRightOperand().getResult()
+ else
+ // This is C++, where the result is an lvalue for the left operand,
+ // and that lvalue is not being loaded as part of this expression.
+ result = this.getLeftOperand().getResult()
+ }
final TranslatedExpr getLeftOperand() {
result = getTranslatedExpr(expr.getLValue().getFullyConverted())
@@ -1617,7 +1646,21 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
result = this.getRightOperand().getFirstInstruction()
}
- final override Instruction getResult() { result = this.getUnloadedLeftOperand().getResult() }
+ final override Instruction getResult() {
+ // The following distinction is needed to work around extractor limitations
+ // in old versions of the extractor.
+ if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher()
+ then
+ // If this is C, then the result of an assignment is a prvalue for the new
+ // value assigned to the left operand. If this is C++, then the result is
+ // an lvalue, but that lvalue is being loaded as part of this expression.
+ // EDG doesn't mark this as a load.
+ result = this.getStoredValue()
+ else
+ // This is C++, where the result is an lvalue for the left operand,
+ // and that lvalue is not being loaded as part of this expression.
+ result = this.getUnloadedLeftOperand().getResult()
+ }
final TranslatedExpr getUnloadedLeftOperand() {
result = this.getLoadedLeftOperand().getOperand()
@@ -2155,15 +2198,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
not this.elseIsVoid() and tag = ConditionValueFalseStoreTag()
) and
opcode instanceof Opcode::Store and
- (
+ if isExtractorFrontendVersion65OrHigher()
+ then
not expr.hasLValueToRValueConversion() and
resultType = this.getResultType()
or
expr.hasLValueToRValueConversion() and
resultType = getTypeForPRValue(expr.getType())
- )
+ else resultType = this.getResultType()
or
- not expr.hasLValueToRValueConversion() and
+ (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and
tag = ConditionValueResultLoadTag() and
opcode instanceof Opcode::Load and
resultType = this.getResultType()
@@ -2193,15 +2237,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
)
or
tag = ConditionValueResultTempAddressTag() and
- (
+ if isExtractorFrontendVersion65OrHigher()
+ then
not expr.hasLValueToRValueConversion() and
result = this.getInstruction(ConditionValueResultLoadTag())
or
expr.hasLValueToRValueConversion() and
result = this.getParent().getChildSuccessor(this)
- )
+ else result = this.getInstruction(ConditionValueResultLoadTag())
or
- not expr.hasLValueToRValueConversion() and
+ (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and
tag = ConditionValueResultLoadTag() and
result = this.getParent().getChildSuccessor(this)
)
@@ -2230,7 +2275,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
result = this.getElse().getResult()
)
or
- not expr.hasLValueToRValueConversion() and
+ (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and
tag = ConditionValueResultLoadTag() and
operandTag instanceof AddressOperandTag and
result = this.getInstruction(ConditionValueResultTempAddressTag())
@@ -2240,13 +2285,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
not this.resultIsVoid() and
tag = ConditionValueTempVar() and
- (
+ if isExtractorFrontendVersion65OrHigher()
+ then
not expr.hasLValueToRValueConversion() and
type = this.getResultType()
or
expr.hasLValueToRValueConversion() and
type = getTypeForPRValue(expr.getType())
- )
+ else type = this.getResultType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
@@ -2261,13 +2307,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
final override Instruction getResult() {
not this.resultIsVoid() and
- (
+ if isExtractorFrontendVersion65OrHigher()
+ then
expr.hasLValueToRValueConversion() and
result = this.getInstruction(ConditionValueResultTempAddressTag())
or
not expr.hasLValueToRValueConversion() and
result = this.getInstruction(ConditionValueResultLoadTag())
- )
+ else result = this.getInstruction(ConditionValueResultLoadTag())
}
override Instruction getChildSuccessor(TranslatedElement child) {
@@ -3226,9 +3273,19 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) {
(
expr instanceof AssignExpr
or
- expr instanceof AssignOperation
+ expr instanceof AssignOperation and
+ (
+ not expr.isPRValueCategory() // is C++
+ or
+ isExtractorFrontendVersion65OrHigher()
+ )
or
- expr instanceof PrefixCrementOperation
+ expr instanceof PrefixCrementOperation and
+ (
+ not expr.isPRValueCategory() // is C++
+ or
+ isExtractorFrontendVersion65OrHigher()
+ )
or
// Because the load is on the `e` in `e++`.
expr instanceof PostfixCrementOperation
diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
index 1318fd37b7fa..6a99a7e342b3 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll
@@ -19,6 +19,7 @@ private import implementations.Strtok
private import implementations.Strset
private import implementations.Strcrement
private import implementations.Strnextc
+private import implementations.Strtol
private import implementations.StdContainer
private import implementations.StdPair
private import implementations.StdMap
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
index 41bd9ae0db7b..915bcbce6556 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll
@@ -13,7 +13,7 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
PureStrFunction() {
this.hasGlobalOrStdOrBslName([
atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr",
- "strspn", strtol(), strrev(), strcmp(), strlwr(), strupr()
+ "strspn", strrev(), strcmp(), strlwr(), strupr()
])
}
@@ -70,8 +70,6 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
private string atoi() { result = ["atof", "atoi", "atol", "atoll"] }
-private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] }
-
private string strlwr() {
result = ["_strlwr", "_wcslwr", "_mbslwr", "_strlwr_l", "_wcslwr_l", "_mbslwr_l"]
}
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll
index f2759e4a7378..6ccc4eb2fbe1 100644
--- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll
@@ -32,6 +32,8 @@ private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEf
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReturnValue()
+ or
+ input.isParameterDeref(0) and output.isReturnValueDeref()
}
override predicate hasOnlySpecificReadSideEffects() { none() }
diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll
new file mode 100644
index 000000000000..30e95622924d
--- /dev/null
+++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll
@@ -0,0 +1,54 @@
+import semmle.code.cpp.models.interfaces.ArrayFunction
+import semmle.code.cpp.models.interfaces.Taint
+import semmle.code.cpp.models.interfaces.Alias
+import semmle.code.cpp.models.interfaces.SideEffect
+
+private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] }
+
+/**
+ * The standard function `strtol` and its assorted variants
+ */
+private class Strtol extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction {
+ Strtol() { this.hasGlobalOrStdOrBslName(strtol()) }
+
+ override predicate hasArrayInput(int bufParam) {
+ // All the functions given by `strtol()` takes a `const char*` input as the first parameter
+ bufParam = 0
+ }
+
+ override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 }
+
+ override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
+ (
+ input.isParameter(0)
+ or
+ input.isParameterDeref(0)
+ ) and
+ output.isReturnValue()
+ or
+ input.isParameter(0) and
+ output.isParameterDeref(1)
+ }
+
+ override predicate parameterNeverEscapes(int i) {
+ // Parameter 0 does escape into parameter 1.
+ i = 1
+ }
+
+ override predicate parameterEscapesOnlyViaReturn(int i) { none() }
+
+ override predicate parameterIsAlwaysReturned(int i) { none() }
+
+ override predicate hasOnlySpecificReadSideEffects() { any() }
+
+ override predicate hasOnlySpecificWriteSideEffects() { any() }
+
+ override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
+ i = 0 and
+ buffer = true
+ }
+
+ override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
+ i = 1 and buffer = false and mustWrite = false
+ }
+}
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll
index 328f85151b58..0e801fb75c37 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll
@@ -8,6 +8,18 @@ class SemLocation instanceof Location {
*/
string toString() { result = super.toString() }
+ /** Gets the 1-based line number (inclusive) where this location starts. */
+ int getStartLine() { result = super.getStartLine() }
+
+ /** Gets the 1-based column number (inclusive) where this location starts. */
+ int getStartColumn() { result = super.getStartColumn() }
+
+ /** Gets the 1-based line number (inclusive) where this location ends. */
+ int getEndLine() { result = super.getEndLine() }
+
+ /** Gets the 1-based column number (inclusive) where this location ends. */
+ int getEndColumn() { result = super.getEndColumn() }
+
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll
index 8767c53aa195..2cdeb9544ab7 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll
@@ -1,5 +1,7 @@
-private import RangeAnalysisStage
private import RangeAnalysisImpl
+private import codeql.rangeanalysis.RangeAnalysis
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType
module FloatDelta implements DeltaSig {
class Delta = float;
@@ -20,7 +22,7 @@ module FloatDelta implements DeltaSig {
Delta fromFloat(float f) { result = f }
}
-module FloatOverflow implements OverflowSig {
+module FloatOverflow implements OverflowSig {
predicate semExprDoesNotOverflow(boolean positively, SemExpr expr) {
exists(float lb, float ub, float delta |
typeBounds(expr.getSemType(), lb, ub) and
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll
deleted file mode 100644
index 83698b56229c..000000000000
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll
+++ /dev/null
@@ -1,29 +0,0 @@
-private import RangeAnalysisStage
-
-module IntDelta implements DeltaSig {
- class Delta = int;
-
- bindingset[d]
- bindingset[result]
- float toFloat(Delta d) { result = d }
-
- bindingset[d]
- bindingset[result]
- int toInt(Delta d) { result = d }
-
- bindingset[n]
- bindingset[result]
- Delta fromInt(int n) { result = n }
-
- bindingset[f]
- Delta fromFloat(float f) {
- result =
- min(float diff, float res |
- diff = (res - f) and res = f.ceil()
- or
- diff = (f - res) and res = f.floor()
- |
- res order by diff
- )
- }
-}
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll
index 9b00aca362f1..c53b0b85eb2a 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll
@@ -12,11 +12,13 @@
private import ModulusAnalysisSpecific::Private
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
private import ConstantAnalysis
private import RangeUtils
-private import RangeAnalysisStage
+private import codeql.rangeanalysis.RangeAnalysis
+private import RangeAnalysisImpl
-module ModulusAnalysis Bounds, UtilSig U> {
+module ModulusAnalysis Bounds, UtilSig U> {
pragma[nomagic]
private predicate valueFlowStepSsaEqFlowCond(
SemSsaReadPosition pos, SemSsaVariable v, SemExpr e, int delta
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll
index 42edb904c3f4..fc729766d2da 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll
@@ -3,10 +3,11 @@
*/
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
-private import RangeAnalysisStage
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
+private import RangeAnalysisImpl
+private import codeql.rangeanalysis.RangeAnalysis
-module CppLangImplConstant implements LangSig {
+module CppLangImplConstant implements LangSig {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll
index 938857c0c2de..cbbd5d092bbb 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll
@@ -1,13 +1,104 @@
-private import RangeAnalysisStage
private import RangeAnalysisConstantSpecific
private import RangeAnalysisRelativeSpecific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
private import RangeUtils
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticGuard
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound as SemanticBound
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticSSA
+private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType as SemanticType
+private import SemanticType
+private import codeql.rangeanalysis.RangeAnalysis
+private import ConstantAnalysis as ConstantAnalysis
-module ConstantBounds implements BoundSig {
+module Sem implements Semantic {
+ class Expr = SemExpr;
+
+ class ConstantIntegerExpr = ConstantAnalysis::SemConstantIntegerExpr;
+
+ class BinaryExpr = SemBinaryExpr;
+
+ class AddExpr = SemAddExpr;
+
+ class SubExpr = SemSubExpr;
+
+ class MulExpr = SemMulExpr;
+
+ class DivExpr = SemDivExpr;
+
+ class RemExpr = SemRemExpr;
+
+ class BitAndExpr = SemBitAndExpr;
+
+ class BitOrExpr = SemBitOrExpr;
+
+ class ShiftLeftExpr = SemShiftLeftExpr;
+
+ class ShiftRightExpr = SemShiftRightExpr;
+
+ class ShiftRightUnsignedExpr = SemShiftRightUnsignedExpr;
+
+ class RelationalExpr = SemRelationalExpr;
+
+ class UnaryExpr = SemUnaryExpr;
+
+ class ConvertExpr = SemConvertExpr;
+
+ class BoxExpr = SemBoxExpr;
+
+ class UnboxExpr = SemUnboxExpr;
+
+ class NegateExpr = SemNegateExpr;
+
+ class AddOneExpr = SemAddOneExpr;
+
+ class SubOneExpr = SemSubOneExpr;
+
+ class ConditionalExpr = SemConditionalExpr;
+
+ class BasicBlock = SemBasicBlock;
+
+ class Guard = SemGuard;
+
+ predicate implies_v2 = semImplies_v2/4;
+
+ predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3;
+
+ class Type = SemType;
+
+ class IntegerType = SemIntegerType;
+
+ class FloatingPointType = SemFloatingPointType;
+
+ class AddressType = SemAddressType;
+
+ class SsaVariable = SemSsaVariable;
+
+ class SsaPhiNode = SemSsaPhiNode;
+
+ class SsaExplicitUpdate = SemSsaExplicitUpdate;
+
+ class SsaReadPosition = SemSsaReadPosition;
+
+ class SsaReadPositionPhiInputEdge = SemSsaReadPositionPhiInputEdge;
+
+ class SsaReadPositionBlock = SemSsaReadPositionBlock;
+
+ predicate backEdge = semBackEdge/3;
+
+ predicate conversionCannotOverflow(Type fromType, Type toType) {
+ SemanticType::conversionCannotOverflow(fromType, toType)
+ }
+}
+
+module SignAnalysis implements SignAnalysisSig {
+ private import SignAnalysisCommon as SA
+ import SA::SignAnalysis
+}
+
+module ConstantBounds implements BoundSig {
class SemBound instanceof SemanticBound::SemBound {
SemBound() {
this instanceof SemanticBound::SemZeroBound
@@ -29,7 +120,7 @@ module ConstantBounds implements BoundSig {
}
}
-module RelativeBounds implements BoundSig {
+module RelativeBounds implements BoundSig {
class SemBound instanceof SemanticBound::SemBound {
SemBound() { not this instanceof SemanticBound::SemZeroBound }
@@ -47,13 +138,38 @@ module RelativeBounds implements BoundSig {
}
}
+module AllBounds implements BoundSig {
+ class SemBound instanceof SemanticBound::SemBound {
+ string toString() { result = super.toString() }
+
+ SemLocation getLocation() { result = super.getLocation() }
+
+ SemExpr getExpr(float delta) { result = super.getExpr(delta) }
+ }
+
+ class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
+
+ class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
+ SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
+ }
+}
+
+private module ModulusAnalysisInstantiated implements ModulusAnalysisSig {
+ class ModBound = AllBounds::SemBound;
+
+ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis as MA
+ import MA::ModulusAnalysis
+}
+
+module Util = RangeUtil;
+
module ConstantStage =
- RangeStage>;
+ RangeStage;
module RelativeStage =
- RangeStage>;
+ RangeStage;
private newtype TSemReason =
TSemNoReason() or
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll
index 7643c4aadb94..114219783860 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll
@@ -3,13 +3,12 @@
*/
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
-private import RangeAnalysisStage
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
-private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.IntDelta
private import RangeAnalysisImpl
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
+private import codeql.rangeanalysis.RangeAnalysis
-module CppLangImplRelative implements LangSig {
+module CppLangImplRelative implements LangSig {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll
index 1b5da03feecf..e3798600f85d 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll
@@ -4,10 +4,11 @@
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import RangeAnalysisRelativeSpecific
-private import RangeAnalysisStage as Range
+private import codeql.rangeanalysis.RangeAnalysis
+private import RangeAnalysisImpl
private import ConstantAnalysis
-module RangeUtil Lang> implements Range::UtilSig {
+module RangeUtil Lang> implements UtilSig {
/**
* Gets an expression that equals `v - d`.
*/
@@ -138,27 +139,33 @@ module RangeUtil Lang> implements Range::Ut
or
not exists(Lang::getAlternateTypeForSsaVariable(var)) and result = var.getType()
}
-}
-/**
- * Holds if `rix` is the number of input edges to `phi`.
- */
-predicate maxPhiInputRank(SemSsaPhiNode phi, int rix) {
- rix = max(int r | rankedPhiInput(phi, _, _, r))
+ import Ranking
}
-/**
- * Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
- * in an arbitrary 1-based numbering of the input edges to `phi`.
- */
-predicate rankedPhiInput(
- SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int r
-) {
- edge.phiInput(phi, inp) and
- edge =
- rank[r](SemSsaReadPositionPhiInputEdge e |
- e.phiInput(phi, _)
- |
- e order by e.getOrigBlock().getUniqueId()
- )
+import Ranking
+
+module Ranking {
+ /**
+ * Holds if `rix` is the number of input edges to `phi`.
+ */
+ predicate maxPhiInputRank(SemSsaPhiNode phi, int rix) {
+ rix = max(int r | rankedPhiInput(phi, _, _, r))
+ }
+
+ /**
+ * Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
+ * in an arbitrary 1-based numbering of the input edges to `phi`.
+ */
+ predicate rankedPhiInput(
+ SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int r
+ ) {
+ edge.phiInput(phi, inp) and
+ edge =
+ rank[r](SemSsaReadPositionPhiInputEdge e |
+ e.phiInput(phi, _)
+ |
+ e order by e.getOrigBlock().getUniqueId()
+ )
+ }
}
diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll
index 9abcdc842abb..20ada012c2a4 100644
--- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll
+++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll
@@ -6,14 +6,15 @@
* three-valued domain `{negative, zero, positive}`.
*/
-private import RangeAnalysisStage
+private import codeql.rangeanalysis.RangeAnalysis
+private import RangeAnalysisImpl
private import SignAnalysisSpecific as Specific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import ConstantAnalysis
private import RangeUtils
private import Sign
-module SignAnalysis Utils> {
+module SignAnalysis Utils> {
/**
* An SSA definition for which the analysis can compute the sign.
*
@@ -507,4 +508,16 @@ module SignAnalysis Utils> {
not semExprSign(e) = TPos() and
not semExprSign(e) = TZero()
}
+
+ /**
+ * Holds if `e` may have positive values. This does not rule out the
+ * possibility for negative values.
+ */
+ predicate semMayBePositive(SemExpr e) { semExprSign(e) = TPos() }
+
+ /**
+ * Holds if `e` may have negative values. This does not rule out the
+ * possibility for positive values.
+ */
+ predicate semMayBeNegative(SemExpr e) { semExprSign(e) = TNeg() }
}
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme
index 5b388693c66d..f79ce79e3b75 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme
@@ -197,6 +197,11 @@ svnchurn(
* C++ dbscheme
*/
+extractor_version(
+ string codeql_version: string ref,
+ string frontend_version: string ref
+)
+
@location = @location_stmt | @location_expr | @location_default ;
/**
diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
index 66cbfef08e6b..bd755b1cba10 100644
--- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
+++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats
@@ -18,20 +18,20 @@
@location_default
- 29768422
+ 29753047
@location_stmt
3814079
-
- @location_expr
- 13167909
-
@diagnostic
5200
+
+ @location_expr
+ 13167909
+
@file
122996
@@ -66,7 +66,7 @@
@namespace_decl
- 308610
+ 308602
@using
@@ -74,7 +74,7 @@
@static_assert
- 133393
+ 133390
@parameter
@@ -82,7 +82,7 @@
@membervariable
- 1053094
+ 1077872
@globalvariable
@@ -90,11 +90,11 @@
@localvariable
- 581163
+ 581158
@enumconstant
- 241303
+ 248647
@errortype
@@ -370,7 +370,7 @@
@type_mention
- 4023013
+ 4060812
@routinetype
@@ -394,7 +394,7 @@
@declspec
- 243334
+ 244509
@msattribute
@@ -454,7 +454,7 @@
@initialiser
- 1698635
+ 1698613
@lambdacapture
@@ -582,7 +582,7 @@
@geexpr
- 59159
+ 59287
@leexpr
@@ -654,7 +654,7 @@
@subscriptexpr
- 367576
+ 367573
@callexpr
@@ -794,7 +794,7 @@
@thisaccess
- 1126162
+ 1126135
@new_expr
@@ -1302,7 +1302,7 @@
@stmt_empty
- 193309
+ 193308
@stmt_continue
@@ -1310,7 +1310,7 @@
@stmt_break
- 102247
+ 102257
@stmt_try_block
@@ -2036,7 +2036,7 @@
seconds
- 9972
+ 12884
@@ -2114,55 +2114,55 @@
12
-
- 2
- 3
- 39
-
3
4
- 797
+ 398
4
5
- 159
+ 598
- 5
+ 6
8
159
- 8
+ 9
10
- 159
+ 79
10
+ 11
+ 119
+
+
+ 11
12
- 159
+ 119
- 12
- 18
+ 13
+ 17
159
- 18
- 22
- 159
+ 17
+ 18
+ 79
- 22
- 55
+ 20
+ 27
159
- 83
- 84
- 39
+ 44
+ 118
+ 119
@@ -2230,17 +2230,17 @@
3
4
- 1515
+ 718
4
5
- 239
+ 1037
5
6
- 279
+ 159
6
@@ -2250,23 +2250,28 @@
7
8
- 79
+ 159
8
9
- 239
+ 159
9
- 24
+ 12
279
- 24
- 91
+ 13
+ 42
279
+
+ 44
+ 96
+ 119
+
@@ -2316,18 +2321,18 @@
39
- 4
- 5
+ 5
+ 6
39
- 123
- 124
+ 160
+ 161
39
- 130
- 131
+ 165
+ 166
39
@@ -2344,12 +2349,12 @@
1
2
- 5465
+ 8018
2
3
- 2273
+ 3071
3
@@ -2358,13 +2363,8 @@
4
- 6
- 877
-
-
- 6
- 43
- 239
+ 46
+ 678
@@ -2380,32 +2380,22 @@
1
2
- 4627
+ 6901
2
3
- 2114
+ 3390
3
4
- 1276
+ 1755
4
- 5
- 797
-
-
- 5
- 7
- 917
-
-
- 7
- 66
- 239
+ 75
+ 837
@@ -2421,12 +2411,12 @@
1
2
- 9573
+ 12525
2
- 3
- 398
+ 4
+ 359
@@ -2770,11 +2760,11 @@
cpu_seconds
- 7343
+ 6938
elapsed_seconds
- 146
+ 134
@@ -2820,17 +2810,22 @@
1
2
- 5982
+ 5465
2
3
- 899
+ 933
3
- 18
- 461
+ 10
+ 528
+
+
+ 16
+ 17
+ 11
@@ -2846,12 +2841,12 @@
1
2
- 6758
+ 6286
2
3
- 584
+ 652
@@ -2867,16 +2862,16 @@
1
2
- 33
+ 22
- 3
- 4
- 22
+ 2
+ 3
+ 11
- 6
- 7
+ 3
+ 4
11
@@ -2885,33 +2880,38 @@
11
- 14
- 15
+ 9
+ 10
11
- 35
- 36
+ 10
+ 11
11
- 144
- 145
+ 33
+ 34
11
- 174
- 175
+ 101
+ 102
11
- 225
- 226
+ 185
+ 186
11
- 248
- 249
+ 249
+ 250
+ 11
+
+
+ 261
+ 262
11
@@ -2928,16 +2928,16 @@
1
2
- 33
+ 22
- 3
- 4
- 22
+ 2
+ 3
+ 11
- 6
- 7
+ 3
+ 4
11
@@ -2946,33 +2946,38 @@
11
- 14
- 15
+ 9
+ 10
11
- 34
- 35
+ 10
+ 11
11
- 124
- 125
+ 32
+ 33
11
- 128
- 129
+ 92
+ 93
11
- 159
- 160
+ 135
+ 136
11
- 223
- 224
+ 160
+ 161
+ 11
+
+
+ 222
+ 223
11
@@ -4695,17 +4700,65 @@
+
+ extractor_version
+ 465
+
+
+ codeql_version
+ 465
+
+
+ frontend_version
+ 465
+
+
+
+
+ codeql_version
+ frontend_version
+
+
+ 12
+
+
+ 1
+ 2
+ 465
+
+
+
+
+
+
+ frontend_version
+ codeql_version
+
+
+ 12
+
+
+ 1
+ 2
+ 465
+
+
+
+
+
+
+
locations_default
- 29768422
+ 29753047
id
- 29768422
+ 29753047
container
- 138371
+ 122996
startLine
@@ -4735,7 +4788,7 @@
1
2
- 29768422
+ 29753047
@@ -4751,7 +4804,7 @@
1
2
- 29768422
+ 29753047
@@ -4767,7 +4820,7 @@
1
2
- 29768422
+ 29753047
@@ -4783,7 +4836,7 @@
1
2
- 29768422
+ 29753047
@@ -4799,7 +4852,7 @@
1
2
- 29768422
+ 29753047
@@ -4814,68 +4867,68 @@
1
- 2
- 15840
+ 11
+ 9783
- 2
- 12
- 10715
+ 11
+ 18
+ 10249
- 13
- 20
- 11647
+ 18
+ 30
+ 9317
- 21
- 36
- 11181
+ 30
+ 42
+ 9783
- 36
- 55
- 11181
+ 43
+ 61
+ 9783
- 55
- 77
- 10715
+ 61
+ 79
+ 9317
- 77
- 102
- 10715
+ 80
+ 106
+ 9783
- 102
+ 109
149
- 10715
+ 9317
149
- 227
- 11181
+ 199
+ 9317
- 228
- 350
- 10715
+ 206
+ 292
+ 9317
- 352
- 604
- 10715
+ 305
+ 469
+ 9317
- 630
- 1494
- 10715
+ 482
+ 850
+ 9317
- 1829
+ 939
2380
- 2329
+ 8386
@@ -4890,68 +4943,73 @@
1
- 2
- 15840
+ 8
+ 9317
- 2
- 9
- 10715
+ 8
+ 13
+ 9317
- 9
- 16
- 11647
+ 13
+ 20
+ 9783
- 16
- 25
- 11181
+ 20
+ 32
+ 9317
- 25
- 40
- 10715
+ 32
+ 43
+ 9783
- 40
- 57
- 10715
+ 44
+ 61
+ 9317
- 58
+ 62
72
- 10715
+ 9317
73
- 103
- 11181
+ 93
+ 9317
- 106
- 141
- 11647
+ 97
+ 128
+ 9317
- 148
- 225
- 10715
+ 128
+ 180
+ 9317
- 225
- 360
- 10715
+ 180
+ 267
+ 9317
- 372
- 1255
- 10715
+ 277
+ 414
+ 9317
- 1455
+ 439
+ 1465
+ 9317
+
+
+ 1557
1569
- 1863
+ 931
@@ -4966,13 +5024,8 @@
1
- 2
- 15840
-
-
- 2
4
- 8386
+ 8852
4
@@ -4991,43 +5044,48 @@
8
- 13
- 12113
+ 10
+ 9317
- 13
- 17
- 11181
+ 10
+ 15
+ 10715
- 17
- 25
+ 15
+ 23
+ 9783
+
+
+ 23
+ 28
11181
- 25
- 31
- 12113
+ 28
+ 34
+ 9783
- 31
- 39
- 11181
+ 34
+ 44
+ 9317
- 39
- 54
- 11181
+ 44
+ 55
+ 9317
- 54
- 67
- 10715
+ 55
+ 66
+ 9783
- 67
+ 66
77
- 7920
+ 8386
@@ -5042,68 +5100,73 @@
1
- 2
- 15840
+ 8
+ 9317
- 2
- 9
- 10715
+ 8
+ 13
+ 9317
- 9
- 16
- 11647
+ 13
+ 20
+ 9783
- 16
- 25
- 11181
+ 20
+ 32
+ 9317
- 25
- 40
- 10715
+ 32
+ 43
+ 9783
- 40
- 57
- 10715
+ 43
+ 60
+ 9317
- 58
+ 61
71
- 10715
+ 9317
72
- 98
- 10715
+ 93
+ 9317
- 101
- 140
- 11647
+ 94
+ 127
+ 9317
- 140
- 222
- 10715
+ 128
+ 179
+ 9317
- 223
- 360
- 11181
+ 180
+ 268
+ 9317
- 372
- 1255
- 10715
+ 278
+ 413
+ 9317
- 1452
+ 437
+ 1465
+ 9317
+
+
+ 1554
1566
- 1863
+ 931
@@ -5118,58 +5181,63 @@
1
- 2
- 15840
+ 9
+ 9783
- 2
- 10
- 11181
+ 9
+ 13
+ 9317
- 10
- 14
- 10715
+ 13
+ 18
+ 9317
- 14
- 21
- 11181
+ 18
+ 26
+ 10249
- 22
- 31
- 11181
+ 27
+ 33
+ 9317
- 31
+ 33
39
- 12579
+ 9317
39
- 48
- 12113
+ 47
+ 10249
- 48
- 56
- 11647
+ 47
+ 54
+ 9317
- 56
- 64
- 12113
+ 54
+ 60
+ 10249
- 64
- 73
- 12113
+ 60
+ 66
+ 9317
- 73
+ 66
+ 74
+ 9783
+
+
+ 74
78
- 10715
+ 9783
78
@@ -5234,7 +5302,7 @@
160
- 298
+ 265
11647
@@ -5285,7 +5353,7 @@
51
- 298
+ 265
74077
@@ -5464,11 +5532,11 @@
247
- 292
+ 286
2795
- 293
+ 291
360
2795
@@ -5585,7 +5653,7 @@
195
- 298
+ 265
1397
@@ -5884,7 +5952,7 @@
160
- 298
+ 265
11181
@@ -5940,7 +6008,7 @@
121
- 298
+ 265
11647
@@ -6119,11 +6187,11 @@
193
- 295
+ 288
3727
- 297
+ 294
495
3727
@@ -6240,7 +6308,7 @@
207
- 298
+ 265
1397
@@ -12259,7 +12327,7 @@
2
3
- 543313
+ 543317
3
@@ -12294,7 +12362,7 @@
11
337
- 224533
+ 224529
339
@@ -14030,11 +14098,11 @@
purefunctions
- 99971
+ 99968
id
- 99971
+ 99968
@@ -16166,11 +16234,11 @@
namespace_decls
- 308610
+ 308602
id
- 308610
+ 308602
namespace_id
@@ -16178,11 +16246,11 @@
location
- 308610
+ 308602
bodylocation
- 308610
+ 308602
@@ -16196,7 +16264,7 @@
1
2
- 308610
+ 308602
@@ -16212,7 +16280,7 @@
1
2
- 308610
+ 308602
@@ -16228,7 +16296,7 @@
1
2
- 308610
+ 308602
@@ -16442,7 +16510,7 @@
1
2
- 308610
+ 308602
@@ -16458,7 +16526,7 @@
1
2
- 308610
+ 308602
@@ -16474,7 +16542,7 @@
1
2
- 308610
+ 308602
@@ -16490,7 +16558,7 @@
1
2
- 308610
+ 308602
@@ -16506,7 +16574,7 @@
1
2
- 308610
+ 308602
@@ -16522,7 +16590,7 @@
1
2
- 308610
+ 308602
@@ -16801,19 +16869,19 @@
static_asserts
- 133393
+ 133390
id
- 133393
+ 133390
condition
- 133393
+ 133390
message
- 29938
+ 29937
location
@@ -16821,7 +16889,7 @@
enclosing
- 4603
+ 4602
@@ -16835,7 +16903,7 @@
1
2
- 133393
+ 133390
@@ -16851,7 +16919,7 @@
1
2
- 133393
+ 133390
@@ -16867,7 +16935,7 @@
1
2
- 133393
+ 133390
@@ -16883,7 +16951,7 @@
1
2
- 133393
+ 133390
@@ -16899,7 +16967,7 @@
1
2
- 133393
+ 133390
@@ -16915,7 +16983,7 @@
1
2
- 133393
+ 133390
@@ -16931,7 +16999,7 @@
1
2
- 133393
+ 133390
@@ -16947,7 +17015,7 @@
1
2
- 133393
+ 133390
@@ -17081,7 +17149,7 @@
4
12
- 1440
+ 1439
12
@@ -17255,12 +17323,12 @@
1
2
- 3861
+ 3860
2
3
- 6219
+ 6218
3
@@ -17368,7 +17436,7 @@
2
3
- 371
+ 370
3
@@ -17905,15 +17973,15 @@
overrides
- 159848
+ 159844
new
- 125042
+ 125039
old
- 15098
+ 15097
@@ -17927,12 +17995,12 @@
1
2
- 90243
+ 90240
2
3
- 34793
+ 34792
3
@@ -17993,19 +18061,19 @@
membervariables
- 1054889
+ 1079662
id
- 1053094
+ 1077872
type_id
- 327229
+ 331092
name
- 450932
+ 462559
@@ -18019,12 +18087,12 @@
1
2
- 1051379
+ 1076161
2
4
- 1715
+ 1710
@@ -18040,7 +18108,7 @@
1
2
- 1053094
+ 1077872
@@ -18056,22 +18124,22 @@
1
2
- 242659
+ 245663
2
3
- 51818
+ 52443
3
10
- 25490
+ 25664
10
- 4152
- 7260
+ 4335
+ 7321
@@ -18087,22 +18155,22 @@
1
2
- 254866
+ 258157
2
3
- 46393
+ 46832
3
- 40
- 24573
+ 46
+ 24908
- 41
- 2031
- 1396
+ 48
+ 2128
+ 1193
@@ -18118,22 +18186,22 @@
1
2
- 294877
+ 303956
2
3
- 86404
+ 87657
3
5
- 41128
+ 41739
5
- 646
- 28522
+ 653
+ 29205
@@ -18149,17 +18217,17 @@
1
2
- 367280
+ 377607
2
3
- 51659
+ 52483
3
- 650
- 31992
+ 657
+ 32468
@@ -18340,11 +18408,11 @@
localvariables
- 581163
+ 581158
id
- 581163
+ 581158
type_id
@@ -18366,7 +18434,7 @@
1
2
- 581163
+ 581158
@@ -18382,7 +18450,7 @@
1
2
- 581163
+ 581158
@@ -18403,7 +18471,7 @@
2
3
- 5412
+ 5408
3
@@ -18413,7 +18481,7 @@
4
7
- 3405
+ 3409
7
@@ -18423,7 +18491,7 @@
18
15847
- 2511
+ 2510
@@ -18439,7 +18507,7 @@
1
2
- 26974
+ 26970
2
@@ -18449,7 +18517,7 @@
3
5
- 2939
+ 2943
5
@@ -18511,7 +18579,7 @@
1
2
- 77144
+ 77143
2
@@ -18652,19 +18720,19 @@
enumconstants
- 241303
+ 248647
id
- 241303
+ 248647
parent
- 28482
+ 29683
index
- 10212
+ 10186
type_id
@@ -18672,11 +18740,11 @@
name
- 241024
+ 248369
location
- 221237
+ 228633
@@ -18690,7 +18758,7 @@
1
2
- 241303
+ 248647
@@ -18706,7 +18774,7 @@
1
2
- 241303
+ 248647
@@ -18722,7 +18790,7 @@
1
2
- 241303
+ 248647
@@ -18738,7 +18806,7 @@
1
2
- 241303
+ 248647
@@ -18754,7 +18822,7 @@
1
2
- 241303
+ 248647
@@ -18770,57 +18838,57 @@
1
2
- 997
+ 1114
2
3
- 4029
+ 4177
3
4
- 5784
+ 6087
4
5
- 3909
+ 4058
5
6
- 3071
+ 3262
6
7
- 1835
+ 1870
7
8
- 1475
+ 1432
8
- 11
- 2592
+ 10
+ 2148
- 11
- 17
- 2353
+ 10
+ 15
+ 2387
- 17
- 84
- 2154
+ 15
+ 34
+ 2307
- 94
+ 35
257
- 279
+ 835
@@ -18836,57 +18904,57 @@
1
2
- 997
+ 1114
2
3
- 4029
+ 4177
3
4
- 5784
+ 6087
4
5
- 3909
+ 4058
5
6
- 3071
+ 3262
6
7
- 1835
+ 1870
7
8
- 1475
+ 1432
8
- 11
- 2592
+ 10
+ 2148
- 11
- 17
- 2353
+ 10
+ 15
+ 2387
- 17
- 84
- 2154
+ 15
+ 34
+ 2307
- 94
+ 35
257
- 279
+ 835
@@ -18902,7 +18970,7 @@
1
2
- 28482
+ 29683
@@ -18918,57 +18986,57 @@
1
2
- 997
+ 1114
2
3
- 4029
+ 4177
3
4
- 5784
+ 6087
4
5
- 3909
+ 4058
5
6
- 3071
+ 3262
6
7
- 1835
+ 1870
7
8
- 1475
+ 1432
8
- 11
- 2592
+ 10
+ 2148
- 11
- 17
- 2353
+ 10
+ 15
+ 2387
- 17
- 84
- 2154
+ 15
+ 34
+ 2307
- 94
+ 35
257
- 279
+ 835
@@ -18984,52 +19052,52 @@
1
2
- 1436
+ 1551
2
3
- 4188
+ 4337
3
4
- 5824
+ 6127
4
5
- 3869
+ 4018
5
6
- 3071
+ 3262
6
7
- 1795
+ 1830
7
8
- 1396
+ 1352
8
11
- 2513
+ 2705
11
- 17
- 2233
+ 18
+ 2268
- 17
+ 18
257
- 2154
+ 2228
@@ -19045,47 +19113,47 @@
1
2
- 2034
+ 2029
2
3
- 1635
+ 1631
3
4
- 1755
+ 1750
4
5
- 877
+ 835
5
9
- 797
+ 795
9
12
- 837
+ 875
12
20
- 877
+ 835
20
- 69
- 797
+ 66
+ 795
- 77
- 715
- 598
+ 70
+ 747
+ 636
@@ -19101,47 +19169,47 @@
1
2
- 2034
+ 2029
2
3
- 1635
+ 1631
3
4
- 1755
+ 1750
4
5
- 877
+ 835
5
9
- 797
+ 795
9
12
- 837
+ 875
12
20
- 877
+ 835
20
- 69
- 797
+ 66
+ 795
- 77
- 715
- 598
+ 70
+ 747
+ 636
@@ -19157,7 +19225,7 @@
1
2
- 10212
+ 10186
@@ -19173,47 +19241,47 @@
1
2
- 2034
+ 2029
2
3
- 1635
+ 1631
3
4
- 1755
+ 1750
4
5
- 877
+ 835
5
9
- 797
+ 795
9
12
- 837
+ 875
12
20
- 877
+ 835
20
- 69
- 797
+ 66
+ 795
- 77
- 712
- 598
+ 70
+ 744
+ 636
@@ -19229,47 +19297,47 @@
1
2
- 2034
+ 2029
2
3
- 1635
+ 1631
3
4
- 1755
+ 1750
4
5
- 877
+ 835
5
9
- 797
+ 795
9
12
- 837
+ 875
12
20
- 877
+ 835
20
- 69
- 797
+ 66
+ 795
- 77
- 715
- 598
+ 70
+ 747
+ 636
@@ -19283,8 +19351,8 @@
12
- 6049
- 6050
+ 6249
+ 6250
39
@@ -19299,8 +19367,8 @@
12
- 714
- 715
+ 746
+ 747
39
@@ -19331,8 +19399,8 @@
12
- 6042
- 6043
+ 6242
+ 6243
39
@@ -19347,8 +19415,8 @@
12
- 5546
- 5547
+ 5746
+ 5747
39
@@ -19365,12 +19433,12 @@
1
2
- 240744
+ 248090
2
3
- 279
+ 278
@@ -19386,12 +19454,12 @@
1
2
- 240744
+ 248090
2
3
- 279
+ 278
@@ -19407,7 +19475,7 @@
1
2
- 241024
+ 248369
@@ -19423,7 +19491,7 @@
1
2
- 241024
+ 248369
@@ -19439,12 +19507,12 @@
1
2
- 240744
+ 248090
2
3
- 279
+ 278
@@ -19460,12 +19528,12 @@
1
2
- 220480
+ 227877
2
205
- 757
+ 756
@@ -19481,7 +19549,7 @@
1
2
- 221237
+ 228633
@@ -19497,12 +19565,12 @@
1
2
- 220480
+ 227877
2
205
- 757
+ 756
@@ -19518,7 +19586,7 @@
1
2
- 221237
+ 228633
@@ -19534,12 +19602,12 @@
1
2
- 220480
+ 227877
2
205
- 757
+ 756
@@ -21924,7 +21992,7 @@
2
3
- 371
+ 370
@@ -22579,19 +22647,19 @@
type_mentions
- 4023013
+ 4060812
id
- 4023013
+ 4060812
type_id
- 197901
+ 200223
location
- 3989544
+ 4027428
kind
@@ -22609,7 +22677,7 @@
1
2
- 4023013
+ 4060812
@@ -22625,7 +22693,7 @@
1
2
- 4023013
+ 4060812
@@ -22641,7 +22709,7 @@
1
2
- 4023013
+ 4060812
@@ -22657,42 +22725,42 @@
1
2
- 97454
+ 98918
2
3
- 21700
+ 22322
3
4
- 8217
+ 8196
4
5
- 10770
+ 10663
5
7
- 14360
+ 14642
7
12
- 15836
+ 15876
12
27
- 15158
+ 15160
27
- 8555
- 14400
+ 8808
+ 14443
@@ -22708,42 +22776,42 @@
1
2
- 97454
+ 98918
2
3
- 21700
+ 22322
3
4
- 8217
+ 8196
4
5
- 10770
+ 10663
5
7
- 14360
+ 14642
7
12
- 15836
+ 15876
12
27
- 15158
+ 15160
27
- 8555
- 14400
+ 8808
+ 14443
@@ -22759,7 +22827,7 @@
1
2
- 197901
+ 200223
@@ -22775,12 +22843,12 @@
1
2
- 3956075
+ 3994044
2
3
- 33468
+ 33383
@@ -22796,12 +22864,12 @@
1
2
- 3956075
+ 3994044
2
3
- 33468
+ 33383
@@ -22817,7 +22885,7 @@
1
2
- 3989544
+ 4027428
@@ -22831,8 +22899,8 @@
12
- 100849
- 100850
+ 102056
+ 102057
39
@@ -22847,8 +22915,8 @@
12
- 4961
- 4962
+ 5032
+ 5033
39
@@ -22863,8 +22931,8 @@
12
- 100010
- 100011
+ 101217
+ 101218
39
@@ -24603,11 +24671,11 @@
funspecifiers
- 12754043
+ 12754079
func_id
- 3899573
+ 3899608
spec_id
@@ -24625,7 +24693,7 @@
1
2
- 314396
+ 314431
2
@@ -24739,8 +24807,8 @@
35
- 77764
- 77765
+ 77765
+ 77766
35
@@ -28309,11 +28377,11 @@
compgenerated
- 8403048
+ 9138729
id
- 8403048
+ 9138729
@@ -29654,7 +29722,7 @@
fun
- 533151
+ 533132
@@ -29689,12 +29757,12 @@
1
2
- 329366
+ 329327
2
3
- 82059
+ 82079
3
@@ -30325,19 +30393,19 @@
fieldoffsets
- 1053094
+ 1077872
id
- 1053094
+ 1077872
byteoffset
- 22658
+ 22879
bitoffset
- 319
+ 318
@@ -30351,7 +30419,7 @@
1
2
- 1053094
+ 1077872
@@ -30367,7 +30435,7 @@
1
2
- 1053094
+ 1077872
@@ -30383,37 +30451,37 @@
1
2
- 13004
+ 12891
2
3
- 1715
+ 1790
3
5
- 1795
+ 1949
5
12
- 1914
+ 1949
12
35
- 1715
+ 1750
35
- 205
- 1715
+ 209
+ 1750
- 244
- 5638
- 797
+ 248
+ 5836
+ 795
@@ -30429,12 +30497,12 @@
1
2
- 21980
+ 22202
2
9
- 678
+ 676
@@ -30448,43 +30516,43 @@
12
- 29
- 30
+ 31
+ 32
39
- 30
- 31
+ 32
+ 33
39
- 33
- 34
+ 37
+ 38
39
- 36
- 37
+ 43
+ 44
39
- 42
- 43
+ 46
+ 47
39
- 43
- 44
+ 53
+ 54
39
- 55
- 56
+ 68
+ 69
39
- 26131
- 26132
+ 26779
+ 26780
39
@@ -30501,7 +30569,7 @@
11
12
- 159
+ 119
12
@@ -30511,11 +30579,11 @@
13
14
- 39
+ 79
- 568
- 569
+ 575
+ 576
39
@@ -30712,23 +30780,23 @@
initialisers
- 1698635
+ 1698613
init
- 1698635
+ 1698613
var
- 722109
+ 722110
expr
- 1698635
+ 1698613
location
- 390823
+ 390813
@@ -30742,7 +30810,7 @@
1
2
- 1698635
+ 1698613
@@ -30758,7 +30826,7 @@
1
2
- 1698635
+ 1698613
@@ -30774,7 +30842,7 @@
1
2
- 1698635
+ 1698613
@@ -30790,17 +30858,17 @@
1
2
- 633984
+ 633988
2
16
- 31466
+ 31465
16
25
- 56657
+ 56656
@@ -30816,17 +30884,17 @@
1
2
- 633984
+ 633988
2
16
- 31466
+ 31465
16
25
- 56657
+ 56656
@@ -30842,7 +30910,7 @@
1
2
- 722102
+ 722104
2
@@ -30863,7 +30931,7 @@
1
2
- 1698635
+ 1698613
@@ -30879,7 +30947,7 @@
1
2
- 1698635
+ 1698613
@@ -30895,7 +30963,7 @@
1
2
- 1698635
+ 1698613
@@ -30911,17 +30979,17 @@
1
2
- 318451
+ 318443
2
3
- 23851
+ 23850
3
15
- 30680
+ 30679
15
@@ -30942,12 +31010,12 @@
1
2
- 341120
+ 341112
2
4
- 35642
+ 35641
4
@@ -30968,17 +31036,17 @@
1
2
- 318451
+ 318443
2
3
- 23851
+ 23850
3
15
- 30680
+ 30679
15
@@ -31346,7 +31414,7 @@
typeid
- 1244631
+ 1244642
value_category
@@ -31411,32 +31479,32 @@
3
4
- 103287
+ 103298
4
5
- 84777
+ 84788
5
8
- 111125
+ 111102
8
14
- 99171
+ 99182
14
42
- 94099
+ 94111
42
125383
- 43226
+ 43215
@@ -31452,7 +31520,7 @@
1
2
- 1075930
+ 1075941
2
@@ -31512,8 +31580,8 @@
11
- 93013
- 93014
+ 93014
+ 93015
11
@@ -32806,7 +32874,7 @@
1
2
- 19745
+ 19744
2
@@ -35297,11 +35365,11 @@
stmtparents
- 4053171
+ 4053248
id
- 4053171
+ 4053248
index
@@ -35309,7 +35377,7 @@
parent
- 1719896
+ 1719942
@@ -35323,7 +35391,7 @@
1
2
- 4053171
+ 4053248
@@ -35339,7 +35407,7 @@
1
2
- 4053171
+ 4053248
@@ -35399,7 +35467,7 @@
77
- 196965
+ 196973
697
@@ -35460,7 +35528,7 @@
77
- 196965
+ 196973
697
@@ -35477,27 +35545,27 @@
1
2
- 987613
+ 987639
2
3
- 373033
+ 373043
3
4
- 105762
+ 105766
4
6
- 111258
+ 111262
6
17
- 129865
+ 129868
17
@@ -35518,27 +35586,27 @@
1
2
- 987613
+ 987639
2
3
- 373033
+ 373043
3
4
- 105762
+ 105766
4
6
- 111258
+ 111262
6
17
- 129865
+ 129868
17
@@ -35564,11 +35632,11 @@
stmt_decl_bind
- 585093
+ 585089
stmt
- 544980
+ 544976
num
@@ -35576,7 +35644,7 @@
decl
- 584988
+ 584984
@@ -35590,7 +35658,7 @@
1
2
- 524119
+ 524115
2
@@ -35611,7 +35679,7 @@
1
2
- 524119
+ 524115
2
@@ -35814,7 +35882,7 @@
1
2
- 584950
+ 584946
2
@@ -35835,7 +35903,7 @@
1
2
- 584988
+ 584984
@@ -35845,11 +35913,11 @@
stmt_decl_entry_bind
- 527554
+ 527550
stmt
- 487743
+ 487740
num
@@ -35857,7 +35925,7 @@
decl_entry
- 527495
+ 527491
@@ -35871,12 +35939,12 @@
1
2
- 467147
+ 467144
2
19
- 20596
+ 20595
@@ -35892,12 +35960,12 @@
1
2
- 467147
+ 467144
2
19
- 20596
+ 20595
@@ -36095,7 +36163,7 @@
1
2
- 527474
+ 527470
3
@@ -36116,7 +36184,7 @@
1
2
- 527495
+ 527491
@@ -36923,11 +36991,11 @@
link_parent
- 39330305
+ 39330622
element
- 4985174
+ 4985209
link_target
@@ -36955,7 +37023,7 @@
9
10
- 4286883
+ 4286918
@@ -36974,48 +37042,48 @@
35
- 121945
- 121946
+ 121946
+ 121947
35
- 122057
- 122058
+ 122058
+ 122059
35
- 122156
- 122157
+ 122157
+ 122158
35
- 122187
- 122188
+ 122188
+ 122189
35
- 122199
- 122200
+ 122200
+ 122201
35
- 122216
- 122217
+ 122217
+ 122218
35
- 124216
- 124217
+ 124217
+ 124218
35
- 128870
- 128871
+ 128871
+ 128872
35
- 131274
- 131275
+ 131275
+ 131276
35
diff --git a/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme
new file mode 100644
index 000000000000..5b388693c66d
--- /dev/null
+++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme
@@ -0,0 +1,2221 @@
+
+/**
+ * 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
+);
+
+/**
+ * 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
+ */
+
+@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
+;
+*/
+
+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,
+ int handle: @variable ref,
+ int promise: @variable 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);
+
+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
+);
+
+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_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable 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
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default 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: @functionorblock 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. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this 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.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @usertype.kind of
+ 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+| 5 = @typedef // classic C: typedef typedef type name
+| 6 = @template
+| 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 // a using name = type style typedef
+;
+*/
+
+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
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+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
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype 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
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int 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
+);
+
+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
+;
+
+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_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
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+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;
+
+@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
+ ;
+
+/*
+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
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ 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
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * 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
+);
+
+/*
+ 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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+);
+
+@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
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_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
+;
+
+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
+);
+
+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
+);
+
+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
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_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
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock 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
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+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(
+ unique 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/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme
new file mode 100644
index 000000000000..f79ce79e3b75
--- /dev/null
+++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme
@@ -0,0 +1,2226 @@
+
+/**
+ * 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
+);
+
+/**
+ * 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
+;
+*/
+
+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,
+ int handle: @variable ref,
+ int promise: @variable 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);
+
+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
+);
+
+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_decl_specifiers(
+ int id: @var_decl ref,
+ string name: string ref
+)
+is_structured_binding(unique int id: @variable 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
+);
+
+namespace_decls(
+ unique int id: @namespace_decl,
+ int namespace_id: @namespace ref,
+ int location: @location_default ref,
+ int bodylocation: @location_default ref
+);
+
+usings(
+ unique int id: @using,
+ int element_id: @element ref,
+ int location: @location_default 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: @functionorblock 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. For example:
+ * ```
+ * int a;
+ * decltype(1+a) b;
+ * ```
+ * Here `expr` is `1+a`.
+ *
+ * Sometimes an additional pair of parentheses around the expression
+ * would change the semantics of this 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.
+ */
+#keyset[id, expr]
+decltypes(
+ int id: @decltype,
+ int expr: @expr ref,
+ int base_type: @type ref,
+ boolean parentheses_would_change_meaning: boolean ref
+);
+
+/*
+case @usertype.kind of
+ 1 = @struct
+| 2 = @class
+| 3 = @union
+| 4 = @enum
+| 5 = @typedef // classic C: typedef typedef type name
+| 6 = @template
+| 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 // a using name = type style typedef
+;
+*/
+
+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
+);
+
+mangled_name(
+ unique int id: @declaration ref,
+ int mangled_name : @mangledname
+);
+
+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
+);
+
+is_proxy_class_for(
+ unique int id: @usertype ref,
+ unique int templ_param_id: @usertype 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
+);
+
+/*
+ Fixed point types
+ precision(1) = short, precision(2) = default, precision(3) = long
+ is_unsigned(1) = unsigned is_unsigned(2) = signed
+ is_fract_type(1) = declared with _Fract
+ saturating(1) = declared with _Sat
+*/
+/* TODO
+fixedpointtypes(
+ unique int id: @fixedpointtype,
+ int precision: int ref,
+ int is_unsigned: int ref,
+ int is_fract_type: int ref,
+ int saturating: int 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
+);
+
+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
+;
+
+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_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
+ /* TODO | @fixedpointtype */
+ | @routinetype
+ | @ptrtomember
+ | @decltype;
+
+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;
+
+@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
+ ;
+
+/*
+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
+ | @assignpaddexpr
+ | @assignpsubexpr
+ ;
+
+@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
+
+@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
+
+/*
+ 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
+);
+
+/*
+ case @deallocator.form of
+ 0 = plain
+ | 1 = size
+ | 2 = alignment
+ | 3 = size_and_alignment
+ ;
+*/
+
+/**
+ * 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
+);
+
+/*
+ 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
+;
+
+@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
+ ;
+
+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
+);
+
+/**
+ * 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
+);
+
+@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
+);
+
+@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
+
+sizeof_bind(
+ unique int expr: @runtime_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
+;
+
+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
+);
+
+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
+);
+
+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
+);
+
+for_initialization(
+ unique int for_stmt: @stmt_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
+);
+
+@functionorblock = @function | @stmt_block;
+
+blockscope(
+ unique int block: @stmt_block ref,
+ int enclosing: @functionorblock 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
+| 18 = @ppd_warning
+;
+
+@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
+
+@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
+
+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(
+ unique 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/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties
new file mode 100644
index 000000000000..90e68eef3c82
--- /dev/null
+++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties
@@ -0,0 +1,2 @@
+description: Introduce extractor version numbers
+compatibility: full
diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected
index b7b2a8eab909..bacd714e6148 100644
--- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected
+++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected
@@ -20,12 +20,8 @@ reverseRead
argHasPostUpdate
postWithInFlow
| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected
index 72818427b846..4b74de5a825f 100644
--- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected
+++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected
@@ -44,8 +44,6 @@ reverseRead
argHasPostUpdate
postWithInFlow
| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
-| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index f134b647a14d..ceb3cde9a8e3 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -2199,6 +2199,19 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
| map.cpp:436:55:436:59 | def | map.cpp:436:19:436:60 | call to pair | TAINT |
| map.cpp:436:63:436:67 | first | map.cpp:436:7:436:67 | call to iterator | |
| map.cpp:437:7:437:9 | m35 | map.cpp:437:7:437:9 | call to unordered_map | |
+| map.cpp:446:23:446:23 | call to map | map.cpp:448:3:448:3 | m | |
+| map.cpp:446:23:446:23 | call to map | map.cpp:449:12:449:12 | m | |
+| map.cpp:446:23:446:23 | call to map | map.cpp:451:1:451:1 | m | |
+| map.cpp:447:12:447:26 | call to indirect_source | map.cpp:448:10:448:10 | p | |
+| map.cpp:448:3:448:3 | m | map.cpp:448:4:448:4 | call to operator[] | TAINT |
+| map.cpp:448:3:448:3 | ref arg m | map.cpp:449:12:449:12 | m | |
+| map.cpp:448:3:448:3 | ref arg m | map.cpp:451:1:451:1 | m | |
+| map.cpp:448:3:448:10 | ... = ... | map.cpp:448:4:448:4 | call to operator[] [post update] | |
+| map.cpp:448:4:448:4 | call to operator[] [post update] | map.cpp:448:3:448:3 | ref arg m | TAINT |
+| map.cpp:448:10:448:10 | p | map.cpp:448:3:448:10 | ... = ... | |
+| map.cpp:449:12:449:12 | m | map.cpp:449:13:449:13 | call to operator[] | TAINT |
+| map.cpp:449:12:449:12 | ref arg m | map.cpp:451:1:451:1 | m | |
+| map.cpp:449:13:449:13 | call to operator[] | map.cpp:450:8:450:8 | q | |
| movableclass.cpp:8:2:8:15 | this | movableclass.cpp:8:27:8:31 | constructor init of field v [pre-this] | |
| movableclass.cpp:8:21:8:22 | _v | movableclass.cpp:8:29:8:30 | _v | |
| movableclass.cpp:8:29:8:30 | _v | movableclass.cpp:8:27:8:31 | constructor init of field v | TAINT |
@@ -6609,6 +6622,27 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
| taint.cpp:711:13:711:13 | s | taint.cpp:711:2:711:8 | call to strncpy | TAINT |
| taint.cpp:711:13:711:13 | s | taint.cpp:711:10:711:10 | ref arg d | TAINT |
| taint.cpp:712:7:712:7 | ref arg d | taint.cpp:709:25:709:25 | d | |
+| taint.cpp:718:17:718:31 | call to indirect_source | taint.cpp:720:27:720:32 | source | |
+| taint.cpp:719:22:719:29 | ,.-;:_ | taint.cpp:720:35:720:39 | delim | |
+| taint.cpp:719:22:719:29 | ,.-;:_ | taint.cpp:722:8:722:12 | delim | |
+| taint.cpp:720:20:720:25 | call to strtok | taint.cpp:721:8:721:16 | tokenized | |
+| taint.cpp:720:27:720:32 | source | taint.cpp:720:20:720:25 | call to strtok | TAINT |
+| taint.cpp:721:8:721:16 | tokenized | taint.cpp:721:7:721:16 | * ... | TAINT |
+| taint.cpp:722:8:722:12 | delim | taint.cpp:722:7:722:12 | * ... | TAINT |
+| taint.cpp:727:24:727:29 | source | taint.cpp:727:24:727:29 | source | |
+| taint.cpp:727:24:727:29 | source | taint.cpp:729:18:729:23 | source | |
+| taint.cpp:728:17:728:23 | 0 | taint.cpp:729:27:729:32 | endptr | |
+| taint.cpp:728:17:728:23 | 0 | taint.cpp:731:7:731:12 | endptr | |
+| taint.cpp:728:17:728:23 | 0 | taint.cpp:732:8:732:13 | endptr | |
+| taint.cpp:729:11:729:16 | call to strtol | taint.cpp:730:7:730:7 | l | |
+| taint.cpp:729:18:729:23 | source | taint.cpp:729:11:729:16 | call to strtol | TAINT |
+| taint.cpp:729:18:729:23 | source | taint.cpp:729:26:729:32 | ref arg & ... | TAINT |
+| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:729:27:729:32 | endptr [inner post update] | |
+| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:731:7:731:12 | endptr | |
+| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:732:8:732:13 | endptr | |
+| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | |
+| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | |
+| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
index 404d6627b27f..8eeb80a0f83e 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
@@ -436,3 +436,16 @@ void test_unordered_map()
sink(m35.emplace(std::pair(source(), "def")).first); // $ MISSING: ast,ir
sink(m35); // $ MISSING: ast,ir
}
+
+namespace {
+ int* indirect_source();
+ void indirect_sink(int*);
+}
+
+void test_indirect_taint() {
+ std::map m;
+ int* p = indirect_source();
+ m[1] = p;
+ int* q = m[1];
+ sink(q); // $ ir MISSING: ast
+}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
index 2df0fc85bb6f..e479d7a11e01 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp
@@ -710,4 +710,24 @@ void test_strncpy(char* d, char* s) {
argument_source(s);
strncpy(d, s, 16);
sink(d); // $ ast ir
+}
+
+char* indirect_source();
+
+void test_strtok_indirect() {
+ char *source = indirect_source();
+ const char* delim = ",.-;:_";
+ char* tokenized = strtok(source, delim);
+ sink(*tokenized); // $ ir MISSING: ast
+ sink(*delim);
+}
+
+long int strtol(const char*, char**, int);
+
+void test_strtol(char *source) {
+ char* endptr = nullptr;
+ long l = strtol(source, &endptr, 10);
+ sink(l); // $ ast,ir
+ sink(endptr); // $ ast,ir
+ sink(*endptr); // $ ast,ir
}
\ No newline at end of file
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql
index ef79f0659210..56c8cd8ba684 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql
@@ -84,6 +84,8 @@ module IRTest {
or
source.asIndirectExpr().(FunctionCall).getTarget().getName() = "source"
or
+ source.asIndirectExpr().(FunctionCall).getTarget().getName() = "indirect_source"
+ or
source.asParameter().getName().matches("source%")
or
exists(FunctionCall fc |
diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
index d714f52629b3..10f1c32005b0 100644
--- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
+++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected
@@ -15938,6 +15938,44 @@ ir.cpp:
# 2104| Type = [CTypedefType,Size_t] size_t
# 2104| ValueCategory = prvalue(load)
# 2105| getStmt(6): [ReturnStmt] return ...
+# 2107| [TopLevelFunction] double strtod(char const*, char**)
+# 2107| :
+# 2107| getParameter(0): [Parameter] str
+# 2107| Type = [PointerType] const char *
+# 2107| getParameter(1): [Parameter] endptr
+# 2107| Type = [PointerType] char **
+# 2109| [TopLevelFunction] char* test_strtod(char*)
+# 2109| :
+# 2109| getParameter(0): [Parameter] s
+# 2109| Type = [CharPointerType] char *
+# 2109| getEntryPoint(): [BlockStmt] { ... }
+# 2110| getStmt(0): [DeclStmt] declaration
+# 2110| getDeclarationEntry(0): [VariableDeclarationEntry] definition of end
+# 2110| Type = [CharPointerType] char *
+# 2111| getStmt(1): [DeclStmt] declaration
+# 2111| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d
+# 2111| Type = [DoubleType] double
+# 2111| getVariable().getInitializer(): [Initializer] initializer for d
+# 2111| getExpr(): [FunctionCall] call to strtod
+# 2111| Type = [DoubleType] double
+# 2111| ValueCategory = prvalue
+# 2111| getArgument(0): [VariableAccess] s
+# 2111| Type = [CharPointerType] char *
+# 2111| ValueCategory = prvalue(load)
+# 2111| getArgument(1): [AddressOfExpr] & ...
+# 2111| Type = [PointerType] char **
+# 2111| ValueCategory = prvalue
+# 2111| getOperand(): [VariableAccess] end
+# 2111| Type = [CharPointerType] char *
+# 2111| ValueCategory = lvalue
+# 2111| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)...
+# 2111| Conversion = [PointerConversion] pointer conversion
+# 2111| Type = [PointerType] const char *
+# 2111| ValueCategory = prvalue
+# 2112| getStmt(2): [ReturnStmt] return ...
+# 2112| getExpr(): [VariableAccess] end
+# 2112| Type = [CharPointerType] char *
+# 2112| ValueCategory = prvalue(load)
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| :
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 150bed79ef4e..d7e3c36d204a 100644
--- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected
@@ -12333,6 +12333,40 @@ ir.cpp:
# 2098| v2098_8(void) = AliasedUse : ~m2104_8
# 2098| v2098_9(void) = ExitFunction :
+# 2109| char* test_strtod(char*)
+# 2109| Block 0
+# 2109| v2109_1(void) = EnterFunction :
+# 2109| m2109_2(unknown) = AliasedDefinition :
+# 2109| m2109_3(unknown) = InitializeNonLocal :
+# 2109| m2109_4(unknown) = Chi : total:m2109_2, partial:m2109_3
+# 2109| r2109_5(glval) = VariableAddress[s] :
+# 2109| m2109_6(char *) = InitializeParameter[s] : &:r2109_5
+# 2109| r2109_7(char *) = Load[s] : &:r2109_5, m2109_6
+# 2109| m2109_8(unknown) = InitializeIndirection[s] : &:r2109_7
+# 2110| r2110_1(glval) = VariableAddress[end] :
+# 2110| m2110_2(char *) = Uninitialized[end] : &:r2110_1
+# 2111| r2111_1(glval) = VariableAddress[d] :
+# 2111| r2111_2(glval) = FunctionAddress[strtod] :
+# 2111| r2111_3(glval) = VariableAddress[s] :
+# 2111| r2111_4(char *) = Load[s] : &:r2111_3, m2109_6
+# 2111| r2111_5(char *) = Convert : r2111_4
+# 2111| r2111_6(glval) = VariableAddress[end] :
+# 2111| r2111_7(char **) = CopyValue : r2111_6
+# 2111| r2111_8(double) = Call[strtod] : func:r2111_2, 0:r2111_5, 1:r2111_7
+# 2111| v2111_9(void) = ^BufferReadSideEffect[0] : &:r2111_5, ~m2109_8
+# 2111| m2111_10(char *) = ^IndirectMayWriteSideEffect[1] : &:r2111_7
+# 2111| m2111_11(char *) = Chi : total:m2110_2, partial:m2111_10
+# 2111| m2111_12(double) = Store[d] : &:r2111_1, r2111_8
+# 2112| r2112_1(glval) = VariableAddress[#return] :
+# 2112| r2112_2(glval) = VariableAddress[end] :
+# 2112| r2112_3(char *) = Load[end] : &:r2112_2, m2111_11
+# 2112| m2112_4(char *) = Store[#return] : &:r2112_1, r2112_3
+# 2109| v2109_9(void) = ReturnIndirection[s] : &:r2109_7, m2109_8
+# 2109| r2109_10(glval) = VariableAddress[#return] :
+# 2109| v2109_11(void) = ReturnValue : &:r2109_10, m2112_4
+# 2109| v2109_12(void) = AliasedUse : m2109_3
+# 2109| v2109_13(void) = ExitFunction :
+
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0
diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp
index 813f7c2448a9..adaae6b7e593 100644
--- a/cpp/ql/test/library-tests/ir/ir/ir.cpp
+++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp
@@ -2104,4 +2104,12 @@ void newArrayCorrectType(size_t n) {
new int[n] { 0, 1, 2 };
}
+double strtod (const char* str, char** endptr);
+
+char* test_strtod(char *s) {
+ char *end;
+ double d = strtod(s, &end);
+ return end;
+}
+
// semmle-extractor-options: -std=c++17 --clang
diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
index af1939abd03c..39d238c1faed 100644
--- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
+++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected
@@ -10004,6 +10004,36 @@
| ir.cpp:2104:11:2104:11 | Address | &:r2104_2 |
| ir.cpp:2104:11:2104:11 | Left | r2104_3 |
| ir.cpp:2104:11:2104:11 | Load | m2098_6 |
+| ir.cpp:2109:7:2109:17 | Address | &:r2109_10 |
+| ir.cpp:2109:7:2109:17 | ChiPartial | partial:m2109_3 |
+| ir.cpp:2109:7:2109:17 | ChiTotal | total:m2109_2 |
+| ir.cpp:2109:7:2109:17 | Load | m2112_4 |
+| ir.cpp:2109:7:2109:17 | SideEffect | m2109_3 |
+| ir.cpp:2109:25:2109:25 | Address | &:r2109_5 |
+| ir.cpp:2109:25:2109:25 | Address | &:r2109_5 |
+| ir.cpp:2109:25:2109:25 | Address | &:r2109_7 |
+| ir.cpp:2109:25:2109:25 | Address | &:r2109_7 |
+| ir.cpp:2109:25:2109:25 | Load | m2109_6 |
+| ir.cpp:2109:25:2109:25 | SideEffect | m2109_8 |
+| ir.cpp:2110:9:2110:11 | Address | &:r2110_1 |
+| ir.cpp:2111:10:2111:10 | Address | &:r2111_1 |
+| ir.cpp:2111:14:2111:19 | CallTarget | func:r2111_2 |
+| ir.cpp:2111:14:2111:19 | StoreValue | r2111_8 |
+| ir.cpp:2111:21:2111:21 | Address | &:r2111_3 |
+| ir.cpp:2111:21:2111:21 | Address | &:r2111_5 |
+| ir.cpp:2111:21:2111:21 | Arg(0) | 0:r2111_5 |
+| ir.cpp:2111:21:2111:21 | Load | m2109_6 |
+| ir.cpp:2111:21:2111:21 | SideEffect | ~m2109_8 |
+| ir.cpp:2111:21:2111:21 | Unary | r2111_4 |
+| ir.cpp:2111:24:2111:27 | Address | &:r2111_7 |
+| ir.cpp:2111:24:2111:27 | Arg(1) | 1:r2111_7 |
+| ir.cpp:2111:24:2111:27 | ChiPartial | partial:m2111_10 |
+| ir.cpp:2111:24:2111:27 | ChiTotal | total:m2110_2 |
+| ir.cpp:2111:25:2111:27 | Unary | r2111_6 |
+| ir.cpp:2112:3:2112:13 | Address | &:r2112_1 |
+| ir.cpp:2112:10:2112:12 | Address | &:r2112_2 |
+| ir.cpp:2112:10:2112:12 | Load | m2111_11 |
+| ir.cpp:2112:10:2112:12 | StoreValue | r2112_3 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
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 c4774b10f89d..f43a105f70ae 100644
--- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
+++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected
@@ -11538,6 +11538,38 @@ ir.cpp:
# 2098| v2098_7(void) = AliasedUse : ~m?
# 2098| v2098_8(void) = ExitFunction :
+# 2109| char* test_strtod(char*)
+# 2109| Block 0
+# 2109| v2109_1(void) = EnterFunction :
+# 2109| mu2109_2(unknown) = AliasedDefinition :
+# 2109| mu2109_3(unknown) = InitializeNonLocal :
+# 2109| r2109_4(glval) = VariableAddress[s] :
+# 2109| mu2109_5(char *) = InitializeParameter[s] : &:r2109_4
+# 2109| r2109_6(char *) = Load[s] : &:r2109_4, ~m?
+# 2109| mu2109_7(unknown) = InitializeIndirection[s] : &:r2109_6
+# 2110| r2110_1(glval) = VariableAddress[end] :
+# 2110| mu2110_2(char *) = Uninitialized[end] : &:r2110_1
+# 2111| r2111_1(glval) = VariableAddress[d] :
+# 2111| r2111_2(glval) = FunctionAddress[strtod] :
+# 2111| r2111_3(glval) = VariableAddress[s] :
+# 2111| r2111_4(char *) = Load[s] : &:r2111_3, ~m?
+# 2111| r2111_5(char *) = Convert : r2111_4
+# 2111| r2111_6(glval) = VariableAddress[end] :
+# 2111| r2111_7(char **) = CopyValue : r2111_6
+# 2111| r2111_8(double) = Call[strtod] : func:r2111_2, 0:r2111_5, 1:r2111_7
+# 2111| v2111_9(void) = ^BufferReadSideEffect[0] : &:r2111_5, ~m?
+# 2111| mu2111_10(char *) = ^IndirectMayWriteSideEffect[1] : &:r2111_7
+# 2111| mu2111_11(double) = Store[d] : &:r2111_1, r2111_8
+# 2112| r2112_1(glval) = VariableAddress[#return] :
+# 2112| r2112_2(glval) = VariableAddress[end] :
+# 2112| r2112_3(char *) = Load[end] : &:r2112_2, ~m?
+# 2112| mu2112_4(char *) = Store[#return] : &:r2112_1, r2112_3
+# 2109| v2109_8(void) = ReturnIndirection[s] : &:r2109_6, ~m?
+# 2109| r2109_9(glval) = VariableAddress[#return] :
+# 2109| v2109_10(void) = ReturnValue : &:r2109_9, ~m?
+# 2109| v2109_11(void) = AliasedUse : ~m?
+# 2109| v2109_12(void) = ExitFunction :
+
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0
diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp
index ff9acbfae1a4..61d171029483 100644
--- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp
+++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp
@@ -56,7 +56,7 @@
while (f3_get(n)) n+=2;
for (int i = 0; i < n; i += 2) {
- range(i); // $ range=>=0 SPURIOUS: range="<=Phi: call to f3_get-1" range="<=Phi: call to f3_get-2"
+ range(i); // $ range=>=0 range="<=Phi: call to f3_get-2"
}
}
@@ -117,3 +117,16 @@ void test_sub(int x, int y, int n) {
}
}
}
+
+void test_div(int x) {
+ if (3 <= x && x <= 7) {
+ range(x / 2); // $ range=>=1 range=<=3
+ range(x / 3); // $ range=>=1 range=<=2
+ range(x >> 2); // $ range=>=0 range=<=1
+ }
+ if (2 <= x && x <= 8) {
+ range(x / 2); // $ range=>=1 range=<=4
+ range(x / 3); // $ range=>=0 range=<=2
+ range(x >> 2); // $ range=>=0 range=<=2
+ }
+}
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
index 141b7091d191..f5a3553ce542 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected
@@ -97,6 +97,10 @@
| test_free.cpp:260:9:260:9 | p |
| test_free.cpp:263:12:263:12 | p |
| test_free.cpp:269:7:269:11 | ... = ... |
+| test_free.cpp:277:11:277:13 | buf |
+| test_free.cpp:282:10:282:12 | buf |
+| test_free.cpp:288:8:288:10 | buf |
+| test_free.cpp:293:8:293:10 | buf |
| virtual.cpp:18:10:18:10 | a |
| virtual.cpp:19:10:19:10 | c |
| virtual.cpp:38:10:38:10 | b |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
index b4ac51dc72e9..6df347582cb8 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected
@@ -12,6 +12,10 @@ edges
| test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... |
| test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... |
| test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... |
+| test_free.cpp:293:8:293:10 | buf | test_free.cpp:294:3:294:13 | ... = ... |
+| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:5:294:7 | s indirection [post update] [buf] |
+| test_free.cpp:294:5:294:7 | s indirection [post update] [buf] | test_free.cpp:295:12:295:12 | s indirection [buf] |
+| test_free.cpp:295:12:295:12 | s indirection [buf] | test_free.cpp:295:14:295:16 | buf |
nodes
| test_free.cpp:11:10:11:10 | a | semmle.label | a |
| test_free.cpp:12:5:12:5 | a | semmle.label | a |
@@ -38,6 +42,11 @@ nodes
| test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... |
| test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... |
| test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... |
+| test_free.cpp:293:8:293:10 | buf | semmle.label | buf |
+| test_free.cpp:294:3:294:13 | ... = ... | semmle.label | ... = ... |
+| test_free.cpp:294:5:294:7 | s indirection [post update] [buf] | semmle.label | s indirection [post update] [buf] |
+| test_free.cpp:295:12:295:12 | s indirection [buf] | semmle.label | s indirection [buf] |
+| test_free.cpp:295:14:295:16 | buf | semmle.label | buf |
subpaths
#select
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
@@ -53,3 +62,4 @@ subpaths
| test_free.cpp:236:9:236:10 | * ... | test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:233:9:233:12 | call to free | call to free |
| test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free |
| test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free |
+| test_free.cpp:295:14:295:16 | buf | test_free.cpp:293:8:293:10 | buf | test_free.cpp:295:14:295:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:293:3:293:6 | call to free | call to free |
diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
index b9ea0ec6fbf3..5c6d2e4c3595 100644
--- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
+++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp
@@ -267,4 +267,30 @@ void test_free_assign() {
void *a = malloc(10);
void *b;
free(b = a); // GOOD
+}
+
+struct MyStruct {
+ char* buf;
+};
+
+void test_free_struct(MyStruct* s) {
+ free(s->buf);
+ char c = s->buf[0]; // BAD [FALSE NEGATIVE]
+}
+
+void test_free_struct2(MyStruct s) {
+ free(s.buf);
+ char c = s.buf[0]; // BAD [FALSE NEGATIVE]
+}
+
+void test_free_struct3(MyStruct s) {
+ char* buf = s.buf;
+ free(buf);
+ char c = s.buf[0]; // BAD [FALSE NEGATIVE]
+}
+
+void test_free_struct4(char* buf, MyStruct s) {
+ free(buf);
+ s.buf = buf;
+ char c = s.buf[0]; // BAD
}
\ No newline at end of file
diff --git a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs
index 664188c41c22..e29cd532a5ce 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs
@@ -186,7 +186,8 @@ private void StubTypedConstant(TypedConstant c)
}
break;
case TypedConstantKind.Enum:
- stubWriter.Write("throw null");
+ stubWriter.Write($"({c.Type!.GetQualifiedName()}) ");
+ stubWriter.Write(c.Value!.ToString());
break;
case TypedConstantKind.Array:
stubWriter.Write("new []{");
@@ -200,7 +201,8 @@ private void StubTypedConstant(TypedConstant c)
}
private static readonly HashSet attributeAllowList = new() {
- "System.FlagsAttribute"
+ "System.FlagsAttribute",
+ "System.AttributeUsageAttribute"
};
private void StubAttribute(AttributeData a, string prefix)
@@ -219,6 +221,14 @@ private void StubAttribute(AttributeData a, string prefix)
{
stubWriter.Write("(");
WriteCommaSep(a.ConstructorArguments, StubTypedConstant);
+ if (a.ConstructorArguments.Any() && a.NamedArguments.Any())
+ stubWriter.Write(",");
+ WriteCommaSep(a.NamedArguments, arg =>
+ {
+ stubWriter.Write(arg.Key);
+ stubWriter.Write(" = ");
+ StubTypedConstant(arg.Value);
+ });
stubWriter.Write(")");
}
stubWriter.WriteLine("]");
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs
index d0130385f42c..08e8f391a342 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs
@@ -82,10 +82,16 @@ private void ExtractArguments(TextWriter trapFile)
var paramName = Symbol.AttributeConstructor?.Parameters[i].Name;
var argSyntax = ctorArguments?.SingleOrDefault(a => a.NameColon is not null && a.NameColon.Name.Identifier.Text == paramName);
+ var isParamsParameter = false;
+
if (argSyntax is null && // couldn't find named argument
ctorArguments?.Count > childIndex && // there're more arguments
ctorArguments[childIndex].NameColon is null) // the argument is positional
{
+ // The current argument is not named
+ // so the previous ones were also not named
+ // so the child index matches the parameter index.
+ isParamsParameter = Symbol?.AttributeConstructor?.Parameters[childIndex].IsParams == true;
argSyntax = ctorArguments[childIndex];
}
@@ -94,6 +100,28 @@ private void ExtractArguments(TextWriter trapFile)
argSyntax?.Expression,
this,
childIndex++);
+
+ if (isParamsParameter &&
+ ctorArguments is not null)
+ {
+ // The current argument is a params argument, so we're processing all the remaining arguments:
+ while (childIndex < ctorArguments.Count)
+ {
+ if (ctorArguments[childIndex].Expression is null)
+ {
+ // This shouldn't happen
+ continue;
+ }
+
+ CreateExpressionFromArgument(
+ constructorArgument,
+ ctorArguments[childIndex].Expression,
+ this,
+ childIndex);
+
+ childIndex++;
+ }
+ }
}
foreach (var namedArgument in Symbol.NamedArguments)
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
index b881161f66f5..08826b7ae8f1 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll
@@ -25,16 +25,8 @@ abstract class Bound extends TBound {
/** Gets an expression that equals this bound. */
Expr getExpr() { result = this.getExpr(0) }
- /**
- * Holds if this element is at the specified location.
- * The location spans column `sc` of line `sl` to
- * column `ec` of line `el` in file `path`.
- * For more information, see
- * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
- */
- predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
- path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
- }
+ /** Gets the location of this bound. */
+ abstract Location getLocation();
}
/**
@@ -45,6 +37,8 @@ class ZeroBound extends Bound, TBoundZero {
override string toString() { result = "0" }
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
+
+ override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
}
/**
@@ -58,9 +52,7 @@ class SsaBound extends Bound, TBoundSsa {
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
- override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
- this.getSsa().getLocation().hasLocationInfo(path, sl, sc, el, ec)
- }
+ override Location getLocation() { result = this.getSsa().getLocation() }
}
/**
@@ -72,7 +64,5 @@ class ExprBound extends Bound, TBoundExpr {
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
- override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
- this.getExpr().getLocation().hasLocationInfo(path, sl, sc, el, ec)
- }
+ override Location getLocation() { result = this.getExpr().getLocation() }
}
diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll
index 3515f2f96c82..3885c11afd14 100644
--- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll
+++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll
@@ -12,6 +12,8 @@ class SsaVariable = SU::SsaVariable;
class Expr = CS::ControlFlow::Nodes::ExprNode;
+class Location = CS::Location;
+
class IntegralType = CS::IntegralType;
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
diff --git a/csharp/ql/src/Stubs/AllStubsFromReference.ql b/csharp/ql/src/Stubs/AllStubsFromReference.ql
deleted file mode 100644
index e8d0debb3169..000000000000
--- a/csharp/ql/src/Stubs/AllStubsFromReference.ql
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Tool to generate C# stubs from a qltest snapshot.
- */
-
-import csharp
-import Stubs
-
-/** All public declarations from assemblies. */
-class AllExternalPublicDeclarations extends GeneratedDeclaration {
- AllExternalPublicDeclarations() { this.fromLibrary() }
-}
-
-from Assembly a
-select a.getFullName(), a.getName(), a.getVersion().toString(), a.getFile().getAbsolutePath(),
- generatedCode(a)
diff --git a/csharp/ql/src/Stubs/AllStubsFromSource.ql b/csharp/ql/src/Stubs/AllStubsFromSource.ql
deleted file mode 100644
index 1a8a816b72ff..000000000000
--- a/csharp/ql/src/Stubs/AllStubsFromSource.ql
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Tool to generate C# stubs from a qltest snapshot.
- */
-
-import csharp
-import Stubs
-
-/** All public declarations from source. */
-class AllDeclarations extends GeneratedDeclaration {
- AllDeclarations() { not this.fromLibrary() }
-}
-
-/** Exclude types from these standard assemblies. */
-private class DefaultLibs extends ExcludedAssembly {
- DefaultLibs() {
- this.getName() = "System.Private.CoreLib" or
- this.getName() = "mscorlib" or
- this.getName() = "System.Runtime"
- }
-}
-
-select concat(generatedCode(_) + "\n\n")
diff --git a/csharp/ql/src/Stubs/MinimalStubsFromSource.ql b/csharp/ql/src/Stubs/MinimalStubsFromSource.ql
deleted file mode 100644
index 14df8576caa5..000000000000
--- a/csharp/ql/src/Stubs/MinimalStubsFromSource.ql
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Tool to generate C# stubs from a qltest snapshot.
- *
- * It finds all declarations used in the source code,
- * and generates minimal C# stubs containing those declarations
- * and their dependencies.
- */
-
-import csharp
-import Stubs
-
-/** Declarations used by source code. */
-class UsedInSource extends GeneratedDeclaration {
- UsedInSource() {
- (
- this = any(Access a).getTarget()
- or
- this = any(Call c).getTarget()
- or
- this = any(TypeMention tm).getType()
- or
- exists(Virtualizable v | v.fromSource() |
- this = v.getImplementee() or this = v.getOverridee()
- )
- or
- this = any(Attribute a).getType().getAConstructor()
- ) and
- this.fromLibrary()
- }
-}
-
-/** Exclude types from these standard assemblies. */
-private class DefaultLibs extends ExcludedAssembly {
- DefaultLibs() {
- this.getName() = "System.Private.CoreLib" or
- this.getName() = "mscorlib" or
- this.getName() = "System.Runtime"
- }
-}
-
-select concat(generatedCode(_) + "\n\n")
diff --git a/csharp/ql/src/Stubs/Stubs.qll b/csharp/ql/src/Stubs/Stubs.qll
deleted file mode 100644
index 78cd18c34ec8..000000000000
--- a/csharp/ql/src/Stubs/Stubs.qll
+++ /dev/null
@@ -1,965 +0,0 @@
-/**
- * Generates C# stubs for use in test code.
- *
- * Extend the abstract class `GeneratedDeclaration` with the declarations that should be generated.
- * This will generate stubs for all the required dependencies as well.
- *
- * Use
- * ```ql
- * select generatedCode()
- * ```
- * to retrieve the generated C# code.
- */
-
-import csharp
-private import semmle.code.csharp.commons.QualifiedName
-private import semmle.code.csharp.frameworks.System
-private import semmle.code.dotnet.DotNet as DotNet // added to handle VoidType as a ValueOrRefType
-
-/** An element that should be in the generated code. */
-abstract class GeneratedElement extends Element { }
-
-/** A member that should be in the generated code. */
-abstract class GeneratedMember extends Member, GeneratedElement { }
-
-/** Class representing all `struct`s, such as user defined ones and built-in ones, like `int`. */
-private class StructExt extends Type {
- StructExt() {
- this instanceof Struct or
- this instanceof SimpleType or
- this instanceof VoidType or
- this instanceof SystemIntPtrType
- }
-}
-
-/** A type that should be in the generated code. */
-abstract private class GeneratedType extends Type, GeneratedElement {
- GeneratedType() {
- (
- this instanceof Interface
- or
- this instanceof Class
- or
- this instanceof StructExt
- or
- this instanceof Enum
- or
- this instanceof DelegateType
- ) and
- not this instanceof ConstructedType and
- not this.getALocation() instanceof ExcludedAssembly
- }
-
- /**
- * Holds if this type is defined in multiple assemblies, and at least one of
- * them is in the `Microsoft.NETCore.App.Ref` folder. In this case, we only stub
- * the type in the assembly in `Microsoft.NETCore.App.Ref`. In case there are
- * multiple assemblies in this folder, then we prefer `System.Runtime`.
- */
- private predicate isDuplicate(Assembly assembly) {
- // type exists in multiple assemblies
- count(this.getALocation().(Assembly)) > 1 and
- // at least one of them is in the `Microsoft.NETCore.App.Ref` folder
- this.getALocation()
- .(Assembly)
- .getFile()
- .getAbsolutePath()
- .matches("%Microsoft.NETCore.App.Ref%") and
- exists(int i |
- i =
- count(Assembly a |
- this.getALocation() = a and
- a.getFile().getAbsolutePath().matches("%Microsoft.NETCore.App.Ref%")
- )
- |
- i = 1 and
- // assemblies not in `Microsoft.NETCore.App.Ref` folder are considered duplicates
- not assembly.getFile().getAbsolutePath().matches("%Microsoft.NETCore.App.Ref%")
- or
- i > 1 and
- // one of the assemblies is named `System.Runtime`
- this.getALocation().(Assembly).getName() = "System.Runtime" and
- // all others are considered duplicates
- assembly.getName() != "System.Runtime"
- )
- }
-
- predicate isInAssembly(Assembly assembly) { this.getALocation() = assembly }
-
- private string stubKeyword() {
- this instanceof Interface and result = "interface"
- or
- this instanceof StructExt and result = "struct"
- or
- this instanceof Class and result = "class"
- or
- this instanceof Enum and result = "enum"
- or
- this instanceof DelegateType and result = "delegate"
- }
-
- private string stubAbstractModifier() {
- if this.(Class).isAbstract() then result = "abstract " else result = ""
- }
-
- private string stubStaticModifier() {
- if this.isStatic() then result = "static " else result = ""
- }
-
- private string stubPartialModifier() {
- if
- count(Assembly a | this.getALocation() = a) <= 1 or
- this instanceof Enum
- then result = ""
- else result = "partial "
- }
-
- private string stubAttributes() {
- if this.(ValueOrRefType).getAnAttribute().getType().hasQualifiedName("System", "FlagsAttribute")
- then result = "[System.Flags]\n"
- else result = ""
- }
-
- /** Gets the entire C# stub code for this type. */
- pragma[nomagic]
- final string getStub(Assembly assembly) {
- this.isInAssembly(assembly) and
- if this.isDuplicate(assembly)
- then
- result =
- "/* Duplicate type '" + this.getName() + "' is not stubbed in this assembly '" +
- assembly.toString() + "'. */\n\n"
- else (
- not this instanceof DelegateType and
- result =
- this.stubAttributes() + stubUnsafe(this) + stubAccessibility(this) +
- this.stubAbstractModifier() + this.stubStaticModifier() + this.stubPartialModifier() +
- this.stubKeyword() + " " + this.getUndecoratedName() + stubGenericArguments(this) +
- this.stubBaseTypesString() + stubTypeParametersConstraints(this) + "\n{\n" +
- this.stubPrivateConstructor() + this.stubMembers(assembly) + "}\n\n"
- or
- result =
- this.stubAttributes() + stubUnsafe(this) + stubAccessibility(this) + this.stubKeyword() +
- " " + stubClassName(this.(DelegateType).getReturnType()) + " " + this.getUndecoratedName()
- + stubGenericArguments(this) + "(" + stubParameters(this) + ");\n\n"
- )
- }
-
- private ValueOrRefType getAnInterestingBaseType() {
- result = this.(ValueOrRefType).getABaseType() and
- not result instanceof ObjectType and
- not result.hasQualifiedName("System", "ValueType") and
- (not result instanceof Interface or result.(Interface).isEffectivelyPublic())
- }
-
- private string stubBaseTypesString() {
- if this instanceof Enum
- then result = " : " + this.(Enum).getUnderlyingType().toStringWithTypes()
- else
- if exists(this.getAnInterestingBaseType())
- then
- result =
- " : " +
- concat(int i, ValueOrRefType t |
- t = this.getAnInterestingBaseType() and
- (if t instanceof Class then i = 0 else i = 1)
- |
- stubClassName(t), ", " order by i, t.getQualifiedName()
- )
- else result = ""
- }
-
- language[monotonicAggregates]
- private string stubMembers(Assembly assembly) {
- result =
- concat(GeneratedMember m |
- m = this.getAGeneratedMember(assembly)
- |
- stubMember(m, assembly)
- order by
- m.getQualifiedNameWithTypes(), stubExplicitImplementation(m)
- )
- }
-
- string stubPrivateConstructor() {
- if
- this instanceof Interface
- or
- this.isStatic()
- or
- this.isAbstract()
- or
- exists(this.(ValueOrRefType).getAConstructor())
- or
- not exists(this.getAnInterestingBaseType())
- or
- not exists(this.getAnInterestingBaseType().getAConstructor())
- or
- exists(Constructor bc |
- bc = this.getAnInterestingBaseType().getAConstructor() and
- bc.getNumberOfParameters() = 0 and
- not bc.isStatic()
- )
- then result = ""
- else
- result =
- " private " + this.getUndecoratedName() + "() : base(" +
- stubDefaultArguments(getBaseConstructor(this), this) + ")" + " => throw null;\n"
- }
-
- private GeneratedMember getAGeneratedMember() { result.getDeclaringType() = this }
-
- pragma[noinline]
- private GeneratedMember getAGeneratedMember(Assembly assembly) {
- result = this.getAGeneratedMember() and assembly = result.getALocation()
- }
-
- final Type getAGeneratedType() {
- result = this.getAnInterestingBaseType()
- or
- result = this.getAGeneratedMember().(Callable).getReturnType()
- or
- result = this.getAGeneratedMember().(Callable).getAParameter().getType()
- or
- result = this.getAGeneratedMember().(Property).getType()
- or
- result = this.getAGeneratedMember().(Field).getType()
- }
-}
-
-/**
- * A declaration that should be generated.
- * This is extended in client code to identify the actual
- * declarations that should be generated.
- */
-abstract class GeneratedDeclaration extends Modifiable {
- GeneratedDeclaration() { this.isEffectivelyPublic() }
-}
-
-private class IndirectType extends GeneratedType {
- IndirectType() {
- this.(ValueOrRefType).getASubType() instanceof GeneratedType
- or
- this.(ValueOrRefType).getAChildType() instanceof GeneratedType
- or
- this.(UnboundGenericType).getAConstructedGeneric().getASubType() instanceof GeneratedType
- or
- exists(GeneratedType t |
- this = getAContainedType(t.getAGeneratedType()).getUnboundDeclaration()
- )
- or
- exists(GeneratedDeclaration decl |
- decl.(Member).getDeclaringType().getUnboundDeclaration() = this
- )
- }
-}
-
-private class RootGeneratedType extends GeneratedType {
- RootGeneratedType() { this = any(GeneratedDeclaration decl).getUnboundDeclaration() }
-}
-
-private Type getAContainedType(Type t) {
- result = t
- or
- result = getAContainedType(t.(ConstructedType).getATypeArgument())
-}
-
-private class RootGeneratedMember extends GeneratedMember {
- RootGeneratedMember() { this = any(GeneratedDeclaration d).getUnboundDeclaration() }
-}
-
-private predicate declarationExists(Virtualizable m) {
- m instanceof GeneratedMember
- or
- m.getLocation() instanceof ExcludedAssembly
-}
-
-private class InheritedMember extends GeneratedMember, Virtualizable {
- InheritedMember() {
- declarationExists(this.getImplementee+())
- or
- declarationExists(this.getAnImplementor+())
- or
- declarationExists(this.getOverridee+())
- or
- declarationExists(this.getAnOverrider+())
- }
-}
-
-private class ExtraGeneratedConstructor extends GeneratedMember, Constructor {
- ExtraGeneratedConstructor() {
- not this.isStatic() and
- not this.isEffectivelyPublic() and
- this.getDeclaringType() instanceof GeneratedType and
- (
- // if the base class has no 0 parameter constructor
- not exists(Constructor c |
- c = this.getDeclaringType().getBaseClass().getAMember() and
- c.getNumberOfParameters() = 0 and
- not c.isStatic()
- )
- or
- // if this constructor might be called from a (generic) derived class
- exists(Class c |
- this.getDeclaringType() = c.getBaseClass().getUnboundDeclaration() and
- this = getBaseConstructor(c).getUnboundDeclaration()
- )
- )
- }
-}
-
-/** A namespace that contains at least one generated type. */
-private class GeneratedNamespace extends Namespace, GeneratedElement {
- GeneratedNamespace() {
- this.getATypeDeclaration() instanceof GeneratedType
- or
- this.getAChildNamespace() instanceof GeneratedNamespace
- }
-
- private string getPreamble() {
- if this.isGlobalNamespace()
- then result = ""
- else result = "namespace " + this.getName() + "\n{\n"
- }
-
- private string getPostAmble() { if this.isGlobalNamespace() then result = "" else result = "}\n" }
-
- final string getStubs(Assembly assembly) {
- result =
- this.getPreamble() + this.getTypeStubs(assembly) + this.getSubNamespaceStubs(assembly) +
- this.getPostAmble()
- }
-
- /** Gets the `n`th generated child namespace, indexed from 0. */
- pragma[nomagic]
- final GeneratedNamespace getChildNamespace(int n) {
- result.getParentNamespace() = this and
- result.getName() =
- rank[n + 1](GeneratedNamespace g | g.getParentNamespace() = this | g.getName())
- }
-
- final int getChildNamespaceCount() {
- result = count(GeneratedNamespace g | g.getParentNamespace() = this)
- }
-
- private predicate isInAssembly(Assembly assembly) {
- any(GeneratedType gt | gt.(DotNet::ValueOrRefType).getDeclaringNamespace() = this)
- .isInAssembly(assembly)
- or
- this.getChildNamespace(_).isInAssembly(assembly)
- }
-
- language[monotonicAggregates]
- string getSubNamespaceStubs(Assembly assembly) {
- this.isInAssembly(assembly) and
- result =
- concat(GeneratedNamespace child, int i |
- child = this.getChildNamespace(i) and child.isInAssembly(assembly)
- |
- child.getStubs(assembly) order by i
- )
- }
-
- string getTypeStubs(Assembly assembly) {
- this.isInAssembly(assembly) and
- result =
- concat(GeneratedType gt |
- gt.(DotNet::ValueOrRefType).getDeclaringNamespace() = this and gt.isInAssembly(assembly)
- |
- gt.getStub(assembly) order by gt.getName()
- )
- }
-}
-
-/**
- * Specify assemblies to exclude.
- * Do not generate any types from these assemblies.
- */
-abstract class ExcludedAssembly extends Assembly { }
-
-private Virtualizable getAccessibilityDeclaringVirtualizable(Virtualizable v) {
- if not v.isOverride()
- then result = v
- else
- if not v.getOverridee().getLocation() instanceof ExcludedAssembly
- then result = getAccessibilityDeclaringVirtualizable(v.getOverridee())
- else result = v
-}
-
-private string stubAccessibility(Member m) {
- if
- m.getDeclaringType() instanceof Interface
- or
- exists(getExplicitImplementedInterface(m))
- or
- m instanceof Constructor and m.isStatic()
- then result = ""
- else
- if m.isPublic()
- then result = "public "
- else
- if m.isProtected()
- then
- if m.isPrivate() or getAccessibilityDeclaringVirtualizable(m).isPrivate()
- then result = "protected private "
- else
- if m.isInternal() or getAccessibilityDeclaringVirtualizable(m).isInternal()
- then result = "protected internal "
- else result = "protected "
- else
- if m.isPrivate()
- then result = "private "
- else
- if m.isInternal()
- then result = "internal "
- else result = "unknown-accessibility"
-}
-
-private string stubModifiers(Member m) {
- result = stubUnsafe(m) + stubAccessibility(m) + stubStaticOrConst(m) + stubOverride(m)
-}
-
-private string stubUnsafe(Member m) {
- if m.(Modifiable).isUnsafe() then result = "unsafe " else result = ""
-}
-
-private string stubStaticOrConst(Member m) {
- if m.(Modifiable).isStatic()
- then result = "static "
- else
- if m.(Modifiable).isConst()
- then result = "const "
- else result = ""
-}
-
-private string stubOverride(Member m) {
- if m.getDeclaringType() instanceof Interface and not m.isStatic()
- then result = ""
- else
- if m.(Virtualizable).isVirtual()
- then result = "virtual "
- else
- if m.(Virtualizable).isAbstract()
- then
- if m.(Virtualizable).isOverride()
- then result = "abstract override "
- else result = "abstract "
- else
- if m.(Virtualizable).isOverride()
- then result = "override "
- else result = ""
-}
-
-private string stubQualifiedNamePrefix(ValueOrRefType t) {
- if t.getParent() instanceof GlobalNamespace
- then result = ""
- else
- if t.getParent() instanceof Namespace
- then result = t.getDeclaringNamespace().getFullName() + "."
- else result = stubClassName(t.getDeclaringType()) + "."
-}
-
-language[monotonicAggregates]
-private string stubClassName(Type t) {
- if t instanceof ObjectType
- then result = "object"
- else
- if t instanceof StringType
- then result = "string"
- else
- if t instanceof IntType
- then result = "int"
- else
- if t instanceof BoolType
- then result = "bool"
- else
- if t instanceof VoidType
- then result = "void"
- else
- if t instanceof FloatType
- then result = "float"
- else
- if t instanceof DoubleType
- then result = "double"
- else
- if t instanceof NullableType
- then result = stubClassName(t.(NullableType).getUnderlyingType()) + "?"
- else
- if t instanceof TypeParameter
- then result = t.getName()
- else
- if t instanceof ArrayType
- then result = stubClassName(t.(ArrayType).getElementType()) + "[]"
- else
- if t instanceof PointerType
- then result = stubClassName(t.(PointerType).getReferentType()) + "*"
- else
- if t instanceof TupleType
- then
- exists(TupleType tt | tt = t |
- if tt.getArity() < 2
- then result = stubClassName(tt.getUnderlyingType())
- else
- result =
- "(" +
- concat(int i, Type element |
- element = tt.getElementType(i)
- |
- stubClassName(element), "," order by i
- ) + ")"
- )
- else
- if t instanceof FunctionPointerType
- then
- exists(
- FunctionPointerType fpt, CallingConvention callconvention,
- string calltext
- |
- fpt = t
- |
- callconvention = fpt.getCallingConvention() and
- (
- if callconvention instanceof UnmanagedCallingConvention
- then calltext = "unmanaged"
- else calltext = ""
- ) and
- result =
- "delegate* " + calltext + "<" +
- concat(int i, Parameter p |
- p = fpt.getParameter(i)
- |
- stubClassName(p.getType()) + "," order by i
- ) + stubClassName(fpt.getReturnType()) + ">"
- )
- else
- if t instanceof ValueOrRefType
- then
- result =
- stubQualifiedNamePrefix(t) + t.getUndecoratedName() +
- stubGenericArguments(t)
- else result = ""
-}
-
-language[monotonicAggregates]
-private string stubGenericArguments(Type t) {
- if t instanceof UnboundGenericType
- then
- result =
- "<" +
- concat(int n |
- exists(t.(UnboundGenericType).getTypeParameter(n))
- |
- t.(UnboundGenericType).getTypeParameter(n).getName(), "," order by n
- ) + ">"
- else
- if t instanceof ConstructedType
- then
- result =
- "<" +
- concat(int n |
- exists(t.(ConstructedType).getTypeArgument(n))
- |
- stubClassName(t.(ConstructedType).getTypeArgument(n)), "," order by n
- ) + ">"
- else result = ""
-}
-
-private string stubGenericMethodParams(Method m) {
- if m instanceof UnboundGenericMethod
- then
- result =
- "<" +
- concat(int n, TypeParameter param |
- param = m.(UnboundGenericMethod).getTypeParameter(n)
- |
- param.getName(), "," order by n
- ) + ">"
- else result = ""
-}
-
-private string stubConstraints(TypeParameterConstraints tpc, int i) {
- tpc.hasConstructorConstraint() and result = "new()" and i = 4
- or
- tpc.hasUnmanagedTypeConstraint() and result = "unmanaged" and i = 0
- or
- tpc.hasValueTypeConstraint() and
- result = "struct" and
- i = 0 and
- not tpc.hasUnmanagedTypeConstraint() and
- not stubClassName(tpc.getATypeConstraint().(Class)) = "System.Enum"
- or
- tpc.hasRefTypeConstraint() and result = "class" and i = 0
- or
- result = tpc.getATypeConstraint().(TypeParameter).getName() and i = 3
- or
- result = stubClassName(tpc.getATypeConstraint().(Interface)) and i = 2
- or
- result = stubClassName(tpc.getATypeConstraint().(Class)) and i = 1
-}
-
-private string stubTypeParameterConstraints(TypeParameter tp) {
- if
- tp.getDeclaringGeneric().(Virtualizable).isOverride() or
- tp.getDeclaringGeneric().(Virtualizable).implementsExplicitInterface()
- then
- if tp.getConstraints().hasValueTypeConstraint()
- then result = " where " + tp.getName() + ": struct"
- else
- if tp.getConstraints().hasRefTypeConstraint()
- then result = " where " + tp.getName() + ": class"
- else result = ""
- else
- exists(TypeParameterConstraints tpc | tpc = tp.getConstraints() |
- result =
- " where " + tp.getName() + ": " +
- strictconcat(string s, int i | s = stubConstraints(tpc, i) | s, ", " order by i)
- )
-}
-
-private string stubTypeParametersConstraints(Declaration d) {
- if d instanceof UnboundGeneric
- then
- result =
- concat(TypeParameter tp |
- tp = d.(UnboundGeneric).getATypeParameter()
- |
- stubTypeParameterConstraints(tp), " "
- )
- else result = ""
-}
-
-private string stubImplementation(Virtualizable c) {
- if c.isAbstract() then result = "" else result = " => throw null"
-}
-
-private predicate isKeyword(string s) {
- s =
- [
- "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
- "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
- "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach",
- "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long",
- "namespace", "new", "null", "object", "operator", "out", "override", "params", "private",
- "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",
- "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try",
- "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void",
- "volatile", "while"
- ]
-}
-
-bindingset[s]
-private string escapeIfKeyword(string s) { if isKeyword(s) then result = "@" + s else result = s }
-
-private string stubParameters(Parameterizable p) {
- result =
- concat(int i, Parameter param |
- param = p.getParameter(i) and not param.getType() instanceof ArglistType
- |
- stubParameterModifiers(param) + stubClassName(param.getType()) + " " +
- escapeIfKeyword(param.getName()) + stubDefaultValue(param), ", "
- order by
- i
- )
-}
-
-private string stubDefaultArguments(Constructor baseCtor, ValueOrRefType callingType) {
- baseCtor = getBaseConstructor(callingType) and
- baseCtor.getNumberOfParameters() > 0 and
- result =
- concat(int i, Parameter param |
- param = baseCtor.getParameter(i) and not param.getType() instanceof ArglistType
- |
- "default(" + stubClassName(param.getType()) + ")", ", " order by i
- )
-}
-
-private string stubParameterModifiers(Parameter p) {
- if p.isOut()
- then result = "out "
- else
- if p.isRef()
- then result = "ref "
- else
- if p.isParams()
- then result = "params "
- else
- if p.isIn()
- then result = "" // Only C# 7.1 so ignore
- else
- if p.hasExtensionMethodModifier()
- then result = "this "
- else result = ""
-}
-
-private string stubDefaultValue(Parameter p) {
- if p.hasDefaultValue()
- then result = " = default(" + stubClassName(p.getType()) + ")"
- else result = ""
-}
-
-private string stubEventAccessors(Event e) {
- if exists(e.(Virtualizable).getExplicitlyImplementedInterface())
- then result = " { add => throw null; remove => throw null; }"
- else result = ";"
-}
-
-/**
- * Returns an interface that `c` explicitly implements, if either of the
- * following also holds.
- * (1) `c` is not static.
- * (2) `c` is static and an implementation of a generic with type constraints.
- * (3) `c` is static and there is another member with the same name
- * but different return type.
- *
- * We use these rules as explicit interfaces are needed in some cases
- * for compilation purposes (both to distinguish members but also to ensure
- * type constraints are satisfied). We can't always use explicit interface
- * implementation due to the generic math support, because then in some cases
- * we will only be able to access a static via a type variable with type
- * constraints (C# 11 language feature).
- */
-private Interface getExplicitImplementedInterface(Virtualizable c) {
- result = unique(Interface i | i = c.getExplicitlyImplementedInterface()) and
- (
- not c.isStatic()
- or
- c.isStatic() and
- (
- not c instanceof Method
- or
- c instanceof Method and
- (
- exists(TypeParameter t | t = c.getImplementee().(UnboundGeneric).getATypeParameter() |
- exists(t.getConstraints().getATypeConstraint())
- )
- or
- exists(Member m |
- (not m.isStatic() or m.(Method).getReturnType() != c.(Method).getReturnType()) and
- m.getName() = c.getName() and
- m.getDeclaringType() = c.getDeclaringType()
- )
- )
- )
- )
-}
-
-private string stubExplicitImplementation(Member c) {
- if exists(getExplicitImplementedInterface(c))
- then result = stubClassName(getExplicitImplementedInterface(c)) + "."
- else result = ""
-}
-
-pragma[noinline]
-private string stubMethod(Method m, Assembly assembly) {
- m instanceof GeneratedMember and
- m.getALocation() = assembly and
- if not m.getDeclaringType() instanceof Enum
- then
- result =
- " " + stubModifiers(m) + stubClassName(m.getReturnType()) + " " +
- stubExplicitImplementation(m) + escapeIfKeyword(m.getUndecoratedName()) +
- stubGenericMethodParams(m) + "(" + stubParameters(m) + ")" +
- stubTypeParametersConstraints(m) + stubImplementation(m) + ";\n"
- else result = " // Stub generator skipped method: " + m.getName() + "\n"
-}
-
-pragma[noinline]
-private string stubOperator(Operator o, Assembly assembly) {
- o instanceof GeneratedMember and
- o.getALocation() = assembly and
- if o instanceof ConversionOperator
- then
- result =
- " " + stubModifiers(o) + stubExplicit(o) + stubExplicitImplementation(o) + "operator " +
- stubChecked(o) + stubClassName(o.getReturnType()) + "(" + stubParameters(o) + ")" +
- stubImplementation(o) + ";\n"
- else
- if not o.getDeclaringType() instanceof Enum
- then
- result =
- " " + stubModifiers(o) + stubClassName(o.getReturnType()) + " " +
- stubExplicitImplementation(o) + "operator " + o.getName() + "(" + stubParameters(o) + ")" +
- stubImplementation(o) + ";\n"
- else result = " // Stub generator skipped operator: " + o.getName() + "\n"
-}
-
-pragma[noinline]
-private string stubEnumConstant(EnumConstant ec, Assembly assembly) {
- ec instanceof GeneratedMember and
- ec.getALocation() = assembly and
- result = " " + escapeIfKeyword(ec.getName()) + " = " + ec.getValue() + ",\n"
-}
-
-pragma[noinline]
-private string stubProperty(Property p, Assembly assembly) {
- p instanceof GeneratedMember and
- p.getALocation() = assembly and
- result =
- " " + stubModifiers(p) + stubClassName(p.getType()) + " " + stubExplicitImplementation(p) +
- escapeIfKeyword(p.getName()) + " { " + stubGetter(p) + stubSetter(p) + "}\n"
-}
-
-pragma[noinline]
-private string stubConstructor(Constructor c, Assembly assembly) {
- c instanceof GeneratedMember and
- c.getALocation() = assembly and
- if c.getDeclaringType() instanceof Enum
- then result = ""
- else
- if
- not c.getDeclaringType() instanceof StructExt or
- c.getNumberOfParameters() > 0
- then
- result =
- " " + stubModifiers(c) + escapeIfKeyword(c.getName()) + "(" + stubParameters(c) + ")" +
- stubConstructorInitializer(c) + " => throw null;\n"
- else result = " // Stub generator skipped constructor \n"
-}
-
-pragma[noinline]
-private string stubIndexer(Indexer i, Assembly assembly) {
- i instanceof GeneratedMember and
- i.getALocation() = assembly and
- result =
- " " + stubIndexerNameAttribute(i) + stubModifiers(i) + stubClassName(i.getType()) + " " +
- stubExplicitImplementation(i) + "this[" + stubParameters(i) + "] { " + stubGetter(i) +
- stubSetter(i) + "}\n"
-}
-
-pragma[noinline]
-private string stubField(Field f, Assembly assembly) {
- f instanceof GeneratedMember and
- f.getALocation() = assembly and
- not f instanceof EnumConstant and // EnumConstants are already stubbed
- exists(string impl |
- (if f.isConst() then impl = " = default" else impl = "") and
- result =
- " " + stubModifiers(f) + stubClassName(f.getType()) + " " + escapeIfKeyword(f.getName()) +
- impl + ";\n"
- )
-}
-
-pragma[noinline]
-private string stubEvent(Event e, Assembly assembly) {
- e instanceof GeneratedMember and
- e.getALocation() = assembly and
- result =
- " " + stubModifiers(e) + "event " + stubClassName(e.getType()) + " " +
- stubExplicitImplementation(e) + escapeIfKeyword(e.getName()) + stubEventAccessors(e) + "\n"
-}
-
-pragma[nomagic]
-private string stubMember(GeneratedMember m, Assembly assembly) {
- result = stubMethod(m, assembly)
- or
- result = stubOperator(m, assembly)
- or
- result = stubEnumConstant(m, assembly)
- or
- result = stubProperty(m, assembly)
- or
- result = stubConstructor(m, assembly)
- or
- result = stubIndexer(m, assembly)
- or
- result = stubField(m, assembly)
- or
- result = stubEvent(m, assembly)
- or
- not m instanceof Method and
- not m instanceof Operator and
- not m instanceof EnumConstant and
- not m instanceof Property and
- not m instanceof Constructor and
- not m instanceof Indexer and
- not m instanceof Field and
- not m instanceof Event and
- m.getALocation() = assembly and
- (
- result = m.(GeneratedType).getStub(assembly) + "\n"
- or
- not m instanceof GeneratedType and
- result = " // ERR: Stub generator didn't handle member: " + m.getName() + "\n"
- )
-}
-
-private string stubIndexerNameAttribute(Indexer i) {
- if i.getName() != "Item"
- then result = "[System.Runtime.CompilerServices.IndexerName(\"" + i.getName() + "\")]\n "
- else result = ""
-}
-
-private Constructor getBaseConstructor(ValueOrRefType type) {
- result =
- min(Constructor bc |
- type.getBaseClass().getAMember() = bc and
- // not the `static` constructor
- not bc.isStatic() and
- // not a `private` constructor, unless it's `private protected`, or if the derived class is nested
- (not bc.isPrivate() or bc.isProtected() or bc.getDeclaringType() = type.getDeclaringType+())
- |
- bc order by bc.getNumberOfParameters(), stubParameters(bc)
- )
-}
-
-private string stubConstructorInitializer(Constructor c) {
- exists(Constructor baseCtor |
- baseCtor = getBaseConstructor(c.getDeclaringType()) and
- if baseCtor.getNumberOfParameters() = 0 or c.isStatic()
- then result = ""
- else result = " : base(" + stubDefaultArguments(baseCtor, c.getDeclaringType()) + ")"
- )
- or
- // abstract base class might not have a constructor
- not exists(Constructor baseCtor |
- c.getDeclaringType().getBaseClass().getAMember() = baseCtor and not baseCtor.isStatic()
- ) and
- result = ""
-}
-
-private string stubExplicit(ConversionOperator op) {
- op instanceof ImplicitConversionOperator and result = "implicit "
- or
- (
- op instanceof ExplicitConversionOperator
- or
- op instanceof CheckedExplicitConversionOperator
- ) and
- result = "explicit "
-}
-
-private string stubChecked(Operator o) {
- if o instanceof CheckedExplicitConversionOperator then result = "checked " else result = ""
-}
-
-private string stubGetter(DeclarationWithGetSetAccessors p) {
- if exists(p.getGetter())
- then if p.isAbstract() then result = "get; " else result = "get => throw null; "
- else result = ""
-}
-
-private string stubSetter(DeclarationWithGetSetAccessors p) {
- if exists(p.getSetter())
- then if p.isAbstract() then result = "set; " else result = "set => throw null; "
- else result = ""
-}
-
-private string stubSemmleExtractorOptions() {
- result =
- concat(string s |
- exists(CommentLine comment |
- s =
- "// original-extractor-options:" +
- comment.getText().regexpCapture("\\w*semmle-extractor-options:(.*)", 1) + "\n"
- )
- )
-}
-
-/** Gets the generated C# code. */
-string generatedCode(Assembly assembly) {
- result =
- "// This file contains auto-generated code.\n" //
- + "// Generated from `" + assembly.getFullName() + "`.\n" //
- + stubSemmleExtractorOptions() + "\n" //
- + any(GeneratedNamespace ns | ns.isGlobalNamespace()).getStubs(assembly)
-}
diff --git a/csharp/ql/src/Stubs/make_stubs.py b/csharp/ql/src/Stubs/make_stubs.py
deleted file mode 100644
index e66371f2b957..000000000000
--- a/csharp/ql/src/Stubs/make_stubs.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Tool to generate 'stub.cs' files inside C# qltest projects.
-# The purpose of this is to stub out assemblies from the qltest case
-# so that the test is self-contained and will still run without them.
-#
-# To do this, it
-# 1. Performs a regular qltest to generate a snapshot
-# 2. Runs a QL query on the snapshot to find out which symbols are needed,
-# then uses QL to generate a string of C# code.
-# 3. Re-runs the test to ensure that it still compiles and passes.
-
-import sys
-import os
-import subprocess
-import helpers
-
-print('Script to generate stub.cs files for C# qltest projects')
-
-if len(sys.argv) < 2:
- print("Please supply a qltest directory.")
- exit(1)
-
-testDir = sys.argv[1]
-
-if not os.path.isdir(testDir):
- print("Directory", testDir, "does not exist")
- exit(1)
-
-# Does it contain a .ql file and a .cs file?
-
-foundCS = False
-foundQL = False
-
-for file in os.listdir(testDir):
- if file.endswith(".cs"):
- foundCS = True
- if file.endswith(".ql") or file.endswith(".qlref"):
- foundQL = True
-
-if not foundQL:
- print("Test directory does not contain .ql files. Please specify a working qltest directory.")
- exit(1)
-
-if not foundCS:
- print("Test directory does not contain .cs files. Please specify a working qltest directory.")
- exit(1)
-
-csharpQueries = os.path.abspath(os.path.dirname(sys.argv[0]))
-outputFile = os.path.join(testDir, 'stubs.cs')
-bqrsFile = os.path.join(testDir, 'stubs.bqrs')
-
-print("Stubbing qltest in", testDir)
-
-if os.path.isfile(outputFile):
- os.remove(outputFile) # It would interfere with the test.
- print("Removed previous", outputFile)
-
-helpers.run_cmd(['codeql', 'test', 'run', '--keep-databases', testDir],
- "codeql test failed. Please fix up the test before proceeding.")
-
-dbDir = os.path.join(testDir, os.path.basename(testDir) + ".testproj")
-
-if not os.path.isdir(dbDir):
- print("Expected database directory " + dbDir + " not found.")
- exit(1)
-
-helpers.run_cmd(['codeql', 'query', 'run', os.path.join(
- csharpQueries, 'MinimalStubsFromSource.ql'), '--database', dbDir, '--output', bqrsFile], 'Failed to run the query to generate output file.')
-
-helpers.run_cmd(['codeql', 'bqrs', 'decode', bqrsFile, '--output',
- outputFile, '--format=text', '--no-titles'], 'Failed to run the query to generate output file.')
-
-helpers.trim_output_file(outputFile)
-
-if os.path.isfile(bqrsFile):
- os.remove(bqrsFile) # Cleanup
- print("Removed temp BQRS file", bqrsFile)
-
-cmd = ['codeql', 'test', 'run', testDir]
-print('Running ' + ' '.join(cmd))
-if subprocess.check_call(cmd):
- print('\nTest failed. You may need to fix up', outputFile)
- print('It may help to view', outputFile, ' in Visual Studio')
- print("Next steps:")
- print('1. Look at the compilation errors, and fix up',
- outputFile, 'so that the test compiles')
- print('2. Re-run codeql test run "' + testDir + '"')
- print('3. git add "' + outputFile + '"')
- exit(1)
-
-print("\nStub generation successful! Next steps:")
-print('1. Edit "semmle-extractor-options" in the .cs files to remove unused references')
-print('2. Re-run codeql test run "' + testDir + '"')
-print('3. git add "' + outputFile + '"')
-print('4. Commit your changes.')
-
-exit(0)
diff --git a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected
index fe29160c8e08..dc7bc9330d99 100644
--- a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected
+++ b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected
@@ -90,6 +90,22 @@ arguments
| attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 |
| attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 |
| attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" |
+| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" |
+| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" |
+| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" |
+| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 |
+| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" |
+| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" |
+| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 |
+| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" |
+| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" |
+| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] |
constructorArguments
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 1 |
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 3 |
@@ -170,6 +186,22 @@ constructorArguments
| attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 |
| attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 |
| attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" |
+| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" |
+| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 |
+| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" |
+| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" |
+| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 |
+| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 |
+| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" |
+| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" |
+| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 |
+| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" |
+| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" |
+| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] |
namedArguments
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |
diff --git a/csharp/ql/test/library-tests/attributes/AttributeElements.expected b/csharp/ql/test/library-tests/attributes/AttributeElements.expected
index ffdef293b70d..11291a73338b 100644
--- a/csharp/ql/test/library-tests/attributes/AttributeElements.expected
+++ b/csharp/ql/test/library-tests/attributes/AttributeElements.expected
@@ -32,6 +32,10 @@
| attributes.cs:126:9:126:11 | get_Prop1 | attributes.cs:125:18:125:29 | [return: My3(...)] | My3Attribute |
| attributes.cs:130:9:130:11 | set_Prop1 | attributes.cs:128:10:128:21 | [My3(...)] | My3Attribute |
| attributes.cs:130:9:130:11 | value | attributes.cs:129:17:129:28 | [My3(...)] | My3Attribute |
+| attributes.cs:142:17:142:18 | M1 | attributes.cs:141:6:141:11 | [Params(...)] | Class1+ParamsAttribute |
+| attributes.cs:145:17:145:18 | M2 | attributes.cs:144:6:144:11 | [Params(...)] | Class1+ParamsAttribute |
+| attributes.cs:148:17:148:18 | M3 | attributes.cs:147:6:147:11 | [Params(...)] | Class1+ParamsAttribute |
+| attributes.cs:151:17:151:18 | M4 | attributes.cs:150:6:150:11 | [Params(...)] | Class1+ParamsAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:10:12:10:24 | [assembly: AssemblyTitle(...)] | System.Reflection.AssemblyTitleAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:11:12:11:30 | [assembly: AssemblyDescription(...)] | System.Reflection.AssemblyDescriptionAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:12:12:12:32 | [assembly: AssemblyConfiguration(...)] | System.Reflection.AssemblyConfigurationAttribute |
diff --git a/csharp/ql/test/library-tests/attributes/PrintAst.expected b/csharp/ql/test/library-tests/attributes/PrintAst.expected
index c35d40d3aeb0..77be3f7461dd 100644
--- a/csharp/ql/test/library-tests/attributes/PrintAst.expected
+++ b/csharp/ql/test/library-tests/attributes/PrintAst.expected
@@ -405,3 +405,59 @@ attributes.cs:
# 130| 0: [AssignExpr] ... = ...
# 130| 0: [FieldAccess] access to field p
# 130| 1: [ParameterAccess] access to parameter value
+# 134| [Class] Class1
+# 136| 5: [Class] ParamsAttribute
+#-----| 3: (Base types)
+# 136| 0: [TypeMention] Attribute
+# 138| 4: [InstanceConstructor] ParamsAttribute
+#-----| 2: (Parameters)
+# 138| 0: [Parameter] s1
+# 138| -1: [TypeMention] string
+# 138| 1: [Parameter] s2
+# 138| -1: [TypeMention] string
+# 138| 2: [Parameter] args
+# 138| -1: [TypeMention] Int32[]
+# 138| 1: [TypeMention] int
+# 138| 4: [BlockStmt] {...}
+# 142| 6: [Method] M1
+# 142| -1: [TypeMention] Void
+#-----| 0: (Attributes)
+# 141| 1: [DefaultAttribute] [Params(...)]
+# 141| -1: [TypeMention] ParamsAttribute
+# 141| 0: [StringLiteralUtf16] "a"
+# 141| 1: [StringLiteralUtf16] "b"
+# 141| 2: [IntLiteral] 1
+# 141| 3: [IntLiteral] 2
+# 141| 4: [IntLiteral] 3
+# 142| 4: [BlockStmt] {...}
+# 145| 7: [Method] M2
+# 145| -1: [TypeMention] Void
+#-----| 0: (Attributes)
+# 144| 1: [DefaultAttribute] [Params(...)]
+# 144| -1: [TypeMention] ParamsAttribute
+# 144| 0: [StringLiteralUtf16] "a"
+# 144| 1: [StringLiteralUtf16] "b"
+# 144| 2: [IntLiteral] 1
+# 144| 3: [IntLiteral] 2
+# 144| 4: [IntLiteral] 3
+# 145| 4: [BlockStmt] {...}
+# 148| 8: [Method] M3
+# 148| -1: [TypeMention] Void
+#-----| 0: (Attributes)
+# 147| 1: [DefaultAttribute] [Params(...)]
+# 147| -1: [TypeMention] ParamsAttribute
+# 147| 0: [StringLiteralUtf16] "a"
+# 147| 1: [StringLiteralUtf16] "b"
+# 147| 2: [IntLiteral] 1
+# 148| 4: [BlockStmt] {...}
+# 151| 9: [Method] M4
+# 151| -1: [TypeMention] Void
+#-----| 0: (Attributes)
+# 150| 1: [DefaultAttribute] [Params(...)]
+# 150| -1: [TypeMention] ParamsAttribute
+# 150| 0: [StringLiteralUtf16] "a"
+# 150| 1: [StringLiteralUtf16] "b"
+# 150| 2: [ArrayCreation] array creation of type Int32[]
+# 150| -1: [ArrayInitializer] { ..., ... }
+# 150| 0: [IntLiteral] 1
+# 151| 4: [BlockStmt] {...}
diff --git a/csharp/ql/test/library-tests/attributes/attributes.cs b/csharp/ql/test/library-tests/attributes/attributes.cs
index 6790d7ff02d6..3f1018c94162 100644
--- a/csharp/ql/test/library-tests/attributes/attributes.cs
+++ b/csharp/ql/test/library-tests/attributes/attributes.cs
@@ -129,4 +129,24 @@ public int Prop1
[param: My3Attribute(14)]
set { p = value; }
}
+}
+
+class Class1
+{
+ public class ParamsAttribute : Attribute
+ {
+ public ParamsAttribute(string s1, string s2, params int[] args) { }
+ }
+
+ [Params("a", "b", 1, 2, 3)]
+ public void M1() { }
+
+ [Params(s1: "a", s2: "b", 1, 2, 3)]
+ public void M2() { }
+
+ [Params(args: 1, s2: "b", s1: "a")]
+ public void M3() { }
+
+ [Params(args: new[] { 1 }, s2: "b", s1: "a")]
+ public void M4() { }
}
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected b/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected
deleted file mode 100644
index 0fd2ca780886..000000000000
--- a/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected
+++ /dev/null
@@ -1 +0,0 @@
-| // This file contains auto-generated code.\n// Generated from `Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace A1\n{\npublic class C1\n{\n}\n\n}\nnamespace A2\n{\nnamespace B2\n{\npublic class C2\n{\n}\n\n}\n}\nnamespace A3\n{\npublic class C3\n{\n}\n\n}\nnamespace A4\n{\npublic class C4\n{\n}\n\nnamespace B4\n{\npublic class D4\n{\n}\n\n}\n}\nnamespace Test\n{\npublic class Class1\n{\npublic class Class11 : Test.Class1.Interface1, Test.Class1.Interface2\n{\n int Test.Class1.Interface2.this[int i] { get => throw null; }\n public void Method1() => throw null;\n void Test.Class1.Interface2.Method2() => throw null;\n}\n\n\npublic class Class12 : Test.Class1.Class11\n{\n}\n\n\npublic abstract class Class13\n{\n protected internal virtual void M() => throw null;\n public virtual void M1() where T: Test.Class1.Class13 => throw null;\n public abstract void M2();\n}\n\n\npublic abstract class Class14 : Test.Class1.Class13\n{\n protected internal override void M() => throw null;\n public override void M1() => throw null;\n public abstract override void M2();\n}\n\n\npublic delegate void Delegate1(T i, int j);\n\n\npublic class GenericType\n{\npublic class X\n{\n}\n\n\n}\n\n\npublic interface Interface1\n{\n void Method1();\n}\n\n\nprotected internal interface Interface2\n{\n int this[int i] { get; }\n void Method2();\n}\n\n\npublic struct Struct1\n{\n public void Method(Test.Class1.Struct1 s = default(Test.Class1.Struct1)) => throw null;\n public int i;\n public static int j = default;\n public System.ValueTuple t1;\n public (int,int) t2;\n}\n\n\n public event Test.Class1.Delegate1 Event1;\n public Test.Class1.GenericType.X Prop { get => throw null; }\n}\n\npublic class Class10\n{\n unsafe public void M1(delegate* unmanaged f) => throw null;\n}\n\npublic class Class11 : Test.IInterface2, Test.IInterface3\n{\n static Test.Class11 Test.IInterface2.operator *(Test.Class11 left, Test.Class11 right) => throw null;\n public static Test.Class11 operator +(Test.Class11 left, Test.Class11 right) => throw null;\n public static Test.Class11 operator -(Test.Class11 left, Test.Class11 right) => throw null;\n static Test.Class11 Test.IInterface2.operator /(Test.Class11 left, Test.Class11 right) => throw null;\n public void M1() => throw null;\n void Test.IInterface2.M2() => throw null;\n public static explicit operator System.Int16(Test.Class11 n) => throw null;\n static explicit Test.IInterface2.operator int(Test.Class11 n) => throw null;\n}\n\npublic class Class3\n{\n public object Item { get => throw null; set => throw null; }\n [System.Runtime.CompilerServices.IndexerName("MyItem")]\n public object this[string index] { get => throw null; set => throw null; }\n}\n\npublic class Class4\n{\n unsafe public void M(int* p) => throw null;\n}\n\npublic class Class5 : Test.IInterface1\n{\n public void M2() => throw null;\n}\n\npublic class Class6 where T: class, Test.IInterface1\n{\n public virtual void M1() where T: class, Test.IInterface1, new() => throw null;\n}\n\npublic class Class7 : Test.Class6\n{\n public override void M1() where T: class => throw null;\n}\n\npublic class Class8\n{\n public static int @this = default;\n}\n\npublic class Class9\n{\npublic class Nested : Test.Class9\n{\n}\n\n\n public Test.Class9.Nested NestedInstance { get => throw null; }\n}\n\npublic enum Enum1 : int\n{\n None1 = 0,\n Some11 = 1,\n Some12 = 2,\n}\n\npublic enum Enum2 : int\n{\n None2 = 2,\n Some21 = 1,\n Some22 = 3,\n}\n\npublic enum Enum3 : int\n{\n None3 = 2,\n Some31 = 1,\n Some32 = 0,\n}\n\npublic enum Enum4 : int\n{\n None4 = 2,\n Some41 = 7,\n Some42 = 6,\n}\n\npublic enum EnumLong : long\n{\n None = 10,\n Some = 223372036854775807,\n}\n\npublic interface IInterface1\n{\n void M1() => throw null;\n void M2();\n}\n\npublic interface IInterface2 where T: Test.IInterface2\n{\n static abstract T operator *(T left, T right);\n static abstract T operator +(T left, T right);\n static virtual T operator -(T left, T right) => throw null;\n static virtual T operator /(T left, T right) => throw null;\n void M1();\n void M2();\n static abstract explicit operator System.Int16(T n);\n static abstract explicit operator int(T n);\n}\n\npublic interface IInterface3 where T: Test.IInterface3\n{\n static abstract T operator +(T left, T right);\n static virtual T operator -(T left, T right) => throw null;\n void M1();\n static abstract explicit operator System.Int16(T n);\n}\n\nunsafe public class MyUnsafeClass\n{\n unsafe public static void M1(delegate* f) => throw null;\n unsafe public static void M2(int*[] x) => throw null;\n unsafe public static System.Char* M3() => throw null;\n public static void M4(int x) => throw null;\n}\n\n}\n\n\n |
diff --git a/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref b/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref
deleted file mode 100644
index 0f7425d26b5b..000000000000
--- a/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Stubs/AllStubsFromSource.ql
diff --git a/csharp/ql/test/query-tests/Stubs/All/Test.cs b/csharp/ql/test/query-tests/Stubs/All/Test.cs
deleted file mode 100644
index 7e3f96bb0004..000000000000
--- a/csharp/ql/test/query-tests/Stubs/All/Test.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-using System;
-
-namespace Test
-{
- public class Class1
- {
- public struct Struct1
- {
- public ValueTuple t1;
- public (int, int) t2;
-
- public int i;
- public const int j = 42;
-
- public void Method(Struct1 s = new Struct1()) => throw null;
- }
-
- public interface Interface1
- {
- void Method1();
- }
-
- internal protected interface Interface2
- {
- void Method2();
- int this[int i] { get; }
- }
-
- private protected interface Interface3
- {
- void Method3();
- }
-
- public class Class11 : Interface1, Interface2, Interface3
- {
- public Class11(int i) => throw null;
-
- public void Method1() => throw null;
-
- void Interface2.Method2() => throw null;
-
- int Interface2.this[int i] => throw null;
-
- void Interface3.Method3() => throw null;
- }
-
- public delegate void Delegate1(T i, int j);
-
- public event Delegate1 Event1 { add { } remove { } }
-
- public class Class12 : Class11
- {
- public Class12(int i, float j) : base(1) => throw null;
- }
-
- public class GenericType
- {
- public class X { }
- }
-
- public GenericType.X Prop { get; }
-
- public abstract class Class13
- {
- protected internal virtual void M() => throw null;
- public virtual void M1() where T : Class13 => throw null;
- public abstract void M2();
- }
-
- public abstract class Class14 : Class13
- {
- protected internal override void M() => throw null;
- public override void M1() => throw null;
- public abstract override void M2();
- }
-
- }
-
- internal class Class2
- {
- public void M() => throw null;
- }
-
- public class Class3
- {
- public object Item { get; set; }
- [System.Runtime.CompilerServices.IndexerName("MyItem")]
- public object this[string index] { get { return null; } set { } }
- }
-
- public class Class4
- {
- unsafe public void M(int* p) => throw null;
- }
-
- public interface IInterface1
- {
- void M1() => throw null;
- void M2();
- }
-
- public class Class5 : IInterface1
- {
- public void M2() => throw null;
- }
-
- public class Class6 where T : class, IInterface1
- {
- public Class6(int i) => throw null;
-
- public virtual void M1() where T : class, IInterface1, new() => throw null;
- }
-
- public class Class7 : Class6
- {
- public Class7(int i) : base(i) => throw null;
-
- public override void M1() where T : class => throw null;
- }
-
- public class Class8
- {
- public const int @this = 10;
- }
-
- public class Class9
- {
- private Class9(int i) => throw null;
-
- public class Nested : Class9
- {
- internal Nested(int i) : base(i) => throw null;
- }
-
- public Class9.Nested NestedInstance { get; } = new Class9.Nested(1);
- }
-
- public class Class10
- {
- unsafe public void M1(delegate* unmanaged f) => throw null;
- }
-
- public interface IInterface2 where T : IInterface2
- {
- static abstract T operator +(T left, T right);
- static virtual T operator -(T left, T right) => throw null;
- static abstract T operator *(T left, T right);
- static virtual T operator /(T left, T right) => throw null;
- static abstract explicit operator short(T n);
- static abstract explicit operator int(T n);
- void M1();
- void M2();
- }
-
- public interface IInterface3 where T : IInterface3
- {
- static abstract T operator +(T left, T right);
- static virtual T operator -(T left, T right) => throw null;
- static abstract explicit operator short(T n);
- void M1();
- }
-
- public class Class11 : IInterface2, IInterface3
- {
- public static Class11 operator +(Class11 left, Class11 right) => throw null;
- public static Class11 operator -(Class11 left, Class11 right) => throw null;
- static Class11 IInterface2.operator *(Class11 left, Class11 right) => throw null;
- static Class11 IInterface2.operator /(Class11 left, Class11 right) => throw null;
- public void M1() => throw null;
- void IInterface2.M2() => throw null;
- public static explicit operator short(Class11 n) => 0;
- static explicit IInterface2.operator int(Class11 n) => 0;
- }
-
- public unsafe class MyUnsafeClass
- {
- public static void M1(delegate* f) => throw null;
- public static void M2(int*[] x) => throw null;
- public static char* M3() => throw null;
- public static void M4(int x) => throw null;
- }
-
- public enum Enum1
- {
- None1,
- Some11,
- Some12
- }
-
- public enum Enum2
- {
- None2 = 2,
- Some21 = 1,
- Some22 = 3
- }
-
- public enum Enum3
- {
- Some32,
- Some31,
- None3
- }
-
- public enum Enum4
- {
- Some41 = 7,
- None4 = 2,
- Some42 = 6
- }
-
- public enum EnumLong : long
- {
- Some = 223372036854775807,
- None = 10
- }
-}
-
-namespace A1
-{
- namespace B1
- {
-
- }
-
- public class C1 { }
-}
-
-namespace A2
-{
- namespace B2
- {
- public class C2 { }
- }
-}
-
-namespace A3
-{
- public class C3 { }
-}
-
-namespace A4
-{
- namespace B4
- {
- public class D4 { }
- }
-
- public class C4 { }
-}
\ No newline at end of file
diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected
deleted file mode 100644
index dc42176a7cb2..000000000000
--- a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected
+++ /dev/null
@@ -1 +0,0 @@
-| // This file contains auto-generated code.\n// Generated from `System.Collections, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Generic\n{\npublic class Stack : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.ICollection, System.Collections.IEnumerable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n public int Count { get => throw null; }\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public T Peek() => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.NonGeneric, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\npublic class SortedList : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.ICloneable\n{\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual object Clone() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual int Count { get => throw null; }\n public virtual object GetByIndex(int index) => throw null;\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual void Remove(object key) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.Specialized, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Specialized\n{\npublic abstract class NameObjectCollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n public virtual int Count { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public virtual void OnDeserialization(object sender) => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ComponentModel.TypeConverter, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\npublic class TypeConverter\n{\n}\n\n}\nnamespace Timers\n{\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n internal TimersDescriptionAttribute(string description, string unused) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Expressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n}\nnamespace Runtime\n{\nnamespace CompilerServices\n{\npublic class CallSite\n{\n internal CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) => throw null;\n}\n\npublic class CallSite : System.Runtime.CompilerServices.CallSite where T: class\n{\n private CallSite() : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n private CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n}\n\npublic abstract class CallSiteBinder\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Parallel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n internal ParallelQuery(System.Linq.Parallel.QuerySettings specifiedSettings) => throw null;\n}\n\nnamespace Parallel\n{\ninternal struct QuerySettings\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Queryable, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ObjectModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class TypeConverterAttribute : System.Attribute\n{\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n}\n\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Private.Uri, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n public override string ToString() => throw null;\n}\n\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Runtime.Serialization.Primitives, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Runtime\n{\nnamespace Serialization\n{\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Text.RegularExpressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Text\n{\nnamespace RegularExpressions\n{\npublic class Capture\n{\n internal Capture(string text, int index, int length) => throw null;\n public override string ToString() => throw null;\n}\n\npublic class GeneratedRegexAttribute : System.Attribute\n{\n public GeneratedRegexAttribute(string pattern) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds, string cultureName) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, string cultureName) => throw null;\n}\n\npublic class Group : System.Text.RegularExpressions.Capture\n{\n internal Group(string text, int[] caps, int capcount, string name) : base(default(string), default(int), default(int)) => throw null;\n}\n\npublic class Match : System.Text.RegularExpressions.Group\n{\n internal Match(System.Text.RegularExpressions.Regex regex, int capcount, string text, int textLength) : base(default(string), default(int[]), default(int), default(string)) => throw null;\n}\n\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n public override string ToString() => throw null;\n}\n\n[System.Flags]\npublic enum RegexOptions : int\n{\n IgnoreCase = 1,\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace System\n{\nnamespace Web\n{\npublic class HtmlString : System.Web.IHtmlString\n{\n}\n\npublic class HttpContextBase\n{\n public virtual System.Web.HttpRequestBase Request { get => throw null; }\n}\n\npublic class HttpCookie\n{\n}\n\npublic abstract class HttpCookieCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n}\n\npublic class HttpRequest\n{\n}\n\npublic class HttpRequestBase\n{\n public virtual System.Collections.Specialized.NameValueCollection QueryString { get => throw null; }\n}\n\npublic class HttpResponse\n{\n}\n\npublic class HttpResponseBase\n{\n}\n\npublic class HttpServerUtility\n{\n}\n\npublic interface IHtmlString\n{\n}\n\npublic interface IHttpHandler\n{\n}\n\npublic interface IServiceProvider\n{\n}\n\npublic class UnvalidatedRequestValues\n{\n}\n\npublic class UnvalidatedRequestValuesBase\n{\n}\n\nnamespace Mvc\n{\npublic class ActionMethodSelectorAttribute : System.Attribute\n{\n}\n\npublic class ActionResult\n{\n}\n\npublic class ControllerContext\n{\n}\n\npublic class FilterAttribute : System.Attribute\n{\n}\n\npublic class GlobalFilterCollection\n{\n}\n\ninternal interface IFilterProvider\n{\n}\n\npublic interface IViewDataContainer\n{\n}\n\npublic class ViewContext : System.Web.Mvc.ControllerContext\n{\n}\n\npublic class ViewResult : System.Web.Mvc.ViewResultBase\n{\n}\n\npublic class ViewResultBase : System.Web.Mvc.ActionResult\n{\n}\n\n}\nnamespace Routing\n{\npublic class RequestContext\n{\n}\n\npublic class Route\n{\n}\n\npublic class RouteCollection\n{\n}\n\npublic class RouteTable\n{\n}\n\n}\nnamespace Script\n{\nnamespace Serialization\n{\npublic abstract class JavaScriptTypeResolver\n{\n}\n\n}\n}\nnamespace Security\n{\npublic class MembershipUser\n{\n}\n\n}\nnamespace SessionState\n{\npublic class HttpSessionState\n{\n}\n\n}\nnamespace UI\n{\npublic class Control\n{\n}\n\nnamespace WebControls\n{\npublic class WebControl : System.Web.UI.Control\n{\n}\n\n}\n}\n}\n}\n\n\n |
diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref
deleted file mode 100644
index 53cbcd647b7a..000000000000
--- a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Stubs/MinimalStubsFromSource.ql
diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs b/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs
deleted file mode 100644
index b3f4aca07c1e..000000000000
--- a/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using System;
-using System.IO;
-using System.Text;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.UI.WebControls;
-using System.Text.RegularExpressions;
-
-public class RegexHandler
-{
- private static readonly string JAVA_CLASS_REGEX = "^(([a-z])+.)+[A-Z]([a-z])+$";
-
- public void ProcessRequest()
- {
- string userInput = "";
-
- // BAD:
- // Artificial regexes
- new Regex("^([a-z]+)+$").Match(userInput);
- new Regex("^([a-z]*)*$").Replace(userInput, "");
- // Known exponential blowup regex for e-mail address validation
- // Problematic part is: ([a-zA-Z0-9]+))*
- new Regex("^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$").Match(userInput);
- // Known exponential blowup regex for Java class name validation
- // Problematic part is: (([a-z])+.)+
- new Regex(JAVA_CLASS_REGEX).Match(userInput);
- // Static use
- Regex.Match(userInput, JAVA_CLASS_REGEX);
- // GOOD:
- new Regex("^(([a-b]+[c-z]+)+$").Match(userInput);
- new Regex("^([a-z]+)+$", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)).Match(userInput);
- Regex.Match(userInput, JAVA_CLASS_REGEX, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1));
- // Known possible FP.
- new Regex("^[a-z0-9]+([_.-][a-z0-9]+)*$").Match(userInput);
- }
-}
-
-// The only purpose of this class is to make sure the extractor extracts the
-// relevant library methods
-public class LibraryTypeDataFlow
-{
- void M()
- {
- int i;
- int.Parse("");
- int.TryParse("", out i);
-
- bool b;
- bool.Parse("");
- bool.TryParse("", out b);
-
- Uri uri = null;
- uri.ToString();
-
- StringReader sr = new StringReader("");
-
- string s = new string(new[] { 'a' });
- string.Join("", "", "", "");
-
- StringBuilder sb = new StringBuilder("");
-
- Lazy l = new Lazy(() => 42);
-
- IEnumerable ie = null;
- ie.GetEnumerator();
- ie.AsParallel();
- ie.AsQueryable();
- IEnumerable ieint = null;
- ieint.Select(x => x);
- List list = null;
- list.Find(x => x > 0);
- Stack stack = null;
- stack.Peek();
- ArrayList al = null;
- ArrayList.FixedSize(al);
- SortedList sl = null;
- sl.GetByIndex(0);
-
- Convert.ToInt32("0");
-
- DataContract dc = null;
- s = dc.AString;
-
- KeyValuePair kvp = new KeyValuePair(0, "");
-
- IEnumerator ienum = null;
- object o = ienum.Current;
-
- IEnumerator ienumint = null;
- i = ienumint.Current;
-
- var task = new Task(() => { });
- Task.WhenAll(null, null);
- Task.WhenAny(null, null);
- Task.Factory.ContinueWhenAll((Task[])null, (Func)null);
-
- var task2 = new Task(() => 42);
- Task.Factory.ContinueWhenAny(new Task[] { task2 }, t => t.Result.ToString());
-
- Encoding.Unicode.GetString(Encoding.Unicode.GetBytes(""));
-
- Path.Combine("", "");
- Path.GetDirectoryName("");
- Path.GetExtension("");
- Path.GetFileName("");
- Path.GetFileNameWithoutExtension("");
- Path.GetPathRoot("");
- HttpContextBase context = null;
- string name = context.Request.QueryString["name"];
- }
-
- [DataContract]
- public class DataContract
- {
- [DataMember]
- public string AString { get; set; }
- }
-}
diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/options b/csharp/ql/test/query-tests/Stubs/Minimal/options
deleted file mode 100644
index 52687b5cf455..000000000000
--- a/csharp/ql/test/query-tests/Stubs/Minimal/options
+++ /dev/null
@@ -1 +0,0 @@
-semmle-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll
diff --git a/csharp/ql/test/query-tests/Stubs/References/Test.cs b/csharp/ql/test/query-tests/Stubs/References/Test.cs
deleted file mode 100644
index e73d69497d2e..000000000000
--- a/csharp/ql/test/query-tests/Stubs/References/Test.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Test
-{
- public class Class1
- {
- }
-}
diff --git a/csharp/ql/test/query-tests/Stubs/References/files.expected b/csharp/ql/test/query-tests/Stubs/References/files.expected
deleted file mode 100644
index 2a197bd49aed..000000000000
--- a/csharp/ql/test/query-tests/Stubs/References/files.expected
+++ /dev/null
@@ -1 +0,0 @@
-| Test.cs:0:0:0:0 | Test.cs |
diff --git a/csharp/ql/test/query-tests/Stubs/References/files.ql b/csharp/ql/test/query-tests/Stubs/References/files.ql
deleted file mode 100644
index bea5557a25f1..000000000000
--- a/csharp/ql/test/query-tests/Stubs/References/files.ql
+++ /dev/null
@@ -1,5 +0,0 @@
-import csharp
-
-from File f
-where f.fromSource()
-select f
diff --git a/csharp/ql/test/query-tests/Stubs/References/options b/csharp/ql/test/query-tests/Stubs/References/options
deleted file mode 100644
index d469ae7afb88..000000000000
--- a/csharp/ql/test/query-tests/Stubs/References/options
+++ /dev/null
@@ -1,3 +0,0 @@
-semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
-semmle-extractor-options: /nostdlib
-semmle-extractor-options: /noconfig
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs
index 616385358b97..da6e78c128b4 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs
@@ -6,6 +6,7 @@ namespace AspNetCore
{
namespace Authorization
{
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class AllowAnonymousAttribute : System.Attribute, Microsoft.AspNetCore.Authorization.IAllowAnonymous
{
public AllowAnonymousAttribute() => throw null;
@@ -120,6 +121,7 @@ public static partial class AuthorizationServiceExtensions
public static System.Threading.Tasks.Task AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService service, System.Security.Claims.ClaimsPrincipal user, Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) => throw null;
public static System.Threading.Tasks.Task AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService service, System.Security.Claims.ClaimsPrincipal user, string policyName) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class AuthorizeAttribute : System.Attribute, Microsoft.AspNetCore.Authorization.IAuthorizeData
{
public string AuthenticationSchemes { get => throw null; set { } }
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs
index 042e1a767545..b8b7c67eb2ae 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs
@@ -6,6 +6,7 @@ namespace AspNetCore
{
namespace Components
{
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)]
public sealed class BindInputElementAttribute : System.Attribute
{
public string ChangeAttribute { get => throw null; }
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs
index 5015bd3a9f98..518725e9c7d5 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs
@@ -73,6 +73,7 @@ public static class BindConverter
public static bool TryConvertToTimeOnly(object obj, System.Globalization.CultureInfo culture, out System.TimeOnly value) => throw null;
public static bool TryConvertToTimeOnly(object obj, System.Globalization.CultureInfo culture, string format, out System.TimeOnly value) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)]
public sealed class BindElementAttribute : System.Attribute
{
public string ChangeAttribute { get => throw null; }
@@ -81,11 +82,13 @@ public sealed class BindElementAttribute : System.Attribute
public string Suffix { get => throw null; }
public string ValueAttribute { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public sealed class CascadingParameterAttribute : System.Attribute
{
public CascadingParameterAttribute() => throw null;
public string Name { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = false)]
public sealed class CascadingTypeParameterAttribute : System.Attribute
{
public CascadingTypeParameterAttribute(string name) => throw null;
@@ -161,6 +164,7 @@ public class DynamicComponent : Microsoft.AspNetCore.Components.IComponent
public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) => throw null;
public System.Type Type { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false)]
public sealed class EditorRequiredAttribute : System.Attribute
{
public EditorRequiredAttribute() => throw null;
@@ -300,6 +304,7 @@ public struct EventCallbackWorkItem
public static readonly Microsoft.AspNetCore.Components.EventCallbackWorkItem Empty;
public System.Threading.Tasks.Task InvokeAsync(object arg) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)]
public sealed class EventHandlerAttribute : System.Attribute
{
public string AttributeName { get => throw null; }
@@ -336,6 +341,7 @@ public class ComponentStatePersistenceManager
public Microsoft.AspNetCore.Components.PersistentComponentState State { get => throw null; }
}
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public sealed class InjectAttribute : System.Attribute
{
public InjectAttribute() => throw null;
@@ -345,6 +351,7 @@ public interface IPersistentComponentStateStore
System.Threading.Tasks.Task> GetPersistedStateAsync();
System.Threading.Tasks.Task PersistStateAsync(System.Collections.Generic.IReadOnlyDictionary state);
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public sealed class LayoutAttribute : System.Attribute
{
public LayoutAttribute(System.Type layoutType) => throw null;
@@ -447,6 +454,7 @@ public abstract class OwningComponentBase : Microsoft.AspNetCore.Compo
protected OwningComponentBase() => throw null;
protected TService Service { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public sealed class ParameterAttribute : System.Attribute
{
public bool CaptureUnmatchedValues { get => throw null; set { } }
@@ -647,6 +655,7 @@ public enum RenderTreeFrameType : short
Markup = 8,
}
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = false)]
public sealed class RouteAttribute : System.Attribute
{
public RouteAttribute(string template) => throw null;
@@ -714,6 +723,7 @@ public class Router : Microsoft.AspNetCore.Components.IComponent, System.IDispos
public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) => throw null;
}
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public sealed class SupplyParameterFromQueryAttribute : System.Attribute
{
public SupplyParameterFromQueryAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs
index ccee0b3f9915..11e0b379bbb6 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs
@@ -25,10 +25,12 @@ public class CorsPolicyMetadata : Microsoft.AspNetCore.Cors.Infrastructure.ICors
public CorsPolicyMetadata(Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy policy) => throw null;
public Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy Policy { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = false)]
public class DisableCorsAttribute : System.Attribute, Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.IDisableCorsAttribute
{
public DisableCorsAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class EnableCorsAttribute : System.Attribute, Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.IEnableCorsAttribute
{
public EnableCorsAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs
index e03088e509dd..ccc28330ad79 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs
@@ -34,6 +34,7 @@ public static partial class HostingEnvironmentExtensions
public static bool IsProduction(this Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment) => throw null;
public static bool IsStaging(this Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = true)]
public sealed class HostingStartupAttribute : System.Attribute
{
public HostingStartupAttribute(System.Type hostingStartupType) => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs
index 392bccee3da1..9b767d8e4732 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs
@@ -105,6 +105,7 @@ public interface ICorsMetadata
}
namespace Http
{
+ [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false, AllowMultiple = false)]
public sealed class AsParametersAttribute : System.Attribute
{
public AsParametersAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs
index b6f38080c296..51d392fd4711 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs
@@ -6,11 +6,13 @@ namespace AspNetCore
{
namespace Http
{
+ [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)]
public sealed class EndpointDescriptionAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IEndpointDescriptionMetadata
{
public EndpointDescriptionAttribute(string description) => throw null;
public string Description { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)]
public sealed class EndpointSummaryAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IEndpointSummaryMetadata
{
public EndpointSummaryAttribute(string summary) => throw null;
@@ -195,6 +197,7 @@ public static partial class SessionExtensions
public static void SetInt32(this Microsoft.AspNetCore.Http.ISession session, string key, int value) => throw null;
public static void SetString(this Microsoft.AspNetCore.Http.ISession session, string key, string value) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4164, Inherited = false, AllowMultiple = false)]
public sealed class TagsAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.ITagsMetadata
{
public TagsAttribute(params string[] tags) => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs
index 2b69a8d7dd77..8f413e6dcdad 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs
@@ -67,6 +67,7 @@ public class AcceptedResult : Microsoft.AspNetCore.Mvc.ObjectResult
public string Location { get => throw null; set { } }
public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = true, Inherited = true)]
public sealed class AcceptVerbsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider
{
public AcceptVerbsAttribute(string method) => throw null;
@@ -80,6 +81,7 @@ public sealed class AcceptVerbsAttribute : System.Attribute, Microsoft.AspNetCor
}
namespace ActionConstraints
{
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public abstract class ActionMethodSelectorAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata
{
public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) => throw null;
@@ -96,10 +98,12 @@ public class HttpMethodActionConstraint : Microsoft.AspNetCore.Mvc.ActionConstra
public int Order { get => throw null; }
}
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class ActionContextAttribute : System.Attribute
{
public ActionContextAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public sealed class ActionNameAttribute : System.Attribute
{
public ActionNameAttribute(string name) => throw null;
@@ -138,15 +142,18 @@ public class ApiBehaviorOptions : System.Collections.Generic.IEnumerable throw null; set { } }
public bool SuppressModelStateInvalidFilter { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)5, AllowMultiple = false, Inherited = true)]
public class ApiControllerAttribute : Microsoft.AspNetCore.Mvc.ControllerAttribute, Microsoft.AspNetCore.Mvc.Infrastructure.IApiBehaviorMetadata, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
public ApiControllerAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public sealed class ApiConventionMethodAttribute : System.Attribute
{
public System.Type ConventionType { get => throw null; }
public ApiConventionMethodAttribute(System.Type conventionType, string methodName) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)5, AllowMultiple = true, Inherited = true)]
public sealed class ApiConventionTypeAttribute : System.Attribute
{
public System.Type ConventionType { get => throw null; }
@@ -159,6 +166,7 @@ public class ApiDescriptionActionData
}
namespace ApiExplorer
{
+ [System.AttributeUsage((System.AttributeTargets)2112, AllowMultiple = false, Inherited = false)]
public sealed class ApiConventionNameMatchAttribute : System.Attribute
{
public ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior matchBehavior) => throw null;
@@ -176,6 +184,7 @@ public sealed class ApiConventionResult
public ApiConventionResult(System.Collections.Generic.IReadOnlyList responseMetadataProviders) => throw null;
public System.Collections.Generic.IReadOnlyList ResponseMetadataProviders { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)]
public sealed class ApiConventionTypeMatchAttribute : System.Attribute
{
public ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior matchBehavior) => throw null;
@@ -216,6 +225,7 @@ public interface IApiResponseTypeMetadataProvider
System.Collections.Generic.IReadOnlyList GetSupportedContentTypes(string contentType, System.Type objectType);
}
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class ApiExplorerSettingsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupNameProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionVisibilityProvider
{
public ApiExplorerSettingsAttribute() => throw null;
@@ -442,6 +452,7 @@ public abstract class ApplicationPart
protected ApplicationPart() => throw null;
public abstract string Name { get; }
}
+ [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)]
public sealed class ApplicationPartAttribute : System.Attribute
{
public string AssemblyName { get => throw null; }
@@ -494,12 +505,14 @@ public class NullApplicationPartFactory : Microsoft.AspNetCore.Mvc.ApplicationPa
public NullApplicationPartFactory() => throw null;
public override System.Collections.Generic.IEnumerable GetApplicationParts(System.Reflection.Assembly assembly) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)]
public sealed class ProvideApplicationPartFactoryAttribute : System.Attribute
{
public ProvideApplicationPartFactoryAttribute(System.Type factoryType) => throw null;
public ProvideApplicationPartFactoryAttribute(string factoryTypeName) => throw null;
public System.Type GetFactoryType() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)]
public sealed class RelatedAssemblyAttribute : System.Attribute
{
public string AssemblyFileName { get => throw null; }
@@ -507,6 +520,7 @@ public sealed class RelatedAssemblyAttribute : System.Attribute
public static System.Collections.Generic.IReadOnlyList GetRelatedAssemblies(System.Reflection.Assembly assembly, bool throwOnError) => throw null;
}
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class AreaAttribute : Microsoft.AspNetCore.Mvc.Routing.RouteValueAttribute
{
public AreaAttribute(string areaName) : base(default(string), default(string)) => throw null;
@@ -541,6 +555,7 @@ public class BadRequestResult : Microsoft.AspNetCore.Mvc.StatusCodeResult
{
public BadRequestResult() : base(default(int)) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)2052, AllowMultiple = false, Inherited = true)]
public class BindAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider
{
public BindAttribute(params string[] include) => throw null;
@@ -549,11 +564,13 @@ public class BindAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBin
public string Prefix { get => throw null; set { } }
public System.Func PropertyFilter { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class BindPropertiesAttribute : System.Attribute
{
public BindPropertiesAttribute() => throw null;
public bool SupportsGet { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class BindPropertyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBinderTypeProviderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IRequestPredicateProvider
{
public System.Type BinderType { get => throw null; set { } }
@@ -607,6 +624,7 @@ public class ConflictResult : Microsoft.AspNetCore.Mvc.StatusCodeResult
{
public ConflictResult() : base(default(int)) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class ConsumesAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IAcceptsMetadata, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiRequestMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IResourceFilter
{
public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) => throw null;
@@ -630,6 +648,7 @@ public class ContentResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.As
public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null;
public int? StatusCode { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class ControllerAttribute : System.Attribute
{
public ControllerAttribute() => throw null;
@@ -817,6 +836,7 @@ public class ControllerContext : Microsoft.AspNetCore.Mvc.ActionContext
public ControllerContext(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null;
public virtual System.Collections.Generic.IList ValueProviderFactories { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class ControllerContextAttribute : System.Attribute
{
public ControllerContextAttribute() => throw null;
@@ -1237,6 +1257,7 @@ public struct Enumerator : System.IDisposable, System.Collections.Generic.IEnume
protected abstract System.Collections.Generic.KeyValuePair this[int index] { get; }
}
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class DisableRequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -1275,6 +1296,7 @@ public class FileStreamResult : Microsoft.AspNetCore.Mvc.FileResult
}
namespace Filters
{
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public abstract class ActionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter
{
protected ActionFilterAttribute() => throw null;
@@ -1286,6 +1308,7 @@ public abstract class ActionFilterAttribute : System.Attribute, Microsoft.AspNet
public virtual System.Threading.Tasks.Task OnResultExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext context, Microsoft.AspNetCore.Mvc.Filters.ResultExecutionDelegate next) => throw null;
public int Order { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public abstract class ExceptionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
protected ExceptionFilterAttribute() => throw null;
@@ -1313,6 +1336,7 @@ public static class FilterScope
public static readonly int Global;
public static readonly int Last;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public abstract class ResultFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter
{
protected ResultFilterAttribute() => throw null;
@@ -1334,6 +1358,7 @@ public class ForbidResult : Microsoft.AspNetCore.Mvc.ActionResult
public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null;
public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class FormatFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -1471,6 +1496,7 @@ public abstract class TextOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters.
public abstract System.Threading.Tasks.Task WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.Text.Encoding selectedEncoding);
}
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromBodyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromBodyMetadata
{
bool Microsoft.AspNetCore.Http.Metadata.IFromBodyMetadata.AllowEmpty { get => throw null; }
@@ -1478,30 +1504,35 @@ public class FromBodyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Mode
public FromBodyAttribute() => throw null;
public Microsoft.AspNetCore.Mvc.ModelBinding.EmptyBodyBehavior EmptyBodyBehavior { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromFormAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromFormMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; }
public FromFormAttribute() => throw null;
public string Name { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromHeaderAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromHeaderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; }
public FromHeaderAttribute() => throw null;
public string Name { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromQueryAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromQueryMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; }
public FromQueryAttribute() => throw null;
public string Name { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromRouteAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromRouteMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; }
public FromRouteAttribute() => throw null;
public string Name { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)]
public class FromServicesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromServiceMetadata
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; }
@@ -1565,10 +1596,12 @@ public abstract class ActionDescriptorCollectionProvider : Microsoft.AspNetCore.
protected ActionDescriptorCollectionProvider() => throw null;
public abstract Microsoft.Extensions.Primitives.IChangeToken GetChangeToken();
}
+ [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = false)]
public sealed class ActionResultObjectValueAttribute : System.Attribute
{
public ActionResultObjectValueAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)]
public sealed class ActionResultStatusCodeAttribute : System.Attribute
{
public ActionResultStatusCodeAttribute() => throw null;
@@ -1604,6 +1637,7 @@ public class DefaultOutputFormatterSelector : Microsoft.AspNetCore.Mvc.Infrastru
public DefaultOutputFormatterSelector(Microsoft.Extensions.Options.IOptions options, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) => throw null;
public override Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter SelectFormatter(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext context, System.Collections.Generic.IList formatters, Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection contentTypes) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public sealed class DefaultStatusCodeAttribute : System.Attribute
{
public DefaultStatusCodeAttribute(int statusCode) => throw null;
@@ -1813,6 +1847,7 @@ public class LocalRedirectResult : Microsoft.AspNetCore.Mvc.ActionResult
public string Url { get => throw null; set { } }
public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class MiddlewareFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public System.Type ConfigurationType { get => throw null; }
@@ -1821,6 +1856,7 @@ public class MiddlewareFilterAttribute : System.Attribute, Microsoft.AspNetCore.
public bool IsReusable { get => throw null; }
public int Order { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)2204, AllowMultiple = false, Inherited = true)]
public class ModelBinderAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBinderTypeProviderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider
{
public System.Type BinderType { get => throw null; set { } }
@@ -2065,6 +2101,7 @@ public enum BindingBehavior
Never = 1,
Required = 2,
}
+ [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)]
public class BindingBehaviorAttribute : System.Attribute
{
public Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior Behavior { get => throw null; }
@@ -2078,10 +2115,12 @@ public abstract class BindingSourceValueProvider : Microsoft.AspNetCore.Mvc.Mode
public virtual Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider Filter(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) => throw null;
public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult GetValue(string key);
}
+ [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)]
public sealed class BindNeverAttribute : Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehaviorAttribute
{
public BindNeverAttribute() : base(default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior)) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)]
public sealed class BindRequiredAttribute : Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehaviorAttribute
{
public BindRequiredAttribute() : base(default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior)) => throw null;
@@ -2583,6 +2622,7 @@ public static partial class ModelValidatorProviderExtensions
public static void RemoveType(this System.Collections.Generic.IList list) where TModelValidatorProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider => throw null;
public static void RemoveType(this System.Collections.Generic.IList list, System.Type type) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)]
public sealed class ValidateNeverAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IPropertyValidationFilter
{
public ValidateNeverAttribute() => throw null;
@@ -2633,6 +2673,7 @@ public static partial class ValueProviderFactoryExtensions
public static void RemoveType(this System.Collections.Generic.IList list, System.Type type) => throw null;
}
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class ModelMetadataTypeAttribute : System.Attribute
{
public ModelMetadataTypeAttribute(System.Type type) => throw null;
@@ -2676,14 +2717,17 @@ public class NoContentResult : Microsoft.AspNetCore.Mvc.StatusCodeResult
{
public NoContentResult() : base(default(int)) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public sealed class NonActionAttribute : System.Attribute
{
public NonActionAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public sealed class NonControllerAttribute : System.Attribute
{
public NonControllerAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class NonViewComponentAttribute : System.Attribute
{
public NonViewComponentAttribute() => throw null;
@@ -2722,6 +2766,7 @@ public class PhysicalFileResult : Microsoft.AspNetCore.Mvc.FileResult
public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null;
public string FileName { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class ProducesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter
{
public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { get => throw null; set { } }
@@ -2734,6 +2779,7 @@ public class ProducesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiE
public int StatusCode { get => throw null; }
public System.Type Type { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public sealed class ProducesDefaultResponseTypeAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDefaultResponseMetadataProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
public ProducesDefaultResponseTypeAttribute() => throw null;
@@ -2742,11 +2788,13 @@ public sealed class ProducesDefaultResponseTypeAttribute : System.Attribute, Mic
public int StatusCode { get => throw null; }
public System.Type Type { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)69, AllowMultiple = false, Inherited = true)]
public sealed class ProducesErrorResponseTypeAttribute : System.Attribute
{
public ProducesErrorResponseTypeAttribute(System.Type type) => throw null;
public System.Type Type { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class ProducesResponseTypeAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata
{
public ProducesResponseTypeAttribute(int statusCode) => throw null;
@@ -2823,6 +2871,7 @@ public class RedirectToRouteResult : Microsoft.AspNetCore.Mvc.ActionResult, Micr
public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get => throw null; set { } }
public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class RequestFormLimitsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public bool BufferBody { get => throw null; set { } }
@@ -2840,6 +2889,7 @@ public class RequestFormLimitsAttribute : System.Attribute, Microsoft.AspNetCore
public int ValueCountLimit { get => throw null; set { } }
public int ValueLengthLimit { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class RequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -2848,6 +2898,7 @@ public class RequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.
long? Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata.MaxRequestBodySize { get => throw null; }
public int Order { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, Inherited = true, AllowMultiple = false)]
public class RequireHttpsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public RequireHttpsAttribute() => throw null;
@@ -2856,6 +2907,7 @@ public class RequireHttpsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.
public int Order { get => throw null; set { } }
public bool Permanent { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class ResponseCacheAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public string CacheProfileName { get => throw null; set { } }
@@ -2876,6 +2928,7 @@ public enum ResponseCacheLocation
Client = 1,
None = 2,
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class RouteAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider
{
public RouteAttribute(string template) => throw null;
@@ -2893,6 +2946,7 @@ public abstract class DynamicRouteValueTransformer
public object State { get => throw null; set { } }
public abstract System.Threading.Tasks.ValueTask TransformAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary values);
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = true, Inherited = true)]
public abstract class HttpMethodAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider
{
public HttpMethodAttribute(System.Collections.Generic.IEnumerable httpMethods) => throw null;
@@ -2927,6 +2981,7 @@ public class KnownRouteValueConstraint : Microsoft.AspNetCore.Routing.IParameter
public KnownRouteValueConstraint(Microsoft.AspNetCore.Mvc.Infrastructure.IActionDescriptorCollectionProvider actionDescriptorCollectionProvider) => throw null;
public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public abstract class RouteValueAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteValueProvider
{
protected RouteValueAttribute(string routeKey, string routeValue) => throw null;
@@ -2968,6 +3023,7 @@ public sealed class SerializableError : System.Collections.Generic.Dictionary throw null;
public SerializableError(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class ServiceFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -3007,6 +3063,7 @@ public class StatusCodeResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft
public int StatusCode { get => throw null; }
int? Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult.StatusCode { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)]
public class TypeFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public object[] Arguments { get => throw null; set { } }
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs
index 0095fefebbf8..41e0d9290a84 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs
@@ -53,6 +53,7 @@ public abstract class ValidationProviderAttribute : System.Attribute
public abstract System.Collections.Generic.IEnumerable GetValidationAttributes();
}
}
+ [System.AttributeUsage((System.AttributeTargets)132, AllowMultiple = false, Inherited = true)]
public sealed class HiddenInputAttribute : System.Attribute
{
public HiddenInputAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs
index 6a400b960cc0..87d84d8ed604 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs
@@ -79,6 +79,7 @@ public interface IViewCompilerProvider
{
Microsoft.AspNetCore.Mvc.Razor.Compilation.IViewCompiler GetCompiler();
}
+ [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)]
public class RazorViewAttribute : System.Attribute
{
public RazorViewAttribute(string path, System.Type viewType) => throw null;
@@ -107,6 +108,7 @@ public sealed class TagHelperMemoryCacheProvider
}
namespace Internal
{
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class RazorInjectAttribute : System.Attribute
{
public RazorInjectAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs
index cde917a0ddeb..7cc84bb8b970 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs
@@ -400,6 +400,7 @@ public abstract class PageLoader : Microsoft.AspNetCore.Mvc.RazorPages.Infrastru
public abstract System.Threading.Tasks.Task LoadAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor);
public virtual System.Threading.Tasks.Task LoadAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.EndpointMetadataCollection endpointMetadata) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class PageModelAttribute : System.Attribute
{
public PageModelAttribute() => throw null;
@@ -464,6 +465,7 @@ public interface IPageModelFactoryProvider
System.Action CreateModelDisposer(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor descriptor);
System.Func CreateModelFactory(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor descriptor);
}
+ [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)]
public class NonHandlerAttribute : System.Attribute
{
public NonHandlerAttribute() => throw null;
@@ -604,6 +606,7 @@ public class PageContext : Microsoft.AspNetCore.Mvc.ActionContext
public virtual Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; set { } }
public virtual System.Collections.Generic.IList> ViewStartFactories { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class PageContextAttribute : System.Attribute
{
public PageContextAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs
index 64af1faa7eb7..4303910db3ac 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs
@@ -6,6 +6,7 @@ namespace AspNetCore
{
namespace Mvc
{
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class AutoValidateAntiforgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -130,6 +131,7 @@ public sealed class ViewNotFoundEventData : Microsoft.AspNetCore.Mvc.Diagnostics
public string ViewName { get => throw null; }
}
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class IgnoreAntiforgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public IgnoreAntiforgeryTokenAttribute() => throw null;
@@ -165,6 +167,7 @@ public class MvcViewOptions : System.Collections.Generic.IEnumerable throw null; set { } }
public System.Collections.Generic.IList ViewEngines { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class PageRemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase
{
public PageRemoteAttribute() => throw null;
@@ -184,6 +187,7 @@ public class PartialViewResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsof
public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { get => throw null; set { } }
public string ViewName { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class RemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase
{
protected RemoteAttribute() => throw null;
@@ -193,6 +197,7 @@ public class RemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase
protected override string GetUrl(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context) => throw null;
protected string RouteName { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public abstract class RemoteAttributeBase : System.ComponentModel.DataAnnotations.ValidationAttribute, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidator
{
public string AdditionalFields { get => throw null; set { } }
@@ -608,17 +613,20 @@ public class ViewContext : Microsoft.AspNetCore.Mvc.ActionContext
public System.IO.TextWriter Writer { get => throw null; set { } }
}
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class SkipStatusCodePagesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IResourceFilter, Microsoft.AspNetCore.Http.Metadata.ISkipStatusCodePagesMetadata
{
public SkipStatusCodePagesAttribute() => throw null;
public void OnResourceExecuted(Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext context) => throw null;
public void OnResourceExecuting(Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext context) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)128, Inherited = true, AllowMultiple = false)]
public sealed class TempDataAttribute : System.Attribute
{
public TempDataAttribute() => throw null;
public string Key { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -648,6 +656,7 @@ public abstract class ViewComponent
public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; }
public Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine ViewEngine { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)]
public class ViewComponentAttribute : System.Attribute
{
public ViewComponentAttribute() => throw null;
@@ -762,6 +771,7 @@ public class ViewComponentContext
public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; }
public System.IO.TextWriter Writer { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class ViewComponentContextAttribute : System.Attribute
{
public ViewComponentContextAttribute() => throw null;
@@ -811,6 +821,7 @@ public class ViewViewComponentResult : Microsoft.AspNetCore.Mvc.IViewComponentRe
public string ViewName { get => throw null; set { } }
}
}
+ [System.AttributeUsage((System.AttributeTargets)128, Inherited = true, AllowMultiple = false)]
public sealed class ViewDataAttribute : System.Attribute
{
public ViewDataAttribute() => throw null;
@@ -1212,6 +1223,7 @@ public class PartialViewResultExecutor : Microsoft.AspNetCore.Mvc.ViewFeatures.V
public virtual Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult FindView(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.PartialViewResult viewResult) => throw null;
protected Microsoft.Extensions.Logging.ILogger Logger { get => throw null; }
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public class SaveTempDataAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter
{
public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null;
@@ -1288,6 +1300,7 @@ public class ViewComponentResultExecutor : Microsoft.AspNetCore.Mvc.Infrastructu
public ViewComponentResultExecutor(Microsoft.Extensions.Options.IOptions mvcHelperOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory tempDataDictionaryFactory, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory) => throw null;
public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.ViewComponentResult result) => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class ViewContextAttribute : System.Attribute
{
public ViewContextAttribute() => throw null;
@@ -1334,6 +1347,7 @@ public class ViewDataDictionary : Microsoft.AspNetCore.Mvc.ViewFeatures.
public ViewDataDictionary(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary source, object model) : base(default(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)) => throw null;
public TModel Model { get => throw null; set { } }
}
+ [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)]
public class ViewDataDictionaryAttribute : System.Attribute
{
public ViewDataDictionaryAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs
index 0ad5295bbef6..d0928b92469f 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs
@@ -39,6 +39,7 @@ public interface IOutputCacheStore
System.Threading.Tasks.ValueTask GetAsync(string key, System.Threading.CancellationToken cancellationToken);
System.Threading.Tasks.ValueTask SetAsync(string key, byte[] value, string[] tags, System.TimeSpan validFor, System.Threading.CancellationToken cancellationToken);
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public sealed class OutputCacheAttribute : System.Attribute
{
public OutputCacheAttribute() => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs
index 6fa8fb2c1156..f12f92bec5a5 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs
@@ -24,10 +24,12 @@ public static partial class RateLimiterServiceCollectionExtensions
}
namespace RateLimiting
{
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public sealed class DisableRateLimitingAttribute : System.Attribute
{
public DisableRateLimitingAttribute() => throw null;
}
+ [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)]
public sealed class EnableRateLimitingAttribute : System.Attribute
{
public EnableRateLimitingAttribute(string policyName) => throw null;
diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs
index 58ade22f1eb5..fcb7e1de4f1e 100644
--- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs
+++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs
@@ -22,6 +22,7 @@ public abstract class RazorCompiledItem
public abstract System.Collections.Generic.IReadOnlyList